Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: pkg/compiler/lib/src/inferrer/builder.dart

Issue 2968743002: Use .callMethod instead of LocalFunctionElement as key in inference (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 ClosureRepresentationInfo; 7 import '../closure.dart' show ClosureRepresentationInfo;
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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 SemanticSendResolvedMixin<TypeInformation, dynamic>, 49 SemanticSendResolvedMixin<TypeInformation, dynamic>,
50 CompoundBulkMixin<TypeInformation, dynamic>, 50 CompoundBulkMixin<TypeInformation, dynamic>,
51 SetIfNullBulkMixin<TypeInformation, dynamic>, 51 SetIfNullBulkMixin<TypeInformation, dynamic>,
52 PrefixBulkMixin<TypeInformation, dynamic>, 52 PrefixBulkMixin<TypeInformation, dynamic>,
53 PostfixBulkMixin<TypeInformation, dynamic>, 53 PostfixBulkMixin<TypeInformation, dynamic>,
54 ErrorBulkMixin<TypeInformation, dynamic>, 54 ErrorBulkMixin<TypeInformation, dynamic>,
55 NewBulkMixin<TypeInformation, dynamic>, 55 NewBulkMixin<TypeInformation, dynamic>,
56 SetBulkMixin<TypeInformation, dynamic> 56 SetBulkMixin<TypeInformation, dynamic>
57 implements SemanticSendVisitor<TypeInformation, dynamic> { 57 implements SemanticSendVisitor<TypeInformation, dynamic> {
58 final Compiler compiler; 58 final Compiler compiler;
59 final ExecutableElement analyzedElement; 59 final MemberElement analyzedElement;
60 final ResolvedAst resolvedAst; 60 final ResolvedAst resolvedAst;
61 final TypeSystem types; 61 final TypeSystem types;
62 final Map<JumpTarget, List<LocalsHandler>> breaksFor = 62 final Map<JumpTarget, List<LocalsHandler>> breaksFor =
63 new Map<JumpTarget, List<LocalsHandler>>(); 63 new Map<JumpTarget, List<LocalsHandler>>();
64 final Map<JumpTarget, List<LocalsHandler>> continuesFor = 64 final Map<JumpTarget, List<LocalsHandler>> continuesFor =
65 new Map<JumpTarget, List<LocalsHandler>>(); 65 new Map<JumpTarget, List<LocalsHandler>>();
66 LocalsHandler locals; 66 LocalsHandler locals;
67 final List<TypeInformation> cascadeReceiverStack = 67 final List<TypeInformation> cascadeReceiverStack =
68 new List<TypeInformation>(); 68 new List<TypeInformation>();
69 69
70 TypeInformation returnType; 70 TypeInformation returnType;
71 bool visitingInitializers = false; 71 bool visitingInitializers = false;
72 bool isConstructorRedirect = false; 72 bool isConstructorRedirect = false;
73 bool seenSuperConstructorCall = false; 73 bool seenSuperConstructorCall = false;
74 SideEffects sideEffects = new SideEffects.empty(); 74 SideEffects sideEffects = new SideEffects.empty();
75 final MemberElement outermostElement; 75 final MemberElement outermostElement;
76 final InferrerEngine inferrer; 76 final InferrerEngine inferrer;
77 final Setlet<Entity> capturedVariables = new Setlet<Entity>(); 77 final Setlet<Entity> capturedVariables = new Setlet<Entity>();
78 final GlobalTypeInferenceElementData memberData; 78 final GlobalTypeInferenceElementData memberData;
79 79
80 ElementGraphBuilder.internal( 80 ElementGraphBuilder.internal(
81 ExecutableElement analyzedElement, 81 MemberElement analyzedElement,
82 this.resolvedAst, 82 this.resolvedAst,
83 this.outermostElement, 83 this.outermostElement,
84 InferrerEngine inferrer, 84 InferrerEngine inferrer,
85 this.compiler, 85 this.compiler,
86 this.locals) 86 this.locals)
87 : this.analyzedElement = analyzedElement, 87 : this.analyzedElement = analyzedElement,
88 this.inferrer = inferrer, 88 this.inferrer = inferrer,
89 this.types = inferrer.types, 89 this.types = inferrer.types,
90 this.memberData = inferrer.dataOfMember(analyzedElement.memberContext) { 90 this.memberData = inferrer.dataOfMember(analyzedElement.memberContext) {
91 assert(outermostElement != null); 91 assert(outermostElement != null);
92 if (locals != null) return; 92 if (locals != null) return;
93 ast.Node node; 93 ast.Node node;
94 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 94 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
95 node = resolvedAst.node; 95 node = resolvedAst.node;
96 } 96 }
97 FieldInitializationScope fieldScope = 97 FieldInitializationScope fieldScope =
98 analyzedElement.isGenerativeConstructor 98 analyzedElement.isGenerativeConstructor
99 ? new FieldInitializationScope(types) 99 ? new FieldInitializationScope(types)
100 : null; 100 : null;
101 locals = 101 locals =
102 new LocalsHandler(inferrer, types, compiler.options, node, fieldScope); 102 new LocalsHandler(inferrer, types, compiler.options, node, fieldScope);
103 } 103 }
104 104
105 ElementGraphBuilder(ExecutableElement element, ResolvedAst resolvedAst, 105 ElementGraphBuilder(MemberElement element, ResolvedAst resolvedAst,
106 Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler]) 106 Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler])
107 : this.internal(element, resolvedAst, element.memberContext, inferrer, 107 : this.internal(element, resolvedAst, element.memberContext, inferrer,
108 compiler, handler); 108 compiler, handler);
109 109
110 TreeElements get elements => resolvedAst.elements; 110 TreeElements get elements => resolvedAst.elements;
111 111
112 bool accumulateIsChecks = false; 112 bool accumulateIsChecks = false;
113 bool conditionIsSimple = false; 113 bool conditionIsSimple = false;
114 List<ast.Send> isChecks; 114 List<ast.Send> isChecks;
115 int loopLevel = 0; 115 int loopLevel = 0;
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 closureData.forEachCapturedVariable((variable, field) { 916 closureData.forEachCapturedVariable((variable, field) {
917 locals.setCaptured(variable, field); 917 locals.setCaptured(variable, field);
918 }); 918 });
919 closureData.forEachBoxedVariable((variable, field) { 919 closureData.forEachBoxedVariable((variable, field) {
920 locals.setCapturedAndBoxed(variable, field); 920 locals.setCapturedAndBoxed(variable, field);
921 }); 921 });
922 if (analyzedElement.isField) { 922 if (analyzedElement.isField) {
923 return visit(initializer); 923 return visit(initializer);
924 } 924 }
925 925
926 FunctionElement function = analyzedElement; 926 MethodElement function = analyzedElement;
927 FunctionSignature signature = function.functionSignature; 927 FunctionSignature signature = function.functionSignature;
928 signature.forEachOptionalParameter((FormalElement _element) { 928 signature.forEachOptionalParameter((FormalElement _element) {
929 ParameterElement element = _element; 929 ParameterElement element = _element;
930 ast.Expression defaultValue = element.initializer; 930 ast.Expression defaultValue = element.initializer;
931 // TODO(25566): The default value of a parameter of a redirecting factory 931 // TODO(25566): The default value of a parameter of a redirecting factory
932 // constructor comes from the corresponding parameter of the target. 932 // constructor comes from the corresponding parameter of the target.
933 933
934 // If this is a default value from a different context (because 934 // If this is a default value from a different context (because
935 // the current function is synthetic, e.g., a constructor from 935 // the current function is synthetic, e.g., a constructor from
936 // a mixin application), we have to start a new inferrer visitor 936 // a mixin application), we have to start a new inferrer visitor
937 // with the correct context. 937 // with the correct context.
938 // TODO(johnniwinther): Remove once function signatures are fixed. 938 // TODO(johnniwinther): Remove once function signatures are fixed.
939 ElementGraphBuilder visitor = this; 939 ElementGraphBuilder visitor = this;
940 if (inferrer.hasAlreadyComputedTypeOfParameterDefault(element)) return; 940 if (inferrer.hasAlreadyComputedTypeOfParameterDefault(element)) return;
941 if (element.functionDeclaration != analyzedElement) { 941 if (element.functionDeclaration.isLocal) {
Siggi Cherem (dart-lang) 2017/06/30 18:13:54 I was a bit confused by this extra check, but I th
Johnni Winther 2017/06/30 19:02:02 Copied in :)
942 LocalFunctionElement localFunction = element.functionDeclaration;
943 assert(
944 localFunction.callMethod == analyzedElement,
945 failedAt(
946 element,
947 "Unexpected function declaration "
948 "${localFunction.callMethod}, expected ${analyzedElement}."));
949 } else if (element.functionDeclaration != analyzedElement) {
942 ConstructorElement constructor = element.functionDeclaration; 950 ConstructorElement constructor = element.functionDeclaration;
943 visitor = new ElementGraphBuilder(constructor, 951 visitor = new ElementGraphBuilder(constructor,
944 element.functionDeclaration.resolvedAst, compiler, inferrer); 952 element.functionDeclaration.resolvedAst, compiler, inferrer);
945 } 953 }
946 TypeInformation type = 954 TypeInformation type =
947 (defaultValue == null) ? types.nullType : visitor.visit(defaultValue); 955 (defaultValue == null) ? types.nullType : visitor.visit(defaultValue);
948 inferrer.setDefaultTypeOfParameter(element, type); 956 inferrer.setDefaultTypeOfParameter(element, type);
949 }); 957 });
950 958
951 if (inferrer.isNativeMember(analyzedElement)) { 959 if (closedWorld.nativeData.isNativeMember(analyzedElement)) {
952 // Native methods do not have a body, and we currently just say 960 // Native methods do not have a body, and we currently just say
953 // they return dynamic. 961 // they return dynamic.
954 return types.dynamicType; 962 return types.dynamicType;
955 } 963 }
956 964
957 if (analyzedElement.isGenerativeConstructor) { 965 if (analyzedElement.isGenerativeConstructor) {
958 isThisExposed = false; 966 isThisExposed = false;
959 signature.forEachParameter((FormalElement _element) { 967 signature.forEachParameter((FormalElement _element) {
960 ParameterElement element = _element; 968 ParameterElement element = _element;
961 TypeInformation parameterType = inferrer.typeOfParameter(element); 969 TypeInformation parameterType = inferrer.typeOfParameter(element);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 case AsyncMarker.ASYNC: 1068 case AsyncMarker.ASYNC:
1061 recordReturnType(types.asyncFutureType); 1069 recordReturnType(types.asyncFutureType);
1062 break; 1070 break;
1063 1071
1064 case AsyncMarker.ASYNC_STAR: 1072 case AsyncMarker.ASYNC_STAR:
1065 recordReturnType(types.asyncStarStreamType); 1073 recordReturnType(types.asyncStarStreamType);
1066 break; 1074 break;
1067 } 1075 }
1068 } 1076 }
1069 1077
1070 inferrer.closedWorldRefiner 1078 MethodElement declaration = analyzedElement.declaration;
1071 .registerSideEffects(analyzedElement.declaration, sideEffects); 1079 inferrer.closedWorldRefiner.registerSideEffects(declaration, sideEffects);
1072 assert(breaksFor.isEmpty); 1080 assert(breaksFor.isEmpty);
1073 assert(continuesFor.isEmpty); 1081 assert(continuesFor.isEmpty);
1074 return returnType; 1082 return returnType;
1075 } 1083 }
1076 1084
1077 TypeInformation visitFunctionExpression(ast.FunctionExpression node) { 1085 TypeInformation visitFunctionExpression(ast.FunctionExpression node) {
1078 // We loose track of [this] in closures (see issue 20840). To be on 1086 // We loose track of [this] in closures (see issue 20840). To be on
1079 // the safe side, we mark [this] as exposed here. We could do better by 1087 // the safe side, we mark [this] as exposed here. We could do better by
1080 // analyzing the closure. 1088 // analyzing the closure.
1081 // TODO(herhut): Analyze whether closure exposes this. 1089 // TODO(herhut): Analyze whether closure exposes this.
1082 isThisExposed = true; 1090 isThisExposed = true;
1083 LocalFunctionElement element = elements.getFunctionDefinition(node); 1091 LocalFunctionElement element = elements.getFunctionDefinition(node);
1084 // We don'TypeInformation put the closure in the work queue of the 1092 // We don'TypeInformation put the closure in the work queue of the
1085 // inferrer, because it will share information with its enclosing 1093 // inferrer, because it will share information with its enclosing
1086 // method, like for example the types of local variables. 1094 // method, like for example the types of local variables.
1087 LocalsHandler closureLocals = 1095 LocalsHandler closureLocals =
1088 new LocalsHandler.from(locals, node, useOtherTryBlock: false); 1096 new LocalsHandler.from(locals, node, useOtherTryBlock: false);
1089 ElementGraphBuilder visitor = new ElementGraphBuilder( 1097 ElementGraphBuilder visitor = new ElementGraphBuilder(element.callMethod,
1090 element, element.resolvedAst, compiler, inferrer, closureLocals); 1098 element.resolvedAst, compiler, inferrer, closureLocals);
1091 visitor.run(); 1099 visitor.run();
1092 inferrer.recordReturnTypeOfLocalFunction(element, visitor.returnType); 1100 inferrer.recordReturnType(element.callMethod, visitor.returnType);
1093 1101
1094 // Record the types of captured non-boxed variables. Types of 1102 // Record the types of captured non-boxed variables. Types of
1095 // these variables may already be there, because of an analysis of 1103 // these variables may already be there, because of an analysis of
1096 // a previous closure. 1104 // a previous closure.
1097 ClosureRepresentationInfo nestedClosureData = compiler 1105 ClosureRepresentationInfo nestedClosureData = compiler
1098 .backendStrategy.closureDataLookup 1106 .backendStrategy.closureDataLookup
1099 .getClosureRepresentationInfo(element); 1107 .getClosureRepresentationInfo(element);
1100 nestedClosureData.forEachCapturedVariable((variable, field) { 1108 nestedClosureData.forEachCapturedVariable((variable, field) {
1101 if (!nestedClosureData.isVariableBoxed(variable)) { 1109 if (!nestedClosureData.isVariableBoxed(variable)) {
1102 if (variable == nestedClosureData.thisLocal) { 1110 if (variable == nestedClosureData.thisLocal) {
1103 inferrer.recordTypeOfField(field, thisType); 1111 inferrer.recordTypeOfField(field, thisType);
1104 } 1112 }
1105 // The type is null for type parameters. 1113 // The type is null for type parameters.
1106 if (locals.locals[variable] == null) return; 1114 if (locals.locals[variable] == null) return;
1107 inferrer.recordTypeOfField(field, locals.locals[variable]); 1115 inferrer.recordTypeOfField(field, locals.locals[variable]);
1108 } 1116 }
1109 capturedVariables.add(variable); 1117 capturedVariables.add(variable);
1110 }); 1118 });
1111 1119
1112 return inferrer.concreteTypes.putIfAbsent(node, () { 1120 return inferrer.concreteTypes.putIfAbsent(node, () {
1113 return types.allocateClosureForLocalFunction(node, element); 1121 return types.allocateClosureForMethod(node, element.callMethod);
1114 }); 1122 });
1115 } 1123 }
1116 1124
1117 TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) { 1125 TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) {
1118 LocalFunctionElement element = 1126 LocalFunctionElement element =
1119 elements.getFunctionDefinition(node.function); 1127 elements.getFunctionDefinition(node.function);
1120 TypeInformation type = 1128 TypeInformation type =
1121 inferrer.concreteTypes.putIfAbsent(node.function, () { 1129 inferrer.concreteTypes.putIfAbsent(node.function, () {
1122 return types.allocateClosureForLocalFunction(node.function, element); 1130 return types.allocateClosureForMethod(node.function, element.callMethod);
1123 }); 1131 });
1124 locals.update(element, type, node); 1132 locals.update(element, type, node);
1125 visit(node.function); 1133 visit(node.function);
1126 return type; 1134 return type;
1127 } 1135 }
1128 1136
1129 TypeInformation visitStringInterpolation(ast.StringInterpolation node) { 1137 TypeInformation visitStringInterpolation(ast.StringInterpolation node) {
1130 // Interpolation could have any effects since it could call any toString() 1138 // Interpolation could have any effects since it could call any toString()
1131 // method. 1139 // method.
1132 // TODO(sra): This could be modelled by a call to toString() but with a 1140 // TODO(sra): This could be modelled by a call to toString() but with a
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after
2688 LocalFunctionElement function, 2696 LocalFunctionElement function,
2689 ast.NodeList arguments, 2697 ast.NodeList arguments,
2690 CallStructure callStructure, 2698 CallStructure callStructure,
2691 _) { 2699 _) {
2692 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments); 2700 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments);
2693 Selector selector = elements.getSelector(node); 2701 Selector selector = elements.getSelector(node);
2694 TypeMask mask = memberData.typeOfSend(node); 2702 TypeMask mask = memberData.typeOfSend(node);
2695 // This only works for function statements. We need a 2703 // This only works for function statements. We need a
2696 // more sophisticated type system with function types to support 2704 // more sophisticated type system with function types to support
2697 // more. 2705 // more.
2698 return inferrer.registerCalledLocalFunction(node, selector, mask, 2706 return inferrer.registerCalledMember(node, selector, mask, outermostElement,
2699 outermostElement, function, argumentTypes, sideEffects, inLoop); 2707 function.callMethod, argumentTypes, sideEffects, inLoop);
2700 } 2708 }
2701 2709
2702 @override 2710 @override
2703 TypeInformation visitLocalFunctionIncompatibleInvoke( 2711 TypeInformation visitLocalFunctionIncompatibleInvoke(
2704 ast.Send node, 2712 ast.Send node,
2705 LocalFunctionElement function, 2713 LocalFunctionElement function,
2706 ast.NodeList arguments, 2714 ast.NodeList arguments,
2707 CallStructure callStructure, 2715 CallStructure callStructure,
2708 _) { 2716 _) {
2709 analyzeArguments(node.arguments); 2717 analyzeArguments(node.arguments);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2790 return types.boolType; 2798 return types.boolType;
2791 } else if (types.isNull(arguments.positional[0])) { 2799 } else if (types.isNull(arguments.positional[0])) {
2792 potentiallyAddNullCheck(node, node.receiver); 2800 potentiallyAddNullCheck(node, node.receiver);
2793 return types.boolType; 2801 return types.boolType;
2794 } 2802 }
2795 } 2803 }
2796 return handleDynamicSend(node, selector, mask, receiverType, arguments); 2804 return handleDynamicSend(node, selector, mask, receiverType, arguments);
2797 } 2805 }
2798 2806
2799 void recordReturnType(TypeInformation type) { 2807 void recordReturnType(TypeInformation type) {
2800 if (analyzedElement.isLocal) { 2808 returnType =
2801 returnType = inferrer.addReturnTypeForLocalFunction( 2809 inferrer.addReturnTypeForMethod(analyzedElement, returnType, type);
2802 analyzedElement, returnType, type);
2803 } else {
2804 returnType =
2805 inferrer.addReturnTypeForMethod(analyzedElement, returnType, type);
2806 }
2807 } 2810 }
2808 2811
2809 TypeInformation synthesizeForwardingCall( 2812 TypeInformation synthesizeForwardingCall(
2810 Spannable node, ConstructorElement element) { 2813 Spannable node, ConstructorElement element) {
2811 element = element.implementation; 2814 element = element.implementation;
2812 FunctionElement function = analyzedElement; 2815 MethodElement function = analyzedElement;
2813 FunctionSignature signature = function.functionSignature; 2816 FunctionSignature signature = function.functionSignature;
2814 FunctionSignature calleeSignature = element.functionSignature; 2817 FunctionSignature calleeSignature = element.functionSignature;
2815 if (!calleeSignature.isCompatibleWith(signature)) { 2818 if (!calleeSignature.isCompatibleWith(signature)) {
2816 return types.nonNullEmpty(); 2819 return types.nonNullEmpty();
2817 } 2820 }
2818 2821
2819 List<TypeInformation> unnamed = <TypeInformation>[]; 2822 List<TypeInformation> unnamed = <TypeInformation>[];
2820 signature.forEachRequiredParameter((FormalElement _element) { 2823 signature.forEachRequiredParameter((FormalElement _element) {
2821 ParameterElement element = _element; 2824 ParameterElement element = _element;
2822 assert(locals.use(element) != null); 2825 assert(locals.use(element) != null);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2933 Selector moveNextSelector = Selectors.moveNext; 2936 Selector moveNextSelector = Selectors.moveNext;
2934 TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node); 2937 TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node);
2935 2938
2936 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, 2939 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector,
2937 iteratorMask, expressionType, new ArgumentsTypes.empty()); 2940 iteratorMask, expressionType, new ArgumentsTypes.empty());
2938 2941
2939 return handleForInLoop(node, iteratorType, currentSelector, currentMask, 2942 return handleForInLoop(node, iteratorType, currentSelector, currentMask,
2940 moveNextSelector, moveNextMask); 2943 moveNextSelector, moveNextMask);
2941 } 2944 }
2942 } 2945 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698