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

Unified Diff: pkg/analyzer/lib/src/generated/constant.dart

Issue 772133002: Evaluate annotations using ConstantValueComputer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/element.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/constant.dart
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index 7eaf916bdb2bc110453a677d7d37ba26c9904e76..b756a9d84dc44c21a314c1e4148d4be4717aea7e 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -228,9 +228,10 @@ class ConstantEvaluator {
}
/**
- * Instances of the class `ConstantFinder` are used to traverse the AST structures of all of
- * the compilation units being resolved and build a table mapping constant variable elements to the
- * declarations of those variables.
+ * Instances of the class `ConstantFinder` are used to traverse the AST
+ * structures of all of the compilation units being resolved and build tables
+ * of the constant variables, constant constructors, constant constructor
+ * invocations, and annotations found in those compilation units.
*/
class ConstantFinder extends RecursiveAstVisitor<Object> {
/**
@@ -251,6 +252,18 @@ class ConstantFinder extends RecursiveAstVisitor<Object> {
final List<InstanceCreationExpression> constructorInvocations =
new List<InstanceCreationExpression>();
+ /**
+ * A collection of annotations.
+ */
+ final List<Annotation> annotations = <Annotation>[];
+
+ @override
+ Object visitAnnotation(Annotation node) {
+ super.visitAnnotation(node);
+ annotations.add(node);
+ return null;
+ }
+
@override
Object visitConstructorDeclaration(ConstructorDeclaration node) {
super.visitConstructorDeclaration(node);
@@ -357,6 +370,11 @@ class ConstantValueComputer {
List<InstanceCreationExpression> _constructorInvocations;
/**
+ * A collection of annotations.
+ */
+ List<Annotation> _annotations;
+
+ /**
* The set of variables declared on the command line using '-D'.
*/
final DeclaredVariables _declaredVariables;
@@ -410,6 +428,7 @@ class ConstantValueComputer {
_variableDeclarationMap = _constantFinder.variableMap;
constructorDeclarationMap = _constantFinder.constructorMap;
_constructorInvocations = _constantFinder.constructorInvocations;
+ _annotations = _constantFinder.annotations;
_variableDeclarationMap.values.forEach((VariableDeclaration declaration) {
ReferenceFinder referenceFinder = new ReferenceFinder(
declaration,
@@ -498,6 +517,12 @@ class ConstantValueComputer {
}
}
}
+ // Since no constant can depend on an annotation, we don't waste time
+ // including them in the topological sort. We just process all the
+ // annotations after all other constants are finished.
+ for (Annotation annotation in _annotations) {
+ _computeValueFor(annotation);
+ }
}
/**
@@ -647,6 +672,44 @@ class ConstantValueComputer {
new EvaluationResultImpl.con2(dartObject, errorListener.errors);
}
}
+ } else if (constNode is Annotation) {
+ ElementAnnotationImpl elementAnnotation = constNode.elementAnnotation;
+ // elementAnnotation is null if the annotation couldn't be resolved, in
+ // which case we skip it.
+ if (elementAnnotation != null) {
+ Element element = elementAnnotation.element;
+ if (element is PropertyAccessorElement &&
+ element.variable is VariableElementImpl) {
+ // The annotation is a reference to a compile-time constant variable.
+ // Just copy the evaluation result.
+ VariableElementImpl variableElement =
+ element.variable as VariableElementImpl;
+ elementAnnotation.evaluationResult = variableElement.evaluationResult;
+ } else if (element is ConstructorElementImpl &&
+ constNode.arguments != null) {
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ CompilationUnit sourceCompilationUnit =
+ constNode.getAncestor((node) => node is CompilationUnit);
+ ErrorReporter errorReporter =
+ new ErrorReporter(errorListener, sourceCompilationUnit.element.source);
+ ConstantVisitor constantVisitor =
+ createConstantVisitor(errorReporter);
+ DartObjectImpl result = _evaluateConstructorCall(
+ constNode,
+ constNode.arguments.arguments,
+ element,
+ constantVisitor,
+ errorReporter);
+ elementAnnotation.evaluationResult =
+ new EvaluationResultImpl.con2(result, errorListener.errors);
+ } else {
+ // This may happen for invalid code (e.g. failing to pass arguments
+ // to an annotation which references a const constructor). The error
+ // is detected elsewhere, so just silently ignore it here.
+ elementAnnotation.evaluationResult =
+ new EvaluationResultImpl.con1(null);
+ }
+ }
} else {
// Should not happen.
AnalysisEngine.instance.logger.logError(
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/element.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698