| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 'package:js_runtime/shared/embedded_names.dart'; | 5 import 'package:js_runtime/shared/embedded_names.dart'; |
| 6 import 'package:kernel/ast.dart' as ir; | 6 import 'package:kernel/ast.dart' as ir; |
| 7 | 7 |
| 8 import '../closure.dart'; | 8 import '../closure.dart'; |
| 9 import '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../compiler.dart'; | 10 import '../compiler.dart'; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 } | 138 } |
| 139 | 139 |
| 140 void assertAtResolvedAstFor(ir.Node node) { | 140 void assertAtResolvedAstFor(ir.Node node) { |
| 141 assert(invariant(getElement(node), | 141 assert(invariant(getElement(node), |
| 142 _resolvedAst.element == getElement(node).declaration)); | 142 _resolvedAst.element == getElement(node).declaration)); |
| 143 } | 143 } |
| 144 | 144 |
| 145 Compiler get _compiler => _backend.compiler; | 145 Compiler get _compiler => _backend.compiler; |
| 146 TreeElements get elements => _resolvedAst.elements; | 146 TreeElements get elements => _resolvedAst.elements; |
| 147 DiagnosticReporter get reporter => _compiler.reporter; | 147 DiagnosticReporter get reporter => _compiler.reporter; |
| 148 MemberElement get _target => _resolvedAst.element; | |
| 149 | |
| 150 GlobalTypeInferenceResults get _globalInferenceResults => | |
| 151 _compiler.globalInference.results; | |
| 152 | |
| 153 GlobalTypeInferenceElementResult _resultOf(MemberElement e) => | |
| 154 _globalInferenceResults | |
| 155 .resultOfMember(e is ConstructorBodyElementX ? e.constructor : e); | |
| 156 | 148 |
| 157 ConstantValue getConstantForSymbol(ir.SymbolLiteral node) { | 149 ConstantValue getConstantForSymbol(ir.SymbolLiteral node) { |
| 158 if (kernel.syntheticNodes.contains(node)) { | 150 if (kernel.syntheticNodes.contains(node)) { |
| 159 return _backend.constantSystem | 151 return _backend.constantSystem |
| 160 .createSymbol(_compiler.commonElements, node.value); | 152 .createSymbol(_compiler.commonElements, node.value); |
| 161 } | 153 } |
| 162 ast.Node astNode = getNode(node); | 154 ast.Node astNode = getNode(node); |
| 163 ConstantValue constantValue = _backend.constants | 155 ConstantValue constantValue = _backend.constants |
| 164 .getConstantValueForNode(astNode, _resolvedAst.elements); | 156 .getConstantValueForNode(astNode, _resolvedAst.elements); |
| 165 assert(invariant(astNode, constantValue != null, | 157 assert(invariant(astNode, constantValue != null, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 | 215 |
| 224 Local getLocal(ir.VariableDeclaration variable) { | 216 Local getLocal(ir.VariableDeclaration variable) { |
| 225 // If this is a synthetic local, return the synthetic local | 217 // If this is a synthetic local, return the synthetic local |
| 226 if (variable.name == null) { | 218 if (variable.name == null) { |
| 227 return _syntheticLocals.putIfAbsent( | 219 return _syntheticLocals.putIfAbsent( |
| 228 variable, () => new SyntheticLocal("x", null, null)); | 220 variable, () => new SyntheticLocal("x", null, null)); |
| 229 } | 221 } |
| 230 return getElement(variable) as LocalElement; | 222 return getElement(variable) as LocalElement; |
| 231 } | 223 } |
| 232 | 224 |
| 233 TypeMask getReturnTypeOf(FunctionEntity function) { | |
| 234 return TypeMaskFactory.inferredReturnTypeForElement( | |
| 235 function, _globalInferenceResults); | |
| 236 } | |
| 237 | |
| 238 FunctionSignature getFunctionSignature(ir.FunctionNode function) { | 225 FunctionSignature getFunctionSignature(ir.FunctionNode function) { |
| 239 return getElement(function).asFunctionElement().functionSignature; | 226 return getElement(function).asFunctionElement().functionSignature; |
| 240 } | 227 } |
| 241 | 228 |
| 242 ir.Field getFieldFromElement(FieldElement field) { | 229 ir.Field getFieldFromElement(FieldElement field) { |
| 243 return kernel.fields[field]; | 230 return kernel.fields[field]; |
| 244 } | 231 } |
| 245 | 232 |
| 246 TypeMask typeOfInvocation(ir.MethodInvocation send, ClosedWorld closedWorld) { | |
| 247 ast.Node operatorNode = kernel.nodeToAstOperator[send]; | |
| 248 if (operatorNode != null) { | |
| 249 return _resultOf(_target).typeOfOperator(operatorNode); | |
| 250 } | |
| 251 if (send.name.name == '[]=') { | |
| 252 return closedWorld.commonMasks.dynamicType; | |
| 253 } | |
| 254 return _resultOf(_target).typeOfSend(getNode(send)); | |
| 255 } | |
| 256 | |
| 257 TypeMask typeOfGet(ir.PropertyGet getter) { | |
| 258 return _resultOf(_target).typeOfSend(getNode(getter)); | |
| 259 } | |
| 260 | |
| 261 TypeMask typeOfSet(ir.PropertySet setter, ClosedWorld closedWorld) { | |
| 262 return closedWorld.commonMasks.dynamicType; | |
| 263 } | |
| 264 | |
| 265 TypeMask typeOfSend(ir.Expression send) { | |
| 266 assert(send is ir.InvocationExpression || send is ir.PropertyGet); | |
| 267 return _resultOf(_target).typeOfSend(getNode(send)); | |
| 268 } | |
| 269 | |
| 270 TypeMask typeOfListLiteral(MemberElement owner, ir.ListLiteral listLiteral, | |
| 271 ClosedWorld closedWorld) { | |
| 272 ast.Node node = getNodeOrNull(listLiteral); | |
| 273 if (node == null) { | |
| 274 assertNodeIsSynthetic(listLiteral); | |
| 275 return closedWorld.commonMasks.growableListType; | |
| 276 } | |
| 277 return _resultOf(owner).typeOfListLiteral(getNode(listLiteral)) ?? | |
| 278 closedWorld.commonMasks.dynamicType; | |
| 279 } | |
| 280 | |
| 281 TypeMask typeOfIterator(ir.ForInStatement forInStatement) { | |
| 282 return _resultOf(_target).typeOfIterator(getNode(forInStatement)); | |
| 283 } | |
| 284 | |
| 285 TypeMask typeOfIteratorCurrent(ir.ForInStatement forInStatement) { | |
| 286 return _resultOf(_target).typeOfIteratorCurrent(getNode(forInStatement)); | |
| 287 } | |
| 288 | |
| 289 TypeMask typeOfIteratorMoveNext(ir.ForInStatement forInStatement) { | |
| 290 return _resultOf(_target).typeOfIteratorMoveNext(getNode(forInStatement)); | |
| 291 } | |
| 292 | |
| 293 bool isJsIndexableIterator( | |
| 294 ir.ForInStatement forInStatement, ClosedWorld closedWorld) { | |
| 295 TypeMask mask = typeOfIterator(forInStatement); | |
| 296 return mask != null && | |
| 297 mask.satisfies( | |
| 298 _compiler.commonElements.jsIndexableClass, closedWorld) && | |
| 299 // String is indexable but not iterable. | |
| 300 !mask.satisfies(_compiler.commonElements.jsStringClass, closedWorld); | |
| 301 } | |
| 302 | |
| 303 bool isFixedLength(TypeMask mask, ClosedWorld closedWorld) { | 233 bool isFixedLength(TypeMask mask, ClosedWorld closedWorld) { |
| 304 if (mask.isContainer && (mask as ContainerTypeMask).length != null) { | 234 if (mask.isContainer && (mask as ContainerTypeMask).length != null) { |
| 305 // A container on which we have inferred the length. | 235 // A container on which we have inferred the length. |
| 306 return true; | 236 return true; |
| 307 } | 237 } |
| 308 // TODO(sra): Recognize any combination of fixed length indexables. | 238 // TODO(sra): Recognize any combination of fixed length indexables. |
| 309 if (mask.containsOnly(closedWorld.commonElements.jsFixedArrayClass) || | 239 if (mask.containsOnly(closedWorld.commonElements.jsFixedArrayClass) || |
| 310 mask.containsOnly( | 240 mask.containsOnly( |
| 311 closedWorld.commonElements.jsUnmodifiableArrayClass) || | 241 closedWorld.commonElements.jsUnmodifiableArrayClass) || |
| 312 mask.containsOnlyString(closedWorld) || | 242 mask.containsOnlyString(closedWorld) || |
| 313 closedWorld.commonMasks.isTypedArray(mask)) { | 243 closedWorld.commonMasks.isTypedArray(mask)) { |
| 314 return true; | 244 return true; |
| 315 } | 245 } |
| 316 return false; | 246 return false; |
| 317 } | 247 } |
| 318 | 248 |
| 319 TypeMask inferredIndexType(ir.ForInStatement forInStatement) { | |
| 320 return TypeMaskFactory.inferredTypeForSelector(new Selector.index(), | |
| 321 typeOfIterator(forInStatement), _globalInferenceResults); | |
| 322 } | |
| 323 | |
| 324 TypeMask getInferredTypeOf(MemberEntity member) { | |
| 325 return TypeMaskFactory.inferredTypeForMember( | |
| 326 member, _globalInferenceResults); | |
| 327 } | |
| 328 | |
| 329 TypeMask selectorTypeOf(Selector selector, TypeMask mask) { | |
| 330 return TypeMaskFactory.inferredTypeForSelector( | |
| 331 selector, mask, _globalInferenceResults); | |
| 332 } | |
| 333 | |
| 334 TypeMask typeFromNativeBehavior( | |
| 335 native.NativeBehavior nativeBehavior, ClosedWorld closedWorld) { | |
| 336 return TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); | |
| 337 } | |
| 338 | |
| 339 ConstantValue getConstantFor(ir.Node node) { | 249 ConstantValue getConstantFor(ir.Node node) { |
| 340 // Some `null`s are not mapped when they correspond to errors, e.g. missing | 250 // Some `null`s are not mapped when they correspond to errors, e.g. missing |
| 341 // `const` initializers. | 251 // `const` initializers. |
| 342 if (node is ir.NullLiteral) return new NullConstantValue(); | 252 if (node is ir.NullLiteral) return new NullConstantValue(); |
| 343 | 253 |
| 344 ConstantValue constantValue = | 254 ConstantValue constantValue = |
| 345 _backend.constants.getConstantValueForNode(getNode(node), elements); | 255 _backend.constants.getConstantValueForNode(getNode(node), elements); |
| 346 assert(invariant(getNode(node), constantValue != null, | 256 assert(invariant(getNode(node), constantValue != null, |
| 347 message: 'No constant computed for $node')); | 257 message: 'No constant computed for $node')); |
| 348 return constantValue; | 258 return constantValue; |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 JumpTarget continueTarget = | 608 JumpTarget continueTarget = |
| 699 astAdapter.getJumpTarget(switchCase, isContinueTarget: true); | 609 astAdapter.getJumpTarget(switchCase, isContinueTarget: true); |
| 700 assert(continueTarget is KernelJumpTarget); | 610 assert(continueTarget is KernelJumpTarget); |
| 701 targetIndexMap[continueTarget] = switchIndex; | 611 targetIndexMap[continueTarget] = switchIndex; |
| 702 assert(builder.jumpTargets[continueTarget] == null); | 612 assert(builder.jumpTargets[continueTarget] == null); |
| 703 builder.jumpTargets[continueTarget] = this; | 613 builder.jumpTargets[continueTarget] = this; |
| 704 switchIndex++; | 614 switchIndex++; |
| 705 } | 615 } |
| 706 } | 616 } |
| 707 } | 617 } |
| 618 |
| 619 class KernelAstTypeInferenceMap implements KernelToTypeInferenceMap { |
| 620 final KernelAstAdapter _astAdapter; |
| 621 |
| 622 KernelAstTypeInferenceMap(this._astAdapter); |
| 623 |
| 624 MemberElement get _target => _astAdapter._resolvedAst.element; |
| 625 |
| 626 GlobalTypeInferenceResults get _globalInferenceResults => |
| 627 _astAdapter._compiler.globalInference.results; |
| 628 |
| 629 GlobalTypeInferenceElementResult _resultOf(MemberElement e) => |
| 630 _globalInferenceResults |
| 631 .resultOfMember(e is ConstructorBodyElementX ? e.constructor : e); |
| 632 |
| 633 TypeMask getReturnTypeOf(FunctionEntity function) { |
| 634 return TypeMaskFactory.inferredReturnTypeForElement( |
| 635 function, _globalInferenceResults); |
| 636 } |
| 637 |
| 638 TypeMask typeOfInvocation(ir.MethodInvocation send, ClosedWorld closedWorld) { |
| 639 ast.Node operatorNode = _astAdapter.kernel.nodeToAstOperator[send]; |
| 640 if (operatorNode != null) { |
| 641 return _resultOf(_target).typeOfOperator(operatorNode); |
| 642 } |
| 643 if (send.name.name == '[]=') { |
| 644 return closedWorld.commonMasks.dynamicType; |
| 645 } |
| 646 return _resultOf(_target).typeOfSend(_astAdapter.getNode(send)); |
| 647 } |
| 648 |
| 649 TypeMask typeOfGet(ir.PropertyGet getter) { |
| 650 return _resultOf(_target).typeOfSend(_astAdapter.getNode(getter)); |
| 651 } |
| 652 |
| 653 TypeMask typeOfSet(ir.PropertySet setter, ClosedWorld closedWorld) { |
| 654 return closedWorld.commonMasks.dynamicType; |
| 655 } |
| 656 |
| 657 TypeMask typeOfListLiteral(MemberElement owner, ir.ListLiteral listLiteral, |
| 658 ClosedWorld closedWorld) { |
| 659 ast.Node node = _astAdapter.getNodeOrNull(listLiteral); |
| 660 if (node == null) { |
| 661 _astAdapter.assertNodeIsSynthetic(listLiteral); |
| 662 return closedWorld.commonMasks.growableListType; |
| 663 } |
| 664 return _resultOf(owner) |
| 665 .typeOfListLiteral(_astAdapter.getNode(listLiteral)) ?? |
| 666 closedWorld.commonMasks.dynamicType; |
| 667 } |
| 668 |
| 669 TypeMask typeOfIterator(ir.ForInStatement forInStatement) { |
| 670 return _resultOf(_target) |
| 671 .typeOfIterator(_astAdapter.getNode(forInStatement)); |
| 672 } |
| 673 |
| 674 TypeMask typeOfIteratorCurrent(ir.ForInStatement forInStatement) { |
| 675 return _resultOf(_target) |
| 676 .typeOfIteratorCurrent(_astAdapter.getNode(forInStatement)); |
| 677 } |
| 678 |
| 679 TypeMask typeOfIteratorMoveNext(ir.ForInStatement forInStatement) { |
| 680 return _resultOf(_target) |
| 681 .typeOfIteratorMoveNext(_astAdapter.getNode(forInStatement)); |
| 682 } |
| 683 |
| 684 bool isJsIndexableIterator( |
| 685 ir.ForInStatement forInStatement, ClosedWorld closedWorld) { |
| 686 TypeMask mask = typeOfIterator(forInStatement); |
| 687 return mask != null && |
| 688 mask.satisfies( |
| 689 closedWorld.commonElements.jsIndexableClass, closedWorld) && |
| 690 // String is indexable but not iterable. |
| 691 !mask.satisfies(closedWorld.commonElements.jsStringClass, closedWorld); |
| 692 } |
| 693 |
| 694 TypeMask inferredIndexType(ir.ForInStatement forInStatement) { |
| 695 return TypeMaskFactory.inferredTypeForSelector(new Selector.index(), |
| 696 typeOfIterator(forInStatement), _globalInferenceResults); |
| 697 } |
| 698 |
| 699 TypeMask getInferredTypeOf(MemberEntity member) { |
| 700 return TypeMaskFactory.inferredTypeForMember( |
| 701 member, _globalInferenceResults); |
| 702 } |
| 703 |
| 704 TypeMask selectorTypeOf(Selector selector, TypeMask mask) { |
| 705 return TypeMaskFactory.inferredTypeForSelector( |
| 706 selector, mask, _globalInferenceResults); |
| 707 } |
| 708 |
| 709 TypeMask typeFromNativeBehavior( |
| 710 native.NativeBehavior nativeBehavior, ClosedWorld closedWorld) { |
| 711 return TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); |
| 712 } |
| 713 } |
| OLD | NEW |