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 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 // any nodes. | 248 // any nodes. |
249 var nodes = new HashMap<Element, AstNode>.identity(); | 249 var nodes = new HashMap<Element, AstNode>.identity(); |
250 var sdkBootstrappingFns = new List<FunctionElement>(); | 250 var sdkBootstrappingFns = new List<FunctionElement>(); |
251 for (var unit in compilationUnits) { | 251 for (var unit in compilationUnits) { |
252 if (_isDartRuntime(unit.element.library)) { | 252 if (_isDartRuntime(unit.element.library)) { |
253 sdkBootstrappingFns.addAll(unit.element.functions); | 253 sdkBootstrappingFns.addAll(unit.element.functions); |
254 } | 254 } |
255 _collectElements(unit, nodes); | 255 _collectElements(unit, nodes); |
256 } | 256 } |
257 _loader = new ElementLoader(nodes); | 257 _loader = new ElementLoader(nodes); |
258 if (compilationUnits.isNotEmpty) { | |
259 _constField = new ConstFieldVisitor(types, | |
260 dummySource: compilationUnits.first.element.source); | |
261 } | |
258 | 262 |
259 // Add implicit dart:core dependency so it is first. | 263 // Add implicit dart:core dependency so it is first. |
260 emitLibraryName(dartCoreLibrary); | 264 emitLibraryName(dartCoreLibrary); |
261 | 265 |
262 // Emit SDK bootstrapping functions first, if any. | 266 // Emit SDK bootstrapping functions first, if any. |
263 sdkBootstrappingFns.forEach(_emitDeclaration); | 267 sdkBootstrappingFns.forEach(_emitDeclaration); |
264 | 268 |
265 // Visit each compilation unit and emit its code. | 269 // Visit each compilation unit and emit its code. |
266 // | 270 // |
267 // NOTE: declarations are not necessarily emitted in this order. | 271 // NOTE: declarations are not necessarily emitted in this order. |
268 // Order will be changed as needed so the resulting code can execute. | 272 // Order will be changed as needed so the resulting code can execute. |
269 // This is done by forward declaring items. | 273 // This is done by forward declaring items. |
270 compilationUnits.forEach(visitCompilationUnit); | 274 compilationUnits.forEach(_finishDeclarationsInUnit); |
271 | 275 |
272 // Declare imports | 276 // Declare imports |
273 _finishImports(items); | 277 _finishImports(items); |
274 | 278 |
275 // Discharge the type table cache variables and | 279 // Discharge the type table cache variables and |
276 // hoisted definitions. | 280 // hoisted definitions. |
277 items.addAll(_typeTable.discharge()); | 281 items.addAll(_typeTable.discharge()); |
278 | 282 |
279 // Add the module's code (produced by visiting compilation units, above) | 283 // Add the module's code (produced by visiting compilation units, above) |
280 _copyAndFlattenBlocks(items, _moduleItems); | 284 _copyAndFlattenBlocks(items, _moduleItems); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
432 return _visit(node); | 436 return _visit(node); |
433 }); | 437 }); |
434 | 438 |
435 if (item != null) _moduleItems.add(item); | 439 if (item != null) _moduleItems.add(item); |
436 } | 440 } |
437 | 441 |
438 void _declareBeforeUse(Element e) { | 442 void _declareBeforeUse(Element e) { |
439 _loader.declareBeforeUse(e, _emitDeclaration); | 443 _loader.declareBeforeUse(e, _emitDeclaration); |
440 } | 444 } |
441 | 445 |
442 @override | 446 void _finishDeclarationsInUnit(CompilationUnit unit) { |
443 void visitCompilationUnit(CompilationUnit unit) { | 447 // NOTE: this method isn't the right place to initialize |
444 _constField = new ConstFieldVisitor(types, unit.element.source); | 448 // per-compilation-unit state. Declarations can be visited out of order, |
445 | 449 // this is only to catch things that haven't been emitted yet. |
450 // | |
451 // See _emitDeclaration. | |
446 for (var declaration in unit.declarations) { | 452 for (var declaration in unit.declarations) { |
447 var element = declaration.element; | 453 var element = declaration.element; |
448 if (element != null) { | 454 if (element != null) { |
449 _emitDeclaration(element); | 455 _emitDeclaration(element); |
450 } else { | 456 } else { |
451 declaration.accept(this); | 457 declaration.accept(this); |
452 } | 458 } |
453 } | 459 } |
454 for (var directive in unit.directives) { | 460 for (var directive in unit.directives) { |
455 directive.accept(this); | 461 directive.accept(this); |
(...skipping 3779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4235 /// For example `null.toString()` is legal in Dart, so we need to generate | 4241 /// For example `null.toString()` is legal in Dart, so we need to generate |
4236 /// that as `dart.toString(obj)`. | 4242 /// that as `dart.toString(obj)`. |
4237 bool _isObjectMemberCall(Expression target, String memberName) { | 4243 bool _isObjectMemberCall(Expression target, String memberName) { |
4238 if (!isObjectMember(memberName)) { | 4244 if (!isObjectMember(memberName)) { |
4239 return false; | 4245 return false; |
4240 } | 4246 } |
4241 | 4247 |
4242 // Check if the target could be `null`, is dynamic, or may be an extension | 4248 // Check if the target could be `null`, is dynamic, or may be an extension |
4243 // native type. In all of those cases we need defensive code generation. | 4249 // native type. In all of those cases we need defensive code generation. |
4244 var type = getStaticType(target); | 4250 var type = getStaticType(target); |
4251 | |
4245 return isNullable(target) || | 4252 return isNullable(target) || |
4253 _targetIsFunction(target) || | |
4246 type.isDynamic || | 4254 type.isDynamic || |
4247 (_extensionTypes.hasNativeSubtype(type) && target is! SuperExpression); | 4255 (_extensionTypes.hasNativeSubtype(type) && target is! SuperExpression); |
4248 } | 4256 } |
4249 | 4257 |
4258 bool _targetIsFunction(Expression expr) { | |
4259 Element element = null; | |
4260 if (expr is PropertyAccess) { | |
vsm
2016/06/16 23:41:13
Is this sufficient? I.e., what about FunctionExpr
Jennifer Messerly
2016/06/16 23:44:14
I think those should be handled by isNullable (I s
| |
4261 element = expr.propertyName.staticElement; | |
4262 } else if (expr is Identifier) { | |
4263 element = expr.staticElement; | |
4264 } | |
4265 return element is FunctionElement || element is MethodElement; | |
4266 } | |
4267 | |
4250 /// Shared code for [PrefixedIdentifier] and [PropertyAccess]. | 4268 /// Shared code for [PrefixedIdentifier] and [PropertyAccess]. |
4251 JS.Expression _emitAccess( | 4269 JS.Expression _emitAccess( |
4252 Expression target, SimpleIdentifier memberId, DartType resultType) { | 4270 Expression target, SimpleIdentifier memberId, DartType resultType) { |
4253 Element member = memberId.staticElement; | 4271 Element member = memberId.staticElement; |
4254 if (member is PropertyAccessorElement) { | 4272 if (member is PropertyAccessorElement) { |
4255 member = (member as PropertyAccessorElement).variable; | 4273 member = (member as PropertyAccessorElement).variable; |
4256 } | 4274 } |
4257 String memberName = memberId.name; | 4275 String memberName = memberId.name; |
4258 var typeArgs = _getTypeArgs(member, resultType); | 4276 var typeArgs = _getTypeArgs(member, resultType); |
4259 | 4277 |
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5133 } | 5151 } |
5134 | 5152 |
5135 bool isLibraryPrefix(Expression node) => | 5153 bool isLibraryPrefix(Expression node) => |
5136 node is SimpleIdentifier && node.staticElement is PrefixElement; | 5154 node is SimpleIdentifier && node.staticElement is PrefixElement; |
5137 | 5155 |
5138 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 5156 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
5139 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 5157 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
5140 | 5158 |
5141 bool _isDartRuntime(LibraryElement l) => | 5159 bool _isDartRuntime(LibraryElement l) => |
5142 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 5160 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
OLD | NEW |