mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Make it possible to inherit from any constructable host object
This CL makes it possible for authors to extend any host object (e.g., DOM objects) and to use those objects in all the usual places they can be used in the API. R=esprehn@chromium.org Review URL: https://codereview.chromium.org/936193005
This commit is contained in:
parent
74290d5007
commit
f562073fe2
@ -106,7 +106,7 @@ def argument_context(interface, method, argument, index):
|
||||
idl_type = argument.idl_type
|
||||
this_cpp_value = cpp_value(interface, method, index)
|
||||
auto_scope = not 'DartNoAutoScope' in extended_attributes
|
||||
arg_index = index + 1 if not (method.is_static or method.is_constructor) else index
|
||||
arg_index = index + 1 if not method.is_static else index
|
||||
preprocessed_type = str(idl_type.preprocessed_type)
|
||||
local_cpp_type = idl_type.cpp_type_args(argument.extended_attributes, raw_type=True)
|
||||
default_value = argument.default_cpp_value
|
||||
|
||||
@ -19,16 +19,17 @@ part of sky.core;
|
||||
{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
abstract class {{interface_name}} extends {{ parent_interface if parent_interface else 'NativeFieldWrapperClass2' }} {
|
||||
{% if not constructors %}abstract {% endif -%}
|
||||
class {{interface_name}} extends {{ parent_interface if parent_interface else 'NativeFieldWrapperClass2' }} {
|
||||
// Constructors
|
||||
{# TODO(eseidel): We only ever have one constructor. #}
|
||||
{%- for constructor in constructors -%}
|
||||
static {{interface_name}} _constructor({{ args_macro(constructor.arguments) }}) native "{{interface_name}}_constructorCallback";
|
||||
factory {{interface_name}}({{ args_macro(constructor.arguments) }}) => _constructor(
|
||||
{%- for constructor in constructors %}
|
||||
void _constructor({{ args_macro(constructor.arguments) }}) native "{{interface_name}}_constructorCallback";
|
||||
{{interface_name}}({{ args_macro(constructor.arguments) }}) { _constructor(
|
||||
{%- for arg in constructor.arguments -%}
|
||||
{{ arg.name }}{% if not loop.last %}, {% endif %}
|
||||
{%- endfor -%}
|
||||
);
|
||||
); }
|
||||
{% endfor %}
|
||||
|
||||
// Attributes
|
||||
|
||||
@ -335,7 +335,7 @@ static void {{static_method_name(constructor.name, overload_index)}}(Dart_Native
|
||||
ExceptionState es;
|
||||
{% endif %}
|
||||
{{generate_arguments(constructor) | indent(8)}}
|
||||
{{callback_return(constructor, constructor.dart_set_return_value, constructor.cpp_value) | indent(8)}}
|
||||
{{constructor.cpp_value}}->AssociateWithDartWrapper(args);
|
||||
{% if constructor.has_exception_state %}
|
||||
if (es.had_exception()) {
|
||||
exception = es.GetDartException(args, {{constructor.auto_scope}});
|
||||
@ -368,6 +368,8 @@ static void eventConstructorCallback(Dart_NativeArguments args)
|
||||
{% macro generate_resolver_constructor(dart_class, class_name, constructor) %}
|
||||
{% for native_entry in constructor.native_entries %}
|
||||
{% set resolver_string = native_entry.resolver_string %}
|
||||
{% set args_one_based = constructor.number_of_arguments + 1 %}
|
||||
{% set args_required_one_based = constructor.number_of_required_arguments + 1 %}
|
||||
{% if constructor.overload_index %}
|
||||
{% set constructor_name = static_method_name(constructor.name) + "Dispatcher" %}
|
||||
{% else %}
|
||||
@ -376,9 +378,9 @@ static void eventConstructorCallback(Dart_NativeArguments args)
|
||||
{% if has_custom_constructor %}
|
||||
if (name == "{{resolver_string}}") {
|
||||
{% elif constructor.number_of_arguments == constructor.number_of_required_arguments %}
|
||||
if (argumentCount == {{constructor.number_of_arguments}} && name == "{{resolver_string}}") {
|
||||
if (argumentCount == {{args_one_based}} && name == "{{resolver_string}}") {
|
||||
{% else %}
|
||||
if (argumentCount >= {{constructor.number_of_required_arguments}} && argumentCount <= {{constructor.number_of_arguments}} && name == "{{resolver_string}}") {
|
||||
if (argumentCount >= {{args_required_one_based}} && argumentCount <= {{args_one_based}} && name == "{{resolver_string}}") {
|
||||
{% endif %}
|
||||
*autoSetupScope = {{constructor.auto_scope}};
|
||||
return {{dart_class}}Internal::{{constructor_name}};
|
||||
|
||||
@ -41,6 +41,29 @@ Dart_Handle DartWrappable::CreateDartWrapper(DartState* dart_state) {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
void DartWrappable::AssociateWithDartWrapper(Dart_NativeArguments args) {
|
||||
DCHECK(!dart_wrapper_);
|
||||
|
||||
Dart_Handle wrapper = Dart_GetNativeArgument(args, 0);
|
||||
CHECK(!LogIfError(wrapper));
|
||||
|
||||
intptr_t native_fields[kNumberOfNativeFields];
|
||||
CHECK(!LogIfError(Dart_GetNativeFieldsOfArgument(
|
||||
args, 0, kNumberOfNativeFields, native_fields)));
|
||||
CHECK(!native_fields[kPeerIndex]);
|
||||
CHECK(!native_fields[kWrapperInfoIndex]);
|
||||
|
||||
const DartWrapperInfo& info = GetDartWrapperInfo();
|
||||
CHECK(!LogIfError(Dart_SetNativeInstanceField(
|
||||
wrapper, kPeerIndex, reinterpret_cast<intptr_t>(this))));
|
||||
CHECK(!LogIfError(Dart_SetNativeInstanceField(
|
||||
wrapper, kWrapperInfoIndex, reinterpret_cast<intptr_t>(&info))));
|
||||
|
||||
info.ref_object(this); // Balanced in FinalizeDartWrapper.
|
||||
dart_wrapper_ = Dart_NewPrologueWeakPersistentHandle(
|
||||
wrapper, this, info.size_in_bytes, &FinalizeDartWrapper);
|
||||
}
|
||||
|
||||
void DartWrappable::FinalizeDartWrapper(void* isolate_callback_data,
|
||||
Dart_WeakPersistentHandle wrapper,
|
||||
void* peer) {
|
||||
|
||||
@ -40,6 +40,7 @@ class DartWrappable {
|
||||
virtual void AcceptDartGCVisitor(DartGCVisitor& visitor) const;
|
||||
|
||||
Dart_Handle CreateDartWrapper(DartState* dart_state);
|
||||
void AssociateWithDartWrapper(Dart_NativeArguments args);
|
||||
Dart_WeakPersistentHandle dart_wrapper() const { return dart_wrapper_; }
|
||||
|
||||
protected:
|
||||
@ -133,7 +134,7 @@ struct DartConverter<RefPtr<T>> {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static T* GetReceiver(Dart_NativeArguments args) {
|
||||
inline T* GetReceiver(Dart_NativeArguments args) {
|
||||
intptr_t receiver;
|
||||
Dart_Handle result = Dart_GetNativeReceiver(args, &receiver);
|
||||
DCHECK(!Dart_IsError(result));
|
||||
|
||||
6
tests/dom/inherit-from-text-expected.txt
Normal file
6
tests/dom/inherit-from-text-expected.txt
Normal file
@ -0,0 +1,6 @@
|
||||
CONSOLE: unittest-suite-wait-for-done
|
||||
CONSOLE: PASS: should be able to insert in DOM
|
||||
CONSOLE:
|
||||
CONSOLE: All 1 tests passed.
|
||||
CONSOLE: unittest-suite-success
|
||||
DONE
|
||||
31
tests/dom/inherit-from-text.sky
Normal file
31
tests/dom/inherit-from-text.sky
Normal file
@ -0,0 +1,31 @@
|
||||
<sky>
|
||||
<script>
|
||||
import "../resources/third_party/unittest/unittest.dart";
|
||||
import "../resources/unit.dart";
|
||||
|
||||
import "dart:sky";
|
||||
|
||||
class CustomText extends Text {
|
||||
CustomText() : super("awesome");
|
||||
|
||||
bool get isCustom => true;
|
||||
}
|
||||
|
||||
void main() {
|
||||
initUnit();
|
||||
|
||||
test("should be able to insert in DOM", () {
|
||||
var child = new CustomText();
|
||||
expect(child.isCustom, isTrue);
|
||||
expect(child.parentNode, isNull);
|
||||
expect(child.data, equals("awesome"));
|
||||
|
||||
var parent = document.createElement("div");
|
||||
parent.appendChild(child);
|
||||
expect(child.parentNode, equals(parent));
|
||||
expect(parent.firstChild, equals(child));
|
||||
expect(parent.firstChild.isCustom, isTrue);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</sky>
|
||||
Loading…
x
Reference in New Issue
Block a user