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

Side by Side 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, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library engine.constant; 8 library engine.constant;
9 9
10 import 'dart:collection'; 10 import 'dart:collection';
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 _constructorInvocations = _constantFinder.constructorInvocations; 435 _constructorInvocations = _constantFinder.constructorInvocations;
436 _annotations = _constantFinder.annotations; 436 _annotations = _constantFinder.annotations;
437 _variableDeclarationMap.values.forEach((VariableDeclaration declaration) { 437 _variableDeclarationMap.values.forEach((VariableDeclaration declaration) {
438 ReferenceFinder referenceFinder = new ReferenceFinder(declaration, 438 ReferenceFinder referenceFinder = new ReferenceFinder(declaration,
439 referenceGraph, _variableDeclarationMap, constructorDeclarationMap); 439 referenceGraph, _variableDeclarationMap, constructorDeclarationMap);
440 referenceGraph.addNode(declaration); 440 referenceGraph.addNode(declaration);
441 declaration.initializer.accept(referenceFinder); 441 declaration.initializer.accept(referenceFinder);
442 }); 442 });
443 constructorDeclarationMap.forEach((ConstructorElement element, 443 constructorDeclarationMap.forEach((ConstructorElement element,
444 ConstructorDeclaration declaration) { 444 ConstructorDeclaration declaration) {
445 ConstructorElement redirectedConstructor =
446 _getConstRedirectedConstructor(element);
447 if (redirectedConstructor != null) {
448 ConstructorElement redirectedConstructorBase =
449 _getConstructorBase(redirectedConstructor);
450 ConstructorDeclaration redirectedConstructorDeclaration =
451 findConstructorDeclaration(redirectedConstructorBase);
452 referenceGraph.addEdge(declaration, redirectedConstructorDeclaration);
453 return;
454 }
445 ReferenceFinder referenceFinder = new ReferenceFinder(declaration, 455 ReferenceFinder referenceFinder = new ReferenceFinder(declaration,
446 referenceGraph, _variableDeclarationMap, constructorDeclarationMap); 456 referenceGraph, _variableDeclarationMap, constructorDeclarationMap);
447 referenceGraph.addNode(declaration); 457 referenceGraph.addNode(declaration);
448 bool superInvocationFound = false; 458 bool superInvocationFound = false;
449 NodeList<ConstructorInitializer> initializers = declaration.initializers; 459 NodeList<ConstructorInitializer> initializers = declaration.initializers;
450 for (ConstructorInitializer initializer in initializers) { 460 for (ConstructorInitializer initializer in initializers) {
451 if (initializer is SuperConstructorInvocation) { 461 if (initializer is SuperConstructorInvocation) {
452 superInvocationFound = true; 462 superInvocationFound = true;
453 } 463 }
454 initializer.accept(referenceFinder); 464 initializer.accept(referenceFinder);
(...skipping 26 matching lines...) Expand all
481 } 491 }
482 } 492 }
483 } 493 }
484 }); 494 });
485 for (InstanceCreationExpression expression in _constructorInvocations) { 495 for (InstanceCreationExpression expression in _constructorInvocations) {
486 referenceGraph.addNode(expression); 496 referenceGraph.addNode(expression);
487 ConstructorElement constructor = expression.staticElement; 497 ConstructorElement constructor = expression.staticElement;
488 if (constructor == null) { 498 if (constructor == null) {
489 continue; 499 continue;
490 } 500 }
491 constructor = _followConstantRedirectionChain(constructor);
492 ConstructorDeclaration declaration = 501 ConstructorDeclaration declaration =
493 findConstructorDeclaration(constructor); 502 findConstructorDeclaration(constructor);
494 // An instance creation expression depends both on the constructor and 503 // An instance creation expression depends both on the constructor and
495 // the arguments passed to it. 504 // the arguments passed to it.
496 ReferenceFinder referenceFinder = new ReferenceFinder(expression, 505 ReferenceFinder referenceFinder = new ReferenceFinder(expression,
497 referenceGraph, _variableDeclarationMap, constructorDeclarationMap); 506 referenceGraph, _variableDeclarationMap, constructorDeclarationMap);
498 if (declaration != null) { 507 if (declaration != null) {
499 referenceGraph.addEdge(expression, declaration); 508 referenceGraph.addEdge(expression, declaration);
500 } 509 }
501 expression.argumentList.accept(referenceFinder); 510 expression.argumentList.accept(referenceFinder);
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 * reached which is not a const factory constructor. Return the constant 987 * reached which is not a const factory constructor. Return the constant
979 * constructor which terminates the chain of factory redirections, if the 988 * constructor which terminates the chain of factory redirections, if the
980 * chain terminates. If there is a problem (e.g. a redirection can't be found, 989 * chain terminates. If there is a problem (e.g. a redirection can't be found,
981 * or a cycle is encountered), the chain will be followed as far as possible 990 * or a cycle is encountered), the chain will be followed as far as possible
982 * and then a const factory constructor will be returned. 991 * and then a const factory constructor will be returned.
983 */ 992 */
984 ConstructorElement _followConstantRedirectionChain( 993 ConstructorElement _followConstantRedirectionChain(
985 ConstructorElement constructor) { 994 ConstructorElement constructor) {
986 HashSet<ConstructorElement> constructorsVisited = 995 HashSet<ConstructorElement> constructorsVisited =
987 new HashSet<ConstructorElement>(); 996 new HashSet<ConstructorElement>();
988 while (constructor.isFactory) { 997 while (true) {
989 if (identical( 998 ConstructorElement redirectedConstructor =
990 constructor.enclosingElement.type, typeProvider.symbolType)) { 999 _getConstRedirectedConstructor(constructor);
991 // The dart:core.Symbol has a const factory constructor that redirects 1000 if (redirectedConstructor == null) {
992 // to dart:_internal.Symbol. That in turn redirects to an external
993 // const constructor, which we won't be able to evaluate.
994 // So stop following the chain of redirections at dart:core.Symbol, and
995 // let [evaluateInstanceCreationExpression] handle it specially.
996 break; 1001 break;
997 } 1002 } else {
998 ConstructorElement constructorBase = _getConstructorBase(constructor); 1003 ConstructorElement constructorBase = _getConstructorBase(constructor);
999 constructorsVisited.add(constructorBase); 1004 constructorsVisited.add(constructorBase);
1000 ConstructorElement redirectedConstructor = 1005 ConstructorElement redirectedConstructorBase =
1001 constructor.redirectedConstructor; 1006 _getConstructorBase(redirectedConstructor);
1002 if (redirectedConstructor == null) { 1007 if (constructorsVisited.contains(redirectedConstructorBase)) {
1003 // This can happen if constructor is an external factory constructor. 1008 // Cycle in redirecting factory constructors--this is not allowed
1004 break; 1009 // and is checked elsewhere--see
1005 } 1010 // [ErrorVerifier.checkForRecursiveFactoryRedirect()]).
1006 if (!redirectedConstructor.isConst) { 1011 break;
1007 // Delegating to a non-const constructor--this is not allowed (and 1012 }
1008 // is checked elsewhere--see
1009 // [ErrorVerifier.checkForRedirectToNonConstConstructor()]).
1010 break;
1011 }
1012 ConstructorElement redirectedConstructorBase =
1013 _getConstructorBase(redirectedConstructor);
1014 if (constructorsVisited.contains(redirectedConstructorBase)) {
1015 // Cycle in redirecting factory constructors--this is not allowed
1016 // and is checked elsewhere--see
1017 // [ErrorVerifier.checkForRecursiveFactoryRedirect()]).
1018 break;
1019 } 1013 }
1020 constructor = redirectedConstructor; 1014 constructor = redirectedConstructor;
1021 } 1015 }
1022 return constructor; 1016 return constructor;
1023 } 1017 }
1024 1018
1025 /** 1019 /**
1026 * Generate an error indicating that the given [constant] is not a valid 1020 * Generate an error indicating that the given [constant] is not a valid
1027 * compile-time constant because it references at least one of the constants 1021 * compile-time constant because it references at least one of the constants
1028 * in the given [cycle], each of which directly or indirectly references the 1022 * in the given [cycle], each of which directly or indirectly references the
1029 * constant. 1023 * constant.
1030 */ 1024 */
1031 void _generateCycleError(List<AstNode> cycle, AstNode constant) { 1025 void _generateCycleError(List<AstNode> cycle, AstNode constant) {
1032 // TODO(brianwilkerson) Implement this. 1026 // TODO(brianwilkerson) Implement this.
1033 } 1027 }
1034 1028
1029 /**
1030 * If [constructor] redirects to another const constructor, return the
1031 * const constructor it redirects to. Otherwise return `null`.
1032 */
1033 ConstructorElement _getConstRedirectedConstructor(
1034 ConstructorElement constructor) {
1035 if (!constructor.isFactory) {
1036 return null;
1037 }
1038 if (identical(constructor.enclosingElement.type, typeProvider.symbolType)) {
1039 // The dart:core.Symbol has a const factory constructor that redirects
1040 // to dart:_internal.Symbol. That in turn redirects to an external
1041 // const constructor, which we won't be able to evaluate.
1042 // So stop following the chain of redirections at dart:core.Symbol, and
1043 // let [evaluateInstanceCreationExpression] handle it specially.
1044 return null;
1045 }
1046 ConstructorElement redirectedConstructor =
1047 constructor.redirectedConstructor;
1048 if (redirectedConstructor == null) {
1049 // This can happen if constructor is an external factory constructor.
1050 return null;
1051 }
1052 if (!redirectedConstructor.isConst) {
1053 // Delegating to a non-const constructor--this is not allowed (and
1054 // is checked elsewhere--see
1055 // [ErrorVerifier.checkForRedirectToNonConstConstructor()]).
1056 return null;
1057 }
1058 return redirectedConstructor;
1059 }
1060
1035 ConstructorElement _getConstructorBase(ConstructorElement constructor) { 1061 ConstructorElement _getConstructorBase(ConstructorElement constructor) {
1036 while (constructor is ConstructorMember) { 1062 while (constructor is ConstructorMember) {
1037 constructor = (constructor as ConstructorMember).baseElement; 1063 constructor = (constructor as ConstructorMember).baseElement;
1038 } 1064 }
1039 return constructor; 1065 return constructor;
1040 } 1066 }
1041 1067
1042 /** 1068 /**
1043 * Check if the object [obj] matches the type [type] according to runtime type 1069 * Check if the object [obj] matches the type [type] according to runtime type
1044 * checking rules. 1070 * checking rules.
(...skipping 4020 matching lines...) Expand 10 before | Expand all | Expand 10 after
5065 return BoolState.from(_element == rightElement); 5091 return BoolState.from(_element == rightElement);
5066 } else if (rightOperand is DynamicState) { 5092 } else if (rightOperand is DynamicState) {
5067 return BoolState.UNKNOWN_VALUE; 5093 return BoolState.UNKNOWN_VALUE;
5068 } 5094 }
5069 return BoolState.FALSE_STATE; 5095 return BoolState.FALSE_STATE;
5070 } 5096 }
5071 5097
5072 @override 5098 @override
5073 String toString() => _element == null ? "-unknown-" : _element.name; 5099 String toString() => _element == null ? "-unknown-" : _element.name;
5074 } 5100 }
OLDNEW
« 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