Chromium Code Reviews| 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 |