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

Unified Diff: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ElementResolver.java

Issue 15277005: Fixes for issues 10017 and 10161 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ElementResolver.java
===================================================================
--- editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ElementResolver.java (revision 22889)
+++ editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ElementResolver.java (working copy)
@@ -16,10 +16,14 @@
import com.google.dart.engine.AnalysisEngine;
import com.google.dart.engine.ast.ASTNode;
import com.google.dart.engine.ast.ASTVisitor;
+import com.google.dart.engine.ast.AnnotatedNode;
+import com.google.dart.engine.ast.Annotation;
import com.google.dart.engine.ast.ArgumentList;
import com.google.dart.engine.ast.AssignmentExpression;
import com.google.dart.engine.ast.BinaryExpression;
import com.google.dart.engine.ast.BreakStatement;
+import com.google.dart.engine.ast.ClassDeclaration;
+import com.google.dart.engine.ast.ClassTypeAlias;
import com.google.dart.engine.ast.Combinator;
import com.google.dart.engine.ast.CommentReference;
import com.google.dart.engine.ast.CompilationUnit;
@@ -28,10 +32,14 @@
import com.google.dart.engine.ast.ConstructorInitializer;
import com.google.dart.engine.ast.ConstructorName;
import com.google.dart.engine.ast.ContinueStatement;
+import com.google.dart.engine.ast.DeclaredIdentifier;
import com.google.dart.engine.ast.ExportDirective;
import com.google.dart.engine.ast.Expression;
+import com.google.dart.engine.ast.FieldDeclaration;
import com.google.dart.engine.ast.FieldFormalParameter;
+import com.google.dart.engine.ast.FunctionDeclaration;
import com.google.dart.engine.ast.FunctionExpressionInvocation;
+import com.google.dart.engine.ast.FunctionTypeAlias;
import com.google.dart.engine.ast.HideCombinator;
import com.google.dart.engine.ast.Identifier;
import com.google.dart.engine.ast.ImportDirective;
@@ -54,8 +62,11 @@
import com.google.dart.engine.ast.SimpleIdentifier;
import com.google.dart.engine.ast.SuperConstructorInvocation;
import com.google.dart.engine.ast.SuperExpression;
+import com.google.dart.engine.ast.TopLevelVariableDeclaration;
import com.google.dart.engine.ast.TypeName;
import com.google.dart.engine.ast.TypeParameter;
+import com.google.dart.engine.ast.VariableDeclaration;
+import com.google.dart.engine.ast.VariableDeclarationList;
import com.google.dart.engine.ast.visitor.SimpleASTVisitor;
import com.google.dart.engine.element.ClassElement;
import com.google.dart.engine.element.CompilationUnitElement;
@@ -79,8 +90,10 @@
import com.google.dart.engine.error.ErrorCode;
import com.google.dart.engine.error.StaticTypeWarningCode;
import com.google.dart.engine.error.StaticWarningCode;
+import com.google.dart.engine.internal.element.AnnotationImpl;
import com.google.dart.engine.internal.element.ClassElementImpl;
import com.google.dart.engine.internal.element.ConstructorElementImpl;
+import com.google.dart.engine.internal.element.ElementImpl;
import com.google.dart.engine.internal.element.FieldFormalParameterElementImpl;
import com.google.dart.engine.internal.element.LabelElementImpl;
import com.google.dart.engine.internal.element.MultiplyDefinedElementImpl;
@@ -98,6 +111,7 @@
import com.google.dart.engine.type.TypeVariableType;
import com.google.dart.engine.utilities.dart.ParameterKind;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -365,6 +379,18 @@
}
@Override
+ public Void visitClassDeclaration(ClassDeclaration node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
+ @Override
+ public Void visitClassTypeAlias(ClassTypeAlias node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
+ @Override
public Void visitCommentReference(CommentReference node) {
Identifier identifier = node.getIdentifier();
if (identifier instanceof SimpleIdentifier) {
@@ -468,28 +494,24 @@
@Override
public Void visitConstructorDeclaration(ConstructorDeclaration node) {
super.visitConstructorDeclaration(node);
- // set redirected factory constructor
- {
+ ConstructorElement element = node.getElement();
+ if (element instanceof ConstructorElementImpl) {
+ ConstructorElementImpl constructorElement = (ConstructorElementImpl) element;
+ // set redirected factory constructor
ConstructorName redirectedNode = node.getRedirectedConstructor();
if (redirectedNode != null) {
ConstructorElement redirectedElement = redirectedNode.getElement();
- ConstructorElement element = node.getElement();
- if (element instanceof ConstructorElementImpl) {
- ((ConstructorElementImpl) element).setRedirectedConstructor(redirectedElement);
- }
+ constructorElement.setRedirectedConstructor(redirectedElement);
}
- }
- // set redirected generate constructor
- for (ConstructorInitializer initializer : node.getInitializers()) {
- if (initializer instanceof RedirectingConstructorInvocation) {
- ConstructorElement redirectedElement = ((RedirectingConstructorInvocation) initializer).getElement();
- ConstructorElement element = node.getElement();
- if (element instanceof ConstructorElementImpl) {
- ((ConstructorElementImpl) element).setRedirectedConstructor(redirectedElement);
+ // set redirected generate constructor
+ for (ConstructorInitializer initializer : node.getInitializers()) {
+ if (initializer instanceof RedirectingConstructorInvocation) {
+ ConstructorElement redirectedElement = ((RedirectingConstructorInvocation) initializer).getElement();
+ constructorElement.setRedirectedConstructor(redirectedElement);
}
}
+ setMetadata(constructorElement, node);
}
- // done
return null;
}
@@ -552,6 +574,12 @@
}
@Override
+ public Void visitDeclaredIdentifier(DeclaredIdentifier node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
+ @Override
public Void visitExportDirective(ExportDirective node) {
Element element = node.getElement();
if (element instanceof ExportElement) {
@@ -559,6 +587,7 @@
// TODO(brianwilkerson) Figure out whether the element can ever be something other than an
// ExportElement
resolveCombinators(((ExportElement) element).getExportedLibrary(), node.getCombinators());
+ setMetadata(element, node);
}
return null;
}
@@ -627,13 +656,25 @@
}
@Override
+ public Void visitFunctionDeclaration(FunctionDeclaration node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
+ @Override
public Void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
// TODO(brianwilkerson) Can we ever resolve the function being invoked?
- //resolveNamedArguments(node.getArgumentList(), invokedFunction);
+ //resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
return null;
}
@Override
+ public Void visitFunctionTypeAlias(FunctionTypeAlias node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
+ @Override
public Void visitImportDirective(ImportDirective node) {
SimpleIdentifier prefixNode = node.getPrefix();
if (prefixNode != null) {
@@ -655,6 +696,7 @@
if (library != null) {
resolveCombinators(library, node.getCombinators());
}
+ setMetadata(element, node);
}
return null;
}
@@ -696,11 +738,23 @@
ConstructorElement invokedConstructor = node.getConstructorName().getElement();
staticElementMap.put(node, invokedConstructor);
node.setElement(invokedConstructor);
- resolveNamedArguments(node.getArgumentList(), invokedConstructor);
+ resolveArgumentsToParameters(node.getArgumentList(), invokedConstructor);
return null;
}
@Override
+ public Void visitLibraryDirective(LibraryDirective node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
+ @Override
+ public Void visitMethodDeclaration(MethodDeclaration node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
+ @Override
public Void visitMethodInvocation(MethodInvocation node) {
//
// We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or 'm(a1, ..., an)'. The
@@ -740,17 +794,19 @@
CALL_METHOD_NAME,
resolver.getDefiningLibrary());
if (callMethod != null) {
- resolveNamedArguments(node.getArgumentList(), callMethod);
+ resolveArgumentsToParameters(node.getArgumentList(), callMethod);
}
} else if (getterReturnType instanceof FunctionType) {
Element functionElement = ((FunctionType) getterReturnType).getElement();
if (functionElement instanceof ExecutableElement) {
- resolveNamedArguments(node.getArgumentList(), (ExecutableElement) functionElement);
+ resolveArgumentsToParameters(
+ node.getArgumentList(),
+ (ExecutableElement) functionElement);
}
}
}
} else if (recordedElement instanceof ExecutableElement) {
- resolveNamedArguments(node.getArgumentList(), (ExecutableElement) recordedElement);
+ resolveArgumentsToParameters(node.getArgumentList(), (ExecutableElement) recordedElement);
}
//
// Then check for error conditions.
@@ -814,6 +870,18 @@
}
@Override
+ public Void visitPartDirective(PartDirective node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
+ @Override
+ public Void visitPartOfDirective(PartOfDirective node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
+ @Override
public Void visitPostfixExpression(PostfixExpression node) {
Expression operand = node.getOperand();
String methodName = getPostfixOperator(node);
@@ -936,7 +1004,7 @@
}
staticElementMap.put(node, element);
node.setElement(element);
- resolveNamedArguments(node.getArgumentList(), element);
+ resolveArgumentsToParameters(node.getArgumentList(), element);
return null;
}
@@ -1013,7 +1081,7 @@
}
staticElementMap.put(node, element);
node.setElement(element);
- resolveNamedArguments(node.getArgumentList(), element);
+ resolveArgumentsToParameters(node.getArgumentList(), element);
return null;
}
@@ -1034,10 +1102,34 @@
variable.setBound(bound.getType());
}
}
+ setMetadata(node.getElement(), node);
return null;
}
+ @Override
+ public Void visitVariableDeclaration(VariableDeclaration node) {
+ setMetadata(node.getElement(), node);
+ return null;
+ }
+
/**
+ * Generate annotation elements for each of the annotations in the given node list and add them to
+ * the given list of elements.
+ *
+ * @param annotationList the list of elements to which new elements are to be added
+ * @param annotations the AST nodes used to generate new elements
+ */
+ private void addAnnotations(ArrayList<AnnotationImpl> annotationList,
+ NodeList<Annotation> annotations) {
+ for (Annotation annotationNode : annotations) {
+ Element resolvedElement = annotationNode.getElement();
+ if (resolvedElement != null) {
+ annotationList.add(new AnnotationImpl(resolvedElement));
+ }
+ }
+ }
+
+ /**
* Given that we have found code to invoke the given element, return the error code that should be
* reported, or {@code null} if no error should be reported.
*
@@ -1192,26 +1284,6 @@
}
/**
- * 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
- * @param name the name being searched for
- * @return the parameter with the given name
- */
- private ParameterElement findNamedParameter(ParameterElement[] parameters, String name) {
- for (ParameterElement parameter : parameters) {
- if (parameter.getParameterKind() == ParameterKind.NAMED) {
- String parameterName = parameter.getName();
- if (parameterName != null && parameterName.equals(name)) {
- return parameter;
- }
- }
- }
- return null;
- }
-
- /**
* Return the name of the method invoked by the given index expression.
*
* @param node the index expression being invoked
@@ -1762,6 +1834,67 @@
return element;
}
+ /**
+ * Given a list of arguments and the element that will be invoked using those argument, compute
+ * the list of parameters that correspond to the list of arguments.
+ *
+ * @param argumentList the list of arguments being passed to the element
+ * @param executableElement the element that will be invoked with the arguments
+ */
+ private void resolveArgumentsToParameters(ArgumentList argumentList,
+ ExecutableElement executableElement) {
+ if (executableElement == null) {
+ return;
+ }
+ ParameterElement[] parameters = executableElement.getParameters();
+ ArrayList<ParameterElement> requiredParameters = new ArrayList<ParameterElement>();
+ ArrayList<ParameterElement> positionalParameters = new ArrayList<ParameterElement>();
+ HashMap<String, ParameterElement> namedParameters = new HashMap<String, ParameterElement>();
+ for (ParameterElement parameter : parameters) {
+ ParameterKind kind = parameter.getParameterKind();
+ if (kind == ParameterKind.REQUIRED) {
+ requiredParameters.add(parameter);
+ } else if (kind == ParameterKind.POSITIONAL) {
+ positionalParameters.add(parameter);
+ } else {
+ namedParameters.put(parameter.getName(), parameter);
+ }
+ }
+ ArrayList<ParameterElement> unnamedParameters = new ArrayList<ParameterElement>(
+ requiredParameters);
+ unnamedParameters.addAll(positionalParameters);
+ int unnamedParameterCount = unnamedParameters.size();
+ int unnamedIndex = 0;
+
+ NodeList<Expression> arguments = argumentList.getArguments();
+ int argumentCount = arguments.size();
+ if (argumentCount < requiredParameters.size()) {
+ // TODO(brianwilkerson) Report this error (not enough arguments)
+ }
+ ParameterElement[] resolvedParameters = new ParameterElement[argumentCount];
+ for (int i = 0; i < argumentCount; i++) {
+ Expression argument = arguments.get(i);
+ if (argument instanceof NamedExpression) {
+ SimpleIdentifier nameNode = ((NamedExpression) argument).getName().getLabel();
+ String name = nameNode.getName();
+ ParameterElement element = namedParameters.get(name);
+ if (element == null) {
+ // TODO(brianwilkerson) Report this error (no corresponding parameter for named argument)
+ } else {
+ resolvedParameters[i] = element;
+ recordResolution(nameNode, element);
+ }
+ } else {
+ if (unnamedIndex < unnamedParameterCount) {
+ resolvedParameters[i] = unnamedParameters.get(unnamedIndex++);
+ } else {
+ // TODO(brianwilkerson) Report this error (too many positional arguments) exactly once
+ }
+ }
+ }
+ argumentList.setCorrespondingParameters(resolvedParameters);
+ }
+
// /**
// * Report the {@link StaticTypeWarningCode}s <code>UNDEFINED_SETTER</code> and
// * <code>UNDEFINED_GETTER</code>.
@@ -1865,8 +1998,8 @@
return element;
}
}
- //return targetElement;
}
+ // TODO(brianwilkerson) Report this error.
return null;
}
@@ -1901,34 +2034,11 @@
}
}
}
+ // TODO(brianwilkerson) Report this error.
return element;
}
/**
- * Resolve the names associated with any named arguments to the parameter elements named by the
- * argument.
- *
- * @param argumentList the arguments to be resolved
- * @param invokedMethod the method or function defining the parameters to which the named
- * arguments are to be resolved
- */
- private void resolveNamedArguments(ArgumentList argumentList, ExecutableElement invokedMethod) {
- if (invokedMethod == null) {
- return;
- }
- ParameterElement[] parameters = invokedMethod.getParameters();
- for (Expression argument : argumentList.getArguments()) {
- if (argument instanceof NamedExpression) {
- SimpleIdentifier name = ((NamedExpression) argument).getName().getLabel();
- ParameterElement parameter = findNamedParameter(parameters, name.getName());
- if (parameter != null) {
- recordResolution(name, parameter);
- }
- }
- }
- }
-
- /**
* Given that we are accessing a property of the given type with the given name, return the
* element that represents the property.
*
@@ -2123,6 +2233,36 @@
}
/**
+ * Given a node that can have annotations associated with it and the element to which that node
+ * has been resolved, create the annotations in the element model representing the annotations on
+ * the node.
+ *
+ * @param element the element to which the node has been resolved
+ * @param node the node that can have annotations associated with it
+ */
+ private void setMetadata(Element element, AnnotatedNode node) {
+ if (!(element instanceof ElementImpl)) {
+ return;
+ }
+ ArrayList<AnnotationImpl> annotationList = new ArrayList<AnnotationImpl>();
+ addAnnotations(annotationList, node.getMetadata());
+ if (node instanceof VariableDeclaration && node.getParent() instanceof VariableDeclarationList) {
+ VariableDeclarationList list = (VariableDeclarationList) node.getParent();
+ addAnnotations(annotationList, list.getMetadata());
+ if (list.getParent() instanceof FieldDeclaration) {
+ FieldDeclaration fieldDeclaration = (FieldDeclaration) list.getParent();
+ addAnnotations(annotationList, fieldDeclaration.getMetadata());
+ } else if (list.getParent() instanceof TopLevelVariableDeclaration) {
+ TopLevelVariableDeclaration variableDeclaration = (TopLevelVariableDeclaration) list.getParent();
+ addAnnotations(annotationList, variableDeclaration.getMetadata());
+ }
+ }
+ if (!annotationList.isEmpty()) {
+ ((ElementImpl) element).setMetadata(annotationList.toArray(new AnnotationImpl[annotationList.size()]));
+ }
+ }
+
+ /**
* Return {@code true} if we should report an error as a result of looking up a member in the
* given type and not finding any member.
*

Powered by Google App Engine
This is Rietveld 408576698