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 library dev_compiler.src.codegen.js_codegen; | 5 library dev_compiler.src.codegen.js_codegen; |
6 | 6 |
7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; | 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; | 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 if (node is! FunctionDeclaration) _flushLibraryProperties(_moduleItems); | 241 if (node is! FunctionDeclaration) _flushLibraryProperties(_moduleItems); |
242 | 242 |
243 var code = _visit(node); | 243 var code = _visit(node); |
244 if (code != null) _moduleItems.add(code); | 244 if (code != null) _moduleItems.add(code); |
245 } | 245 } |
246 | 246 |
247 @override | 247 @override |
248 void visitLibraryDirective(LibraryDirective node) { | 248 void visitLibraryDirective(LibraryDirective node) { |
249 assert(_jsModuleValue == null); | 249 assert(_jsModuleValue == null); |
250 | 250 |
251 var jsName = findAnnotation(node.element, isJsNameAnnotation); | 251 var jsName = findAnnotation(node.element, isJSAnnotation); |
252 _jsModuleValue = | 252 _jsModuleValue = |
253 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); | 253 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); |
254 } | 254 } |
255 | 255 |
256 @override | 256 @override |
257 void visitImportDirective(ImportDirective node) { | 257 void visitImportDirective(ImportDirective node) { |
258 // Nothing to do yet, but we'll want to convert this to an ES6 import once | 258 // Nothing to do yet, but we'll want to convert this to an ES6 import once |
259 // we have support for modules. | 259 // we have support for modules. |
260 } | 260 } |
261 | 261 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 return _finishClassDef(element.type, classDecl); | 402 return _finishClassDef(element.type, classDecl); |
403 } | 403 } |
404 | 404 |
405 JS.Statement _emitJsType(String dartClassName, DartObject jsName) { | 405 JS.Statement _emitJsType(String dartClassName, DartObject jsName) { |
406 var jsTypeName = | 406 var jsTypeName = |
407 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); | 407 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); |
408 | 408 |
409 if (jsTypeName != null && jsTypeName != dartClassName) { | 409 if (jsTypeName != null && jsTypeName != dartClassName) { |
410 // We export the JS type as if it was a Dart type. For example this allows | 410 // We export the JS type as if it was a Dart type. For example this allows |
411 // `dom.InputElement` to actually be HTMLInputElement. | 411 // `dom.InputElement` to actually be HTMLInputElement. |
412 // TODO(jmesserly): if we had the JsName on the Element, we could just | 412 // TODO(jmesserly): if we had the JS name on the Element, we could just |
413 // generate it correctly when we refer to it. | 413 // generate it correctly when we refer to it. |
414 if (isPublic(dartClassName)) _addExport(dartClassName); | 414 if (isPublic(dartClassName)) _addExport(dartClassName); |
415 return js.statement('let # = #;', [dartClassName, jsTypeName]); | 415 return js.statement('let # = #;', [dartClassName, jsTypeName]); |
416 } | 416 } |
417 return null; | 417 return null; |
418 } | 418 } |
419 | 419 |
420 @override | 420 @override |
421 JS.Statement visitClassDeclaration(ClassDeclaration node) { | 421 JS.Statement visitClassDeclaration(ClassDeclaration node) { |
422 var classElem = node.element; | 422 var classElem = node.element; |
423 var type = classElem.type; | 423 var type = classElem.type; |
424 var jsName = findAnnotation(classElem, isJsNameAnnotation); | 424 var jsName = findAnnotation(classElem, isJSAnnotation); |
425 | 425 |
426 if (jsName != null) return _emitJsType(node.name.name, jsName); | 426 if (jsName != null) return _emitJsType(node.name.name, jsName); |
427 | 427 |
428 var ctors = <ConstructorDeclaration>[]; | 428 var ctors = <ConstructorDeclaration>[]; |
429 var fields = <FieldDeclaration>[]; | 429 var fields = <FieldDeclaration>[]; |
430 var methods = <MethodDeclaration>[]; | 430 var methods = <MethodDeclaration>[]; |
431 for (var member in node.members) { | 431 for (var member in node.members) { |
432 if (member is ConstructorDeclaration) { | 432 if (member is ConstructorDeclaration) { |
433 ctors.add(member); | 433 ctors.add(member); |
434 } else if (member is FieldDeclaration && !member.isStatic) { | 434 } else if (member is FieldDeclaration && !member.isStatic) { |
(...skipping 2279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2714 var target = _getTarget(node); | 2714 var target = _getTarget(node); |
2715 if (_useNativeJsIndexer(target.staticType)) { | 2715 if (_useNativeJsIndexer(target.staticType)) { |
2716 return new JS.PropertyAccess(_visit(target), _visit(node.index)); | 2716 return new JS.PropertyAccess(_visit(target), _visit(node.index)); |
2717 } | 2717 } |
2718 return _emitSend(target, '[]', [node.index]); | 2718 return _emitSend(target, '[]', [node.index]); |
2719 } | 2719 } |
2720 | 2720 |
2721 // TODO(jmesserly): ideally we'd check the method and see if it is marked | 2721 // TODO(jmesserly): ideally we'd check the method and see if it is marked |
2722 // `external`, but that doesn't work because it isn't in the element model. | 2722 // `external`, but that doesn't work because it isn't in the element model. |
2723 bool _useNativeJsIndexer(DartType type) => | 2723 bool _useNativeJsIndexer(DartType type) => |
2724 findAnnotation(type.element, isJsNameAnnotation) != null; | 2724 findAnnotation(type.element, isJSAnnotation) != null; |
2725 | 2725 |
2726 /// Gets the target of a [PropertyAccess], [IndexExpression], or | 2726 /// Gets the target of a [PropertyAccess], [IndexExpression], or |
2727 /// [MethodInvocation]. These three nodes can appear in a [CascadeExpression]. | 2727 /// [MethodInvocation]. These three nodes can appear in a [CascadeExpression]. |
2728 Expression _getTarget(node) { | 2728 Expression _getTarget(node) { |
2729 assert(node is IndexExpression || | 2729 assert(node is IndexExpression || |
2730 node is PropertyAccess || | 2730 node is PropertyAccess || |
2731 node is MethodInvocation); | 2731 node is MethodInvocation); |
2732 return node.isCascaded ? _cascadeTarget : node.target; | 2732 return node.isCascaded ? _cascadeTarget : node.target; |
2733 } | 2733 } |
2734 | 2734 |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3347 | 3347 |
3348 /// A special kind of element created by the compiler, signifying a temporary | 3348 /// A special kind of element created by the compiler, signifying a temporary |
3349 /// variable. These objects use instance equality, and should be shared | 3349 /// variable. These objects use instance equality, and should be shared |
3350 /// everywhere in the tree where they are treated as the same variable. | 3350 /// everywhere in the tree where they are treated as the same variable. |
3351 class TemporaryVariableElement extends LocalVariableElementImpl { | 3351 class TemporaryVariableElement extends LocalVariableElementImpl { |
3352 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3352 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
3353 | 3353 |
3354 int get hashCode => identityHashCode(this); | 3354 int get hashCode => identityHashCode(this); |
3355 bool operator ==(Object other) => identical(this, other); | 3355 bool operator ==(Object other) => identical(this, other); |
3356 } | 3356 } |
OLD | NEW |