| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 /// Analysis to determine how to generate code for typed JavaScript interop. | 5 /// Analysis to determine how to generate code for typed JavaScript interop. |
| 6 library compiler.src.js_backend.js_interop_analysis; | 6 library compiler.src.js_backend.js_interop_analysis; |
| 7 | 7 |
| 8 import '../common/names.dart' show Identifiers; | 8 import '../common/names.dart' show Identifiers; |
| 9 import '../compiler.dart' show Compiler; | 9 import '../compiler.dart' show Compiler; |
| 10 import '../diagnostics/messages.dart' show MessageKind; | 10 import '../diagnostics/messages.dart' show MessageKind; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 void processJsInteropAnnotation(Element e) { | 61 void processJsInteropAnnotation(Element e) { |
| 62 for (MetadataAnnotation annotation in e.implementation.metadata) { | 62 for (MetadataAnnotation annotation in e.implementation.metadata) { |
| 63 ConstantValue constant = backend.compiler.constants.getConstantValue( | 63 ConstantValue constant = backend.compiler.constants.getConstantValue( |
| 64 annotation.constant); | 64 annotation.constant); |
| 65 if (constant == null || constant is! ConstructedConstantValue) continue; | 65 if (constant == null || constant is! ConstructedConstantValue) continue; |
| 66 ConstructedConstantValue constructedConstant = constant; | 66 ConstructedConstantValue constructedConstant = constant; |
| 67 if (constructedConstant.type.element == backend.jsAnnotationClass) { | 67 if (constructedConstant.type.element == backend.jsAnnotationClass) { |
| 68 ConstantValue value = constructedConstant.fields[nameField]; | 68 ConstantValue value = constructedConstant.fields[nameField]; |
| 69 if (value.isString) { | 69 if (value.isString) { |
| 70 StringConstantValue stringValue = value; | 70 StringConstantValue stringValue = value; |
| 71 e.setJsInteropName(stringValue.primitiveValue.slowToString()); | 71 backend.setJsInteropName( |
| 72 e, stringValue.primitiveValue.slowToString()); |
| 72 } else { | 73 } else { |
| 73 // TODO(jacobr): report a warning if the value is not a String. | 74 // TODO(jacobr): report a warning if the value is not a String. |
| 74 e.setJsInteropName(''); | 75 backend.setJsInteropName(e, ''); |
| 75 } | 76 } |
| 76 enabledJsInterop = true; | 77 enabledJsInterop = true; |
| 77 return; | 78 return; |
| 78 } | 79 } |
| 79 } | 80 } |
| 80 } | 81 } |
| 81 | 82 |
| 82 void processJsInteropAnnotationsInLibrary(LibraryElement library) { | 83 void processJsInteropAnnotationsInLibrary(LibraryElement library) { |
| 83 processJsInteropAnnotation(library); | 84 processJsInteropAnnotation(library); |
| 84 library.implementation.forEachLocalMember((Element element) { | 85 library.implementation.forEachLocalMember((Element element) { |
| 85 processJsInteropAnnotation(element); | 86 processJsInteropAnnotation(element); |
| 86 if (!element.isClass || !element.isJsInterop) return; | 87 if (!element.isClass || !backend.isJsInterop(element)) return; |
| 87 | 88 |
| 88 ClassElement classElement = element; | 89 ClassElement classElement = element; |
| 89 | 90 |
| 90 if (!classElement | 91 if (!classElement |
| 91 .implementsInterface(backend.jsJavaScriptObjectClass)) { | 92 .implementsInterface(backend.jsJavaScriptObjectClass)) { |
| 92 backend.reporter.reportErrorMessage(classElement, | 93 backend.reporter.reportErrorMessage(classElement, |
| 93 MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS, { | 94 MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS, { |
| 94 'cls': classElement.name, | 95 'cls': classElement.name, |
| 95 'superclass': classElement.superclass.name | 96 'superclass': classElement.superclass.name |
| 96 }); | 97 }); |
| 97 } | 98 } |
| 98 | 99 |
| 99 classElement.forEachMember( | 100 classElement.forEachMember( |
| 100 (ClassElement classElement, Element member) { | 101 (ClassElement classElement, Element member) { |
| 101 processJsInteropAnnotation(member); | 102 processJsInteropAnnotation(member); |
| 102 | 103 |
| 103 if (!member.isSynthesized && | 104 if (!member.isSynthesized && |
| 104 classElement.isJsInterop && | 105 backend.isJsInterop(classElement) && |
| 105 member is FunctionElement) { | 106 member is FunctionElement) { |
| 106 FunctionElement fn = member; | 107 FunctionElement fn = member; |
| 107 if (!fn.isExternal && !fn.isAbstract) { | 108 if (!fn.isExternal && !fn.isAbstract) { |
| 108 backend.reporter.reportErrorMessage( | 109 backend.reporter.reportErrorMessage( |
| 109 fn, | 110 fn, |
| 110 MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER, | 111 MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER, |
| 111 {'cls': classElement.name, 'member': member.name}); | 112 {'cls': classElement.name, 'member': member.name}); |
| 112 } | 113 } |
| 113 } | 114 } |
| 114 }); | 115 }); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 133 var name = backend.namer.invocationName(selector); | 134 var name = backend.namer.invocationName(selector); |
| 134 statements.add(js.statement( | 135 statements.add(js.statement( |
| 135 'Function.prototype.# = function(#) { return this(#) }', | 136 'Function.prototype.# = function(#) { return this(#) }', |
| 136 [name, parameters, parameters])); | 137 [name, parameters, parameters])); |
| 137 } | 138 } |
| 138 }); | 139 }); |
| 139 }); | 140 }); |
| 140 return new jsAst.Block(statements); | 141 return new jsAst.Block(statements); |
| 141 } | 142 } |
| 142 } | 143 } |
| OLD | NEW |