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

Unified Diff: pkg/analyzer_experimental/lib/src/generated/resolver.dart

Issue 14050010: New analyzer_experimental snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer_experimental/lib/src/generated/resolver.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/resolver.dart b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
index ddfe703cec11d361e37f5f9023ca0a8918d87f58..143632f44680de10a723a5384a74fe40a19aced4 100644
--- a/pkg/analyzer_experimental/lib/src/generated/resolver.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
@@ -4,6 +4,7 @@
library engine.resolver;
import 'dart:collection';
+import 'dart:uri' show Uri;
import 'java_core.dart';
import 'java_engine.dart';
import 'instrumentation.dart';
@@ -568,7 +569,7 @@ class ElementBuilder extends RecursiveASTVisitor<Object> {
((variable as FieldElementImpl)).static = matches(((node.parent.parent as FieldDeclaration)).keyword, sc.Keyword.STATIC);
}
}
- return super.visitVariableDeclaration(node);
+ return null;
}
List<Type2> createTypeVariableTypes(List<TypeVariableElement> typeVariables) {
int typeVariableCount = typeVariables.length;
@@ -793,6 +794,14 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
*/
InternalAnalysisContext _context;
/**
+ * The error listener to which errors will be reported.
+ */
+ AnalysisErrorListener _errorListener;
+ /**
+ * The line information associated with the source for which an element is being built, or{@code null} if we are not building an element.
+ */
+ LineInfo _lineInfo;
+ /**
* The HTML element being built.
*/
HtmlElementImpl _htmlElement;
@@ -803,9 +812,11 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
/**
* Initialize a newly created HTML unit builder.
* @param context the analysis context in which the element model will be built
+ * @param errorListener the error listener to which errors will be reported
*/
- HtmlUnitBuilder(InternalAnalysisContext context) {
+ HtmlUnitBuilder(InternalAnalysisContext context, AnalysisErrorListener errorListener) {
this._context = context;
+ this._errorListener = errorListener;
}
/**
* Build the HTML element for the given source.
@@ -821,6 +832,7 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
* @throws AnalysisException if the analysis could not be performed
*/
HtmlElementImpl buildHtmlElement2(Source source2, ht.HtmlUnit unit) {
+ _lineInfo = _context.computeLineInfo(source2);
HtmlElementImpl result = new HtmlElementImpl(_context, source2.shortName);
result.source = source2;
_htmlElement = result;
@@ -840,30 +852,43 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
Object visitXmlTagNode(ht.XmlTagNode node) {
if (isScriptNode(node)) {
Source htmlSource = _htmlElement.source;
- String scriptSourcePath = getScriptSourcePath(node);
+ ht.XmlAttributeNode scriptAttribute = getScriptSourcePath(node);
+ String scriptSourcePath = scriptAttribute == null ? null : scriptAttribute.text;
if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePath == null) {
EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl(node);
String contents = node.content;
- AnalysisErrorListener errorListener = new AnalysisErrorListener_5();
- sc.StringScanner scanner = new sc.StringScanner(null, contents, errorListener);
+ int attributeEnd2 = node.attributeEnd.end;
+ LineInfo_Location location = _lineInfo.getLocation(attributeEnd2);
+ sc.StringScanner scanner = new sc.StringScanner(htmlSource, contents, _errorListener);
+ scanner.setSourceStart(location.lineNumber, location.columnNumber, attributeEnd2);
sc.Token firstToken = scanner.tokenize();
List<int> lineStarts2 = scanner.lineStarts;
- Parser parser = new Parser(null, errorListener);
+ Parser parser = new Parser(null, _errorListener);
CompilationUnit unit = parser.parseCompilationUnit(firstToken);
+ unit.lineInfo = new LineInfo(lineStarts2);
try {
CompilationUnitBuilder builder = new CompilationUnitBuilder();
CompilationUnitElementImpl elem = builder.buildCompilationUnit(htmlSource, unit);
LibraryElementImpl library = new LibraryElementImpl(_context, null);
library.definingCompilationUnit = elem;
script.scriptLibrary = library;
- } on AnalysisException catch (e) {
- print(e);
+ } on AnalysisException catch (exception) {
+ print(exception);
}
_scripts.add(script);
} else {
ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl(node);
if (scriptSourcePath != null) {
- script.scriptSource = _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
+ try {
+ new Uri(scriptSourcePath);
+ Source scriptSource = _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
+ script.scriptSource = scriptSource;
+ if (!scriptSource.exists()) {
+ reportError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribute.offset + 1, scriptSourcePath.length, []);
+ }
+ } on URISyntaxException catch (exception) {
+ reportError(HtmlWarningCode.INVALID_URI, scriptAttribute.offset + 1, scriptSourcePath.length, []);
+ }
}
_scripts.add(script);
}
@@ -873,15 +898,14 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
return null;
}
/**
- * Return the value of the source attribute if it exists.
+ * Return the first source attribute for the given tag node, or {@code null} if it does not exist.
* @param node the node containing attributes
- * @return the source path or {@code null} if not defined
+ * @return the source attribute contained in the given tag
*/
- String getScriptSourcePath(ht.XmlTagNode node) {
+ ht.XmlAttributeNode getScriptSourcePath(ht.XmlTagNode node) {
for (ht.XmlAttributeNode attribute in node.attributes) {
if (attribute.name.lexeme == _SRC) {
- String text2 = attribute.text;
- return text2 != null && text2.length > 0 ? text2 : null;
+ return attribute;
}
}
return null;
@@ -908,9 +932,16 @@ class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
}
return false;
}
-}
-class AnalysisErrorListener_5 implements AnalysisErrorListener {
- void onError(AnalysisError error) {
+ /**
+ * Report an error with the given error code at the given location. Use the given arguments to
+ * compose the error message.
+ * @param errorCode the error code of the error to be reported
+ * @param offset the offset of the first character to be highlighted
+ * @param length the number of characters to be highlighted
+ * @param arguments the arguments used to compose the error message
+ */
+ void reportError(ErrorCode errorCode, int offset, int length, List<Object> arguments) {
+ _errorListener.onError(new AnalysisError.con2(_htmlElement.source, offset, length, errorCode, arguments));
}
}
/**
@@ -1500,6 +1531,63 @@ class ElementResolver extends SimpleASTVisitor<Object> {
}
return null;
}
+ Object visitCommentReference(CommentReference node) {
+ Identifier identifier2 = node.identifier;
+ if (identifier2 is SimpleIdentifier) {
+ SimpleIdentifier simpleIdentifier = identifier2 as SimpleIdentifier;
+ visitSimpleIdentifier(simpleIdentifier);
+ Element element2 = simpleIdentifier.element;
+ if (element2 != null) {
+ if (element2.library != _resolver.definingLibrary) {
+ }
+ if (node.newKeyword != null) {
+ if (element2 is ClassElement) {
+ ConstructorElement constructor = ((element2 as ClassElement)).unnamedConstructor;
+ recordResolution(simpleIdentifier, constructor);
+ } else {
+ }
+ }
+ }
+ } else if (identifier2 is PrefixedIdentifier) {
+ PrefixedIdentifier prefixedIdentifier = identifier2 as PrefixedIdentifier;
+ SimpleIdentifier prefix2 = prefixedIdentifier.prefix;
+ SimpleIdentifier name = prefixedIdentifier.identifier;
+ visitSimpleIdentifier(prefix2);
+ Element element3 = prefix2.element;
+ if (element3 != null) {
+ if (element3 is PrefixElement) {
+ element3 = _resolver.nameScope.lookup(identifier2, _resolver.definingLibrary);
+ recordResolution(name, element3);
+ return null;
+ }
+ if (element3.library != _resolver.definingLibrary) {
+ }
+ if (node.newKeyword == null) {
+ if (element3 is ClassElement) {
+ Element memberElement = lookupGetterOrMethod(((element3 as ClassElement)).type, name.name);
+ if (memberElement == null) {
+ memberElement = ((element3 as ClassElement)).getNamedConstructor(name.name);
+ }
+ if (memberElement == null) {
+ reportGetterOrSetterNotFound(prefixedIdentifier, name, element3.name);
+ } else {
+ recordResolution(name, memberElement);
+ }
+ } else {
+ }
+ } else {
+ if (element3 is ClassElement) {
+ ConstructorElement constructor = ((element3 as ClassElement)).getNamedConstructor(name.name);
+ if (constructor != null) {
+ recordResolution(name, constructor);
+ }
+ } else {
+ }
+ }
+ }
+ }
+ return null;
+ }
Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
FieldElement fieldElement = null;
SimpleIdentifier fieldName2 = node.fieldName;
@@ -1565,9 +1653,17 @@ class ElementResolver extends SimpleASTVisitor<Object> {
if (!fieldElement.isSynthetic()) {
ParameterElement parameterElement = node.element;
if (parameterElement is FieldFormalParameterElementImpl) {
- ((parameterElement as FieldFormalParameterElementImpl)).field = fieldElement;
+ FieldFormalParameterElementImpl fieldFormal = parameterElement as FieldFormalParameterElementImpl;
+ fieldFormal.field = fieldElement;
+ Type2 declaredType = fieldFormal.type;
+ Type2 fieldType = fieldElement.type;
+ if (node.type == null) {
+ fieldFormal.type = fieldType;
+ }
if (fieldElement.isStatic()) {
_resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [fieldName]);
+ } else if (declaredType != null && fieldType != null && !declaredType.isAssignableTo(fieldType)) {
+ _resolver.reportError(StaticWarningCode.FIELD_INITIALIZER_WITH_INVALID_TYPE, node, [declaredType.name, fieldType.name]);
}
}
}
@@ -1732,7 +1828,9 @@ class ElementResolver extends SimpleASTVisitor<Object> {
if (targetTypeName == null) {
_resolver.reportError(StaticTypeWarningCode.UNDEFINED_FUNCTION, methodName2, [methodName2.name]);
} else {
- _resolver.reportError(StaticTypeWarningCode.UNDEFINED_METHOD, methodName2, [methodName2.name, targetTypeName]);
+ if (!doesClassDeclareNoSuchMethod(targetType.element)) {
+ _resolver.reportError(StaticTypeWarningCode.UNDEFINED_METHOD, methodName2, [methodName2.name, targetTypeName]);
+ }
}
}
return null;
@@ -1890,12 +1988,15 @@ class ElementResolver extends SimpleASTVisitor<Object> {
}
}
if (memberElement == null) {
- if (identifier.inSetterContext()) {
- _resolver.reportError(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, targetType.name]);
- } else if (identifier.inGetterContext()) {
- _resolver.reportError(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, targetType.name]);
- } else {
- _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, identifier, [identifier.name]);
+ if (!doesClassDeclareNoSuchMethod(targetType.element)) {
+ if (identifier.inSetterContext()) {
+ _resolver.reportError(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, targetType.name]);
+ } else if (identifier.inGetterContext()) {
+ _resolver.reportError(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, targetType.name]);
+ } else {
+ System.out.println("two ${identifier.name}");
+ _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, identifier, [identifier.name]);
+ }
}
} else {
recordResolution(identifier, memberElement);
@@ -1952,7 +2053,9 @@ class ElementResolver extends SimpleASTVisitor<Object> {
}
}
if (element == null) {
- _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
+ if (!doesClassDeclareNoSuchMethod(enclosingClass2)) {
+ _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
+ }
}
recordResolution(node, element);
return null;
@@ -1994,6 +2097,27 @@ class ElementResolver extends SimpleASTVisitor<Object> {
return null;
}
/**
+ * Return {@code true} if the passed {@link Element} is a {@link ClassElement} that declares a
+ * method "noSuchMethod".
+ * @param element the {@link Element} to evaluate
+ * @return {@code true} if the passed {@link Element} is a {@link ClassElement} that declares a
+ * method "noSuchMethod"
+ */
+ bool doesClassDeclareNoSuchMethod(Element element) {
+ if (element == null) {
+ return false;
+ }
+ if (element is! ClassElementImpl) {
+ return false;
+ }
+ ClassElementImpl classElement = element as ClassElementImpl;
+ MethodElement method = classElement.lookUpMethod("noSuchMethod", _resolver.definingLibrary);
+ if (method == null) {
+ return false;
+ }
+ return true;
+ }
+ /**
* Search through the array of parameters for a parameter whose name matches the given name.
* Return the parameter with the given name, or {@code null} if there is no such parameter.
* @param parameters the parameters being searched
@@ -2101,6 +2225,66 @@ class ElementResolver extends SimpleASTVisitor<Object> {
return lookUpGetterInInterfaces(superclass2, getterName, visitedInterfaces);
}
/**
+ * Look up the method or getter with the given name in the given type. Return the element
+ * representing the method or getter that was found, or {@code null} if there is no method or
+ * getter with the given name.
+ * @param type the type in which the method or getter is defined
+ * @param memberName the name of the method or getter being looked up
+ * @return the element representing the method or getter that was found
+ */
+ ExecutableElement lookupGetterOrMethod(Type2 type, String memberName) {
+ type = resolveTypeVariable(type);
+ if (type is InterfaceType) {
+ InterfaceType interfaceType = type as InterfaceType;
+ ExecutableElement member = interfaceType.lookUpMethod(memberName, _resolver.definingLibrary);
+ if (member != null) {
+ return member;
+ }
+ member = interfaceType.lookUpGetter(memberName, _resolver.definingLibrary);
+ if (member != null) {
+ return member;
+ }
+ return lookUpGetterOrMethodInInterfaces(interfaceType, memberName, new Set<ClassElement>());
+ }
+ return null;
+ }
+ /**
+ * Look up the method or getter with the given name in the interfaces implemented by the given
+ * type, either directly or indirectly. Return the element representing the method or getter that
+ * was found, or {@code null} if there is no method or getter with the given name.
+ * @param targetType the type in which the method or getter might be defined
+ * @param memberName the name of the method or getter being looked up
+ * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
+ * to prevent infinite recursion and to optimize the search
+ * @return the element representing the method or getter that was found
+ */
+ ExecutableElement lookUpGetterOrMethodInInterfaces(InterfaceType targetType, String memberName, Set<ClassElement> visitedInterfaces) {
+ ClassElement targetClass = targetType.element;
+ if (visitedInterfaces.contains(targetClass)) {
+ return null;
+ }
+ javaSetAdd(visitedInterfaces, targetClass);
+ ExecutableElement member = targetType.getMethod(memberName);
+ if (member != null) {
+ return member;
+ }
+ member = targetType.getGetter(memberName);
+ if (member != null) {
+ return member;
+ }
+ for (InterfaceType interfaceType in targetType.interfaces) {
+ member = lookUpGetterOrMethodInInterfaces(interfaceType, memberName, visitedInterfaces);
+ if (member != null) {
+ return member;
+ }
+ }
+ InterfaceType superclass2 = targetType.superclass;
+ if (superclass2 == null) {
+ return null;
+ }
+ return lookUpGetterInInterfaces(superclass2, memberName, visitedInterfaces);
+ }
+ /**
* Find the element corresponding to the given label node in the current label scope.
* @param parentNode the node containing the given label
* @param labelNode the node representing the label being looked up
@@ -2284,14 +2468,17 @@ class ElementResolver extends SimpleASTVisitor<Object> {
}
}
/**
- * Report the {@link StaticTypeWarningCode}s <code>UNDEFINED_SETTER</code> and
- * <code>UNDEFINED_GETTER</code>.
+ * Report the {@link StaticTypeWarningCode}s <code>UNDEFINED_SETTER</code> and <code>UNDEFINED_GETTER</code>.
* @param node the prefixed identifier that gives the context to determine if the error on the
* undefined identifier is a getter or a setter
* @param identifier the identifier in the passed prefix identifier
* @param typeName the name of the type of the left hand side of the passed prefixed identifier
*/
void reportGetterOrSetterNotFound(PrefixedIdentifier node, SimpleIdentifier identifier2, String typeName) {
+ Type2 targetType = getType(node);
+ if (targetType != null && doesClassDeclareNoSuchMethod(targetType.element)) {
+ return;
+ }
bool isSetterContext = node.identifier.inSetterContext();
ErrorCode errorCode = isSetterContext ? StaticTypeWarningCode.UNDEFINED_SETTER : StaticTypeWarningCode.UNDEFINED_GETTER;
_resolver.reportError(errorCode, identifier2, [identifier2.name, typeName]);
@@ -2791,10 +2978,10 @@ class LibraryResolver {
* @param analysisContext the analysis context in which the library is being analyzed
*/
LibraryResolver.con1(InternalAnalysisContext analysisContext) {
- _jtd_constructor_263_impl(analysisContext);
+ _jtd_constructor_264_impl(analysisContext);
}
- _jtd_constructor_263_impl(InternalAnalysisContext analysisContext) {
- _jtd_constructor_264_impl(analysisContext, null);
+ _jtd_constructor_264_impl(InternalAnalysisContext analysisContext) {
+ _jtd_constructor_265_impl(analysisContext, null);
}
/**
* Initialize a newly created library resolver to resolve libraries within the given context.
@@ -2802,9 +2989,9 @@ class LibraryResolver {
* @param errorListener the listener to which analysis errors will be reported
*/
LibraryResolver.con2(InternalAnalysisContext analysisContext2, AnalysisErrorListener additionalAnalysisErrorListener) {
- _jtd_constructor_264_impl(analysisContext2, additionalAnalysisErrorListener);
+ _jtd_constructor_265_impl(analysisContext2, additionalAnalysisErrorListener);
}
- _jtd_constructor_264_impl(InternalAnalysisContext analysisContext2, AnalysisErrorListener additionalAnalysisErrorListener) {
+ _jtd_constructor_265_impl(InternalAnalysisContext analysisContext2, AnalysisErrorListener additionalAnalysisErrorListener) {
this._analysisContext = analysisContext2;
this._recordingErrorListener = new RecordingErrorListener();
if (additionalAnalysisErrorListener == null) {
@@ -3219,19 +3406,20 @@ class LibraryResolver {
void recordResults() {
Map<Source, LibraryElement> elementMap = new Map<Source, LibraryElement>();
for (Library library in _librariesInCycles) {
- recordResults2(library.librarySource, library.definingCompilationUnit);
+ Source librarySource2 = library.librarySource;
+ recordResults2(librarySource2, librarySource2, library.definingCompilationUnit);
for (Source source in library.compilationUnitSources) {
- recordResults2(source, library.getAST(source));
+ recordResults2(source, librarySource2, library.getAST(source));
}
elementMap[library.librarySource] = library.libraryElement;
}
_analysisContext.recordLibraryElements(elementMap);
}
- void recordResults2(Source source, CompilationUnit unit) {
+ void recordResults2(Source source, Source librarySource, CompilationUnit unit) {
List<AnalysisError> errors = _recordingErrorListener.getErrors2(source);
unit.resolutionErrors = errors;
- _analysisContext.recordResolvedCompilationUnit(source, unit);
- _analysisContext.recordResolutionErrors(source, errors, unit.lineInfo);
+ _analysisContext.recordResolvedCompilationUnit(source, librarySource, unit);
+ _analysisContext.recordResolutionErrors(source, librarySource, errors, unit.lineInfo);
}
/**
* Resolve the identifiers and perform type analysis in the libraries in the current cycle.
@@ -3326,9 +3514,9 @@ class ResolverVisitor extends ScopedVisitor {
* @param typeProvider the object used to access the types from the core library
*/
ResolverVisitor.con1(Library library, Source source, TypeProvider typeProvider) : super.con1(library, source, typeProvider) {
- _jtd_constructor_265_impl(library, source, typeProvider);
+ _jtd_constructor_266_impl(library, source, typeProvider);
}
- _jtd_constructor_265_impl(Library library, Source source, TypeProvider typeProvider) {
+ _jtd_constructor_266_impl(Library library, Source source, TypeProvider typeProvider) {
this._elementResolver = new ElementResolver(this);
this._typeAnalyzer = new StaticTypeAnalyzer(this);
}
@@ -3342,9 +3530,9 @@ class ResolverVisitor extends ScopedVisitor {
* during resolution
*/
ResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) : super.con2(definingLibrary, source, typeProvider, errorListener) {
- _jtd_constructor_266_impl(definingLibrary, source, typeProvider, errorListener);
+ _jtd_constructor_267_impl(definingLibrary, source, typeProvider, errorListener);
}
- _jtd_constructor_266_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
+ _jtd_constructor_267_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
this._elementResolver = new ElementResolver(this);
this._typeAnalyzer = new StaticTypeAnalyzer(this);
}
@@ -3360,16 +3548,57 @@ class ResolverVisitor extends ScopedVisitor {
if (element != null) {
Type2 type2 = node.type.type;
if (type2 != null) {
- _overrideManager.setType(element, type2);
+ override(element, getType(element), type2);
}
}
}
return null;
}
Object visitAssertStatement(AssertStatement node) {
- Expression condition2 = node.condition;
- condition2.accept(this);
- propagateTrueState(condition2);
+ super.visitAssertStatement(node);
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ propagateTrueState(node.condition);
+ }
+ return null;
+ }
+ Object visitBinaryExpression(BinaryExpression node) {
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ sc.TokenType operatorType = node.operator.type;
+ if (identical(operatorType, sc.TokenType.AMPERSAND_AMPERSAND)) {
+ Expression leftOperand2 = node.leftOperand;
+ leftOperand2.accept(this);
+ Expression rightOperand2 = node.rightOperand;
+ if (rightOperand2 != null) {
+ try {
+ _overrideManager.enterScope();
+ propagateTrueState(leftOperand2);
+ rightOperand2.accept(this);
+ } finally {
+ _overrideManager.exitScope();
+ }
+ }
+ } else if (identical(operatorType, sc.TokenType.BAR_BAR)) {
+ Expression leftOperand3 = node.leftOperand;
+ leftOperand3.accept(this);
+ Expression rightOperand3 = node.rightOperand;
+ if (rightOperand3 != null) {
+ try {
+ _overrideManager.enterScope();
+ propagateFalseState(leftOperand3);
+ rightOperand3.accept(this);
+ } finally {
+ _overrideManager.exitScope();
+ }
+ }
+ } else {
+ node.leftOperand.accept(this);
+ node.rightOperand.accept(this);
+ }
+ node.accept(_elementResolver);
+ node.accept(_typeAnalyzer);
+ } else {
+ super.visitBinaryExpression(node);
+ }
return null;
}
Object visitBreakStatement(BreakStatement node) {
@@ -3389,53 +3618,65 @@ class ResolverVisitor extends ScopedVisitor {
}
return null;
}
- Object visitComment(Comment node) => null;
+ Object visitCommentReference(CommentReference node) {
+ node.accept(_elementResolver);
+ node.accept(_typeAnalyzer);
+ return null;
+ }
Object visitCompilationUnit(CompilationUnit node) {
- try {
- _overrideManager.enterScope();
- for (Directive directive in node.directives) {
- directive.accept(this);
- }
- List<CompilationUnitMember> classes = new List<CompilationUnitMember>();
- for (CompilationUnitMember declaration in node.declarations) {
- if (declaration is ClassDeclaration) {
- classes.add(declaration);
- } else {
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ try {
+ _overrideManager.enterScope();
+ for (Directive directive in node.directives) {
+ directive.accept(this);
+ }
+ List<CompilationUnitMember> classes = new List<CompilationUnitMember>();
+ for (CompilationUnitMember declaration in node.declarations) {
+ if (declaration is ClassDeclaration) {
+ classes.add(declaration);
+ } else {
+ declaration.accept(this);
+ }
+ }
+ for (CompilationUnitMember declaration in classes) {
declaration.accept(this);
}
+ } finally {
+ _overrideManager.exitScope();
}
- for (CompilationUnitMember declaration in classes) {
- declaration.accept(this);
- }
- } finally {
- _overrideManager.exitScope();
+ node.accept(_elementResolver);
+ node.accept(_typeAnalyzer);
+ } else {
+ super.visitCompilationUnit(node);
}
return null;
}
Object visitConditionalExpression(ConditionalExpression node) {
- Expression condition2 = node.condition;
- condition2.accept(this);
- Expression thenExpression2 = node.thenExpression;
- if (thenExpression2 != null) {
- try {
- _overrideManager.enterScope();
- propagateTrueState(condition2);
- thenExpression2.accept(this);
- } finally {
- _overrideManager.exitScope();
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ Expression condition2 = node.condition;
+ condition2.accept(this);
+ Expression thenExpression2 = node.thenExpression;
+ if (thenExpression2 != null) {
+ try {
+ _overrideManager.enterScope();
+ propagateTrueState(condition2);
+ thenExpression2.accept(this);
+ } finally {
+ _overrideManager.exitScope();
+ }
}
- }
- Expression elseExpression2 = node.elseExpression;
- if (elseExpression2 != null) {
- try {
- _overrideManager.enterScope();
- propagateFalseState(condition2);
- elseExpression2.accept(this);
- } finally {
- _overrideManager.exitScope();
+ Expression elseExpression2 = node.elseExpression;
+ if (elseExpression2 != null) {
+ try {
+ _overrideManager.enterScope();
+ propagateFalseState(condition2);
+ elseExpression2.accept(this);
+ } finally {
+ _overrideManager.exitScope();
+ }
}
- }
- if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ node.accept(_elementResolver);
+ node.accept(_typeAnalyzer);
bool thenIsAbrupt = thenExpression2 != null && isAbruptTermination(thenExpression2);
bool elseIsAbrupt = elseExpression2 != null && isAbruptTermination(elseExpression2);
if (elseIsAbrupt && !thenIsAbrupt) {
@@ -3443,6 +3684,8 @@ class ResolverVisitor extends ScopedVisitor {
} else if (thenIsAbrupt && !elseIsAbrupt) {
propagateFalseState(condition2);
}
+ } else {
+ super.visitConditionalExpression(node);
}
return null;
}
@@ -3473,33 +3716,56 @@ class ResolverVisitor extends ScopedVisitor {
return null;
}
Object visitFieldDeclaration(FieldDeclaration node) {
- try {
- _overrideManager.enterScope();
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ try {
+ _overrideManager.enterScope();
+ super.visitFieldDeclaration(node);
+ } finally {
+ Map<Element, Type2> overrides = captureOverrides(node.fields);
+ _overrideManager.exitScope();
+ applyOverrides(overrides);
+ }
+ } else {
super.visitFieldDeclaration(node);
- } finally {
- Map<Element, Type2> overrides = captureOverrides(node.fields);
- _overrideManager.exitScope();
- for (MapEntry<Element, Type2> entry in getMapEntrySet(overrides)) {
- _overrideManager.setType(entry.getKey(), entry.getValue());
+ }
+ return null;
+ }
+ Object visitForEachStatement(ForEachStatement node) {
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ try {
+ _overrideManager.enterScope();
+ super.visitForEachStatement(node);
+ } finally {
+ _overrideManager.exitScope();
}
+ } else {
+ super.visitForEachStatement(node);
}
return null;
}
Object visitForStatement(ForStatement node) {
- try {
- _overrideManager.enterScope();
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ try {
+ _overrideManager.enterScope();
+ super.visitForStatement(node);
+ } finally {
+ _overrideManager.exitScope();
+ }
+ } else {
super.visitForStatement(node);
- } finally {
- _overrideManager.exitScope();
}
return null;
}
Object visitFunctionBody(FunctionBody node) {
- try {
- _overrideManager.enterScope();
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ try {
+ _overrideManager.enterScope();
+ super.visitFunctionBody(node);
+ } finally {
+ _overrideManager.exitScope();
+ }
+ } else {
super.visitFunctionBody(node);
- } finally {
- _overrideManager.exitScope();
}
return null;
}
@@ -3518,39 +3784,45 @@ class ResolverVisitor extends ScopedVisitor {
ExecutableElement outerFunction = _enclosingFunction;
try {
_enclosingFunction = node.element;
- _overrideManager.enterScope();
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ _overrideManager.enterScope();
+ }
super.visitFunctionExpression(node);
} finally {
- _overrideManager.exitScope();
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ _overrideManager.exitScope();
+ }
_enclosingFunction = outerFunction;
}
return null;
}
Object visitHideCombinator(HideCombinator node) => null;
Object visitIfStatement(IfStatement node) {
- Expression condition2 = node.condition;
- condition2.accept(this);
- Statement thenStatement2 = node.thenStatement;
- if (thenStatement2 != null) {
- try {
- _overrideManager.enterScope();
- propagateTrueState(condition2);
- thenStatement2.accept(this);
- } finally {
- _overrideManager.exitScope();
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ Expression condition2 = node.condition;
+ condition2.accept(this);
+ Statement thenStatement2 = node.thenStatement;
+ if (thenStatement2 != null) {
+ try {
+ _overrideManager.enterScope();
+ propagateTrueState(condition2);
+ thenStatement2.accept(this);
+ } finally {
+ _overrideManager.exitScope();
+ }
}
- }
- Statement elseStatement2 = node.elseStatement;
- if (elseStatement2 != null) {
- try {
- _overrideManager.enterScope();
- propagateFalseState(condition2);
- elseStatement2.accept(this);
- } finally {
- _overrideManager.exitScope();
+ Statement elseStatement2 = node.elseStatement;
+ if (elseStatement2 != null) {
+ try {
+ _overrideManager.enterScope();
+ propagateFalseState(condition2);
+ elseStatement2.accept(this);
+ } finally {
+ _overrideManager.exitScope();
+ }
}
- }
- if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ node.accept(_elementResolver);
+ node.accept(_typeAnalyzer);
bool thenIsAbrupt = thenStatement2 != null && isAbruptTermination2(thenStatement2);
bool elseIsAbrupt = elseStatement2 != null && isAbruptTermination2(elseStatement2);
if (elseIsAbrupt && !thenIsAbrupt) {
@@ -3558,6 +3830,8 @@ class ResolverVisitor extends ScopedVisitor {
} else if (thenIsAbrupt && !elseIsAbrupt) {
propagateFalseState(condition2);
}
+ } else {
+ super.visitIfStatement(node);
}
return null;
}
@@ -3612,37 +3886,68 @@ class ResolverVisitor extends ScopedVisitor {
return null;
}
Object visitSwitchCase(SwitchCase node) {
- try {
- _overrideManager.enterScope();
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ try {
+ _overrideManager.enterScope();
+ super.visitSwitchCase(node);
+ } finally {
+ _overrideManager.exitScope();
+ }
+ } else {
super.visitSwitchCase(node);
- } finally {
- _overrideManager.exitScope();
}
return null;
}
Object visitSwitchDefault(SwitchDefault node) {
- try {
- _overrideManager.enterScope();
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ try {
+ _overrideManager.enterScope();
+ super.visitSwitchDefault(node);
+ } finally {
+ _overrideManager.exitScope();
+ }
+ } else {
super.visitSwitchDefault(node);
- } finally {
- _overrideManager.exitScope();
}
return null;
}
Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- try {
- _overrideManager.enterScope();
- super.visitTopLevelVariableDeclaration(node);
- } finally {
- Map<Element, Type2> overrides = captureOverrides(node.variables);
- _overrideManager.exitScope();
- for (MapEntry<Element, Type2> entry in getMapEntrySet(overrides)) {
- _overrideManager.setType(entry.getKey(), entry.getValue());
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ try {
+ _overrideManager.enterScope();
+ super.visitTopLevelVariableDeclaration(node);
+ } finally {
+ Map<Element, Type2> overrides = captureOverrides(node.variables);
+ _overrideManager.exitScope();
+ applyOverrides(overrides);
}
+ } else {
+ super.visitTopLevelVariableDeclaration(node);
}
return null;
}
Object visitTypeName(TypeName node) => null;
+ Object visitWhileStatement(WhileStatement node) {
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ Expression condition2 = node.condition;
+ condition2.accept(this);
+ Statement body2 = node.body;
+ if (body2 != null) {
+ try {
+ _overrideManager.enterScope();
+ propagateTrueState(condition2);
+ body2.accept(this);
+ } finally {
+ _overrideManager.exitScope();
+ }
+ }
+ node.accept(_elementResolver);
+ node.accept(_typeAnalyzer);
+ } else {
+ super.visitWhileStatement(node);
+ }
+ return null;
+ }
/**
* Return the class element representing the class containing the current node, or {@code null} if
* the current node is not contained in a class.
@@ -3669,6 +3974,34 @@ class ResolverVisitor extends ScopedVisitor {
}
return null;
}
+ void visitForEachStatementInScope(ForEachStatement node) {
+ if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) {
+ DeclaredIdentifier loopVariable2 = node.loopVariable;
+ safelyVisit(loopVariable2);
+ Expression iterator2 = node.iterator;
+ if (iterator2 != null) {
+ iterator2.accept(this);
+ if (loopVariable2 != null) {
+ LocalVariableElement loopElement = loopVariable2.element;
+ override(loopElement, loopElement.type, getIteratorElementType(iterator2));
+ }
+ }
+ safelyVisit(node.body);
+ node.accept(_elementResolver);
+ node.accept(_typeAnalyzer);
+ } else {
+ super.visitForEachStatementInScope(node);
+ }
+ }
+ /**
+ * Apply a set of overrides that were previously captured.
+ * @param overrides the overrides to be applied
+ */
+ void applyOverrides(Map<Element, Type2> overrides) {
+ for (MapEntry<Element, Type2> entry in getMapEntrySet(overrides)) {
+ _overrideManager.setType(entry.getKey(), entry.getValue());
+ }
+ }
/**
* Return a map from the elements for the variables in the given list that have their types
* overridden to the overriding type.
@@ -3693,6 +4026,44 @@ class ResolverVisitor extends ScopedVisitor {
return overrides;
}
/**
+ * The given expression is the expression used to compute the iterator for a for-each statement.
+ * Attempt to compute the type of objects that will be assigned to the loop variable and return
+ * that type. Return {@code null} if the type could not be determined.
+ * @param iterator the iterator for a for-each statement
+ * @return the type of objects that will be assigned to the loop variable
+ */
+ Type2 getIteratorElementType(Expression iteratorExpression) {
+ Type2 expressionType = iteratorExpression.staticType;
+ if (expressionType is InterfaceType) {
+ PropertyAccessorElement iterator = ((expressionType as InterfaceType)).lookUpGetter("iterator", definingLibrary);
+ if (iterator == null) {
+ return null;
+ }
+ Type2 iteratorType = iterator.type.returnType;
+ if (iteratorType is InterfaceType) {
+ PropertyAccessorElement current = ((iteratorType as InterfaceType)).lookUpGetter("current", definingLibrary);
+ if (current == null) {
+ return null;
+ }
+ return current.type.returnType;
+ }
+ }
+ return null;
+ }
+ /**
+ * Return the type of the given (overridable) element.
+ * @param element the element whose type is to be returned
+ * @return the type of the given element
+ */
+ Type2 getType(Element element) {
+ if (element is LocalVariableElement) {
+ return ((element as LocalVariableElement)).type;
+ } else if (element is ParameterElement) {
+ return ((element as ParameterElement)).type;
+ }
+ return null;
+ }
+ /**
* Return {@code true} if the given expression terminates abruptly (that is, if any expression
* following the given expression will not be reached).
* @param expression the expression being tested
@@ -3726,6 +4097,27 @@ class ResolverVisitor extends ScopedVisitor {
return false;
}
/**
+ * If it is appropriate to do so, override the type of the given element. Use the static type and
+ * inferred type of the element to determine whether or not it is appropriate.
+ * @param element the element whose type might be overridden
+ * @param staticType the static type of the element
+ * @param inferredType the inferred type of the element
+ */
+ void override(VariableElement element, Type2 staticType, Type2 inferredType) {
+ if (identical(inferredType, BottomTypeImpl.instance)) {
+ return;
+ }
+ if (element is PropertyInducingElement) {
+ PropertyInducingElement variable = element as PropertyInducingElement;
+ if (!variable.isConst() && !variable.isFinal()) {
+ return;
+ }
+ }
+ if (staticType == null || (inferredType != null && inferredType.isMoreSpecificThan(staticType))) {
+ _overrideManager.setType(element, inferredType);
+ }
+ }
+ /**
* Propagate any type information that results from knowing that the given condition will have
* evaluated to 'false'.
* @param condition the condition that will have evaluated to 'false'
@@ -3737,11 +4129,11 @@ class ResolverVisitor extends ScopedVisitor {
if (condition is IsExpression) {
IsExpression is2 = condition as IsExpression;
if (is2.notOperator != null) {
- Element element = getOverridableElement(is2.expression);
+ VariableElement element = getOverridableElement(is2.expression);
if (element != null) {
Type2 type2 = is2.type.type;
if (type2 != null) {
- _overrideManager.setType(element, type2);
+ override(element, getType(element), type2);
}
}
}
@@ -3765,11 +4157,11 @@ class ResolverVisitor extends ScopedVisitor {
if (condition is IsExpression) {
IsExpression is2 = condition as IsExpression;
if (is2.notOperator == null) {
- Element element = getOverridableElement(is2.expression);
+ VariableElement element = getOverridableElement(is2.expression);
if (element != null) {
Type2 type2 = is2.type.type;
if (type2 != null) {
- _overrideManager.setType(element, type2);
+ override(element, getType(element), type2);
}
}
}
@@ -3838,9 +4230,9 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
* @param typeProvider the object used to access the types from the core library
*/
ScopedVisitor.con1(Library library, Source source2, TypeProvider typeProvider2) {
- _jtd_constructor_267_impl(library, source2, typeProvider2);
+ _jtd_constructor_268_impl(library, source2, typeProvider2);
}
- _jtd_constructor_267_impl(Library library, Source source2, TypeProvider typeProvider2) {
+ _jtd_constructor_268_impl(Library library, Source source2, TypeProvider typeProvider2) {
this._definingLibrary = library.libraryElement;
this._source = source2;
LibraryScope libraryScope2 = library.libraryScope;
@@ -3858,9 +4250,9 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
* during resolution
*/
ScopedVisitor.con2(LibraryElement definingLibrary2, Source source2, TypeProvider typeProvider2, AnalysisErrorListener errorListener2) {
- _jtd_constructor_268_impl(definingLibrary2, source2, typeProvider2, errorListener2);
+ _jtd_constructor_269_impl(definingLibrary2, source2, typeProvider2, errorListener2);
}
- _jtd_constructor_268_impl(LibraryElement definingLibrary2, Source source2, TypeProvider typeProvider2, AnalysisErrorListener errorListener2) {
+ _jtd_constructor_269_impl(LibraryElement definingLibrary2, Source source2, TypeProvider typeProvider2, AnalysisErrorListener errorListener2) {
this._definingLibrary = definingLibrary2;
this._source = source2;
this._errorListener = errorListener2;
@@ -3959,7 +4351,7 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
Scope outerNameScope = _nameScope;
_nameScope = new EnclosedScope(_nameScope);
try {
- super.visitForEachStatement(node);
+ visitForEachStatementInScope(node);
} finally {
_nameScope = outerNameScope;
_labelScope = outerLabelScope;
@@ -4115,7 +4507,7 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
* @param arguments the arguments to the error, used to compose the error message
*/
void reportError(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
- _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.length, errorCode, [arguments]));
+ _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.length, errorCode, arguments));
}
/**
* Report an error with the given error code and arguments.
@@ -4124,7 +4516,16 @@ abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
* @param arguments the arguments to the error, used to compose the error message
*/
void reportError3(ErrorCode errorCode, sc.Token token, List<Object> arguments) {
- _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, [arguments]));
+ _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, arguments));
+ }
+ /**
+ * Visit the given statement after it's scope has been created. This replaces the normal call to
+ * the inherited visit method so that ResolverVisitor can intervene when type propagation is
+ * enabled.
+ * @param node the statement to be visited
+ */
+ void visitForEachStatementInScope(ForEachStatement node) {
+ super.visitForEachStatement(node);
}
/**
* Add scopes for each of the given labels.
@@ -4310,17 +4711,17 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
* The static type of the expression <i>e<sub>1</sub>.v = e<sub>2</sub></i> is the static type of
* <i>e<sub>2</sub></i>.
* <p>
- * ... an assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</sub></i> ...
+ * ... an assignment of the form <i>e<sub>1</sub>[[e<sub>2</sub>]] = e<sub>3</sub></i> ...
* <p>
- * The static type of the expression <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</sub></i> is the
+ * The static type of the expression <i>e<sub>1</sub>[[e<sub>2</sub>]] = e<sub>3</sub></i> is the
* static type of <i>e<sub>3</sub></i>.
* <p>
* A compound assignment of the form <i>v op= e</i> is equivalent to <i>v = v op e</i>. A compound
* assignment of the form <i>C.v op= e</i> is equivalent to <i>C.v = C.v op e</i>. A compound
* assignment of the form <i>e<sub>1</sub>.v op= e<sub>2</sub></i> is equivalent to <i>((x) => x.v
* = x.v op e<sub>2</sub>)(e<sub>1</sub>)</i> where <i>x</i> is a variable that is not used in
- * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] op=
- * e<sub>3</sub></i> is equivalent to <i>((a, i) => a[i] = a[i] op e<sub>3</sub>)(e<sub>1</sub>,
+ * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>[[e<sub>2</sub>]] op=
+ * e<sub>3</sub></i> is equivalent to <i>((a, i) => a[[i]] = a[[i]] op e<sub>3</sub>)(e<sub>1</sub>,
* e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not used in
* <i>e<sub>3</sub></i>. </blockquote>
*/
@@ -4435,10 +4836,10 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
}
/**
* The Dart Language Specification, 12.9: <blockquote>The static type of a function literal of the
- * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub>
- * x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub> = dk]) => e</i> is
- * <i>(T<sub>1</sub>, &hellip;, Tn, [T<sub>n+1</sub> x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>
- * x<sub>n+k</sub>]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is the static type of
+ * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub>, [[T<sub>n+1</sub>
+ * x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub> = dk]]) => e</i> is
+ * <i>(T<sub>1</sub>, &hellip;, Tn, [[T<sub>n+1</sub> x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>
+ * x<sub>n+k</sub>]]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is the static type of
* <i>e</i>. In any case where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is
* considered to have been specified as dynamic.
* <p>
@@ -4450,9 +4851,9 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
* &lt;= i &lt;= n</i>, is not specified, it is considered to have been specified as dynamic.
* <p>
* The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
- * T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub> x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub>
- * x<sub>n+k</sub> = dk]) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
- * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>]) &rarr; dynamic</i>. In any case
+ * T<sub>n</sub> a<sub>n</sub>, [[T<sub>n+1</sub> x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub>
+ * x<sub>n+k</sub> = dk]]) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [[T<sub>n+1</sub>
+ * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>]]) &rarr; dynamic</i>. In any case
* where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is considered to have been
* specified as dynamic.
* <p>
@@ -4486,8 +4887,8 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => recordReturnType(node, node.element);
/**
* The Dart Language Specification, 12.29: <blockquote>An assignable expression of the form
- * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of the operator method
- * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</blockquote>
+ * <i>e<sub>1</sub>[[e<sub>2</sub>]]</i> is evaluated as a method invocation of the operator method
+ * <i>[[]]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</blockquote>
*/
Object visitIndexExpression(IndexExpression node) {
if (node.inSetterContext()) {
@@ -4532,10 +4933,10 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
Object visitIsExpression(IsExpression node) => recordType(node, _typeProvider.boolType);
/**
* The Dart Language Specification, 12.6: <blockquote>The static type of a list literal of the
- * form <i><b>const</b> &lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or the form
- * <i>&lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is {@code List&lt;E&gt;}. The static
- * type a list literal of the form <i><b>const</b> [e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or
- * the form <i>[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is {@code List&lt;dynamic&gt;}.</blockquote>
+ * form <i><b>const</b> &lt;E&gt;[[e<sub>1</sub>, &hellip;, e<sub>n</sub>]]</i> or the form
+ * <i>&lt;E&gt;[[e<sub>1</sub>, &hellip;, e<sub>n</sub>]]</i> is {@code List&lt;E&gt;}. The static
+ * type a list literal of the form <i><b>const</b> [[e<sub>1</sub>, &hellip;, e<sub>n</sub>]]</i> or
+ * the form <i>[[e<sub>1</sub>, &hellip;, e<sub>n</sub>]]</i> is {@code List&lt;dynamic&gt;}.</blockquote>
*/
Object visitListLiteral(ListLiteral node) {
TypeArgumentList typeArguments2 = node.typeArguments;
@@ -4679,7 +5080,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
* A postfix expression of the form <i>e1.v++</i> is equivalent to <i>(x){var r = x.v; x.v = r +
* 1; return r}(e1)</i>.
* <p>
- * A postfix expression of the form <i>e1[e2]++</i> is equivalent to <i>(a, i){var r = a[i]; a[i]
+ * A postfix expression of the form <i>e1[[e2]]++</i> is equivalent to <i>(a, i){var r = a[[i]]; a[[i]]
* = r + 1; return r}(e1, e2)</i>
* <p>
* A postfix expression of the form <i>v--</i>, where <i>v</i> is an identifier, is equivalent to
@@ -4691,7 +5092,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
* A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var r = x.v; x.v = r -
* 1; return r}(e1)</i>.
* <p>
- * A postfix expression of the form <i>e1[e2]--</i> is equivalent to <i>(a, i){var r = a[i]; a[i]
+ * A postfix expression of the form <i>e1[[e2]]--</i> is equivalent to <i>(a, i){var r = a[[i]]; a[[i]]
* = r - 1; return r}(e1, e2)</i></blockquote>
*/
Object visitPostfixExpression(PostfixExpression node) => recordType(node, getType2(node.operand));
@@ -4758,8 +5159,8 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
* p<sub>k</sub>: p<sub>k</sub>);}</i> if <i>m</i> has required parameters <i>r<sub>1</sub>,
* &hellip;, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> &hellip; p<sub>k</sub></i>
* with defaults <i>d<sub>1</sub>, &hellip;, d<sub>k</sub></i>.</li>
- * <li><i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, [p<sub>1</sub> = d<sub>1</sub>, &hellip;,
- * p<sub>k</sub> = d<sub>k</sub>]){return o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
+ * <li><i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, [[p<sub>1</sub> = d<sub>1</sub>, &hellip;,
+ * p<sub>k</sub> = d<sub>k</sub>]]){return o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
* p<sub>1</sub>, &hellip;, p<sub>k</sub>);}</i> if <i>m</i> has required parameters
* <i>r<sub>1</sub>, &hellip;, r<sub>n</sub></i>, and optional positional parameters
* <i>p<sub>1</sub> &hellip; p<sub>k</sub></i> with defaults <i>d<sub>1</sub>, &hellip;,
@@ -5041,6 +5442,11 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
}
return null;
}
+ /**
+ * Return the type of the given (overridable) element.
+ * @param element the element whose type is to be returned
+ * @return the type of the given element
+ */
Type2 getType(Element element) {
if (element is LocalVariableElement) {
return ((element as LocalVariableElement)).type;
@@ -5064,7 +5470,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
/**
* Return the type that should be recorded for a node that resolved to the given accessor.
* @param accessor the accessor that the node resolved to
- * @param context if the accessor element has context [by being the RHS of a{@link PrefixedIdentifier} or {@link PropertyAccess}], and the return type of the
+ * @param context if the accessor element has context [[by being the RHS of a{@link PrefixedIdentifier} or {@link PropertyAccess}]], and the return type of the
* accessor is a parameter type, then the type of the LHS can be used to get more
* specific type information
* @return the type that should be recorded for a node that resolved to the given accessor
@@ -5138,7 +5544,7 @@ class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
* @param inferredType the inferred type of the element
*/
void override(VariableElement element, Type2 staticType, Type2 inferredType) {
- if (identical(inferredType, BottomTypeImpl.instance) || element is! VariableElement) {
+ if (identical(inferredType, BottomTypeImpl.instance)) {
return;
}
if (element is PropertyInducingElement) {
@@ -5553,9 +5959,9 @@ class TypeResolverVisitor extends ScopedVisitor {
* @param typeProvider the object used to access the types from the core library
*/
TypeResolverVisitor.con1(Library library, Source source, TypeProvider typeProvider) : super.con1(library, source, typeProvider) {
- _jtd_constructor_273_impl(library, source, typeProvider);
+ _jtd_constructor_274_impl(library, source, typeProvider);
}
- _jtd_constructor_273_impl(Library library, Source source, TypeProvider typeProvider) {
+ _jtd_constructor_274_impl(Library library, Source source, TypeProvider typeProvider) {
_dynamicType = typeProvider.dynamicType;
}
/**
@@ -5568,9 +5974,9 @@ class TypeResolverVisitor extends ScopedVisitor {
* during resolution
*/
TypeResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) : super.con2(definingLibrary, source, typeProvider, errorListener) {
- _jtd_constructor_274_impl(definingLibrary, source, typeProvider, errorListener);
+ _jtd_constructor_275_impl(definingLibrary, source, typeProvider, errorListener);
}
- _jtd_constructor_274_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
+ _jtd_constructor_275_impl(LibraryElement definingLibrary, Source source, TypeProvider typeProvider, AnalysisErrorListener errorListener) {
_dynamicType = typeProvider.dynamicType;
}
Object visitCatchClause(CatchClause node) {
@@ -5781,7 +6187,11 @@ class TypeResolverVisitor extends ScopedVisitor {
} else {
simpleIdentifier = ((typeName as PrefixedIdentifier)).prefix;
}
- reportError(StaticWarningCode.UNDEFINED_CLASS, simpleIdentifier, [simpleIdentifier.name]);
+ if (simpleIdentifier.name == "boolean") {
+ reportError(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, simpleIdentifier, []);
+ } else {
+ reportError(StaticWarningCode.UNDEFINED_CLASS, simpleIdentifier, [simpleIdentifier.name]);
+ }
setElement(typeName, _dynamicType.element);
typeName.staticType = _dynamicType;
node.type = _dynamicType;
@@ -6252,16 +6662,26 @@ class FunctionTypeScope extends EnclosedScope {
* @param typeElement the element representing the type alias represented by this scope
*/
FunctionTypeScope(Scope enclosingScope, FunctionTypeAliasElement typeElement) : super(new EnclosedScope(enclosingScope)) {
- defineTypeParameters(typeElement);
+ defineTypeVariables(typeElement);
+ defineParameters(typeElement);
}
/**
- * Define the type parameters for the function type alias.
+ * Define the parameters for the function type alias.
* @param typeElement the element representing the type represented by this scope
*/
- void defineTypeParameters(FunctionTypeAliasElement typeElement) {
- Scope parameterScope = enclosingScope;
- for (TypeVariableElement parameter in typeElement.typeVariables) {
- parameterScope.define(parameter);
+ void defineParameters(FunctionTypeAliasElement typeElement) {
+ for (ParameterElement parameter in typeElement.parameters) {
+ define(parameter);
+ }
+ }
+ /**
+ * Define the type variables for the function type alias.
+ * @param typeElement the element representing the type represented by this scope
+ */
+ void defineTypeVariables(FunctionTypeAliasElement typeElement) {
+ Scope typeVariableScope = enclosingScope;
+ for (TypeVariableElement typeVariable in typeElement.typeVariables) {
+ typeVariableScope.define(typeVariable);
}
}
}
@@ -6297,10 +6717,10 @@ class LabelScope {
* @param onSwitchMember {@code true} if this label is associated with a {@code switch} member
*/
LabelScope.con1(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
- _jtd_constructor_279_impl(outerScope, onSwitchStatement, onSwitchMember);
+ _jtd_constructor_280_impl(outerScope, onSwitchStatement, onSwitchMember);
}
- _jtd_constructor_279_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
- _jtd_constructor_280_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
+ _jtd_constructor_280_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
+ _jtd_constructor_281_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
}
/**
* Initialize a newly created scope to represent the given label.
@@ -6309,9 +6729,9 @@ class LabelScope {
* @param element the element to which the label resolves
*/
LabelScope.con2(LabelScope outerScope2, String label2, LabelElement element2) {
- _jtd_constructor_280_impl(outerScope2, label2, element2);
+ _jtd_constructor_281_impl(outerScope2, label2, element2);
}
- _jtd_constructor_280_impl(LabelScope outerScope2, String label2, LabelElement element2) {
+ _jtd_constructor_281_impl(LabelScope outerScope2, String label2, LabelElement element2) {
this._outerScope = outerScope2;
this._label = label2;
this._element = element2;
@@ -6985,6 +7405,11 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
*/
bool _isInSystemLibrary = false;
/**
+ * The class containing the AST nodes being visited, or {@code null} if we are not in the scope of
+ * a class.
+ */
+ ClassElement _enclosingClass;
+ /**
* The method or function that we are currently visiting, or {@code null} if we are not inside a
* method or function.
*/
@@ -7037,7 +7462,9 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
}
}
Object visitClassDeclaration(ClassDeclaration node) {
+ ClassElement outerClass = _enclosingClass;
try {
+ _enclosingClass = node.element;
checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
ClassElement classElement = node.element;
if (classElement != null) {
@@ -7053,6 +7480,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
return super.visitClassDeclaration(node);
} finally {
_initialFieldElementsMap = null;
+ _enclosingClass = outerClass;
}
}
Object visitClassTypeAlias(ClassTypeAlias node) {
@@ -7077,6 +7505,10 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
_enclosingFunction = outerFunction;
}
}
+ Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ checkForPrivateOptionalParameter(node);
+ return super.visitDefaultFormalParameter(node);
+ }
Object visitDoStatement(DoStatement node) {
checkForNonBoolCondition(node.condition);
return super.visitDoStatement(node);
@@ -7133,14 +7565,41 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
}
return super.visitInstanceCreationExpression(node);
}
+ Object visitListLiteral(ListLiteral node) {
+ if (node.modifier != null) {
+ TypeArgumentList typeArguments2 = node.typeArguments;
+ if (typeArguments2 != null) {
+ NodeList<TypeName> arguments2 = typeArguments2.arguments;
+ if (arguments2.length != 0) {
+ checkForInvalidTypeArgumentInConstTypedLiteral(arguments2, CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
+ }
+ }
+ }
+ return super.visitListLiteral(node);
+ }
Object visitMapLiteral(MapLiteral node) {
- checkForInvalidTypeArgumentForKey(node);
+ TypeArgumentList typeArguments2 = node.typeArguments;
+ if (typeArguments2 != null) {
+ NodeList<TypeName> arguments2 = typeArguments2.arguments;
+ if (arguments2.length != 0) {
+ checkForInvalidTypeArgumentForKey(arguments2);
+ if (node.modifier != null) {
+ checkForInvalidTypeArgumentInConstTypedLiteral(arguments2, CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
+ }
+ }
+ }
return super.visitMapLiteral(node);
}
Object visitMethodDeclaration(MethodDeclaration node) {
ExecutableElement previousFunction = _enclosingFunction;
try {
_enclosingFunction = node.element;
+ if (node.isSetter()) {
+ checkForWrongNumberOfParametersForSetter(node);
+ } else if (node.isOperator()) {
+ checkForOptionalParameterInOperator(node);
+ }
+ checkForConcreteClassWithAbstractMember(node);
return super.visitMethodDeclaration(node);
} finally {
_enclosingFunction = previousFunction;
@@ -7155,7 +7614,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
return super.visitRethrowExpression(node);
}
Object visitReturnStatement(ReturnStatement node) {
- checkForReturnOfInvalidType(node);
+ checkForAllReturnStatementErrorCodes(node);
return super.visitReturnStatement(node);
}
Object visitSimpleFormalParameter(SimpleFormalParameter node) {
@@ -7259,6 +7718,46 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
return foundError;
}
/**
+ * This checks that the return statement of the form <i>return e;</i> is not in a generative
+ * constructor.
+ * <p>
+ * This checks that return statements without expressions are not in a generative constructor and
+ * the return type is not assignable to {@code null}; that is, we don't have {@code return;} if
+ * the enclosing method has a return type.
+ * <p>
+ * This checks that the return type matches the type of the declared return type in the enclosing
+ * method or function.
+ * @param node the return statement to evaluate
+ * @return {@code true} if and only if an error code is generated on the passed node
+ * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR
+ * @see StaticWarningCode#RETURN_WITHOUT_VALUE
+ * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
+ */
+ bool checkForAllReturnStatementErrorCodes(ReturnStatement node) {
+ FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
+ Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType;
+ Expression returnExpression = node.expression;
+ bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !((_enclosingFunction as ConstructorElement)).isFactory();
+ if (returnExpression != null) {
+ if (isGenerativeConstructor) {
+ _errorReporter.reportError(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, returnExpression, []);
+ return true;
+ }
+ if (!expectedReturnType.isVoid()) {
+ Type2 actualReturnType = getType(returnExpression);
+ if (!actualReturnType.isAssignableTo(expectedReturnType)) {
+ _errorReporter.reportError(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [actualReturnType.name, expectedReturnType.name, _enclosingFunction.name]);
+ return true;
+ }
+ }
+ } else {
+ if (!isGenerativeConstructor && !VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) {
+ _errorReporter.reportError(StaticWarningCode.RETURN_WITHOUT_VALUE, node, []);
+ }
+ }
+ return false;
+ }
+ /**
* This verifies that the passed argument definition test identifier is a parameter.
* @param node the {@link ArgumentDefinitionTest} to evaluate
* @return return {@code true} if and only if an error code is generated on the passed node
@@ -7338,6 +7837,21 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
}
return false;
}
+ /**
+ * This verifies that the passed method declaration is abstract only if the enclosing class is
+ * also abstract.
+ * @param node the method declaration to evaluate
+ * @return {@code true} if and only if an error code is generated on the passed node
+ * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER
+ */
+ bool checkForConcreteClassWithAbstractMember(MethodDeclaration node) {
+ if (node.isAbstract() && _enclosingClass != null && !_enclosingClass.isAbstract()) {
+ SimpleIdentifier methodName = node.name;
+ _errorReporter.reportError(StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, methodName, [methodName.name, _enclosingClass.name]);
+ return true;
+ }
+ return false;
+ }
bool checkForConflictingConstructorNameAndMember(ConstructorDeclaration node) {
ConstructorElement constructorElement = node.element;
SimpleIdentifier constructorName = node.name;
@@ -7633,21 +8147,13 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
return false;
}
/**
- * Checks to ensure that native function bodies can only in SDK code.
- * @param node the map literal to test
+ * Checks to ensure that first type argument to a map literal must be the 'String' type.
+ * @param arguments a non-{@code null}, non-empty {@link TypeName} node list from the respective{@link MapLiteral}
* @return return {@code true} if and only if an error code is generated on the passed node
* @see CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_FOR_KEY
*/
- bool checkForInvalidTypeArgumentForKey(MapLiteral node) {
- TypeArgumentList typeArgumentList = node.typeArguments;
- if (typeArgumentList == null) {
- return false;
- }
- NodeList<TypeName> arguments2 = typeArgumentList.arguments;
- if (arguments2.length == 0) {
- return false;
- }
- TypeName firstArgument = arguments2[0];
+ bool checkForInvalidTypeArgumentForKey(NodeList<TypeName> arguments) {
+ TypeName firstArgument = arguments[0];
Type2 firstArgumentType = firstArgument.type;
if (firstArgumentType != null && firstArgumentType != _typeProvider.stringType) {
_errorReporter.reportError(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_FOR_KEY, firstArgument, []);
@@ -7656,6 +8162,23 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
return false;
}
/**
+ * Checks to ensure that the passed {@link ListLiteral} or {@link MapLiteral} does not have a type
+ * parameter as a type argument.
+ * @param arguments a non-{@code null}, non-empty {@link TypeName} node list from the respective{@link ListLiteral} or {@link MapLiteral}
+ * @param errorCode either {@link CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_LIST} or{@link CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_MAP}
+ * @return {@code true} if and only if an error code is generated on the passed node
+ */
+ bool checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> arguments, ErrorCode errorCode) {
+ bool foundError = false;
+ for (TypeName typeName in arguments) {
+ if (typeName.type is TypeVariableType) {
+ _errorReporter.reportError(errorCode, typeName, [typeName.name]);
+ foundError = true;
+ }
+ }
+ return foundError;
+ }
+ /**
* Checks to ensure that native function bodies can only in SDK code.
* @param node the native function body to test
* @return return {@code true} if and only if an error code is generated on the passed node
@@ -7707,6 +8230,48 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
return false;
}
/**
+ * This verifies the passed operator-method declaration, does not have an optional parameter.
+ * <p>
+ * This method assumes that the method declaration was tested to be an operator declaration before
+ * being called.
+ * @param node the method declaration to evaluate
+ * @return {@code true} if and only if an error code is generated on the passed node
+ * @see CompileTimeErrorCode#OPTIONAL_PARAMETER_IN_OPERATOR
+ */
+ bool checkForOptionalParameterInOperator(MethodDeclaration node) {
+ FormalParameterList parameterList = node.parameters;
+ if (parameterList == null) {
+ return false;
+ }
+ bool foundError = false;
+ NodeList<FormalParameter> formalParameters = parameterList.parameters;
+ for (FormalParameter formalParameter in formalParameters) {
+ if (formalParameter.kind.isOptional()) {
+ _errorReporter.reportError(CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, formalParameter, []);
+ foundError = true;
+ }
+ }
+ return foundError;
+ }
+ /**
+ * This checks for named optional parameters that begin with '_'.
+ * @param node the default formal parameter to evaluate
+ * @return {@code true} if and only if an error code is generated on the passed node
+ * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER
+ */
+ bool checkForPrivateOptionalParameter(DefaultFormalParameter node) {
+ sc.Token separator2 = node.separator;
+ if (separator2 != null && separator2.lexeme == ":") {
+ NormalFormalParameter parameter2 = node.parameter;
+ SimpleIdentifier name = parameter2.identifier;
+ if (!name.isSynthetic() && name.name.startsWith("_")) {
+ _errorReporter.reportError(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node, []);
+ return true;
+ }
+ }
+ return false;
+ }
+ /**
* This checks that the rethrow is inside of a catch clause.
* @param node the rethrow expression to evaluate
* @return {@code true} if and only if an error code is generated on the passed node
@@ -7720,28 +8285,8 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
return false;
}
/**
- * This checks that the return type matches the type of the declared return type in the enclosing
- * method or function.
- * @param node the return statement to evaluate
- * @return return {@code true} if and only if an error code is generated on the passed node
- * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
- */
- bool checkForReturnOfInvalidType(ReturnStatement node) {
- FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
- Type2 expectedReturnType = functionType == null ? null : functionType.returnType;
- Expression returnExpression = node.expression;
- if (expectedReturnType != null && !expectedReturnType.isVoid() && returnExpression != null) {
- Type2 actualReturnType = getType(returnExpression);
- if (!actualReturnType.isAssignableTo(expectedReturnType)) {
- _errorReporter.reportError(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [actualReturnType.name, expectedReturnType.name, _enclosingFunction.name]);
- return true;
- }
- }
- return false;
- }
- /**
* This verifies that the type arguments in the passed instance creation expression are all within
- * their bounds as specified by the class element where the constructor [that is being invoked] is
+ * their bounds as specified by the class element where the constructor [[that is being invoked]] is
* declared.
* @param node the instance creation expression to evaluate
* @param typeName the {@link TypeName} of the {@link ConstructorName} from the{@link InstanceCreationExpression}, this is the AST node that the error is attached to
@@ -7769,6 +8314,27 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
return false;
}
/**
+ * This verifies if the passed setter method declaration, has only one parameter.
+ * <p>
+ * This method assumes that the method declaration was tested to be a setter before being called.
+ * @param node the method declaration to evaluate
+ * @return return {@code true} if and only if an error code is generated on the passed node
+ * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER
+ */
+ bool checkForWrongNumberOfParametersForSetter(MethodDeclaration node) {
+ FormalParameterList parameterList = node.parameters;
+ if (parameterList == null) {
+ return false;
+ }
+ NodeList<FormalParameter> formalParameters = parameterList.parameters;
+ int numberOfParameters = formalParameters.length;
+ if (numberOfParameters != 1) {
+ _errorReporter.reportError(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, node.name, [numberOfParameters]);
+ return true;
+ }
+ return false;
+ }
+ /**
* Return the type of the given expression that is to be used for type analysis.
* @param expression the expression whose type is to be returned
* @return the type of the given expression

Powered by Google App Engine
This is Rietveld 408576698