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

Unified Diff: pkg/analyzer/lib/src/task/dart.dart

Issue 1319703003: Handle cycles when infering static variables (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/task/dart.dart
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 2a0815c95129c49f673bd02319741249d6c2a5ee..8a75bbbce6c3a6cae2a5be55df923f3ae13ea7dc 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -2561,40 +2561,52 @@ class InferStaticVariableTypeTask extends InferStaticVariableTask {
VariableElementImpl variable = target;
CompilationUnit unit = getRequiredInput(UNIT_INPUT);
TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
- //
- // Re-resolve the variable's initializer so that the inferred types of other
- // variables will be propagated.
- //
- NodeLocator locator = new NodeLocator(variable.nameOffset);
- AstNode node = locator.searchWithin(unit);
- VariableDeclaration declaration =
- node.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration);
- if (declaration == null || declaration.name != node) {
- throw new AnalysisException(
- "NodeLocator failed to find a variable's declaration");
- }
- RecordingErrorListener errorListener = new RecordingErrorListener();
- Expression initializer = declaration.initializer;
- ResolutionContext resolutionContext =
- ResolutionContextBuilder.contextFor(initializer, errorListener);
- ResolverVisitor visitor = new ResolverVisitor(
- variable.library, variable.source, typeProvider, errorListener,
- nameScope: resolutionContext.scope);
- if (resolutionContext.enclosingClassDeclaration != null) {
- visitor.prepareToResolveMembersInClass(
- resolutionContext.enclosingClassDeclaration);
- }
- visitor.initForIncrementalResolution();
- initializer.accept(visitor);
- //
- // Record the type of the variable.
- //
- DartType newType = initializer.staticType;
- variable.type = newType;
- (variable.initializer as ExecutableElementImpl).returnType = newType;
- if (variable is PropertyInducingElementImpl) {
- setReturnType(variable.getter, newType);
- setParameterType(variable.setter, newType);
+ if (dependencyCycle == null) {
+ //
+ // Re-resolve the variable's initializer so that the inferred types of other
+ // variables will be propagated.
+ //
+ NodeLocator locator = new NodeLocator(variable.nameOffset);
+ AstNode node = locator.searchWithin(unit);
+ VariableDeclaration declaration = node
+ .getAncestor((AstNode ancestor) => ancestor is VariableDeclaration);
+ if (declaration == null || declaration.name != node) {
+ throw new AnalysisException(
+ "NodeLocator failed to find a variable's declaration");
+ }
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ Expression initializer = declaration.initializer;
+ ResolutionContext resolutionContext =
+ ResolutionContextBuilder.contextFor(initializer, errorListener);
+ ResolverVisitor visitor = new ResolverVisitor(
+ variable.library, variable.source, typeProvider, errorListener,
+ nameScope: resolutionContext.scope);
+ if (resolutionContext.enclosingClassDeclaration != null) {
+ visitor.prepareToResolveMembersInClass(
+ resolutionContext.enclosingClassDeclaration);
+ }
+ visitor.initForIncrementalResolution();
+ initializer.accept(visitor);
+ //
+ // Record the type of the variable.
+ //
+ DartType newType = initializer.staticType;
+ if (newType == null || newType.isBottom) {
+ newType = typeProvider.dynamicType;
+ }
+ variable.type = newType;
+ (variable.initializer as ExecutableElementImpl).returnType = newType;
+ if (variable is PropertyInducingElementImpl) {
+ setReturnType(variable.getter, newType);
+ setParameterType(variable.setter, newType);
+ }
+ } else {
+ // TODO(brianwilkerson) For now we simply don't infer any type for
+ // variables or fields involved in a cycle. We could try to be smarter
+ // by re-resolving the initializer in a context in which the types of all
+ // of the variables in the cycle are assumed to be `null`, but it isn't
+ // clear to me that this would produce better results often enough to
+ // warrent the extra effort.
Leaf 2015/08/31 21:07:03 warrent -> warrant
Brian Wilkerson 2015/08/31 21:27:47 Thanks! I really miss spell checking :-(
}
//
// Record outputs.
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698