Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: pkg/compiler/lib/src/native/enqueue.dart

Issue 971053003: Sets the native name of static native methods by using the @JSName with the @Native tag of the encl… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/compiler/dart2js_native/static_methods_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of native; 5 part of native;
6 6
7 /** 7 /**
8 * This could be an abstract class but we use it as a stub for the dart_backend. 8 * This could be an abstract class but we use it as a stub for the dart_backend.
9 */ 9 */
10 class NativeEnqueuer { 10 class NativeEnqueuer {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 void logSummary(log(message)) {} 58 void logSummary(log(message)) {}
59 59
60 // Do not use annotations in dart2dart. 60 // Do not use annotations in dart2dart.
61 ClassElement get annotationCreatesClass => null; 61 ClassElement get annotationCreatesClass => null;
62 ClassElement get annotationReturnsClass => null; 62 ClassElement get annotationReturnsClass => null;
63 ClassElement get annotationJsNameClass => null; 63 ClassElement get annotationJsNameClass => null;
64 } 64 }
65 65
66 66
67 abstract class NativeEnqueuerBase implements NativeEnqueuer { 67 abstract class NativeEnqueuerBase implements NativeEnqueuer {
68 static final RegExp _identifier = new RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$');
68 69
69 /** 70 /**
70 * The set of all native classes. Each native class is in [nativeClasses] and 71 * The set of all native classes. Each native class is in [nativeClasses] and
71 * exactly one of [unusedClasses], [pendingClasses] and [registeredClasses]. 72 * exactly one of [unusedClasses], [pendingClasses] and [registeredClasses].
72 */ 73 */
73 final Set<ClassElement> nativeClasses = new Set<ClassElement>(); 74 final Set<ClassElement> nativeClasses = new Set<ClassElement>();
74 75
75 final Set<ClassElement> registeredClasses = new Set<ClassElement>(); 76 final Set<ClassElement> registeredClasses = new Set<ClassElement>();
76 final Set<ClassElement> pendingClasses = new Set<ClassElement>(); 77 final Set<ClassElement> pendingClasses = new Set<ClassElement>();
77 final Set<ClassElement> unusedClasses = new Set<ClassElement>(); 78 final Set<ClassElement> unusedClasses = new Set<ClassElement>();
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 // function or a non-method property in the prototype chain, must be coded 393 // function or a non-method property in the prototype chain, must be coded
393 // using a JS-call. 394 // using a JS-call.
394 if (element.isInstanceMember) { 395 if (element.isInstanceMember) {
395 setNativeName(element); 396 setNativeName(element);
396 } 397 }
397 } 398 }
398 } 399 }
399 400
400 handleMethodAnnotations(Element method) { 401 handleMethodAnnotations(Element method) {
401 if (isNativeMethod(method)) { 402 if (isNativeMethod(method)) {
402 setNativeName(method); 403 if (method.isStatic) {
404 setNativeNameForStaticMethod(method);
405 } else {
406 setNativeName(method);
407 }
403 } 408 }
404 } 409 }
405 410
406 /// Sets the native name of [element], either from an annotation, or 411 /// Sets the native name of [element], either from an annotation, or
407 /// defaulting to the Dart name. 412 /// defaulting to the Dart name.
408 void setNativeName(Element element) { 413 void setNativeName(Element element) {
409 String name = findJsNameFromAnnotation(element); 414 String name = findJsNameFromAnnotation(element);
410 if (name == null) name = element.name; 415 if (name == null) name = element.name;
411 element.setNative(name); 416 element.setNative(name);
412 } 417 }
413 418
419 /// Sets the native name of the static native method [element], using the
420 /// following rules:
421 /// 1. If [element] has a @JSName annotation that is an identifier, qualify
422 /// that identifier to the @Native name of the enclosing class
423 /// 2. If [element] has a @JSName annotation that is not an identifier,
424 /// use the declared @JSName as the expression
425 /// 3. If [element] does not have a @JSName annotation, qualify the name of
426 /// the method with the @Native name of the enclosing class.
427 void setNativeNameForStaticMethod(Element element) {
428 String name = findJsNameFromAnnotation(element);
429 if (name == null) name = element.name;
430 if (isIdentifier(name)) {
431 List<String> nativeNames = nativeTagsOfClassRaw(element.enclosingClass);
432 if (nativeNames.length != 1) {
433 compiler.internalError(element,
434 'Unable to determine a native name for the enclosing class, '
435 'options: $nativeNames');
436 }
437 element.setNative('${nativeNames[0]}.$name');
438 } else {
439 element.setNative(name);
440 }
441 }
442
443 bool isIdentifier(String s) => _identifier.hasMatch(s);
444
414 bool isNativeMethod(FunctionElementX element) { 445 bool isNativeMethod(FunctionElementX element) {
415 if (!element.library.canUseNative) return false; 446 if (!element.library.canUseNative) return false;
416 // Native method? 447 // Native method?
417 return compiler.withCurrentElement(element, () { 448 return compiler.withCurrentElement(element, () {
418 Node node = element.parseNode(compiler); 449 Node node = element.parseNode(compiler);
419 if (node is! FunctionExpression) return false; 450 if (node is! FunctionExpression) return false;
420 FunctionExpression functionExpression = node; 451 FunctionExpression functionExpression = node;
421 node = functionExpression.body; 452 node = functionExpression.body;
422 Token token = node.getBeginToken(); 453 Token token = node.getBeginToken();
423 if (identical(token.stringValue, 'native')) return true; 454 if (identical(token.stringValue, 'native')) return true;
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 superclass, 663 superclass,
633 () => <ClassElement>[]); 664 () => <ClassElement>[]);
634 directSubtypes.add(cls); 665 directSubtypes.add(cls);
635 } 666 }
636 667
637 void logSummary(log(message)) { 668 void logSummary(log(message)) {
638 log('Compiled ${registeredClasses.length} native classes, ' 669 log('Compiled ${registeredClasses.length} native classes, '
639 '${unusedClasses.length} native classes omitted.'); 670 '${unusedClasses.length} native classes omitted.');
640 } 671 }
641 } 672 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js_native/static_methods_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698