| 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 |