Index: sdk/lib/_internal/compiler/implementation/native_handler.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart |
index 124c173dd0ea642af88b82047b89608865fb6639..ee8c27794ef7da39997b42f1e5275e55de82eb3c 100644 |
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart |
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart |
@@ -35,18 +35,15 @@ class NativeEnqueuer { |
/// Initial entry point to native enqueuer. |
void processNativeClasses(Collection<LibraryElement> libraries) {} |
- /// Notification of a main Enqueuer worklist element. For methods, adds |
- /// information from metadata attributes, and computes types instantiated due |
- /// to calling the method. |
void registerElement(Element element) {} |
- /// Notification of native field. Adds information from metadata attributes. |
- void registerField(Element field) {} |
+ /// Method is a member of a native class. |
+ void registerMethod(Element method) {} |
- /// Computes types instantiated due to getting a native field. |
+ /// Compute types instantiated due to getting a native field. |
void registerFieldLoad(Element field) {} |
- /// Computes types instantiated due to setting a native field. |
+ /// Compute types instantiated due to setting a native field. |
void registerFieldStore(Element field) {} |
/** |
@@ -96,7 +93,6 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
ClassElement _annotationCreatesClass; |
ClassElement _annotationReturnsClass; |
- ClassElement _annotationJsNameClass; |
/// Subclasses of [NativeEnqueuerBase] are constructed by the backend. |
NativeEnqueuerBase(this.world, this.compiler, this.enableLiveTypeAnalysis); |
@@ -126,22 +122,16 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
} |
ClassElement get annotationCreatesClass { |
- findAnnotationClasses(); |
+ if (_annotationCreatesClass == null) findAnnotationClasses(); |
return _annotationCreatesClass; |
} |
ClassElement get annotationReturnsClass { |
- findAnnotationClasses(); |
+ if (_annotationReturnsClass == null) findAnnotationClasses(); |
return _annotationReturnsClass; |
} |
- ClassElement get annotationJsNameClass { |
- findAnnotationClasses(); |
- return _annotationJsNameClass; |
- } |
- |
void findAnnotationClasses() { |
- if (_annotationCreatesClass != null) return; |
ClassElement find(name) { |
Element e = compiler.findHelper(name); |
if (e == null || e is! ClassElement) { |
@@ -151,41 +141,8 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
} |
_annotationCreatesClass = find(const SourceString('Creates')); |
_annotationReturnsClass = find(const SourceString('Returns')); |
- _annotationJsNameClass = find(const SourceString('JSName')); |
} |
- /// Returns the JSName annotation string or `null` if no JSName annotation is |
- /// present. |
- String findJsNameFromAnnotation(Element element) { |
- String name = null; |
- ClassElement annotationClass = annotationJsNameClass; |
- for (Link<MetadataAnnotation> link = element.metadata; |
- !link.isEmpty; |
- link = link.tail) { |
- MetadataAnnotation annotation = link.head.ensureResolved(compiler); |
- var value = annotation.value; |
- if (value is! ConstructedConstant) continue; |
- if (value.type is! InterfaceType) continue; |
- if (!identical(value.type.element, annotationClass)) continue; |
- |
- var fields = value.fields; |
- // TODO(sra): Better validation of the constant. |
- if (fields.length != 1 || fields[0] is! StringConstant) { |
- PartialMetadataAnnotation partial = annotation; |
- compiler.cancel( |
- 'Annotations needs one string: ${partial.parseNode(compiler)}'); |
- } |
- String specString = fields[0].toDartString().slowToString(); |
- if (name == null) { |
- name = specString; |
- } else { |
- PartialMetadataAnnotation partial = annotation; |
- compiler.cancel( |
- 'Too many JSName annotations: ${partial.parseNode(compiler)}'); |
- } |
- } |
- return name; |
- } |
enqueueClass(ClassElement classElement, cause) { |
assert(unusedClasses.contains(classElement)); |
@@ -225,15 +182,8 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
if (element.isFunction()) return registerMethod(element); |
} |
- registerField(Element element) { |
- if (element.enclosingElement.isNative()) { |
- setNativeName(element); |
- } |
- } |
- |
registerMethod(Element method) { |
if (isNativeMethod(method)) { |
- setNativeName(method); |
processNativeBehavior( |
NativeBehavior.ofMethod(method, compiler), |
method); |
@@ -241,14 +191,6 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
} |
} |
- /// Sets the native name of [element], either from an annotation, or |
- /// defaulting to the Dart name. |
- void setNativeName(Element element) { |
- String name = findJsNameFromAnnotation(element); |
- if (name == null) name = element.name.slowToString(); |
- element.setNative(name); |
- } |
- |
bool isNativeMethod(Element element) { |
if (!element.getLibrary().canUseNative) return false; |
// Native method? |
@@ -724,15 +666,15 @@ Token handleNativeFunctionBody(ElementListener listener, Token token) { |
} |
SourceString checkForNativeClass(ElementListener listener) { |
- SourceString nativeTagInfo; |
+ SourceString nativeName; |
Node node = listener.nodes.head; |
if (node != null |
&& node.asIdentifier() != null |
&& node.asIdentifier().source.stringValue == 'native') { |
- nativeTagInfo = node.asIdentifier().token.next.value; |
+ nativeName = node.asIdentifier().token.next.value; |
listener.popNode(); |
} |
- return nativeTagInfo; |
+ return nativeName; |
} |
bool isOverriddenMethod(FunctionElement element, |
@@ -751,6 +693,7 @@ final RegExp nativeRedirectionRegExp = new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$'); |
void handleSsaNative(SsaBuilder builder, Expression nativeBody) { |
Compiler compiler = builder.compiler; |
FunctionElement element = builder.work.element; |
+ element.setNative(); |
NativeEmitter nativeEmitter = builder.emitter.nativeEmitter; |
// If what we're compiling is a getter named 'typeName' and the native |
// class is named 'DOMType', we generate a call to the typeNameOf |
@@ -780,22 +723,22 @@ void handleSsaNative(SsaBuilder builder, Expression nativeBody) { |
} |
// Check which pattern this native method follows: |
- // 1) foo() native; |
- // hasBody = false, isRedirecting = false |
- // 2) foo() native "bar"; |
- // hasBody = false, isRedirecting = true, no longer supported. |
- // 3) foo() native "return 42"; |
- // hasBody = true, isRedirecting = false |
+ // 1) foo() native; hasBody = false, isRedirecting = false |
+ // 2) foo() native "bar"; hasBody = false, isRedirecting = true |
+ // 3) foo() native "return 42"; hasBody = true, isRedirecting = false |
bool hasBody = false; |
- String nativeMethodName = element.nativeName(); |
+ bool isRedirecting = false; |
+ String nativeMethodName = element.name.slowToString(); |
if (nativeBody != null) { |
LiteralString jsCode = nativeBody.asLiteralString(); |
String str = jsCode.dartString.slowToString(); |
if (nativeRedirectionRegExp.hasMatch(str)) { |
- compiler.cancel("Deprecated syntax, use @JSName('name') instead.", |
- node: nativeBody); |
+ nativeMethodName = str; |
+ isRedirecting = true; |
+ nativeEmitter.addRedirectingMethod(element, nativeMethodName); |
+ } else { |
+ hasBody = true; |
} |
- hasBody = true; |
} |
if (!hasBody) { |