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

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

Issue 1043843003: Rework handling of factory redirects in constant evaluation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 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 | no next file » | 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 d14bba86194ac45e0a211366f9c7bb0b3bc5030f..5b400a8c3b8acb86427b9ad31d85976e40cad061 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -442,6 +442,16 @@ class ConstantValueComputer {
});
constructorDeclarationMap.forEach((ConstructorElement element,
ConstructorDeclaration declaration) {
+ ConstructorElement redirectedConstructor =
+ _getConstRedirectedConstructor(element);
+ if (redirectedConstructor != null) {
+ ConstructorElement redirectedConstructorBase =
+ _getConstructorBase(redirectedConstructor);
+ ConstructorDeclaration redirectedConstructorDeclaration =
+ findConstructorDeclaration(redirectedConstructorBase);
+ referenceGraph.addEdge(declaration, redirectedConstructorDeclaration);
+ return;
+ }
ReferenceFinder referenceFinder = new ReferenceFinder(declaration,
referenceGraph, _variableDeclarationMap, constructorDeclarationMap);
referenceGraph.addNode(declaration);
@@ -488,7 +498,6 @@ class ConstantValueComputer {
if (constructor == null) {
continue;
}
- constructor = _followConstantRedirectionChain(constructor);
ConstructorDeclaration declaration =
findConstructorDeclaration(constructor);
// An instance creation expression depends both on the constructor and
@@ -985,37 +994,22 @@ class ConstantValueComputer {
ConstructorElement constructor) {
HashSet<ConstructorElement> constructorsVisited =
new HashSet<ConstructorElement>();
- while (constructor.isFactory) {
- if (identical(
- constructor.enclosingElement.type, typeProvider.symbolType)) {
- // The dart:core.Symbol has a const factory constructor that redirects
- // to dart:_internal.Symbol. That in turn redirects to an external
- // const constructor, which we won't be able to evaluate.
- // So stop following the chain of redirections at dart:core.Symbol, and
- // let [evaluateInstanceCreationExpression] handle it specially.
- break;
- }
- ConstructorElement constructorBase = _getConstructorBase(constructor);
- constructorsVisited.add(constructorBase);
+ while (true) {
ConstructorElement redirectedConstructor =
- constructor.redirectedConstructor;
+ _getConstRedirectedConstructor(constructor);
if (redirectedConstructor == null) {
- // This can happen if constructor is an external factory constructor.
- break;
- }
- if (!redirectedConstructor.isConst) {
- // Delegating to a non-const constructor--this is not allowed (and
- // is checked elsewhere--see
- // [ErrorVerifier.checkForRedirectToNonConstConstructor()]).
- break;
- }
- ConstructorElement redirectedConstructorBase =
- _getConstructorBase(redirectedConstructor);
- if (constructorsVisited.contains(redirectedConstructorBase)) {
- // Cycle in redirecting factory constructors--this is not allowed
- // and is checked elsewhere--see
- // [ErrorVerifier.checkForRecursiveFactoryRedirect()]).
break;
+ } else {
+ ConstructorElement constructorBase = _getConstructorBase(constructor);
+ constructorsVisited.add(constructorBase);
+ ConstructorElement redirectedConstructorBase =
+ _getConstructorBase(redirectedConstructor);
+ if (constructorsVisited.contains(redirectedConstructorBase)) {
+ // Cycle in redirecting factory constructors--this is not allowed
+ // and is checked elsewhere--see
+ // [ErrorVerifier.checkForRecursiveFactoryRedirect()]).
+ break;
+ }
}
constructor = redirectedConstructor;
}
@@ -1032,6 +1026,38 @@ class ConstantValueComputer {
// TODO(brianwilkerson) Implement this.
}
+ /**
+ * If [constructor] redirects to another const constructor, return the
+ * const constructor it redirects to. Otherwise return `null`.
+ */
+ ConstructorElement _getConstRedirectedConstructor(
+ ConstructorElement constructor) {
+ if (!constructor.isFactory) {
+ return null;
+ }
+ if (identical(constructor.enclosingElement.type, typeProvider.symbolType)) {
+ // The dart:core.Symbol has a const factory constructor that redirects
+ // to dart:_internal.Symbol. That in turn redirects to an external
+ // const constructor, which we won't be able to evaluate.
+ // So stop following the chain of redirections at dart:core.Symbol, and
+ // let [evaluateInstanceCreationExpression] handle it specially.
+ return null;
+ }
+ ConstructorElement redirectedConstructor =
+ constructor.redirectedConstructor;
+ if (redirectedConstructor == null) {
+ // This can happen if constructor is an external factory constructor.
+ return null;
+ }
+ if (!redirectedConstructor.isConst) {
+ // Delegating to a non-const constructor--this is not allowed (and
+ // is checked elsewhere--see
+ // [ErrorVerifier.checkForRedirectToNonConstConstructor()]).
+ return null;
+ }
+ return redirectedConstructor;
+ }
+
ConstructorElement _getConstructorBase(ConstructorElement constructor) {
while (constructor is ConstructorMember) {
constructor = (constructor as ConstructorMember).baseElement;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698