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 | 2 |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 import 'dart:collection' show HashMap, HashSet; | 6 import 'dart:collection' show HashMap, HashSet; |
7 import 'dart:math' show min, max; | 7 import 'dart:math' show min, max; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| 11 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; |
11 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; | 12 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
12 import 'package:analyzer/dart/element/element.dart'; | 13 import 'package:analyzer/dart/element/element.dart'; |
13 import 'package:analyzer/dart/element/type.dart'; | 14 import 'package:analyzer/dart/element/type.dart'; |
14 import 'package:analyzer/src/dart/ast/token.dart' show StringToken; | 15 import 'package:analyzer/src/dart/ast/token.dart' show StringToken; |
15 import 'package:analyzer/src/dart/element/element.dart' | 16 import 'package:analyzer/src/dart/element/element.dart' |
16 show LocalVariableElementImpl; | 17 show LocalVariableElementImpl; |
17 import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl; | 18 import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl; |
18 import 'package:analyzer/src/dart/sdk/sdk.dart'; | 19 import 'package:analyzer/src/dart/sdk/sdk.dart'; |
19 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | 20 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
20 import 'package:analyzer/src/generated/resolver.dart' | 21 import 'package:analyzer/src/generated/resolver.dart' |
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 // Therefore, dart:core Object gets the one real `constructor` and | 1308 // Therefore, dart:core Object gets the one real `constructor` and |
1308 // immediately bounces to the `new() { ... }` initializer, letting us | 1309 // immediately bounces to the `new() { ... }` initializer, letting us |
1309 // bypass the ES6 restrictions. | 1310 // bypass the ES6 restrictions. |
1310 // | 1311 // |
1311 // TODO(jmesserly): we'll need to rethink this. | 1312 // TODO(jmesserly): we'll need to rethink this. |
1312 // See <https://github.com/dart-lang/dev_compiler/issues/51>. | 1313 // See <https://github.com/dart-lang/dev_compiler/issues/51>. |
1313 // This level of indirection will hurt performance. | 1314 // This level of indirection will hurt performance. |
1314 jsMethods.add(new JS.Method( | 1315 jsMethods.add(new JS.Method( |
1315 _propertyName('constructor'), | 1316 _propertyName('constructor'), |
1316 js.call('function(...args) { return this.new.apply(this, args); }') | 1317 js.call('function(...args) { return this.new.apply(this, args); }') |
1317 as JS.Fun)); | 1318 as JS.Fun)); |
1318 } else if (ctors.isEmpty) { | 1319 } else if (ctors.isEmpty) { |
1319 jsMethods.add(_emitImplicitConstructor(node, fields, virtualFields)); | 1320 jsMethods.add(_emitImplicitConstructor(node, fields, virtualFields)); |
1320 } | 1321 } |
1321 | 1322 |
1322 bool hasJsPeer = findAnnotation(element, isJsPeerInterface) != null; | 1323 bool hasJsPeer = findAnnotation(element, isJsPeerInterface) != null; |
1323 | 1324 |
1324 bool hasIterator = false; | 1325 bool hasIterator = false; |
1325 for (var m in node.members) { | 1326 for (var m in node.members) { |
1326 if (m is ConstructorDeclaration) { | 1327 if (m is ConstructorDeclaration) { |
1327 jsMethods | 1328 jsMethods |
(...skipping 2632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3960 Element target, List<VariableDeclaration> fields) { | 3961 Element target, List<VariableDeclaration> fields) { |
3961 var methods = []; | 3962 var methods = []; |
3962 for (var node in fields) { | 3963 for (var node in fields) { |
3963 var name = node.name.name; | 3964 var name = node.name.name; |
3964 var element = node.element; | 3965 var element = node.element; |
3965 var access = _emitMemberName(name, isStatic: true); | 3966 var access = _emitMemberName(name, isStatic: true); |
3966 methods.add(annotate( | 3967 methods.add(annotate( |
3967 new JS.Method( | 3968 new JS.Method( |
3968 access, | 3969 access, |
3969 js.call('function() { return #; }', _visitInitializer(node)) | 3970 js.call('function() { return #; }', _visitInitializer(node)) |
3970 as JS.Fun, | 3971 as JS.Fun, |
3971 isGetter: true), | 3972 isGetter: true), |
3972 node, | 3973 node, |
3973 _findAccessor(element, getter: true))); | 3974 _findAccessor(element, getter: true))); |
3974 | 3975 |
3975 // TODO(jmesserly): currently uses a dummy setter to indicate writable. | 3976 // TODO(jmesserly): currently uses a dummy setter to indicate writable. |
3976 if (!node.isFinal && !node.isConst) { | 3977 if (!node.isFinal && !node.isConst) { |
3977 methods.add(annotate( | 3978 methods.add(annotate( |
3978 new JS.Method(access, js.call('function(_) {}') as JS.Fun, | 3979 new JS.Method(access, js.call('function(_) {}') as JS.Fun, |
3979 isSetter: true), | 3980 isSetter: true), |
3980 node, | 3981 node, |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4446 | 4447 |
4447 SimpleIdentifier _createTemporary(String name, DartType type, | 4448 SimpleIdentifier _createTemporary(String name, DartType type, |
4448 {bool nullable: true, JS.Expression variable}) { | 4449 {bool nullable: true, JS.Expression variable}) { |
4449 // We use an invalid source location to signal that this is a temporary. | 4450 // We use an invalid source location to signal that this is a temporary. |
4450 // See [_isTemporary]. | 4451 // See [_isTemporary]. |
4451 // TODO(jmesserly): alternatives are | 4452 // TODO(jmesserly): alternatives are |
4452 // * (ab)use Element.isSynthetic, which isn't currently used for | 4453 // * (ab)use Element.isSynthetic, which isn't currently used for |
4453 // LocalVariableElementImpl, so we could repurpose to mean "temp". | 4454 // LocalVariableElementImpl, so we could repurpose to mean "temp". |
4454 // * add a new property to LocalVariableElementImpl. | 4455 // * add a new property to LocalVariableElementImpl. |
4455 // * create a new subtype of LocalVariableElementImpl to mark a temp. | 4456 // * create a new subtype of LocalVariableElementImpl to mark a temp. |
4456 var id = | 4457 var id = astFactory |
4457 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1)); | 4458 .simpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1)); |
4458 | 4459 |
4459 variable ??= new JS.TemporaryId(name); | 4460 variable ??= new JS.TemporaryId(name); |
4460 | 4461 |
4461 id.staticElement = new TemporaryVariableElement.forNode(id, variable); | 4462 id.staticElement = new TemporaryVariableElement.forNode(id, variable); |
4462 id.staticType = type; | 4463 id.staticType = type; |
4463 setIsDynamicInvoke(id, type.isDynamic); | 4464 setIsDynamicInvoke(id, type.isDynamic); |
4464 addTemporaryVariable(id.staticElement, nullable: nullable); | 4465 addTemporaryVariable(id.staticElement, nullable: nullable); |
4465 return id; | 4466 return id; |
4466 } | 4467 } |
4467 | 4468 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4502 /// | 4503 /// |
4503 /// [scope] can be mutated to contain any new temporaries that were created, | 4504 /// [scope] can be mutated to contain any new temporaries that were created, |
4504 /// unless [expr] is a SimpleIdentifier, in which case a temporary is not | 4505 /// unless [expr] is a SimpleIdentifier, in which case a temporary is not |
4505 /// needed. | 4506 /// needed. |
4506 Expression _bindLeftHandSide( | 4507 Expression _bindLeftHandSide( |
4507 Map<JS.MetaLetVariable, JS.Expression> scope, Expression expr, | 4508 Map<JS.MetaLetVariable, JS.Expression> scope, Expression expr, |
4508 {Expression context}) { | 4509 {Expression context}) { |
4509 Expression result; | 4510 Expression result; |
4510 if (expr is IndexExpression) { | 4511 if (expr is IndexExpression) { |
4511 IndexExpression index = expr; | 4512 IndexExpression index = expr; |
4512 result = new IndexExpression.forTarget( | 4513 result = astFactory.indexExpressionForTarget( |
4513 _bindValue(scope, 'o', index.target, context: context), | 4514 _bindValue(scope, 'o', index.target, context: context), |
4514 index.leftBracket, | 4515 index.leftBracket, |
4515 _bindValue(scope, 'i', index.index, context: context), | 4516 _bindValue(scope, 'i', index.index, context: context), |
4516 index.rightBracket); | 4517 index.rightBracket); |
4517 } else if (expr is PropertyAccess) { | 4518 } else if (expr is PropertyAccess) { |
4518 PropertyAccess prop = expr; | 4519 PropertyAccess prop = expr; |
4519 result = new PropertyAccess( | 4520 result = astFactory.propertyAccess( |
4520 _bindValue(scope, 'o', _getTarget(prop), context: context), | 4521 _bindValue(scope, 'o', _getTarget(prop), context: context), |
4521 prop.operator, | 4522 prop.operator, |
4522 prop.propertyName); | 4523 prop.propertyName); |
4523 } else if (expr is PrefixedIdentifier) { | 4524 } else if (expr is PrefixedIdentifier) { |
4524 PrefixedIdentifier ident = expr; | 4525 PrefixedIdentifier ident = expr; |
4525 if (isLibraryPrefix(ident.prefix)) { | 4526 if (isLibraryPrefix(ident.prefix)) { |
4526 return expr; | 4527 return expr; |
4527 } | 4528 } |
4528 result = new PrefixedIdentifier( | 4529 result = astFactory.prefixedIdentifier( |
4529 _bindValue(scope, 'o', ident.prefix, context: context) | 4530 _bindValue(scope, 'o', ident.prefix, context: context) |
4530 as SimpleIdentifier, | 4531 as SimpleIdentifier, |
4531 ident.period, | 4532 ident.period, |
4532 ident.identifier); | 4533 ident.identifier); |
4533 } else { | 4534 } else { |
4534 return expr as SimpleIdentifier; | 4535 return expr as SimpleIdentifier; |
4535 } | 4536 } |
4536 result.staticType = expr.staticType; | 4537 result.staticType = expr.staticType; |
4537 setIsDynamicInvoke(result, isDynamicInvoke(expr)); | 4538 setIsDynamicInvoke(result, isDynamicInvoke(expr)); |
4538 return result; | 4539 return result; |
4539 } | 4540 } |
4540 | 4541 |
(...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5765 var targetIdentifier = target as SimpleIdentifier; | 5766 var targetIdentifier = target as SimpleIdentifier; |
5766 | 5767 |
5767 if (targetIdentifier.staticElement is! PrefixElement) return false; | 5768 if (targetIdentifier.staticElement is! PrefixElement) return false; |
5768 var prefix = targetIdentifier.staticElement as PrefixElement; | 5769 var prefix = targetIdentifier.staticElement as PrefixElement; |
5769 | 5770 |
5770 // The library the prefix is referring to must come from a deferred import. | 5771 // The library the prefix is referring to must come from a deferred import. |
5771 var containingLibrary = (target.root as CompilationUnit).element.library; | 5772 var containingLibrary = (target.root as CompilationUnit).element.library; |
5772 var imports = containingLibrary.getImportsWithPrefix(prefix); | 5773 var imports = containingLibrary.getImportsWithPrefix(prefix); |
5773 return imports.length == 1 && imports[0].isDeferred; | 5774 return imports.length == 1 && imports[0].isDeferred; |
5774 } | 5775 } |
OLD | NEW |