| 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.
|
| *
|
|
|