| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library simple_types_inferrer; | 5 library simple_types_inferrer; |
| 6 | 6 |
| 7 import '../closure.dart' show ClosureClassMap; | 7 import '../closure.dart' show ClosureClassMap; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/names.dart' show Identifiers, Selectors; | 9 import '../common/names.dart' show Identifiers, Selectors; |
| 10 import '../compiler.dart' show Compiler; | 10 import '../compiler.dart' show Compiler; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 import '../resolution/tree_elements.dart' show TreeElements; | 21 import '../resolution/tree_elements.dart' show TreeElements; |
| 22 import '../tree/tree.dart' as ast; | 22 import '../tree/tree.dart' as ast; |
| 23 import '../types/constants.dart' show computeTypeMask; | 23 import '../types/constants.dart' show computeTypeMask; |
| 24 import '../types/types.dart' show TypeMask, GlobalTypeInferenceElementData; | 24 import '../types/types.dart' show TypeMask, GlobalTypeInferenceElementData; |
| 25 import '../universe/call_structure.dart' show CallStructure; | 25 import '../universe/call_structure.dart' show CallStructure; |
| 26 import '../universe/selector.dart' show Selector; | 26 import '../universe/selector.dart' show Selector; |
| 27 import '../universe/side_effects.dart' show SideEffects; | 27 import '../universe/side_effects.dart' show SideEffects; |
| 28 import '../util/util.dart' show Link, Setlet; | 28 import '../util/util.dart' show Link, Setlet; |
| 29 import '../world.dart' show ClosedWorld; | 29 import '../world.dart' show ClosedWorld; |
| 30 import 'inferrer_engine.dart'; | 30 import 'inferrer_engine.dart'; |
| 31 import 'inferrer_visitor.dart'; | 31 import 'locals_handler.dart'; |
| 32 import 'type_graph_nodes.dart'; | 32 import 'type_graph_nodes.dart'; |
| 33 import 'type_system.dart'; | 33 import 'type_system.dart'; |
| 34 | 34 |
| 35 /// [SimpleTypeInferrerVisitor] can be thought of as a type-inference graph | 35 /// [ElementGraphBuilder] can be thought of as a type-inference graph |
| 36 /// builder for a single element. | 36 /// builder for a single element. |
| 37 /// | 37 /// |
| 38 /// Calling [run] will start the work of visiting the body of the code to | 38 /// Calling [run] will start the work of visiting the body of the code to |
| 39 /// construct a set of infernece-nodes that abstractly represent what the code | 39 /// construct a set of infernece-nodes that abstractly represent what the code |
| 40 /// is doing. | 40 /// is doing. |
| 41 /// | 41 /// |
| 42 /// This visitor is parameterized by an [InferenceEngine], which internally | 42 /// This visitor is parameterized by an [InferenceEngine], which internally |
| 43 /// decides how to represent inference nodes. | 43 /// decides how to represent inference nodes. |
| 44 class SimpleTypeInferrerVisitor extends ast.Visitor<TypeInformation> | 44 class ElementGraphBuilder extends ast.Visitor<TypeInformation> |
| 45 with | 45 with |
| 46 SemanticSendResolvedMixin<TypeInformation, dynamic>, | 46 SemanticSendResolvedMixin<TypeInformation, dynamic>, |
| 47 CompoundBulkMixin<TypeInformation, dynamic>, | 47 CompoundBulkMixin<TypeInformation, dynamic>, |
| 48 SetIfNullBulkMixin<TypeInformation, dynamic>, | 48 SetIfNullBulkMixin<TypeInformation, dynamic>, |
| 49 PrefixBulkMixin<TypeInformation, dynamic>, | 49 PrefixBulkMixin<TypeInformation, dynamic>, |
| 50 PostfixBulkMixin<TypeInformation, dynamic>, | 50 PostfixBulkMixin<TypeInformation, dynamic>, |
| 51 ErrorBulkMixin<TypeInformation, dynamic>, | 51 ErrorBulkMixin<TypeInformation, dynamic>, |
| 52 NewBulkMixin<TypeInformation, dynamic>, | 52 NewBulkMixin<TypeInformation, dynamic>, |
| 53 SetBulkMixin<TypeInformation, dynamic> | 53 SetBulkMixin<TypeInformation, dynamic> |
| 54 implements SemanticSendVisitor<TypeInformation, dynamic> { | 54 implements SemanticSendVisitor<TypeInformation, dynamic> { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 67 TypeInformation returnType; | 67 TypeInformation returnType; |
| 68 bool visitingInitializers = false; | 68 bool visitingInitializers = false; |
| 69 bool isConstructorRedirect = false; | 69 bool isConstructorRedirect = false; |
| 70 bool seenSuperConstructorCall = false; | 70 bool seenSuperConstructorCall = false; |
| 71 SideEffects sideEffects = new SideEffects.empty(); | 71 SideEffects sideEffects = new SideEffects.empty(); |
| 72 final Element outermostElement; | 72 final Element outermostElement; |
| 73 final InferrerEngine inferrer; | 73 final InferrerEngine inferrer; |
| 74 final Setlet<Entity> capturedVariables = new Setlet<Entity>(); | 74 final Setlet<Entity> capturedVariables = new Setlet<Entity>(); |
| 75 final GlobalTypeInferenceElementData inTreeData; | 75 final GlobalTypeInferenceElementData inTreeData; |
| 76 | 76 |
| 77 SimpleTypeInferrerVisitor.internal( | 77 ElementGraphBuilder.internal( |
| 78 AstElement analyzedElement, | 78 AstElement analyzedElement, |
| 79 this.resolvedAst, | 79 this.resolvedAst, |
| 80 this.outermostElement, | 80 this.outermostElement, |
| 81 InferrerEngine inferrer, | 81 InferrerEngine inferrer, |
| 82 this.compiler, | 82 this.compiler, |
| 83 this.locals) | 83 this.locals) |
| 84 : this.analyzedElement = analyzedElement, | 84 : this.analyzedElement = analyzedElement, |
| 85 this.inferrer = inferrer, | 85 this.inferrer = inferrer, |
| 86 this.types = inferrer.types, | 86 this.types = inferrer.types, |
| 87 this.inTreeData = inferrer.dataOf(analyzedElement) { | 87 this.inTreeData = inferrer.dataOf(analyzedElement) { |
| 88 assert(outermostElement != null); | 88 assert(outermostElement != null); |
| 89 if (locals != null) return; | 89 if (locals != null) return; |
| 90 ast.Node node; | 90 ast.Node node; |
| 91 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | 91 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
| 92 node = resolvedAst.node; | 92 node = resolvedAst.node; |
| 93 } | 93 } |
| 94 FieldInitializationScope fieldScope = | 94 FieldInitializationScope fieldScope = |
| 95 analyzedElement.isGenerativeConstructor | 95 analyzedElement.isGenerativeConstructor |
| 96 ? new FieldInitializationScope(types) | 96 ? new FieldInitializationScope(types) |
| 97 : null; | 97 : null; |
| 98 locals = | 98 locals = |
| 99 new LocalsHandler(inferrer, types, compiler.options, node, fieldScope); | 99 new LocalsHandler(inferrer, types, compiler.options, node, fieldScope); |
| 100 } | 100 } |
| 101 | 101 |
| 102 SimpleTypeInferrerVisitor(Element element, ResolvedAst resolvedAst, | 102 ElementGraphBuilder(Element element, ResolvedAst resolvedAst, |
| 103 Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler]) | 103 Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler]) |
| 104 : this.internal( | 104 : this.internal( |
| 105 element, | 105 element, |
| 106 resolvedAst, | 106 resolvedAst, |
| 107 element.outermostEnclosingMemberOrTopLevel.implementation, | 107 element.outermostEnclosingMemberOrTopLevel.implementation, |
| 108 inferrer, | 108 inferrer, |
| 109 compiler, | 109 compiler, |
| 110 handler); | 110 handler); |
| 111 | 111 |
| 112 TreeElements get elements => resolvedAst.elements; | 112 TreeElements get elements => resolvedAst.elements; |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 signature.forEachOptionalParameter((ParameterElement element) { | 916 signature.forEachOptionalParameter((ParameterElement element) { |
| 917 ast.Expression defaultValue = element.initializer; | 917 ast.Expression defaultValue = element.initializer; |
| 918 // TODO(25566): The default value of a parameter of a redirecting factory | 918 // TODO(25566): The default value of a parameter of a redirecting factory |
| 919 // constructor comes from the corresponding parameter of the target. | 919 // constructor comes from the corresponding parameter of the target. |
| 920 | 920 |
| 921 // If this is a default value from a different context (because | 921 // If this is a default value from a different context (because |
| 922 // the current function is synthetic, e.g., a constructor from | 922 // the current function is synthetic, e.g., a constructor from |
| 923 // a mixin application), we have to start a new inferrer visitor | 923 // a mixin application), we have to start a new inferrer visitor |
| 924 // with the correct context. | 924 // with the correct context. |
| 925 // TODO(johnniwinther): Remove once function signatures are fixed. | 925 // TODO(johnniwinther): Remove once function signatures are fixed. |
| 926 SimpleTypeInferrerVisitor visitor = this; | 926 ElementGraphBuilder visitor = this; |
| 927 if (inferrer.hasAlreadyComputedTypeOfParameterDefault(element)) return; | 927 if (inferrer.hasAlreadyComputedTypeOfParameterDefault(element)) return; |
| 928 if (element.functionDeclaration != analyzedElement) { | 928 if (element.functionDeclaration != analyzedElement) { |
| 929 visitor = new SimpleTypeInferrerVisitor(element.functionDeclaration, | 929 visitor = new ElementGraphBuilder(element.functionDeclaration, |
| 930 element.functionDeclaration.resolvedAst, compiler, inferrer); | 930 element.functionDeclaration.resolvedAst, compiler, inferrer); |
| 931 } | 931 } |
| 932 TypeInformation type = | 932 TypeInformation type = |
| 933 (defaultValue == null) ? types.nullType : visitor.visit(defaultValue); | 933 (defaultValue == null) ? types.nullType : visitor.visit(defaultValue); |
| 934 inferrer.setDefaultTypeOfParameter(element, type); | 934 inferrer.setDefaultTypeOfParameter(element, type); |
| 935 }); | 935 }); |
| 936 | 936 |
| 937 if (compiler.backend.isNative(analyzedElement)) { | 937 if (compiler.backend.isNative(analyzedElement)) { |
| 938 // Native methods do not have a body, and we currently just say | 938 // Native methods do not have a body, and we currently just say |
| 939 // they return dynamic. | 939 // they return dynamic. |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 // the safe side, we mark [this] as exposed here. We could do better by | 1068 // the safe side, we mark [this] as exposed here. We could do better by |
| 1069 // analyzing the closure. | 1069 // analyzing the closure. |
| 1070 // TODO(herhut): Analyze whether closure exposes this. | 1070 // TODO(herhut): Analyze whether closure exposes this. |
| 1071 isThisExposed = true; | 1071 isThisExposed = true; |
| 1072 LocalFunctionElement element = elements.getFunctionDefinition(node); | 1072 LocalFunctionElement element = elements.getFunctionDefinition(node); |
| 1073 // We don'TypeInformation put the closure in the work queue of the | 1073 // We don'TypeInformation put the closure in the work queue of the |
| 1074 // inferrer, because it will share information with its enclosing | 1074 // inferrer, because it will share information with its enclosing |
| 1075 // method, like for example the types of local variables. | 1075 // method, like for example the types of local variables. |
| 1076 LocalsHandler closureLocals = | 1076 LocalsHandler closureLocals = |
| 1077 new LocalsHandler.from(locals, node, useOtherTryBlock: false); | 1077 new LocalsHandler.from(locals, node, useOtherTryBlock: false); |
| 1078 SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor( | 1078 ElementGraphBuilder visitor = new ElementGraphBuilder( |
| 1079 element, element.resolvedAst, compiler, inferrer, closureLocals); | 1079 element, element.resolvedAst, compiler, inferrer, closureLocals); |
| 1080 visitor.run(); | 1080 visitor.run(); |
| 1081 inferrer.recordReturnType(element, visitor.returnType); | 1081 inferrer.recordReturnType(element, visitor.returnType); |
| 1082 | 1082 |
| 1083 // Record the types of captured non-boxed variables. Types of | 1083 // Record the types of captured non-boxed variables. Types of |
| 1084 // these variables may already be there, because of an analysis of | 1084 // these variables may already be there, because of an analysis of |
| 1085 // a previous closure. | 1085 // a previous closure. |
| 1086 ClosureClassMap nestedClosureData = compiler.closureToClassMapper | 1086 ClosureClassMap nestedClosureData = compiler.closureToClassMapper |
| 1087 .getClosureToClassMapping(element.resolvedAst); | 1087 .getClosureToClassMapping(element.resolvedAst); |
| 1088 nestedClosureData.forEachCapturedVariable((variable, field) { | 1088 nestedClosureData.forEachCapturedVariable((variable, field) { |
| (...skipping 1841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2930 Selector moveNextSelector = Selectors.moveNext; | 2930 Selector moveNextSelector = Selectors.moveNext; |
| 2931 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); | 2931 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); |
| 2932 | 2932 |
| 2933 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, | 2933 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, |
| 2934 iteratorMask, expressionType, new ArgumentsTypes.empty()); | 2934 iteratorMask, expressionType, new ArgumentsTypes.empty()); |
| 2935 | 2935 |
| 2936 return handleForInLoop(node, iteratorType, currentSelector, currentMask, | 2936 return handleForInLoop(node, iteratorType, currentSelector, currentMask, |
| 2937 moveNextSelector, moveNextMask); | 2937 moveNextSelector, moveNextMask); |
| 2938 } | 2938 } |
| 2939 } | 2939 } |
| OLD | NEW |