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

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

Issue 2955353002: Split inference type-info accessors into members, parameters and local functions (Closed)
Patch Set: Updated cf. comments 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(Element element, ResolvedAst resolvedAst, 105 ElementGraphBuilder(AstElement element, ResolvedAst resolvedAst,
106 Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler]) 106 Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler])
107 : this.internal( 107 : this.internal(
108 element, 108 element,
109 resolvedAst, 109 resolvedAst,
110 element.outermostEnclosingMemberOrTopLevel.implementation, 110 element.outermostEnclosingMemberOrTopLevel.implementation,
111 inferrer, 111 inferrer,
112 compiler, 112 compiler,
113 handler); 113 handler);
114 114
115 TreeElements get elements => resolvedAst.elements; 115 TreeElements get elements => resolvedAst.elements;
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 } 884 }
885 885
886 TypeInformation visitCascade(ast.Cascade node) { 886 TypeInformation visitCascade(ast.Cascade node) {
887 // Ignore the result of the cascade send and return the type of the cascade 887 // Ignore the result of the cascade send and return the type of the cascade
888 // receiver. 888 // receiver.
889 visit(node.expression); 889 visit(node.expression);
890 return cascadeReceiverStack.removeLast(); 890 return cascadeReceiverStack.removeLast();
891 } 891 }
892 892
893 void analyzeSuperConstructorCall( 893 void analyzeSuperConstructorCall(
894 AstElement target, ArgumentsTypes arguments) { 894 ConstructorElement target, ArgumentsTypes arguments) {
895 ResolvedAst resolvedAst = target.resolvedAst; 895 ResolvedAst resolvedAst = target.resolvedAst;
896 inferrer.analyze(resolvedAst, arguments); 896 inferrer.analyze(resolvedAst, arguments);
897 isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target); 897 isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target);
898 } 898 }
899 899
900 TypeInformation run() { 900 TypeInformation run() {
901 var node; 901 var node;
902 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 902 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
903 node = resolvedAst.node; 903 node = resolvedAst.node;
904 } 904 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 // constructor comes from the corresponding parameter of the target. 937 // constructor comes from the corresponding parameter of the target.
938 938
939 // If this is a default value from a different context (because 939 // If this is a default value from a different context (because
940 // the current function is synthetic, e.g., a constructor from 940 // the current function is synthetic, e.g., a constructor from
941 // a mixin application), we have to start a new inferrer visitor 941 // a mixin application), we have to start a new inferrer visitor
942 // with the correct context. 942 // with the correct context.
943 // TODO(johnniwinther): Remove once function signatures are fixed. 943 // TODO(johnniwinther): Remove once function signatures are fixed.
944 ElementGraphBuilder visitor = this; 944 ElementGraphBuilder visitor = this;
945 if (inferrer.hasAlreadyComputedTypeOfParameterDefault(element)) return; 945 if (inferrer.hasAlreadyComputedTypeOfParameterDefault(element)) return;
946 if (element.functionDeclaration != analyzedElement) { 946 if (element.functionDeclaration != analyzedElement) {
947 visitor = new ElementGraphBuilder(element.functionDeclaration, 947 ConstructorElement constructor = element.functionDeclaration;
948 visitor = new ElementGraphBuilder(constructor,
948 element.functionDeclaration.resolvedAst, compiler, inferrer); 949 element.functionDeclaration.resolvedAst, compiler, inferrer);
949 } 950 }
950 TypeInformation type = 951 TypeInformation type =
951 (defaultValue == null) ? types.nullType : visitor.visit(defaultValue); 952 (defaultValue == null) ? types.nullType : visitor.visit(defaultValue);
952 inferrer.setDefaultTypeOfParameter(element, type); 953 inferrer.setDefaultTypeOfParameter(element, type);
953 }); 954 });
954 955
955 if (inferrer.isNativeMember(analyzedElement)) { 956 if (inferrer.isNativeMember(analyzedElement)) {
956 // Native methods do not have a body, and we currently just say 957 // Native methods do not have a body, and we currently just say
957 // they return dynamic. 958 // they return dynamic.
958 return types.dynamicType; 959 return types.dynamicType;
959 } 960 }
960 961
961 if (analyzedElement.isGenerativeConstructor) { 962 if (analyzedElement.isGenerativeConstructor) {
962 isThisExposed = false; 963 isThisExposed = false;
963 signature.forEachParameter((FormalElement _element) { 964 signature.forEachParameter((FormalElement _element) {
964 ParameterElement element = _element; 965 ParameterElement element = _element;
965 TypeInformation parameterType = inferrer.typeOfElement(element); 966 TypeInformation parameterType = inferrer.typeOfParameter(element);
966 if (element.isInitializingFormal) { 967 if (element.isInitializingFormal) {
967 InitializingFormalElement initializingFormal = element; 968 InitializingFormalElement initializingFormal = element;
968 if (initializingFormal.fieldElement.isFinal) { 969 if (initializingFormal.fieldElement.isFinal) {
969 inferrer.recordTypeOfFinalField(node, analyzedElement, 970 inferrer.recordTypeOfFinalField(
970 initializingFormal.fieldElement, parameterType); 971 initializingFormal.fieldElement, parameterType);
971 } else { 972 } else {
972 locals.updateField(initializingFormal.fieldElement, parameterType); 973 locals.updateField(initializingFormal.fieldElement, parameterType);
973 inferrer.recordTypeOfNonFinalField(initializingFormal.node, 974 inferrer.recordTypeOfNonFinalField(
974 initializingFormal.fieldElement, parameterType); 975 initializingFormal.fieldElement, parameterType);
975 } 976 }
976 } 977 }
977 locals.update(element, parameterType, node); 978 locals.update(element, parameterType, node);
978 }); 979 });
979 ClassElement cls = analyzedElement.enclosingClass; 980 ClassElement cls = analyzedElement.enclosingClass;
980 Spannable spannable = node; 981 Spannable spannable = node;
981 if (analyzedElement.isSynthesized) { 982 if (analyzedElement.isSynthesized) {
982 spannable = analyzedElement; 983 spannable = analyzedElement;
983 ConstructorElement constructor = analyzedElement; 984 ConstructorElement constructor = analyzedElement;
(...skipping 15 matching lines...) Expand all
999 // For a generative constructor like: `Foo();`, we synthesize 1000 // For a generative constructor like: `Foo();`, we synthesize
1000 // a call to the default super constructor (the one that takes 1001 // a call to the default super constructor (the one that takes
1001 // no argument). Resolution ensures that such a constructor 1002 // no argument). Resolution ensures that such a constructor
1002 // exists. 1003 // exists.
1003 if (!isConstructorRedirect && 1004 if (!isConstructorRedirect &&
1004 !seenSuperConstructorCall && 1005 !seenSuperConstructorCall &&
1005 !cls.isObject) { 1006 !cls.isObject) {
1006 ConstructorElement target = cls.superclass.lookupDefaultConstructor(); 1007 ConstructorElement target = cls.superclass.lookupDefaultConstructor();
1007 ArgumentsTypes arguments = new ArgumentsTypes([], {}); 1008 ArgumentsTypes arguments = new ArgumentsTypes([], {});
1008 analyzeSuperConstructorCall(target, arguments); 1009 analyzeSuperConstructorCall(target, arguments);
1009 inferrer.registerCalledElement(node, null, null, outermostElement, 1010 inferrer.registerCalledMember(node, null, null, outermostElement,
1010 target.implementation, arguments, sideEffects, inLoop); 1011 target.implementation, arguments, sideEffects, inLoop);
1011 } 1012 }
1012 visit(node.body); 1013 visit(node.body);
1013 inferrer.recordExposesThis(analyzedElement, isThisExposed); 1014 inferrer.recordExposesThis(analyzedElement, isThisExposed);
1014 } 1015 }
1015 if (!isConstructorRedirect) { 1016 if (!isConstructorRedirect) {
1016 // Iterate over all instance fields, and give a null type to 1017 // Iterate over all instance fields, and give a null type to
1017 // fields that we haven'TypeInformation initialized for sure. 1018 // fields that we haven'TypeInformation initialized for sure.
1018 cls.forEachInstanceField((_, FieldElement field) { 1019 cls.forEachInstanceField((_, FieldElement field) {
1019 if (field.isFinal) return; 1020 if (field.isFinal) return;
1020 TypeInformation type = locals.fieldScope.readField(field); 1021 TypeInformation type = locals.fieldScope.readField(field);
1021 ResolvedAst resolvedAst = field.resolvedAst; 1022 ResolvedAst resolvedAst = field.resolvedAst;
1022 if (type == null && resolvedAst.body == null) { 1023 if (type == null && resolvedAst.body == null) {
1023 inferrer.recordTypeOfNonFinalField( 1024 inferrer.recordTypeOfNonFinalField(field, types.nullType);
1024 spannable, field, types.nullType);
1025 } 1025 }
1026 }); 1026 });
1027 } 1027 }
1028 if (analyzedElement.isGenerativeConstructor && cls.isAbstract) { 1028 if (analyzedElement.isGenerativeConstructor && cls.isAbstract) {
1029 if (closedWorld.isInstantiated(cls)) { 1029 if (closedWorld.isInstantiated(cls)) {
1030 returnType = types.nonNullSubclass(cls); 1030 returnType = types.nonNullSubclass(cls);
1031 } else { 1031 } else {
1032 // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this 1032 // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this
1033 // case; it's never called. 1033 // case; it's never called.
1034 returnType = types.nonNullEmpty(); 1034 returnType = types.nonNullEmpty();
1035 } 1035 }
1036 } else { 1036 } else {
1037 returnType = types.nonNullExact(cls); 1037 returnType = types.nonNullExact(cls);
1038 } 1038 }
1039 } else { 1039 } else {
1040 signature.forEachParameter((FormalElement _element) { 1040 signature.forEachParameter((FormalElement _element) {
1041 ParameterElement element = _element; 1041 ParameterElement element = _element;
1042 locals.update(element, inferrer.typeOfElement(element), node); 1042 locals.update(element, inferrer.typeOfParameter(element), node);
1043 }); 1043 });
1044 visit(node.body); 1044 visit(node.body);
1045 switch (function.asyncMarker) { 1045 switch (function.asyncMarker) {
1046 case AsyncMarker.SYNC: 1046 case AsyncMarker.SYNC:
1047 if (returnType == null) { 1047 if (returnType == null) {
1048 // No return in the body. 1048 // No return in the body.
1049 returnType = locals.seenReturnOrThrow 1049 returnType = locals.seenReturnOrThrow
1050 ? types.nonNullEmpty() // Body always throws. 1050 ? types.nonNullEmpty() // Body always throws.
1051 : types.nullType; 1051 : types.nullType;
1052 } else if (!locals.seenReturnOrThrow) { 1052 } else if (!locals.seenReturnOrThrow) {
1053 // We haven'TypeInformation seen returns on all branches. So the met hod may 1053 // We haven'TypeInformation seen returns on all branches. So the met hod may
1054 // also return null. 1054 // also return null.
1055 returnType = inferrer.addReturnTypeFor( 1055 recordReturnType(types.nullType);
1056 analyzedElement, returnType, types.nullType);
1057 } 1056 }
1058 break; 1057 break;
1059 1058
1060 case AsyncMarker.SYNC_STAR: 1059 case AsyncMarker.SYNC_STAR:
1061 // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type 1060 // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
1062 // contained is the method body's return type. 1061 // contained is the method body's return type.
1063 returnType = inferrer.addReturnTypeFor( 1062 recordReturnType(types.syncStarIterableType);
1064 analyzedElement, returnType, types.syncStarIterableType);
1065 break; 1063 break;
1066 1064
1067 case AsyncMarker.ASYNC: 1065 case AsyncMarker.ASYNC:
1068 returnType = inferrer.addReturnTypeFor( 1066 recordReturnType(types.asyncFutureType);
1069 analyzedElement, returnType, types.asyncFutureType);
1070 break; 1067 break;
1071 1068
1072 case AsyncMarker.ASYNC_STAR: 1069 case AsyncMarker.ASYNC_STAR:
1073 returnType = inferrer.addReturnTypeFor( 1070 recordReturnType(types.asyncStarStreamType);
1074 analyzedElement, returnType, types.asyncStarStreamType);
1075 break; 1071 break;
1076 } 1072 }
1077 } 1073 }
1078 1074
1079 inferrer.closedWorldRefiner 1075 inferrer.closedWorldRefiner
1080 .registerSideEffects(analyzedElement.declaration, sideEffects); 1076 .registerSideEffects(analyzedElement.declaration, sideEffects);
1081 assert(breaksFor.isEmpty); 1077 assert(breaksFor.isEmpty);
1082 assert(continuesFor.isEmpty); 1078 assert(continuesFor.isEmpty);
1083 return returnType; 1079 return returnType;
1084 } 1080 }
1085 1081
1086 TypeInformation visitFunctionExpression(ast.FunctionExpression node) { 1082 TypeInformation visitFunctionExpression(ast.FunctionExpression node) {
1087 // We loose track of [this] in closures (see issue 20840). To be on 1083 // We loose track of [this] in closures (see issue 20840). To be on
1088 // the safe side, we mark [this] as exposed here. We could do better by 1084 // the safe side, we mark [this] as exposed here. We could do better by
1089 // analyzing the closure. 1085 // analyzing the closure.
1090 // TODO(herhut): Analyze whether closure exposes this. 1086 // TODO(herhut): Analyze whether closure exposes this.
1091 isThisExposed = true; 1087 isThisExposed = true;
1092 LocalFunctionElement element = elements.getFunctionDefinition(node); 1088 LocalFunctionElement element = elements.getFunctionDefinition(node);
1093 // We don'TypeInformation put the closure in the work queue of the 1089 // We don'TypeInformation put the closure in the work queue of the
1094 // inferrer, because it will share information with its enclosing 1090 // inferrer, because it will share information with its enclosing
1095 // method, like for example the types of local variables. 1091 // method, like for example the types of local variables.
1096 LocalsHandler closureLocals = 1092 LocalsHandler closureLocals =
1097 new LocalsHandler.from(locals, node, useOtherTryBlock: false); 1093 new LocalsHandler.from(locals, node, useOtherTryBlock: false);
1098 ElementGraphBuilder visitor = new ElementGraphBuilder( 1094 ElementGraphBuilder visitor = new ElementGraphBuilder(
1099 element, element.resolvedAst, compiler, inferrer, closureLocals); 1095 element, element.resolvedAst, compiler, inferrer, closureLocals);
1100 visitor.run(); 1096 visitor.run();
1101 inferrer.recordReturnType(element, visitor.returnType); 1097 inferrer.recordReturnTypeOfLocalFunction(element, visitor.returnType);
1102 1098
1103 // Record the types of captured non-boxed variables. Types of 1099 // Record the types of captured non-boxed variables. Types of
1104 // these variables may already be there, because of an analysis of 1100 // these variables may already be there, because of an analysis of
1105 // a previous closure. 1101 // a previous closure.
1106 ClosureRepresentationInfo nestedClosureData = compiler 1102 ClosureRepresentationInfo nestedClosureData = compiler
1107 .backendStrategy.closureDataLookup 1103 .backendStrategy.closureDataLookup
1108 .getClosureRepresentationInfo(element); 1104 .getClosureRepresentationInfo(element);
1109 nestedClosureData.forEachCapturedVariable((variable, field) { 1105 nestedClosureData.forEachCapturedVariable((variable, field) {
1110 if (!nestedClosureData.isVariableBoxed(variable)) { 1106 if (!nestedClosureData.isVariableBoxed(variable)) {
1111 if (variable == nestedClosureData.thisLocal) { 1107 if (variable == nestedClosureData.thisLocal) {
1112 inferrer.recordType(field, thisType); 1108 inferrer.recordTypeOfField(field, thisType);
1113 } 1109 }
1114 // The type is null for type parameters. 1110 // The type is null for type parameters.
1115 if (locals.locals[variable] == null) return; 1111 if (locals.locals[variable] == null) return;
1116 inferrer.recordType(field, locals.locals[variable]); 1112 inferrer.recordTypeOfField(field, locals.locals[variable]);
1117 } 1113 }
1118 capturedVariables.add(variable); 1114 capturedVariables.add(variable);
1119 }); 1115 });
1120 1116
1121 return inferrer.concreteTypes.putIfAbsent(node, () { 1117 return inferrer.concreteTypes.putIfAbsent(node, () {
1122 return types.allocateClosure(node, element); 1118 return types.allocateClosure(node, element);
1123 }); 1119 });
1124 } 1120 }
1125 1121
1126 TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) { 1122 TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 if (element.isField) { 1199 if (element.isField) {
1204 ResolvedAst elementResolvedAst = element.resolvedAst; 1200 ResolvedAst elementResolvedAst = element.resolvedAst;
1205 if (!selector.isSetter && 1201 if (!selector.isSetter &&
1206 isInClassOrSubclass(element) && 1202 isInClassOrSubclass(element) &&
1207 !element.isFinal && 1203 !element.isFinal &&
1208 locals.fieldScope.readField(element) == null && 1204 locals.fieldScope.readField(element) == null &&
1209 elementResolvedAst.body == null) { 1205 elementResolvedAst.body == null) {
1210 // If the field is being used before this constructor 1206 // If the field is being used before this constructor
1211 // actually had a chance to initialize it, say it can be 1207 // actually had a chance to initialize it, say it can be
1212 // null. 1208 // null.
1213 inferrer.recordTypeOfNonFinalField( 1209 inferrer.recordTypeOfNonFinalField(element, types.nullType);
1214 resolvedAst.node, element, types.nullType);
1215 } 1210 }
1216 // Accessing a field does not expose [:this:]. 1211 // Accessing a field does not expose [:this:].
1217 return true; 1212 return true;
1218 } 1213 }
1219 // TODO(ngeoffray): We could do better here if we knew what we 1214 // TODO(ngeoffray): We could do better here if we knew what we
1220 // are calling does not expose this. 1215 // are calling does not expose this.
1221 isThisExposed = true; 1216 isThisExposed = true;
1222 return false; 1217 return false;
1223 }); 1218 });
1224 } 1219 }
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 MemberElement single = targets.first; 1984 MemberElement single = targets.first;
1990 if (single.isField) { 1985 if (single.isField) {
1991 locals.updateField(single, rhsType); 1986 locals.updateField(single, rhsType);
1992 } 1987 }
1993 } 1988 }
1994 } 1989 }
1995 handleDynamicSend( 1990 handleDynamicSend(
1996 node, setterSelector, setterMask, receiverType, arguments); 1991 node, setterSelector, setterMask, receiverType, arguments);
1997 } else if (element.isField) { 1992 } else if (element.isField) {
1998 if (element.isFinal) { 1993 if (element.isFinal) {
1999 inferrer.recordTypeOfFinalField( 1994 inferrer.recordTypeOfFinalField(element, rhsType);
2000 node, outermostElement, element, rhsType);
2001 } else { 1995 } else {
2002 if (analyzedElement.isGenerativeConstructor) { 1996 if (analyzedElement.isGenerativeConstructor) {
2003 locals.updateField(element, rhsType); 1997 locals.updateField(element, rhsType);
2004 } 1998 }
2005 if (visitingInitializers) { 1999 if (visitingInitializers) {
2006 inferrer.recordTypeOfNonFinalField(node, element, rhsType); 2000 inferrer.recordTypeOfNonFinalField(element, rhsType);
2007 } else { 2001 } else {
2008 handleDynamicSend( 2002 handleDynamicSend(
2009 node, setterSelector, setterMask, receiverType, arguments); 2003 node, setterSelector, setterMask, receiverType, arguments);
2010 } 2004 }
2011 } 2005 }
2012 } else if (element.isLocal) { 2006 } else if (element.isLocal) {
2013 locals.update(element, rhsType, node); 2007 locals.update(element, rhsType, node);
2014 } 2008 }
2015 return rhsType; 2009 return rhsType;
2016 } 2010 }
(...skipping 20 matching lines...) Expand all
2037 if (!Selectors.noSuchMethod_.signatureApplies(element)) { 2031 if (!Selectors.noSuchMethod_.signatureApplies(element)) {
2038 ClassElement objectClass = closedWorld.commonElements.objectClass; 2032 ClassElement objectClass = closedWorld.commonElements.objectClass;
2039 element = objectClass.lookupMember(Identifiers.noSuchMethod_); 2033 element = objectClass.lookupMember(Identifiers.noSuchMethod_);
2040 } 2034 }
2041 return handleStaticSend(node, selector, mask, element, arguments); 2035 return handleStaticSend(node, selector, mask, element, arguments);
2042 } 2036 }
2043 2037
2044 /// Handle a .call invocation on the values retrieved from the super 2038 /// Handle a .call invocation on the values retrieved from the super
2045 /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter. 2039 /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter.
2046 TypeInformation handleSuperClosureCall( 2040 TypeInformation handleSuperClosureCall(
2047 ast.Send node, Element element, ast.NodeList arguments) { 2041 ast.Send node, MemberElement element, ast.NodeList arguments) {
2048 ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes); 2042 ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes);
2049 Selector selector = elements.getSelector(node); 2043 Selector selector = elements.getSelector(node);
2050 TypeMask mask = inTreeData.typeOfSend(node); 2044 TypeMask mask = inTreeData.typeOfSend(node);
2051 // TODO(herhut): We could do better here if we knew what we 2045 // TODO(herhut): We could do better here if we knew what we
2052 // are calling does not expose this. 2046 // are calling does not expose this.
2053 isThisExposed = true; 2047 isThisExposed = true;
2054 return inferrer.registerCalledClosure( 2048 return inferrer.registerCalledClosure(
2055 node, 2049 node,
2056 selector, 2050 selector,
2057 mask, 2051 mask,
2058 inferrer.typeOfElement(element), 2052 inferrer.typeOfMember(element),
2059 outermostElement, 2053 outermostElement,
2060 argumentTypes, 2054 argumentTypes,
2061 sideEffects, 2055 sideEffects,
2062 inLoop); 2056 inLoop);
2063 } 2057 }
2064 2058
2065 /// Handle an invocation of super [method]. 2059 /// Handle an invocation of super [method].
2066 TypeInformation handleSuperMethodInvoke( 2060 TypeInformation handleSuperMethodInvoke(
2067 ast.Send node, MethodElement method, ArgumentsTypes arguments) { 2061 ast.Send node, MethodElement method, ArgumentsTypes arguments) {
2068 // TODO(herhut): We could do better here if we knew what we 2062 // TODO(herhut): We could do better here if we knew what we
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
2347 ? types.nullType 2341 ? types.nullType
2348 : arguments.positional[1]; 2342 : arguments.positional[1];
2349 2343
2350 return inferrer.concreteTypes.putIfAbsent( 2344 return inferrer.concreteTypes.putIfAbsent(
2351 node, 2345 node,
2352 () => types.allocateList(types.fixedListType, node, outermostElement, 2346 () => types.allocateList(types.fixedListType, node, outermostElement,
2353 elementType, length)); 2347 elementType, length));
2354 } else if (Elements.isConstructorOfTypedArraySubclass( 2348 } else if (Elements.isConstructorOfTypedArraySubclass(
2355 constructor, closedWorld)) { 2349 constructor, closedWorld)) {
2356 int length = findLength(node); 2350 int length = findLength(node);
2357 TypeInformation elementType = inferrer 2351 TypeInformation elementType =
2358 .returnTypeOfElement(target.enclosingClass.lookupMember('[]')); 2352 inferrer.returnTypeOfMember(target.enclosingClass.lookupMember('[]'));
2359 return inferrer.concreteTypes.putIfAbsent( 2353 return inferrer.concreteTypes.putIfAbsent(
2360 node, 2354 node,
2361 () => types.allocateList(types.nonNullExact(target.enclosingClass), 2355 () => types.allocateList(types.nonNullExact(target.enclosingClass),
2362 node, outermostElement, elementType, length)); 2356 node, outermostElement, elementType, length));
2363 } else { 2357 } else {
2364 return returnType; 2358 return returnType;
2365 } 2359 }
2366 } 2360 }
2367 2361
2368 @override 2362 @override
2369 TypeInformation bulkHandleNew(ast.NewExpression node, _) { 2363 TypeInformation bulkHandleNew(ast.NewExpression node, _) {
2370 Element element = elements[node.send]; 2364 Element element = elements[node.send];
2371 return handleConstructorSend(node.send, element); 2365 return handleConstructorSend(node.send, element);
2372 } 2366 }
2373 2367
2374 @override 2368 @override
2375 TypeInformation errorNonConstantConstructorInvoke( 2369 TypeInformation errorNonConstantConstructorInvoke(
2376 ast.NewExpression node, 2370 ast.NewExpression node,
2377 Element element, 2371 Element element,
2378 ResolutionDartType type, 2372 ResolutionDartType type,
2379 ast.NodeList arguments, 2373 ast.NodeList arguments,
2380 CallStructure callStructure, 2374 CallStructure callStructure,
2381 _) { 2375 _) {
2382 return bulkHandleNew(node, _); 2376 return bulkHandleNew(node, _);
2383 } 2377 }
2384 2378
2385 /// Handle invocation of a top level or static field or getter [element]. 2379 /// Handle invocation of a top level or static field or getter [element].
2386 TypeInformation handleStaticFieldOrGetterInvoke( 2380 TypeInformation handleStaticFieldOrGetterInvoke(
2387 ast.Send node, Element element) { 2381 ast.Send node, MemberElement element) {
2388 ArgumentsTypes arguments = analyzeArguments(node.arguments); 2382 ArgumentsTypes arguments = analyzeArguments(node.arguments);
2389 Selector selector = elements.getSelector(node); 2383 Selector selector = elements.getSelector(node);
2390 TypeMask mask = inTreeData.typeOfSend(node); 2384 TypeMask mask = inTreeData.typeOfSend(node);
2391 handleStaticSend(node, selector, mask, element, arguments); 2385 handleStaticSend(node, selector, mask, element, arguments);
2392 return inferrer.registerCalledClosure( 2386 return inferrer.registerCalledClosure(
2393 node, 2387 node,
2394 selector, 2388 selector,
2395 mask, 2389 mask,
2396 inferrer.typeOfElement(element), 2390 inferrer.typeOfMember(element),
2397 outermostElement, 2391 outermostElement,
2398 arguments, 2392 arguments,
2399 sideEffects, 2393 sideEffects,
2400 inLoop); 2394 inLoop);
2401 } 2395 }
2402 2396
2403 /// Handle invocation of a top level or static [function]. 2397 /// Handle invocation of a top level or static [function].
2404 TypeInformation handleStaticFunctionInvoke( 2398 TypeInformation handleStaticFunctionInvoke(
2405 ast.Send node, MethodElement function) { 2399 ast.Send node, MethodElement function) {
2406 if (compiler.backend.isForeign(closedWorld.commonElements, function)) { 2400 if (compiler.backend.isForeign(closedWorld.commonElements, function)) {
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2699 LocalFunctionElement function, 2693 LocalFunctionElement function,
2700 ast.NodeList arguments, 2694 ast.NodeList arguments,
2701 CallStructure callStructure, 2695 CallStructure callStructure,
2702 _) { 2696 _) {
2703 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments); 2697 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments);
2704 Selector selector = elements.getSelector(node); 2698 Selector selector = elements.getSelector(node);
2705 TypeMask mask = inTreeData.typeOfSend(node); 2699 TypeMask mask = inTreeData.typeOfSend(node);
2706 // This only works for function statements. We need a 2700 // This only works for function statements. We need a
2707 // more sophisticated type system with function types to support 2701 // more sophisticated type system with function types to support
2708 // more. 2702 // more.
2709 return inferrer.registerCalledElement(node, selector, mask, 2703 return inferrer.registerCalledLocalFunction(node, selector, mask,
2710 outermostElement, function, argumentTypes, sideEffects, inLoop); 2704 outermostElement, function, argumentTypes, sideEffects, inLoop);
2711 } 2705 }
2712 2706
2713 @override 2707 @override
2714 TypeInformation visitLocalFunctionIncompatibleInvoke( 2708 TypeInformation visitLocalFunctionIncompatibleInvoke(
2715 ast.Send node, 2709 ast.Send node,
2716 LocalFunctionElement function, 2710 LocalFunctionElement function,
2717 ast.NodeList arguments, 2711 ast.NodeList arguments,
2718 CallStructure callStructure, 2712 CallStructure callStructure,
2719 _) { 2713 _) {
2720 analyzeArguments(node.arguments); 2714 analyzeArguments(node.arguments);
2721 return types.dynamicType; 2715 return types.dynamicType;
2722 } 2716 }
2723 2717
2724 TypeInformation handleStaticSend(ast.Node node, Selector selector, 2718 TypeInformation handleStaticSend(ast.Node node, Selector selector,
2725 TypeMask mask, Element element, ArgumentsTypes arguments) { 2719 TypeMask mask, MemberElement element, ArgumentsTypes arguments) {
2726 assert(!element.isFactoryConstructor || 2720 assert(!element.isFactoryConstructor ||
2727 !(element as ConstructorElement).isRedirectingFactory); 2721 !(element as ConstructorElement).isRedirectingFactory);
2728 // Erroneous elements may be unresolved, for example missing getters. 2722 // Erroneous elements may be unresolved, for example missing getters.
2729 if (Elements.isUnresolved(element)) return types.dynamicType; 2723 if (Elements.isUnresolved(element)) return types.dynamicType;
2730 // TODO(herhut): should we follow redirecting constructors here? We would 2724 // TODO(herhut): should we follow redirecting constructors here? We would
2731 // need to pay attention if the constructor is pointing to an erroneous 2725 // need to pay attention if the constructor is pointing to an erroneous
2732 // element. 2726 // element.
2733 return inferrer.registerCalledElement(node, selector, mask, 2727 return inferrer.registerCalledMember(node, selector, mask, outermostElement,
2734 outermostElement, element, arguments, sideEffects, inLoop); 2728 element, arguments, sideEffects, inLoop);
2735 } 2729 }
2736 2730
2737 TypeInformation handleDynamicSend(ast.Node node, Selector selector, 2731 TypeInformation handleDynamicSend(ast.Node node, Selector selector,
2738 TypeMask mask, TypeInformation receiverType, ArgumentsTypes arguments) { 2732 TypeMask mask, TypeInformation receiverType, ArgumentsTypes arguments) {
2739 assert(receiverType != null); 2733 assert(receiverType != null);
2740 if (types.selectorNeedsUpdate(receiverType, mask)) { 2734 if (types.selectorNeedsUpdate(receiverType, mask)) {
2741 mask = receiverType == types.dynamicType 2735 mask = receiverType == types.dynamicType
2742 ? null 2736 ? null
2743 : types.newTypedSelector(receiverType, mask); 2737 : types.newTypedSelector(receiverType, mask);
2744 inferrer.updateSelectorInTree(analyzedElement, node, selector, mask); 2738 inferrer.updateSelectorInTree(analyzedElement, node, selector, mask);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2801 return types.boolType; 2795 return types.boolType;
2802 } else if (types.isNull(arguments.positional[0])) { 2796 } else if (types.isNull(arguments.positional[0])) {
2803 potentiallyAddNullCheck(node, node.receiver); 2797 potentiallyAddNullCheck(node, node.receiver);
2804 return types.boolType; 2798 return types.boolType;
2805 } 2799 }
2806 } 2800 }
2807 return handleDynamicSend(node, selector, mask, receiverType, arguments); 2801 return handleDynamicSend(node, selector, mask, receiverType, arguments);
2808 } 2802 }
2809 2803
2810 void recordReturnType(TypeInformation type) { 2804 void recordReturnType(TypeInformation type) {
2811 returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type); 2805 if (analyzedElement.isLocal) {
2806 returnType = inferrer.addReturnTypeForLocalFunction(
2807 analyzedElement, returnType, type);
2808 } else {
2809 returnType =
2810 inferrer.addReturnTypeForMethod(analyzedElement, returnType, type);
2811 }
2812 } 2812 }
2813 2813
2814 TypeInformation synthesizeForwardingCall( 2814 TypeInformation synthesizeForwardingCall(
2815 Spannable node, ConstructorElement element) { 2815 Spannable node, ConstructorElement element) {
2816 element = element.implementation; 2816 element = element.implementation;
2817 FunctionElement function = analyzedElement; 2817 FunctionElement function = analyzedElement;
2818 FunctionSignature signature = function.functionSignature; 2818 FunctionSignature signature = function.functionSignature;
2819 FunctionSignature calleeSignature = element.functionSignature; 2819 FunctionSignature calleeSignature = element.functionSignature;
2820 if (!calleeSignature.isCompatibleWith(signature)) { 2820 if (!calleeSignature.isCompatibleWith(signature)) {
2821 return types.nonNullEmpty(); 2821 return types.nonNullEmpty();
(...skipping 14 matching lines...) Expand all
2836 named[element.name] = locals.use(element); 2836 named[element.name] = locals.use(element);
2837 }); 2837 });
2838 } else { 2838 } else {
2839 signature.forEachOptionalParameter((FormalElement _element) { 2839 signature.forEachOptionalParameter((FormalElement _element) {
2840 ParameterElement element = _element; 2840 ParameterElement element = _element;
2841 unnamed.add(locals.use(element)); 2841 unnamed.add(locals.use(element));
2842 }); 2842 });
2843 } 2843 }
2844 2844
2845 ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named); 2845 ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named);
2846 return inferrer.registerCalledElement(node, null, null, outermostElement, 2846 return inferrer.registerCalledMember(node, null, null, outermostElement,
2847 element, arguments, sideEffects, inLoop); 2847 element, arguments, sideEffects, inLoop);
2848 } 2848 }
2849 2849
2850 TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { 2850 TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
2851 ConstructorElement element = elements.getRedirectingTargetConstructor(node); 2851 ConstructorElement element = elements.getRedirectingTargetConstructor(node);
2852 if (Elements.isMalformed(element)) { 2852 if (Elements.isMalformed(element)) {
2853 recordReturnType(types.dynamicType); 2853 recordReturnType(types.dynamicType);
2854 } else { 2854 } else {
2855 // We don'TypeInformation create a selector for redirecting factories, and 2855 // We don'TypeInformation create a selector for redirecting factories, and
2856 // the send is just a property access. Therefore we must 2856 // the send is just a property access. Therefore we must
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2938 Selector moveNextSelector = Selectors.moveNext; 2938 Selector moveNextSelector = Selectors.moveNext;
2939 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); 2939 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node);
2940 2940
2941 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, 2941 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector,
2942 iteratorMask, expressionType, new ArgumentsTypes.empty()); 2942 iteratorMask, expressionType, new ArgumentsTypes.empty());
2943 2943
2944 return handleForInLoop(node, iteratorType, currentSelector, currentMask, 2944 return handleForInLoop(node, iteratorType, currentSelector, currentMask,
2945 moveNextSelector, moveNextMask); 2945 moveNextSelector, moveNextMask);
2946 } 2946 }
2947 } 2947 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/elements/modelx.dart ('k') | pkg/compiler/lib/src/inferrer/builder_kernel.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698