OLD | NEW |
---|---|
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 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
392 // function or a non-method property in the prototype chain, must be coded | 392 // function or a non-method property in the prototype chain, must be coded |
393 // using a JS-call. | 393 // using a JS-call. |
394 if (element.isInstanceMember) { | 394 if (element.isInstanceMember) { |
395 setNativeName(element); | 395 setNativeName(element); |
396 } | 396 } |
397 } | 397 } |
398 } | 398 } |
399 | 399 |
400 handleMethodAnnotations(Element method) { | 400 handleMethodAnnotations(Element method) { |
401 if (isNativeMethod(method)) { | 401 if (isNativeMethod(method)) { |
402 setNativeName(method); | 402 if (method.isStatic) { |
403 setStaticNativeMethodName(method); | |
sra1
2015/03/03 02:00:02
better name: setNativeNameForStaticMethod
Harry Terkelsen
2015/03/03 03:02:16
Done.
| |
404 } else { | |
405 setNativeName(method); | |
406 } | |
403 } | 407 } |
404 } | 408 } |
405 | 409 |
406 /// Sets the native name of [element], either from an annotation, or | 410 /// Sets the native name of [element], either from an annotation, or |
407 /// defaulting to the Dart name. | 411 /// defaulting to the Dart name. |
408 void setNativeName(Element element) { | 412 void setNativeName(Element element) { |
409 String name = findJsNameFromAnnotation(element); | 413 String name = findJsNameFromAnnotation(element); |
410 if (name == null) name = element.name; | 414 if (name == null) name = element.name; |
411 element.setNative(name); | 415 element.setNative(name); |
412 } | 416 } |
413 | 417 |
418 /// Sets the native name of the static native method [element], using the | |
419 /// following rules: | |
420 /// 1. If [element] has a @JSName annotation that is an identifier, qualify | |
421 /// that identifier to the @Native name of the enclosing class | |
422 /// 2. If [element] has a @JSName annotation that is not an identifier, | |
423 /// use the declared @JSName as the expression | |
424 /// 3. If [element] does not have a @JSName annotation, qualify the name of | |
425 /// the method with the @Native name of the enclosing class. | |
426 void setStaticNativeMethodName(Element element) { | |
427 String name = findJsNameFromAnnotation(element); | |
428 if (name == null) name = element.name; | |
429 if (isIdentifier(name)) { | |
430 String nativeName = unquote(element.enclosingClass.nativeTagInfo); | |
sra1
2015/03/03 02:00:02
There is code somewhere that parses the tag info.
Harry Terkelsen
2015/03/03 03:02:16
Done.
| |
431 element.setNative('$nativeName.$name'); | |
432 } else { | |
433 element.setNative(name); | |
434 } | |
435 } | |
436 | |
437 bool isIdentifier(String s) => | |
438 new RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$').hasMatch(s); | |
sra1
2015/03/03 02:00:02
Put regexp in a static class variable so it is not
Harry Terkelsen
2015/03/03 03:02:16
Done.
| |
439 | |
440 String unquote(String s) { | |
441 if (s.length < 2) return s; | |
442 if (s[0] == '"' && s[s.length - 1] == '"') { | |
443 return s.substring(1, s.length - 1); | |
444 } | |
445 return s; | |
446 } | |
447 | |
414 bool isNativeMethod(FunctionElementX element) { | 448 bool isNativeMethod(FunctionElementX element) { |
415 if (!element.library.canUseNative) return false; | 449 if (!element.library.canUseNative) return false; |
416 // Native method? | 450 // Native method? |
417 return compiler.withCurrentElement(element, () { | 451 return compiler.withCurrentElement(element, () { |
418 Node node = element.parseNode(compiler); | 452 Node node = element.parseNode(compiler); |
419 if (node is! FunctionExpression) return false; | 453 if (node is! FunctionExpression) return false; |
420 FunctionExpression functionExpression = node; | 454 FunctionExpression functionExpression = node; |
421 node = functionExpression.body; | 455 node = functionExpression.body; |
422 Token token = node.getBeginToken(); | 456 Token token = node.getBeginToken(); |
423 if (identical(token.stringValue, 'native')) return true; | 457 if (identical(token.stringValue, 'native')) return true; |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
632 superclass, | 666 superclass, |
633 () => <ClassElement>[]); | 667 () => <ClassElement>[]); |
634 directSubtypes.add(cls); | 668 directSubtypes.add(cls); |
635 } | 669 } |
636 | 670 |
637 void logSummary(log(message)) { | 671 void logSummary(log(message)) { |
638 log('Compiled ${registeredClasses.length} native classes, ' | 672 log('Compiled ${registeredClasses.length} native classes, ' |
639 '${unusedClasses.length} native classes omitted.'); | 673 '${unusedClasses.length} native classes omitted.'); |
640 } | 674 } |
641 } | 675 } |
OLD | NEW |