| 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 import 'dart:collection' show HashMap, HashSet; | 5 import 'dart:collection' show HashMap, HashSet; |
| 6 import 'dart:math' show min, max; | 6 import 'dart:math' show min, max; |
| 7 | 7 |
| 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; | 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 // `dom.InputElement` to actually be HTMLInputElement. | 591 // `dom.InputElement` to actually be HTMLInputElement. |
| 592 // TODO(jmesserly): if we had the JS name on the Element, we could just | 592 // TODO(jmesserly): if we had the JS name on the Element, we could just |
| 593 // generate it correctly when we refer to it. | 593 // generate it correctly when we refer to it. |
| 594 return js.statement('# = #;', [_emitTopLevelName(e), jsTypeName]); | 594 return js.statement('# = #;', [_emitTopLevelName(e), jsTypeName]); |
| 595 } | 595 } |
| 596 | 596 |
| 597 @override | 597 @override |
| 598 JS.Statement visitClassDeclaration(ClassDeclaration node) { | 598 JS.Statement visitClassDeclaration(ClassDeclaration node) { |
| 599 var classElem = node.element; | 599 var classElem = node.element; |
| 600 | 600 |
| 601 // If this class is annotated with `@JS`, then there is nothing to emit. |
| 602 if (findAnnotation(classElem, isPublicJSAnnotation) != null) return null; |
| 603 |
| 601 // If this is a JavaScript type, emit it now and then exit. | 604 // If this is a JavaScript type, emit it now and then exit. |
| 602 var jsTypeDef = _emitJsType(classElem); | 605 var jsTypeDef = _emitJsType(classElem); |
| 603 if (jsTypeDef != null) return jsTypeDef; | 606 if (jsTypeDef != null) return jsTypeDef; |
| 604 | 607 |
| 605 var ctors = <ConstructorDeclaration>[]; | 608 var ctors = <ConstructorDeclaration>[]; |
| 606 var fields = <FieldDeclaration>[]; | 609 var fields = <FieldDeclaration>[]; |
| 607 var staticFields = <FieldDeclaration>[]; | 610 var staticFields = <FieldDeclaration>[]; |
| 608 var methods = <MethodDeclaration>[]; | 611 var methods = <MethodDeclaration>[]; |
| 609 for (var member in node.members) { | 612 for (var member in node.members) { |
| 610 if (member is ConstructorDeclaration) { | 613 if (member is ConstructorDeclaration) { |
| (...skipping 2402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3013 if (parent is ClassElement) { | 3016 if (parent is ClassElement) { |
| 3014 return getter | 3017 return getter |
| 3015 ? parent.getGetter(element.name) | 3018 ? parent.getGetter(element.name) |
| 3016 : parent.getSetter(element.name); | 3019 : parent.getSetter(element.name); |
| 3017 } | 3020 } |
| 3018 return null; | 3021 return null; |
| 3019 } | 3022 } |
| 3020 | 3023 |
| 3021 JS.Expression _emitConstructorName( | 3024 JS.Expression _emitConstructorName( |
| 3022 ConstructorElement element, DartType type, SimpleIdentifier name) { | 3025 ConstructorElement element, DartType type, SimpleIdentifier name) { |
| 3026 var classElem = element.enclosingElement; |
| 3027 if (findAnnotation(classElem, isPublicJSAnnotation) != null) { |
| 3028 var annotationName = getAnnotationName(classElem, isPublicJSAnnotation); |
| 3029 var typeName = js.string(annotationName ?? classElem.name); |
| 3030 return new JS.PropertyAccess(new JS.Identifier('self'), typeName); |
| 3031 } |
| 3023 var typeName = _emitType(type); | 3032 var typeName = _emitType(type); |
| 3024 if (name != null || element.isFactory) { | 3033 if (name != null || element.isFactory) { |
| 3025 var namedCtor = _constructorName(element); | 3034 var namedCtor = _constructorName(element); |
| 3026 return new JS.PropertyAccess(typeName, namedCtor); | 3035 return new JS.PropertyAccess(typeName, namedCtor); |
| 3027 } | 3036 } |
| 3028 return typeName; | 3037 return typeName; |
| 3029 } | 3038 } |
| 3030 | 3039 |
| 3031 @override | 3040 @override |
| 3032 visitConstructorName(ConstructorName node) { | 3041 visitConstructorName(ConstructorName node) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3050 if (name != null) { | 3059 if (name != null) { |
| 3051 ctor = new JS.PropertyAccess(ctor, _propertyName(name.name)); | 3060 ctor = new JS.PropertyAccess(ctor, _propertyName(name.name)); |
| 3052 } | 3061 } |
| 3053 } else { | 3062 } else { |
| 3054 ctor = _emitConstructorName(element, type, name); | 3063 ctor = _emitConstructorName(element, type, name); |
| 3055 isFactory = element.isFactory; | 3064 isFactory = element.isFactory; |
| 3056 } | 3065 } |
| 3057 var args = _visit(argumentList) as List<JS.Expression>; | 3066 var args = _visit(argumentList) as List<JS.Expression>; |
| 3058 return isFactory ? new JS.Call(ctor, args) : new JS.New(ctor, args); | 3067 return isFactory ? new JS.Call(ctor, args) : new JS.New(ctor, args); |
| 3059 } | 3068 } |
| 3069 if (_isObjectLiteral(element.enclosingElement)) { |
| 3070 return _emitObjectLiteral(argumentList); |
| 3071 } |
| 3060 if (isConst) return _emitConst(emitNew); | 3072 if (isConst) return _emitConst(emitNew); |
| 3061 return emitNew(); | 3073 return emitNew(); |
| 3062 } | 3074 } |
| 3063 | 3075 |
| 3076 bool _isObjectLiteral(ClassElement classElem) { |
| 3077 return findAnnotation(classElem, isPublicJSAnnotation) != null && |
| 3078 findAnnotation(classElem, isJSAnonymousAnnotation) != null; |
| 3079 } |
| 3080 |
| 3081 JS.Expression _emitObjectLiteral(ArgumentList argumentList) { |
| 3082 var args = _visit(argumentList) as List<JS.Expression>; |
| 3083 if (args.isEmpty) { |
| 3084 return js.call('{}'); |
| 3085 } |
| 3086 assert(args.single is JS.ObjectInitializer); |
| 3087 return args.single; |
| 3088 } |
| 3089 |
| 3064 @override | 3090 @override |
| 3065 visitInstanceCreationExpression(InstanceCreationExpression node) { | 3091 visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 3066 var element = node.staticElement; | 3092 var element = node.staticElement; |
| 3067 var constructor = node.constructorName; | 3093 var constructor = node.constructorName; |
| 3068 var name = constructor.name; | 3094 var name = constructor.name; |
| 3069 var type = constructor.type.type; | 3095 var type = constructor.type.type; |
| 3070 return _emitInstanceCreationExpression( | 3096 return _emitInstanceCreationExpression( |
| 3071 element, type, name, node.argumentList, node.isConst); | 3097 element, type, name, node.argumentList, node.isConst); |
| 3072 } | 3098 } |
| 3073 | 3099 |
| (...skipping 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4438 } | 4464 } |
| 4439 | 4465 |
| 4440 bool isLibraryPrefix(Expression node) => | 4466 bool isLibraryPrefix(Expression node) => |
| 4441 node is SimpleIdentifier && node.staticElement is PrefixElement; | 4467 node is SimpleIdentifier && node.staticElement is PrefixElement; |
| 4442 | 4468 |
| 4443 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 4469 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
| 4444 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 4470 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
| 4445 | 4471 |
| 4446 bool _isDartRuntime(LibraryElement l) => | 4472 bool _isDartRuntime(LibraryElement l) => |
| 4447 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 4473 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
| OLD | NEW |