Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
| 10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 899 ParenthesizedExpression parenthesizedExpression) { | 899 ParenthesizedExpression parenthesizedExpression) { |
| 900 if (parenthesizedExpression.parent is ParenthesizedExpression) { | 900 if (parenthesizedExpression.parent is ParenthesizedExpression) { |
| 901 return _wrapParenthesizedExpression( | 901 return _wrapParenthesizedExpression( |
| 902 parenthesizedExpression.parent as ParenthesizedExpression); | 902 parenthesizedExpression.parent as ParenthesizedExpression); |
| 903 } | 903 } |
| 904 return parenthesizedExpression; | 904 return parenthesizedExpression; |
| 905 } | 905 } |
| 906 } | 906 } |
| 907 | 907 |
| 908 /** | 908 /** |
| 909 * Utilities for [LibraryElementImpl] building. | |
| 910 */ | |
| 911 class BuildLibraryElementUtils { | |
| 912 /** | |
| 913 * Look through all of the compilation units defined for the given [library], | |
| 914 * looking for getters and setters that are defined in different compilation | |
| 915 * units but that have the same names. If any are found, make sure that they | |
| 916 * have the same variable element. | |
| 917 */ | |
| 918 static void patchTopLevelAccessors(LibraryElementImpl library) { | |
| 919 // Without parts getters/setters already share the same variable element. | |
| 920 if (library.parts.isEmpty) { | |
| 921 return; | |
| 922 } | |
| 923 // Collect getters and setters. | |
| 924 HashMap<String, PropertyAccessorElement> getters = | |
| 925 new HashMap<String, PropertyAccessorElement>(); | |
| 926 List<PropertyAccessorElement> setters = <PropertyAccessorElement>[]; | |
| 927 _collectAccessors(getters, setters, library.definingCompilationUnit); | |
| 928 for (CompilationUnitElement unit in library.parts) { | |
| 929 _collectAccessors(getters, setters, unit); | |
| 930 } | |
| 931 // Move every setter to the corresponding getter's variable (if exists). | |
| 932 for (PropertyAccessorElement setter in setters) { | |
| 933 PropertyAccessorElement getter = getters[setter.displayName]; | |
| 934 if (getter != null) { | |
| 935 TopLevelVariableElementImpl variable = getter.variable; | |
| 936 TopLevelVariableElementImpl setterVariable = setter.variable; | |
| 937 CompilationUnitElementImpl setterUnit = setterVariable.enclosingElement; | |
| 938 setterUnit.replaceTopLevelVariable(setterVariable, variable); | |
| 939 variable.setter = setter; | |
| 940 (setter as PropertyAccessorElementImpl).variable = variable; | |
| 941 } | |
| 942 } | |
| 943 } | |
| 944 | |
| 945 /** | |
| 946 * Add all of the non-synthetic [getters] and [setters] defined in the given | |
| 947 * [unit] that have no corresponding accessor to one of the given collections. | |
| 948 */ | |
| 949 static void _collectAccessors(Map<String, PropertyAccessorElement> getters, | |
| 950 List<PropertyAccessorElement> setters, CompilationUnitElement unit) { | |
| 951 for (PropertyAccessorElement accessor in unit.accessors) { | |
| 952 if (accessor.isGetter) { | |
| 953 if (!accessor.isSynthetic && accessor.correspondingSetter == null) { | |
| 954 getters[accessor.displayName] = accessor; | |
| 955 } | |
| 956 } else { | |
| 957 if (!accessor.isSynthetic && accessor.correspondingGetter == null) { | |
| 958 setters.add(accessor); | |
| 959 } | |
| 960 } | |
| 961 } | |
| 962 } | |
| 963 } | |
| 964 | |
| 965 /** | |
| 909 * Instances of the class `ClassScope` implement the scope defined by a class. | 966 * Instances of the class `ClassScope` implement the scope defined by a class. |
| 910 */ | 967 */ |
| 911 class ClassScope extends EnclosedScope { | 968 class ClassScope extends EnclosedScope { |
| 912 /** | 969 /** |
| 913 * Initialize a newly created scope enclosed within another scope. | 970 * Initialize a newly created scope enclosed within another scope. |
| 914 * | 971 * |
| 915 * @param enclosingScope the scope in which this scope is lexically enclosed | 972 * @param enclosingScope the scope in which this scope is lexically enclosed |
| 916 * @param typeElement the element representing the type represented by this sc ope | 973 * @param typeElement the element representing the type represented by this sc ope |
| 917 */ | 974 */ |
| 918 ClassScope(Scope enclosingScope, ClassElement typeElement) | 975 ClassScope(Scope enclosingScope, ClassElement typeElement) |
| (...skipping 5808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6727 return this; | 6784 return this; |
| 6728 } else if (_outerScope != null) { | 6785 } else if (_outerScope != null) { |
| 6729 return _outerScope.lookup(targetLabel); | 6786 return _outerScope.lookup(targetLabel); |
| 6730 } else { | 6787 } else { |
| 6731 return null; | 6788 return null; |
| 6732 } | 6789 } |
| 6733 } | 6790 } |
| 6734 } | 6791 } |
| 6735 | 6792 |
| 6736 /** | 6793 /** |
| 6794 * Instances of the class `LibraryResolver` are used to resolve one or more mutu ally dependent | |
|
Paul Berry
2016/01/13 16:12:01
Let's just delete these. They are clearly junk (p
| |
| 6795 * libraries within a single context. | |
| 6796 */ | |
| 6797 | |
| 6798 /** | |
| 6799 * Instances of the class `LibraryResolver` are used to resolve one or more mutu ally dependent | |
| 6800 * libraries within a single context. | |
| 6801 */ | |
| 6802 | |
| 6803 /** | |
| 6737 * Instances of the class `LibraryImportScope` represent the scope containing al l of the names | 6804 * Instances of the class `LibraryImportScope` represent the scope containing al l of the names |
| 6738 * available from imported libraries. | 6805 * available from imported libraries. |
| 6739 */ | 6806 */ |
| 6740 class LibraryImportScope extends Scope { | 6807 class LibraryImportScope extends Scope { |
| 6741 /** | 6808 /** |
| 6742 * The element representing the library in which this scope is enclosed. | 6809 * The element representing the library in which this scope is enclosed. |
| 6743 */ | 6810 */ |
| 6744 final LibraryElement _definingLibrary; | 6811 final LibraryElement _definingLibrary; |
| 6745 | 6812 |
| 6746 /** | 6813 /** |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6935 AnalysisEngine.instance.logger | 7002 AnalysisEngine.instance.logger |
| 6936 .logInformation("Multiply defined SDK element: $foundElement"); | 7003 .logInformation("Multiply defined SDK element: $foundElement"); |
| 6937 return foundElement; | 7004 return foundElement; |
| 6938 } | 7005 } |
| 6939 return new MultiplyDefinedElementImpl( | 7006 return new MultiplyDefinedElementImpl( |
| 6940 _definingLibrary.context, nonSdkElements); | 7007 _definingLibrary.context, nonSdkElements); |
| 6941 } | 7008 } |
| 6942 } | 7009 } |
| 6943 | 7010 |
| 6944 /** | 7011 /** |
| 6945 * Instances of the class `LibraryResolver` are used to resolve one or more mutu ally dependent | |
| 6946 * libraries within a single context. | |
| 6947 */ | |
| 6948 | |
| 6949 /** | |
| 6950 * Instances of the class `LibraryResolver` are used to resolve one or more mutu ally dependent | |
| 6951 * libraries within a single context. | |
| 6952 */ | |
| 6953 | |
| 6954 /** | |
| 6955 * Instances of the class `LibraryScope` implement a scope containing all of the names defined | 7012 * Instances of the class `LibraryScope` implement a scope containing all of the names defined |
| 6956 * in a given library. | 7013 * in a given library. |
| 6957 */ | 7014 */ |
| 6958 class LibraryScope extends EnclosedScope { | 7015 class LibraryScope extends EnclosedScope { |
| 6959 /** | 7016 /** |
| 6960 * Initialize a newly created scope representing the names defined in the give n library. | 7017 * Initialize a newly created scope representing the names defined in the give n library. |
| 6961 * | 7018 * |
| 6962 * @param definingLibrary the element representing the library represented by this scope | 7019 * @param definingLibrary the element representing the library represented by this scope |
| 6963 * @param errorListener the listener that is to be informed when an error is e ncountered | 7020 * @param errorListener the listener that is to be informed when an error is e ncountered |
| 6964 */ | 7021 */ |
| (...skipping 2193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9158 _inferFunctionExpressionsParametersTypes(node.argumentList); | 9215 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 9159 DartType contextType = node.staticInvokeType; | 9216 DartType contextType = node.staticInvokeType; |
| 9160 if (contextType is FunctionType) { | 9217 if (contextType is FunctionType) { |
| 9161 InferenceContext.setType(node.argumentList, contextType); | 9218 InferenceContext.setType(node.argumentList, contextType); |
| 9162 } | 9219 } |
| 9163 safelyVisit(node.argumentList); | 9220 safelyVisit(node.argumentList); |
| 9164 node.accept(typeAnalyzer); | 9221 node.accept(typeAnalyzer); |
| 9165 return null; | 9222 return null; |
| 9166 } | 9223 } |
| 9167 | 9224 |
| 9168 /** | |
| 9169 * Given an [argumentList] and the [parameters] related to the element that | |
| 9170 * will be invoked using those arguments, compute the list of parameters that | |
| 9171 * correspond to the list of arguments. | |
| 9172 * | |
| 9173 * An error will be reported to [onError] if any of the arguments cannot be | |
| 9174 * matched to a parameter. onError can be null to ignore the error. | |
| 9175 * | |
| 9176 * The flag [reportAsError] should be `true` if a compile-time error should be | |
| 9177 * reported; or `false` if a compile-time warning should be reported | |
| 9178 * | |
| 9179 * Returns the parameters that correspond to the arguments. | |
| 9180 */ | |
| 9181 static List<ParameterElement> resolveArgumentsToParameters( | |
| 9182 ArgumentList argumentList, | |
| 9183 List<ParameterElement> parameters, | |
| 9184 void onError(ErrorCode errorCode, AstNode node, [List<Object> arguments]), | |
| 9185 {bool reportAsError: false}) { | |
| 9186 List<ParameterElement> requiredParameters = new List<ParameterElement>(); | |
| 9187 List<ParameterElement> positionalParameters = new List<ParameterElement>(); | |
| 9188 HashMap<String, ParameterElement> namedParameters = | |
| 9189 new HashMap<String, ParameterElement>(); | |
| 9190 for (ParameterElement parameter in parameters) { | |
| 9191 ParameterKind kind = parameter.parameterKind; | |
| 9192 if (kind == ParameterKind.REQUIRED) { | |
| 9193 requiredParameters.add(parameter); | |
| 9194 } else if (kind == ParameterKind.POSITIONAL) { | |
| 9195 positionalParameters.add(parameter); | |
| 9196 } else { | |
| 9197 namedParameters[parameter.name] = parameter; | |
| 9198 } | |
| 9199 } | |
| 9200 List<ParameterElement> unnamedParameters = | |
| 9201 new List<ParameterElement>.from(requiredParameters); | |
| 9202 unnamedParameters.addAll(positionalParameters); | |
| 9203 int unnamedParameterCount = unnamedParameters.length; | |
| 9204 int unnamedIndex = 0; | |
| 9205 NodeList<Expression> arguments = argumentList.arguments; | |
| 9206 int argumentCount = arguments.length; | |
| 9207 List<ParameterElement> resolvedParameters = | |
| 9208 new List<ParameterElement>(argumentCount); | |
| 9209 int positionalArgumentCount = 0; | |
| 9210 HashSet<String> usedNames = new HashSet<String>(); | |
| 9211 bool noBlankArguments = true; | |
| 9212 for (int i = 0; i < argumentCount; i++) { | |
| 9213 Expression argument = arguments[i]; | |
| 9214 if (argument is NamedExpression) { | |
| 9215 SimpleIdentifier nameNode = argument.name.label; | |
| 9216 String name = nameNode.name; | |
| 9217 ParameterElement element = namedParameters[name]; | |
| 9218 if (element == null) { | |
| 9219 ErrorCode errorCode = (reportAsError | |
| 9220 ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER | |
| 9221 : StaticWarningCode.UNDEFINED_NAMED_PARAMETER); | |
| 9222 if (onError != null) { | |
| 9223 onError(errorCode, nameNode, [name]); | |
| 9224 } | |
| 9225 } else { | |
| 9226 resolvedParameters[i] = element; | |
| 9227 nameNode.staticElement = element; | |
| 9228 } | |
| 9229 if (!usedNames.add(name)) { | |
| 9230 if (onError != null) { | |
| 9231 onError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, | |
| 9232 [name]); | |
| 9233 } | |
| 9234 } | |
| 9235 } else { | |
| 9236 if (argument is SimpleIdentifier && argument.name.isEmpty) { | |
| 9237 noBlankArguments = false; | |
| 9238 } | |
| 9239 positionalArgumentCount++; | |
| 9240 if (unnamedIndex < unnamedParameterCount) { | |
| 9241 resolvedParameters[i] = unnamedParameters[unnamedIndex++]; | |
| 9242 } | |
| 9243 } | |
| 9244 } | |
| 9245 if (positionalArgumentCount < requiredParameters.length && | |
| 9246 noBlankArguments) { | |
| 9247 ErrorCode errorCode = (reportAsError | |
| 9248 ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS | |
| 9249 : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS); | |
| 9250 if (onError != null) { | |
| 9251 onError(errorCode, argumentList, | |
| 9252 [requiredParameters.length, positionalArgumentCount]); | |
| 9253 } | |
| 9254 } else if (positionalArgumentCount > unnamedParameterCount && | |
| 9255 noBlankArguments) { | |
| 9256 ErrorCode errorCode = (reportAsError | |
| 9257 ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS | |
| 9258 : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS); | |
| 9259 if (onError != null) { | |
| 9260 onError(errorCode, argumentList, | |
| 9261 [unnamedParameterCount, positionalArgumentCount]); | |
| 9262 } | |
| 9263 } | |
| 9264 return resolvedParameters; | |
| 9265 } | |
| 9266 | |
| 9267 @override | 9225 @override |
| 9268 Object visitNamedExpression(NamedExpression node) { | 9226 Object visitNamedExpression(NamedExpression node) { |
| 9269 InferenceContext.setType(node.expression, InferenceContext.getType(node)); | 9227 InferenceContext.setType(node.expression, InferenceContext.getType(node)); |
| 9270 return super.visitNamedExpression(node); | 9228 return super.visitNamedExpression(node); |
| 9271 } | 9229 } |
| 9272 | 9230 |
| 9273 @override | 9231 @override |
| 9274 Object visitNode(AstNode node) { | 9232 Object visitNode(AstNode node) { |
| 9275 node.visitChildren(this); | 9233 node.visitChildren(this); |
| 9276 node.accept(elementResolver); | 9234 node.accept(elementResolver); |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9883 } | 9841 } |
| 9884 } else if (condition is PrefixExpression) { | 9842 } else if (condition is PrefixExpression) { |
| 9885 PrefixExpression prefix = condition; | 9843 PrefixExpression prefix = condition; |
| 9886 if (prefix.operator.type == TokenType.BANG) { | 9844 if (prefix.operator.type == TokenType.BANG) { |
| 9887 _propagateFalseState(prefix.operand); | 9845 _propagateFalseState(prefix.operand); |
| 9888 } | 9846 } |
| 9889 } else if (condition is ParenthesizedExpression) { | 9847 } else if (condition is ParenthesizedExpression) { |
| 9890 _propagateTrueState(condition.expression); | 9848 _propagateTrueState(condition.expression); |
| 9891 } | 9849 } |
| 9892 } | 9850 } |
| 9851 | |
| 9852 /** | |
| 9853 * Given an [argumentList] and the [parameters] related to the element that | |
| 9854 * will be invoked using those arguments, compute the list of parameters that | |
| 9855 * correspond to the list of arguments. | |
| 9856 * | |
| 9857 * An error will be reported to [onError] if any of the arguments cannot be | |
| 9858 * matched to a parameter. onError can be null to ignore the error. | |
| 9859 * | |
| 9860 * The flag [reportAsError] should be `true` if a compile-time error should be | |
| 9861 * reported; or `false` if a compile-time warning should be reported | |
| 9862 * | |
| 9863 * Returns the parameters that correspond to the arguments. | |
| 9864 */ | |
| 9865 static List<ParameterElement> resolveArgumentsToParameters( | |
| 9866 ArgumentList argumentList, | |
| 9867 List<ParameterElement> parameters, | |
| 9868 void onError(ErrorCode errorCode, AstNode node, [List<Object> arguments]), | |
| 9869 {bool reportAsError: false}) { | |
| 9870 List<ParameterElement> requiredParameters = new List<ParameterElement>(); | |
| 9871 List<ParameterElement> positionalParameters = new List<ParameterElement>(); | |
| 9872 HashMap<String, ParameterElement> namedParameters = | |
| 9873 new HashMap<String, ParameterElement>(); | |
| 9874 for (ParameterElement parameter in parameters) { | |
| 9875 ParameterKind kind = parameter.parameterKind; | |
| 9876 if (kind == ParameterKind.REQUIRED) { | |
| 9877 requiredParameters.add(parameter); | |
| 9878 } else if (kind == ParameterKind.POSITIONAL) { | |
| 9879 positionalParameters.add(parameter); | |
| 9880 } else { | |
| 9881 namedParameters[parameter.name] = parameter; | |
| 9882 } | |
| 9883 } | |
| 9884 List<ParameterElement> unnamedParameters = | |
| 9885 new List<ParameterElement>.from(requiredParameters); | |
| 9886 unnamedParameters.addAll(positionalParameters); | |
| 9887 int unnamedParameterCount = unnamedParameters.length; | |
| 9888 int unnamedIndex = 0; | |
| 9889 NodeList<Expression> arguments = argumentList.arguments; | |
| 9890 int argumentCount = arguments.length; | |
| 9891 List<ParameterElement> resolvedParameters = | |
| 9892 new List<ParameterElement>(argumentCount); | |
| 9893 int positionalArgumentCount = 0; | |
| 9894 HashSet<String> usedNames = new HashSet<String>(); | |
| 9895 bool noBlankArguments = true; | |
| 9896 for (int i = 0; i < argumentCount; i++) { | |
| 9897 Expression argument = arguments[i]; | |
| 9898 if (argument is NamedExpression) { | |
| 9899 SimpleIdentifier nameNode = argument.name.label; | |
| 9900 String name = nameNode.name; | |
| 9901 ParameterElement element = namedParameters[name]; | |
| 9902 if (element == null) { | |
| 9903 ErrorCode errorCode = (reportAsError | |
| 9904 ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER | |
| 9905 : StaticWarningCode.UNDEFINED_NAMED_PARAMETER); | |
| 9906 if (onError != null) { | |
| 9907 onError(errorCode, nameNode, [name]); | |
| 9908 } | |
| 9909 } else { | |
| 9910 resolvedParameters[i] = element; | |
| 9911 nameNode.staticElement = element; | |
| 9912 } | |
| 9913 if (!usedNames.add(name)) { | |
| 9914 if (onError != null) { | |
| 9915 onError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, | |
| 9916 [name]); | |
| 9917 } | |
| 9918 } | |
| 9919 } else { | |
| 9920 if (argument is SimpleIdentifier && argument.name.isEmpty) { | |
| 9921 noBlankArguments = false; | |
| 9922 } | |
| 9923 positionalArgumentCount++; | |
| 9924 if (unnamedIndex < unnamedParameterCount) { | |
| 9925 resolvedParameters[i] = unnamedParameters[unnamedIndex++]; | |
| 9926 } | |
| 9927 } | |
| 9928 } | |
| 9929 if (positionalArgumentCount < requiredParameters.length && | |
| 9930 noBlankArguments) { | |
| 9931 ErrorCode errorCode = (reportAsError | |
| 9932 ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS | |
| 9933 : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS); | |
| 9934 if (onError != null) { | |
| 9935 onError(errorCode, argumentList, | |
| 9936 [requiredParameters.length, positionalArgumentCount]); | |
| 9937 } | |
| 9938 } else if (positionalArgumentCount > unnamedParameterCount && | |
| 9939 noBlankArguments) { | |
| 9940 ErrorCode errorCode = (reportAsError | |
| 9941 ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS | |
| 9942 : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS); | |
| 9943 if (onError != null) { | |
| 9944 onError(errorCode, argumentList, | |
| 9945 [unnamedParameterCount, positionalArgumentCount]); | |
| 9946 } | |
| 9947 } | |
| 9948 return resolvedParameters; | |
| 9949 } | |
| 9893 } | 9950 } |
| 9894 | 9951 |
| 9895 /** | 9952 /** |
| 9896 * The abstract class `Scope` defines the behavior common to name scopes used by the resolver | 9953 * The abstract class `Scope` defines the behavior common to name scopes used by the resolver |
| 9897 * to determine which names are visible at any given point in the code. | 9954 * to determine which names are visible at any given point in the code. |
| 9898 */ | 9955 */ |
| 9899 abstract class Scope { | 9956 abstract class Scope { |
| 9900 /** | 9957 /** |
| 9901 * The prefix used to mark an identifier as being private to its library. | 9958 * The prefix used to mark an identifier as being private to its library. |
| 9902 */ | 9959 */ |
| (...skipping 3654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13557 nonFields.add(node); | 13614 nonFields.add(node); |
| 13558 return null; | 13615 return null; |
| 13559 } | 13616 } |
| 13560 | 13617 |
| 13561 @override | 13618 @override |
| 13562 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 13619 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
| 13563 | 13620 |
| 13564 @override | 13621 @override |
| 13565 Object visitWithClause(WithClause node) => null; | 13622 Object visitWithClause(WithClause node) => null; |
| 13566 } | 13623 } |
| OLD | NEW |