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

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

Issue 2977963002: Use entities in the InferrerEngine interface (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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/inferrer/inferrer_engine.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 953 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 inferrer.setDefaultTypeOfParameter(parameter, type); 964 inferrer.setDefaultTypeOfParameter(parameter, type);
965 }); 965 });
966 966
967 if (closedWorld.nativeData.isNativeMember(analyzedElement)) { 967 if (closedWorld.nativeData.isNativeMember(analyzedElement)) {
968 // Native methods do not have a body, and we currently just say 968 // Native methods do not have a body, and we currently just say
969 // they return dynamic. 969 // they return dynamic.
970 return types.dynamicType; 970 return types.dynamicType;
971 } 971 }
972 972
973 if (analyzedElement.isGenerativeConstructor) { 973 if (analyzedElement.isGenerativeConstructor) {
974 ConstructorElement analyzedConstructor = analyzedElement;
974 isThisExposed = false; 975 isThisExposed = false;
975 signature.forEachParameter((FormalElement _element) { 976 signature.forEachParameter((FormalElement _element) {
976 ParameterElement element = _element; 977 ParameterElement element = _element;
977 TypeInformation parameterType = inferrer.typeOfParameter(element); 978 TypeInformation parameterType = inferrer.typeOfParameter(element);
978 if (element.isInitializingFormal) { 979 if (element.isInitializingFormal) {
979 InitializingFormalElement initializingFormal = element; 980 InitializingFormalElement initializingFormal = element;
980 if (initializingFormal.fieldElement.isFinal) { 981 if (initializingFormal.fieldElement.isFinal) {
981 inferrer.recordTypeOfField( 982 inferrer.recordTypeOfField(
982 initializingFormal.fieldElement, parameterType); 983 initializingFormal.fieldElement, parameterType);
983 } else { 984 } else {
984 locals.updateField(initializingFormal.fieldElement, parameterType); 985 locals.updateField(initializingFormal.fieldElement, parameterType);
985 inferrer.recordTypeOfField( 986 inferrer.recordTypeOfField(
986 initializingFormal.fieldElement, parameterType); 987 initializingFormal.fieldElement, parameterType);
987 } 988 }
988 } 989 }
989 locals.update(element, parameterType, node); 990 locals.update(element, parameterType, node);
990 }); 991 });
991 ClassElement cls = analyzedElement.enclosingClass; 992 ClassElement cls = analyzedConstructor.enclosingClass;
992 Spannable spannable = node; 993 Spannable spannable = node;
993 if (analyzedElement.isSynthesized) { 994 if (analyzedConstructor.isSynthesized) {
994 spannable = analyzedElement; 995 spannable = analyzedConstructor;
995 ConstructorElement constructor = analyzedElement; 996 synthesizeForwardingCall(
996 synthesizeForwardingCall(spannable, constructor.definingConstructor); 997 spannable, analyzedConstructor.definingConstructor);
997 } else { 998 } else {
998 visitingInitializers = true; 999 visitingInitializers = true;
999 if (node.initializers != null) { 1000 if (node.initializers != null) {
1000 for (ast.Node initializer in node.initializers) { 1001 for (ast.Node initializer in node.initializers) {
1001 ast.SendSet fieldInitializer = initializer.asSendSet(); 1002 ast.SendSet fieldInitializer = initializer.asSendSet();
1002 if (fieldInitializer != null) { 1003 if (fieldInitializer != null) {
1003 handleSendSet(fieldInitializer); 1004 handleSendSet(fieldInitializer);
1004 } else { 1005 } else {
1005 Element element = elements[initializer]; 1006 Element element = elements[initializer];
1006 handleConstructorSend(initializer, element); 1007 handleConstructorSend(initializer, element);
1007 } 1008 }
1008 } 1009 }
1009 } 1010 }
1010 visitingInitializers = false; 1011 visitingInitializers = false;
1011 // For a generative constructor like: `Foo();`, we synthesize 1012 // For a generative constructor like: `Foo();`, we synthesize
1012 // a call to the default super constructor (the one that takes 1013 // a call to the default super constructor (the one that takes
1013 // no argument). Resolution ensures that such a constructor 1014 // no argument). Resolution ensures that such a constructor
1014 // exists. 1015 // exists.
1015 if (!isConstructorRedirect && 1016 if (!isConstructorRedirect &&
1016 !seenSuperConstructorCall && 1017 !seenSuperConstructorCall &&
1017 !cls.isObject) { 1018 !cls.isObject) {
1018 ConstructorElement target = cls.superclass.lookupDefaultConstructor(); 1019 ConstructorElement target = cls.superclass.lookupDefaultConstructor();
1019 ArgumentsTypes arguments = new ArgumentsTypes([], {}); 1020 ArgumentsTypes arguments = new ArgumentsTypes([], {});
1020 analyzeSuperConstructorCall(target, arguments); 1021 analyzeSuperConstructorCall(target, arguments);
1021 inferrer.registerCalledMember(node, null, null, outermostElement, 1022 inferrer.registerCalledMember(node, null, null, outermostElement,
1022 target.implementation, arguments, sideEffects, inLoop); 1023 target, arguments, sideEffects, inLoop);
1023 } 1024 }
1024 visit(node.body); 1025 visit(node.body);
1025 inferrer.recordExposesThis(analyzedElement, isThisExposed); 1026 inferrer.recordExposesThis(analyzedConstructor, isThisExposed);
1026 } 1027 }
1027 if (!isConstructorRedirect) { 1028 if (!isConstructorRedirect) {
1028 // Iterate over all instance fields, and give a null type to 1029 // Iterate over all instance fields, and give a null type to
1029 // fields that we haven'TypeInformation initialized for sure. 1030 // fields that we haven'TypeInformation initialized for sure.
1030 cls.forEachInstanceField((_, FieldElement field) { 1031 cls.forEachInstanceField((_, FieldElement field) {
1031 if (field.isFinal) return; 1032 if (field.isFinal) return;
1032 TypeInformation type = locals.fieldScope.readField(field); 1033 TypeInformation type = locals.fieldScope.readField(field);
1033 ResolvedAst resolvedAst = field.resolvedAst; 1034 ResolvedAst resolvedAst = field.resolvedAst;
1034 if (type == null && resolvedAst.body == null) { 1035 if (type == null && resolvedAst.body == null) {
1035 inferrer.recordTypeOfField(field, types.nullType); 1036 inferrer.recordTypeOfField(field, types.nullType);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 bool isThisOrSuper(ast.Node node) => node.isThis() || node.isSuper(); 1200 bool isThisOrSuper(ast.Node node) => node.isThis() || node.isSuper();
1200 1201
1201 bool isInClassOrSubclass(Element element) { 1202 bool isInClassOrSubclass(Element element) {
1202 ClassElement cls = outermostElement.enclosingClass; 1203 ClassElement cls = outermostElement.enclosingClass;
1203 ClassElement enclosing = element.enclosingClass; 1204 ClassElement enclosing = element.enclosingClass;
1204 return closedWorld.isSubclassOf(enclosing, cls); 1205 return closedWorld.isSubclassOf(enclosing, cls);
1205 } 1206 }
1206 1207
1207 void checkIfExposesThis(Selector selector, TypeMask mask) { 1208 void checkIfExposesThis(Selector selector, TypeMask mask) {
1208 if (isThisExposed) return; 1209 if (isThisExposed) return;
1209 inferrer.forEachElementMatching(selector, mask, (dynamic element) { 1210 inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
1210 if (element.isField) { 1211 if (element.isField) {
1211 ResolvedAst elementResolvedAst = element.resolvedAst; 1212 FieldElement field = element;
1213 ResolvedAst elementResolvedAst = field.resolvedAst;
1212 if (!selector.isSetter && 1214 if (!selector.isSetter &&
1213 isInClassOrSubclass(element) && 1215 isInClassOrSubclass(field) &&
1214 !element.isFinal && 1216 !field.isFinal &&
1215 locals.fieldScope.readField(element) == null && 1217 locals.fieldScope.readField(field) == null &&
1216 elementResolvedAst.body == null) { 1218 elementResolvedAst.body == null) {
1217 // If the field is being used before this constructor 1219 // If the field is being used before this constructor
1218 // actually had a chance to initialize it, say it can be 1220 // actually had a chance to initialize it, say it can be
1219 // null. 1221 // null.
1220 inferrer.recordTypeOfField(element, types.nullType); 1222 inferrer.recordTypeOfField(field, types.nullType);
1221 } 1223 }
1222 // Accessing a field does not expose [:this:]. 1224 // Accessing a field does not expose [:this:].
1223 return true; 1225 return true;
1224 } 1226 }
1225 // TODO(ngeoffray): We could do better here if we knew what we 1227 // TODO(ngeoffray): We could do better here if we knew what we
1226 // are calling does not expose this. 1228 // are calling does not expose this.
1227 isThisExposed = true; 1229 isThisExposed = true;
1228 return false; 1230 return false;
1229 }); 1231 });
1230 } 1232 }
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 if (targets.length == 1) { 1996 if (targets.length == 1) {
1995 MemberElement single = targets.first; 1997 MemberElement single = targets.first;
1996 if (single.isField) { 1998 if (single.isField) {
1997 locals.updateField(single, rhsType); 1999 locals.updateField(single, rhsType);
1998 } 2000 }
1999 } 2001 }
2000 } 2002 }
2001 handleDynamicSend( 2003 handleDynamicSend(
2002 node, setterSelector, setterMask, receiverType, arguments); 2004 node, setterSelector, setterMask, receiverType, arguments);
2003 } else if (element.isField) { 2005 } else if (element.isField) {
2004 if (element.isFinal) { 2006 FieldElement field = element;
2005 inferrer.recordTypeOfField(element, rhsType); 2007 if (field.isFinal) {
2008 inferrer.recordTypeOfField(field, rhsType);
2006 } else { 2009 } else {
2007 if (analyzedElement.isGenerativeConstructor) { 2010 if (analyzedElement.isGenerativeConstructor) {
2008 locals.updateField(element, rhsType); 2011 locals.updateField(field, rhsType);
2009 } 2012 }
2010 if (visitingInitializers) { 2013 if (visitingInitializers) {
2011 inferrer.recordTypeOfField(element, rhsType); 2014 inferrer.recordTypeOfField(field, rhsType);
2012 } else { 2015 } else {
2013 handleDynamicSend( 2016 handleDynamicSend(
2014 node, setterSelector, setterMask, receiverType, arguments); 2017 node, setterSelector, setterMask, receiverType, arguments);
2015 } 2018 }
2016 } 2019 }
2017 } else if (element.isLocal) { 2020 } else if (element.isLocal) {
2018 locals.update(element, rhsType, node); 2021 locals.update(element, rhsType, node);
2019 } 2022 }
2020 return rhsType; 2023 return rhsType;
2021 } 2024 }
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2352 ? types.nullType 2355 ? types.nullType
2353 : arguments.positional[1]; 2356 : arguments.positional[1];
2354 2357
2355 return inferrer.concreteTypes.putIfAbsent( 2358 return inferrer.concreteTypes.putIfAbsent(
2356 node, 2359 node,
2357 () => types.allocateList(types.fixedListType, node, outermostElement, 2360 () => types.allocateList(types.fixedListType, node, outermostElement,
2358 elementType, length)); 2361 elementType, length));
2359 } else if (Elements.isConstructorOfTypedArraySubclass( 2362 } else if (Elements.isConstructorOfTypedArraySubclass(
2360 constructor, closedWorld)) { 2363 constructor, closedWorld)) {
2361 int length = findLength(node); 2364 int length = findLength(node);
2362 TypeInformation elementType = 2365 MemberElement member = target.enclosingClass.lookupMember('[]');
2363 inferrer.returnTypeOfMember(target.enclosingClass.lookupMember('[]')); 2366 TypeInformation elementType = inferrer.returnTypeOfMember(member);
2364 return inferrer.concreteTypes.putIfAbsent( 2367 return inferrer.concreteTypes.putIfAbsent(
2365 node, 2368 node,
2366 () => types.allocateList(types.nonNullExact(target.enclosingClass), 2369 () => types.allocateList(types.nonNullExact(target.enclosingClass),
2367 node, outermostElement, elementType, length)); 2370 node, outermostElement, elementType, length));
2368 } else { 2371 } else {
2369 return returnType; 2372 return returnType;
2370 } 2373 }
2371 } 2374 }
2372 2375
2373 @override 2376 @override
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
2809 return types.boolType; 2812 return types.boolType;
2810 } else if (types.isNull(arguments.positional[0])) { 2813 } else if (types.isNull(arguments.positional[0])) {
2811 potentiallyAddNullCheck(node, node.receiver); 2814 potentiallyAddNullCheck(node, node.receiver);
2812 return types.boolType; 2815 return types.boolType;
2813 } 2816 }
2814 } 2817 }
2815 return handleDynamicSend(node, selector, mask, receiverType, arguments); 2818 return handleDynamicSend(node, selector, mask, receiverType, arguments);
2816 } 2819 }
2817 2820
2818 void recordReturnType(TypeInformation type) { 2821 void recordReturnType(TypeInformation type) {
2822 MethodElement analyzedMethod = analyzedElement;
2819 returnType = 2823 returnType =
2820 inferrer.addReturnTypeForMethod(analyzedElement, returnType, type); 2824 inferrer.addReturnTypeForMethod(analyzedMethod, returnType, type);
2821 } 2825 }
2822 2826
2823 TypeInformation synthesizeForwardingCall( 2827 TypeInformation synthesizeForwardingCall(
2824 Spannable node, ConstructorElement element) { 2828 Spannable node, ConstructorElement element) {
2825 assert(element.isDeclaration); 2829 assert(element.isDeclaration);
2826 MethodElement function = analyzedElement.implementation; 2830 MethodElement function = analyzedElement.implementation;
2827 FunctionSignature signature = function.functionSignature; 2831 FunctionSignature signature = function.functionSignature;
2828 FunctionSignature calleeSignature = element.functionSignature; 2832 FunctionSignature calleeSignature = element.functionSignature;
2829 if (!calleeSignature.isCompatibleWith(signature)) { 2833 if (!calleeSignature.isCompatibleWith(signature)) {
2830 return types.nonNullEmpty(); 2834 return types.nonNullEmpty();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2947 Selector moveNextSelector = Selectors.moveNext; 2951 Selector moveNextSelector = Selectors.moveNext;
2948 TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node); 2952 TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node);
2949 2953
2950 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, 2954 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector,
2951 iteratorMask, expressionType, new ArgumentsTypes.empty()); 2955 iteratorMask, expressionType, new ArgumentsTypes.empty());
2952 2956
2953 return handleForInLoop(node, iteratorType, currentSelector, currentMask, 2957 return handleForInLoop(node, iteratorType, currentSelector, currentMask,
2954 moveNextSelector, moveNextMask); 2958 moveNextSelector, moveNextMask);
2955 } 2959 }
2956 } 2960 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/inferrer/inferrer_engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698