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

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

Issue 18010002: Report errors for invalid annotations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 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
diff --git a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ElementResolver.java b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ElementResolver.java
index e8bb6fb342d55d95e7e722b96a17e2102907afd1..14af13e3b6f69e41b99c12dc82ab31278de5e7d4 100644
--- a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ElementResolver.java
+++ b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ElementResolver.java
@@ -925,28 +925,19 @@ public class ElementResolver extends SimpleASTVisitor<Void> {
// TODO(brianwilkerson) The prefix needs to be resolved to the element for the import that
// defines the prefix, not the prefix's element.
recordResolution(identifier, element);
+ // Validate annotation element.
+ if (node.getParent() instanceof Annotation) {
+ Annotation annotation = (Annotation) node.getParent();
+ resolveAnnotationElement(annotation, element, null);
+ return null;
+ }
return null;
}
- //
- // May be annotation, 'const' constructor invocation.
- //
- if (node.getParent() instanceof Annotation && prefixElement instanceof ClassElement) {
+ // May be annotation, resolve invocation of "const" constructor.
+ if (node.getParent() instanceof Annotation) {
Annotation annotation = (Annotation) node.getParent();
- // look up ConstructorElement
- ConstructorElement constructor;
- {
- InterfaceType interfaceType = (InterfaceType) prefix.getStaticType();
- LibraryElement definingLibrary = resolver.getDefiningLibrary();
- constructor = interfaceType.lookUpConstructor(identifier.getName(), definingLibrary);
- }
- // record elements
- recordResolution(identifier, constructor);
- annotation.setElement(constructor);
- // resolve arguments
- resolveAnnotationConstructorInvocationArguments(annotation, constructor);
- // done
- return null;
+ resolveAnnotationElement(annotation, prefixElement, node.getIdentifier());
}
//
@@ -1057,23 +1048,11 @@ public class ElementResolver extends SimpleASTVisitor<Void> {
recordResolution(node, element);
//
- // May be annotation, 'const' constructor invocation.
+ // Validate annotation element.
//
- if (node.getParent() instanceof Annotation && element instanceof ClassElement) {
+ if (node.getParent() instanceof Annotation) {
Annotation annotation = (Annotation) node.getParent();
- // look up ConstructorElement
- ConstructorElement constructor;
- {
- InterfaceType interfaceType = new InterfaceTypeImpl((ClassElement) element);
- LibraryElement definingLibrary = resolver.getDefiningLibrary();
- constructor = interfaceType.lookUpConstructor(null, definingLibrary);
- }
- // record element
- annotation.setElement(constructor);
- // resolve arguments
- resolveAnnotationConstructorInvocationArguments(annotation, constructor);
- // done
- return null;
+ resolveAnnotationElement(annotation, element, null);
}
return null;
}
@@ -2004,16 +1983,77 @@ public class ElementResolver extends SimpleASTVisitor<Void> {
private void resolveAnnotationConstructorInvocationArguments(Annotation annotation,
ConstructorElement constructor) {
- // TODO(scheglov) check that the constructor is 'const' (in ErrorVerifier)
- // resolve arguments to parameters
ArgumentList argumentList = annotation.getArguments();
+ // error will be reported in ConstantVerifier
if (argumentList == null) {
- // TODO(scheglov) report problem (in ErrorVerifier), no arguments for constructor invocation
- } else {
- ParameterElement[] parameters = resolveArgumentsToParameters(true, argumentList, constructor);
- if (parameters != null) {
- argumentList.setCorrespondingStaticParameters(parameters);
+ return;
+ }
+ // resolve arguments to parameters
+ ParameterElement[] parameters = resolveArgumentsToParameters(true, argumentList, constructor);
+ if (parameters != null) {
+ argumentList.setCorrespondingStaticParameters(parameters);
+ }
+ }
+
+ /**
+ * Validates that the given {@link Element} is the constant variable; or resolves it as a
+ * constructor invocation.
+ *
+ * @param annotation the {@link Annotation} to resolve
+ * @param element the current known {@link Element} of the annotation, or {@link ClassElement}
+ * @param nameNode the name of the invoked constructor, may be {@code null} if unnamed constructor
+ * or not a constructor invocation
+ */
+ private void resolveAnnotationElement(Annotation annotation, Element element,
+ SimpleIdentifier nameNode) {
+ // constant variable
+ if (element instanceof PropertyAccessorElement) {
+ PropertyAccessorElement accessorElement = (PropertyAccessorElement) element;
+ // accessor should be synthetic
+ if (!accessorElement.isSynthetic()) {
+ resolver.reportError(CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
+ return;
+ }
+ // variable should be constant
+ VariableElement variableElement = accessorElement.getVariable();
+ if (!variableElement.isConst()) {
+ resolver.reportError(CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
+ }
+ // OK
+ return;
+ }
+ // const constructor invocation
+ if (element instanceof ClassElement) {
+ // prepare constructor name
+ if (nameNode == null) {
+ nameNode = annotation.getConstructorName();
+ }
+ String name = nameNode != null ? nameNode.getName() : null;
+ // look up ConstructorElement
+ ConstructorElement constructor;
+ {
+ InterfaceType interfaceType = new InterfaceTypeImpl((ClassElement) element);
+ LibraryElement definingLibrary = resolver.getDefiningLibrary();
+ constructor = interfaceType.lookUpConstructor(name, definingLibrary);
+ }
+ // not a constructor
+ if (constructor == null) {
+ resolver.reportError(CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
+ return;
}
+ // record element
+ annotation.setElement(constructor);
+ if (nameNode != null) {
+ recordResolution(nameNode, constructor);
+ }
+ // resolve arguments
+ resolveAnnotationConstructorInvocationArguments(annotation, constructor);
+ // OK
+ return;
+ }
+ // something unknown
+ if (element != null) {
+ resolver.reportError(CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
}
}
@@ -2253,6 +2293,15 @@ public class ElementResolver extends SimpleASTVisitor<Void> {
private void resolvePropertyAccess(Expression target, SimpleIdentifier propertyName) {
Type staticType = getStaticType(target);
ExecutableElement staticElement = resolveProperty(target, staticType, propertyName);
+
+ // May be part of annotation, record property element only if exists.
+ // Error was already reported in validateAnnotationElement().
+ if (target.getParent().getParent() instanceof Annotation) {
+ if (staticElement != null) {
+ recordResolution(propertyName, staticElement);
+ }
+ return;
+ }
propertyName.setStaticElement(staticElement);
Type propagatedType = getPropagatedType(target);

Powered by Google App Engine
This is Rietveld 408576698