| OLD | NEW |
| 1 // This code was auto-generated, is not intended to be edited, and is subject to | 1 // This code was auto-generated, is not intended to be edited, and is subject to |
| 2 // significant change. Please see the README file for more information. | 2 // significant change. Please see the README file for more information. |
| 3 | |
| 4 library engine.constant; | 3 library engine.constant; |
| 5 | |
| 6 import 'java_core.dart'; | 4 import 'java_core.dart'; |
| 7 import 'source.dart' show Source; | 5 import 'source.dart' show Source; |
| 8 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; | 6 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; |
| 9 import 'scanner.dart' show TokenType; | 7 import 'scanner.dart' show TokenType; |
| 10 import 'ast.dart'; | 8 import 'ast.dart'; |
| 11 import 'element.dart'; | 9 import 'element.dart'; |
| 12 import 'engine.dart' show AnalysisEngine; | 10 import 'engine.dart' show AnalysisEngine; |
| 13 | |
| 14 | |
| 15 /** | 11 /** |
| 16 * Instances of the class {@code ConstantEvaluator} evaluate constant expression
s to produce their | 12 * Instances of the class {@code ConstantEvaluator} evaluate constant expression
s to produce their |
| 17 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant | 13 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant |
| 18 * expression is one of the following: | 14 * expression is one of the following: |
| 19 * <ul> | 15 * <ul> |
| 20 * <li>A literal number.</li> | 16 * <li>A literal number.</li> |
| 21 * <li>A literal boolean.</li> | 17 * <li>A literal boolean.</li> |
| 22 * <li>A literal string where any interpolated expression is a compile-time cons
tant that evaluates | 18 * <li>A literal string where any interpolated expression is a compile-time cons
tant that evaluates |
| 23 * to a numeric, string or boolean value or to {@code null}.</li> | 19 * to a numeric, string or boolean value or to {@code null}.</li> |
| 24 * <li>{@code null}.</li> | 20 * <li>{@code null}.</li> |
| (...skipping 12 matching lines...) Expand all Loading... |
| 37 * <li>An expression of one of the forms {@code -e}, {@code e1 + e2}, {@code e1
- e2},{@code e1 * e2}, {@code e1 / e2}, {@code e1 ~/ e2}, {@code e1 > e2}, {@cod
e e1 < e2},{@code e1 >= e2}, {@code e1 <= e2} or {@code e1 % e2}, where {@code e
}, {@code e1} and {@code e2}are constant expressions that evaluate to a numeric
value or to {@code null}.</li> | 33 * <li>An expression of one of the forms {@code -e}, {@code e1 + e2}, {@code e1
- e2},{@code e1 * e2}, {@code e1 / e2}, {@code e1 ~/ e2}, {@code e1 > e2}, {@cod
e e1 < e2},{@code e1 >= e2}, {@code e1 <= e2} or {@code e1 % e2}, where {@code e
}, {@code e1} and {@code e2}are constant expressions that evaluate to a numeric
value or to {@code null}.</li> |
| 38 * </ul> | 34 * </ul> |
| 39 * </blockquote> The values returned by instances of this class are therefore {@
code null} and | 35 * </blockquote> The values returned by instances of this class are therefore {@
code null} and |
| 40 * instances of the classes {@code Boolean}, {@code BigInteger}, {@code Double},
{@code String}, and{@code DartObject}. | 36 * instances of the classes {@code Boolean}, {@code BigInteger}, {@code Double},
{@code String}, and{@code DartObject}. |
| 41 * <p> | 37 * <p> |
| 42 * In addition, this class defines several values that can be returned to indica
te various | 38 * In addition, this class defines several values that can be returned to indica
te various |
| 43 * conditions encountered during evaluation. These are documented with the stati
c field that define | 39 * conditions encountered during evaluation. These are documented with the stati
c field that define |
| 44 * those values. | 40 * those values. |
| 45 */ | 41 */ |
| 46 class ConstantEvaluator { | 42 class ConstantEvaluator { |
| 47 | 43 |
| 48 /** | 44 /** |
| 49 * The source containing the expression(s) that will be evaluated. | 45 * The source containing the expression(s) that will be evaluated. |
| 50 */ | 46 */ |
| 51 Source _source; | 47 Source _source; |
| 52 | 48 |
| 53 /** | 49 /** |
| 54 * Initialize a newly created evaluator to evaluate expressions in the given s
ource. | 50 * Initialize a newly created evaluator to evaluate expressions in the given s
ource. |
| 55 * @param source the source containing the expression(s) that will be evaluate
d | 51 * @param source the source containing the expression(s) that will be evaluate
d |
| 56 */ | 52 */ |
| 57 ConstantEvaluator(Source source) { | 53 ConstantEvaluator(Source source) { |
| 58 this._source = source; | 54 this._source = source; |
| 59 } | 55 } |
| 60 EvaluationResult evaluate(Expression expression) { | 56 EvaluationResult evaluate(Expression expression) { |
| 61 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); | 57 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); |
| 62 if (result is ValidResult) { | 58 if (result is ValidResult) { |
| 63 return EvaluationResult.forValue(((result as ValidResult)).value); | 59 return EvaluationResult.forValue(((result as ValidResult)).value); |
| 64 } | 60 } |
| 65 List<AnalysisError> errors = new List<AnalysisError>(); | 61 List<AnalysisError> errors = new List<AnalysisError>(); |
| 66 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { | 62 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { |
| 67 ASTNode node2 = data.node; | 63 ASTNode node2 = data.node; |
| 68 errors.add(new AnalysisError.con2(_source, node2.offset, node2.length, dat
a.errorCode, [])); | 64 errors.add(new AnalysisError.con2(_source, node2.offset, node2.length, dat
a.errorCode, [])); |
| 69 } | 65 } |
| 70 return EvaluationResult.forErrors(new List.from(errors)); | 66 return EvaluationResult.forErrors(new List.from(errors)); |
| 71 } | 67 } |
| 72 } | 68 } |
| 73 | |
| 74 /** | 69 /** |
| 75 * Instances of the class {@code EvaluationResult} represent the result of attem
pting to evaluate an | 70 * Instances of the class {@code EvaluationResult} represent the result of attem
pting to evaluate an |
| 76 * expression. | 71 * expression. |
| 77 */ | 72 */ |
| 78 class EvaluationResult { | 73 class EvaluationResult { |
| 79 | 74 |
| 80 /** | 75 /** |
| 81 * Return an evaluation result representing the result of evaluating an expres
sion that is not a | 76 * Return an evaluation result representing the result of evaluating an expres
sion that is not a |
| 82 * compile-time constant because of the given errors. | 77 * compile-time constant because of the given errors. |
| 83 * @param errors the errors that should be reported for the expression(s) that
were evaluated | 78 * @param errors the errors that should be reported for the expression(s) that
were evaluated |
| 84 * @return the result of evaluating an expression that is not a compile-time c
onstant | 79 * @return the result of evaluating an expression that is not a compile-time c
onstant |
| 85 */ | 80 */ |
| 86 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio
nResult(null, errors); | 81 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio
nResult(null, errors); |
| 87 | 82 |
| 88 /** | 83 /** |
| 89 * Return an evaluation result representing the result of evaluating an expres
sion that is a | 84 * Return an evaluation result representing the result of evaluating an expres
sion that is a |
| 90 * compile-time constant that evaluates to the given value. | 85 * compile-time constant that evaluates to the given value. |
| 91 * @param value the value of the expression | 86 * @param value the value of the expression |
| 92 * @return the result of evaluating an expression that is a compile-time const
ant | 87 * @return the result of evaluating an expression that is a compile-time const
ant |
| 93 */ | 88 */ |
| 94 static EvaluationResult forValue(Object value) => new EvaluationResult(value,
null); | 89 static EvaluationResult forValue(Object value) => new EvaluationResult(value,
null); |
| 95 | 90 |
| 96 /** | 91 /** |
| 97 * The value of the expression. | 92 * The value of the expression. |
| 98 */ | 93 */ |
| 99 Object _value; | 94 Object _value; |
| 100 | 95 |
| 101 /** | 96 /** |
| 102 * The errors that should be reported for the expression(s) that were evaluate
d. | 97 * The errors that should be reported for the expression(s) that were evaluate
d. |
| 103 */ | 98 */ |
| 104 List<AnalysisError> _errors; | 99 List<AnalysisError> _errors; |
| 105 | 100 |
| 106 /** | 101 /** |
| 107 * Initialize a newly created result object with the given state. Clients shou
ld use one of the | 102 * Initialize a newly created result object with the given state. Clients shou
ld use one of the |
| 108 * factory methods: {@link #forErrors(AnalysisError\[\])} and {@link #forValue
(Object)}. | 103 * factory methods: {@link #forErrors(AnalysisError\[\])} and {@link #forValue
(Object)}. |
| 109 * @param value the value of the expression | 104 * @param value the value of the expression |
| 110 * @param errors the errors that should be reported for the expression(s) that
were evaluated | 105 * @param errors the errors that should be reported for the expression(s) that
were evaluated |
| 111 */ | 106 */ |
| 112 EvaluationResult(Object value, List<AnalysisError> errors) { | 107 EvaluationResult(Object value, List<AnalysisError> errors) { |
| 113 this._value = value; | 108 this._value = value; |
| 114 this._errors = errors; | 109 this._errors = errors; |
| 115 } | 110 } |
| 116 | 111 |
| 117 /** | 112 /** |
| 118 * Return an array containing the errors that should be reported for the expre
ssion(s) that were | 113 * Return an array containing the errors that should be reported for the expre
ssion(s) that were |
| 119 * evaluated. If there are no such errors, the array will be empty. The array
can be empty even if | 114 * evaluated. If there are no such errors, the array will be empty. The array
can be empty even if |
| 120 * the expression is not a valid compile time constant if the errors would hav
e been reported by | 115 * the expression is not a valid compile time constant if the errors would hav
e been reported by |
| 121 * other parts of the analysis engine. | 116 * other parts of the analysis engine. |
| 122 */ | 117 */ |
| 123 List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS :
_errors; | 118 List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS :
_errors; |
| 124 | 119 |
| 125 /** | 120 /** |
| 126 * Return the value of the expression, or {@code null} if the expression evalu
ated to {@code null}or if the expression could not be evaluated, either because
it was not a compile-time constant | 121 * Return the value of the expression, or {@code null} if the expression evalu
ated to {@code null}or if the expression could not be evaluated, either because
it was not a compile-time constant |
| 127 * expression or because it would throw an exception when evaluated. | 122 * expression or because it would throw an exception when evaluated. |
| 128 * @return the value of the expression | 123 * @return the value of the expression |
| 129 */ | 124 */ |
| 130 Object get value => _value; | 125 Object get value => _value; |
| 131 | 126 |
| 132 /** | 127 /** |
| 133 * Return {@code true} if the expression is a compile-time constant expression
that would not | 128 * Return {@code true} if the expression is a compile-time constant expression
that would not |
| 134 * throw an exception when evaluated. | 129 * throw an exception when evaluated. |
| 135 * @return {@code true} if the expression is a valid compile-time constant exp
ression | 130 * @return {@code true} if the expression is a valid compile-time constant exp
ression |
| 136 */ | 131 */ |
| 137 bool isValid() => _errors == null; | 132 bool isValid() => _errors == null; |
| 138 } | 133 } |
| 139 | |
| 140 /** | 134 /** |
| 141 * Instances of the class {@code ConstantFinder} are used to traverse the AST st
ructures of all of | 135 * Instances of the class {@code ConstantFinder} are used to traverse the AST st
ructures of all of |
| 142 * the compilation units being resolved and build a table mapping constant varia
ble elements to the | 136 * the compilation units being resolved and build a table mapping constant varia
ble elements to the |
| 143 * declarations of those variables. | 137 * declarations of those variables. |
| 144 */ | 138 */ |
| 145 class ConstantFinder extends RecursiveASTVisitor<Object> { | 139 class ConstantFinder extends RecursiveASTVisitor<Object> { |
| 146 | 140 |
| 147 /** | 141 /** |
| 148 * A table mapping constant variable elements to the declarations of those var
iables. | 142 * A table mapping constant variable elements to the declarations of those var
iables. |
| 149 */ | 143 */ |
| 150 Map<VariableElement, VariableDeclaration> _variableMap = new Map<VariableEleme
nt, VariableDeclaration>(); | 144 Map<VariableElement, VariableDeclaration> _variableMap = new Map<VariableEleme
nt, VariableDeclaration>(); |
| 151 | 145 |
| 152 /** | 146 /** |
| 153 * Return a table mapping constant variable elements to the declarations of th
ose variables. | 147 * Return a table mapping constant variable elements to the declarations of th
ose variables. |
| 154 * @return a table mapping constant variable elements to the declarations of t
hose variables | 148 * @return a table mapping constant variable elements to the declarations of t
hose variables |
| 155 */ | 149 */ |
| 156 Map<VariableElement, VariableDeclaration> get variableMap => _variableMap; | 150 Map<VariableElement, VariableDeclaration> get variableMap => _variableMap; |
| 157 Object visitVariableDeclaration(VariableDeclaration node) { | 151 Object visitVariableDeclaration(VariableDeclaration node) { |
| 158 super.visitVariableDeclaration(node); | 152 super.visitVariableDeclaration(node); |
| 159 Expression initializer2 = node.initializer; | 153 Expression initializer2 = node.initializer; |
| 160 if (initializer2 != null && node.isConst()) { | 154 if (initializer2 != null && node.isConst()) { |
| 161 VariableElement element2 = node.element; | 155 VariableElement element2 = node.element; |
| 162 if (element2 != null) { | 156 if (element2 != null) { |
| 163 _variableMap[element2] = node; | 157 _variableMap[element2] = node; |
| 164 } | 158 } |
| 165 } | 159 } |
| 166 return null; | 160 return null; |
| 167 } | 161 } |
| 168 } | 162 } |
| 169 | |
| 170 /** | 163 /** |
| 171 * Instances of the class {@code ConstantValueComputer} compute the values of co
nstant variables in | 164 * Instances of the class {@code ConstantValueComputer} compute the values of co
nstant variables in |
| 172 * one or more compilation units. The expected usage pattern is for the compilat
ion units to be | 165 * one or more compilation units. The expected usage pattern is for the compilat
ion units to be |
| 173 * added to this computer using the method {@link #add(CompilationUnit)} and the
n for the method{@link #computeValues()} to invoked exactly once. Any use of an
instance after invoking the | 166 * added to this computer using the method {@link #add(CompilationUnit)} and the
n for the method{@link #computeValues()} to invoked exactly once. Any use of an
instance after invoking the |
| 174 * method {@link #computeValues()} will result in unpredictable behavior. | 167 * method {@link #computeValues()} will result in unpredictable behavior. |
| 175 */ | 168 */ |
| 176 class ConstantValueComputer { | 169 class ConstantValueComputer { |
| 177 | 170 |
| 178 /** | 171 /** |
| 179 * The object used to find constant variables in the compilation units that we
re added. | 172 * The object used to find constant variables in the compilation units that we
re added. |
| 180 */ | 173 */ |
| 181 ConstantFinder _constantFinder = new ConstantFinder(); | 174 ConstantFinder _constantFinder = new ConstantFinder(); |
| 182 | 175 |
| 183 /** | 176 /** |
| 184 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to | 177 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to |
| 185 * the other constant variables that are referenced in the head's initializer. | 178 * the other constant variables that are referenced in the head's initializer. |
| 186 */ | 179 */ |
| 187 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle
ment>(); | 180 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle
ment>(); |
| 188 | 181 |
| 189 /** | 182 /** |
| 190 * A table mapping constant variables to the declarations of those variables. | 183 * A table mapping constant variables to the declarations of those variables. |
| 191 */ | 184 */ |
| 192 Map<VariableElement, VariableDeclaration> _declarationMap; | 185 Map<VariableElement, VariableDeclaration> _declarationMap; |
| 193 | 186 |
| 194 /** | 187 /** |
| 195 * Add the constant variables in the given compilation unit to the list of con
stant variables | 188 * Add the constant variables in the given compilation unit to the list of con
stant variables |
| 196 * whose value needs to be computed. | 189 * whose value needs to be computed. |
| 197 * @param unit the compilation unit defining the constant variables to be adde
d | 190 * @param unit the compilation unit defining the constant variables to be adde
d |
| 198 */ | 191 */ |
| 199 void add(CompilationUnit unit) { | 192 void add(CompilationUnit unit) { |
| 200 unit.accept(_constantFinder); | 193 unit.accept(_constantFinder); |
| 201 } | 194 } |
| 202 | 195 |
| 203 /** | 196 /** |
| 204 * Compute values for all of the constant variables in the compilation units t
hat were added. | 197 * Compute values for all of the constant variables in the compilation units t
hat were added. |
| 205 */ | 198 */ |
| 206 void computeValues() { | 199 void computeValues() { |
| 207 _declarationMap = _constantFinder.variableMap; | 200 _declarationMap = _constantFinder.variableMap; |
| 208 for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(
_declarationMap)) { | 201 for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(
_declarationMap)) { |
| 209 VariableElement element = entry.getKey(); | 202 VariableElement element = entry.getKey(); |
| 210 ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceG
raph); | 203 ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceG
raph); |
| 211 _referenceGraph.addNode(element); | 204 _referenceGraph.addNode(element); |
| 212 entry.getValue().initializer.accept(referenceFinder); | 205 entry.getValue().initializer.accept(referenceFinder); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 223 AnalysisEngine.instance.logger.logError("Exiting constant value comput
er with ${_referenceGraph.nodeCount} variables that are neither sinks no in a cy
cle"); | 216 AnalysisEngine.instance.logger.logError("Exiting constant value comput
er with ${_referenceGraph.nodeCount} variables that are neither sinks no in a cy
cle"); |
| 224 return; | 217 return; |
| 225 } | 218 } |
| 226 for (VariableElement variable in variablesInCycle) { | 219 for (VariableElement variable in variablesInCycle) { |
| 227 generateCycleError(variablesInCycle, variable); | 220 generateCycleError(variablesInCycle, variable); |
| 228 } | 221 } |
| 229 _referenceGraph.removeAllNodes(variablesInCycle); | 222 _referenceGraph.removeAllNodes(variablesInCycle); |
| 230 } | 223 } |
| 231 } | 224 } |
| 232 } | 225 } |
| 233 | 226 |
| 234 /** | 227 /** |
| 235 * Compute a value for the given variable. | 228 * Compute a value for the given variable. |
| 236 * @param variable the variable for which a value is to be computed | 229 * @param variable the variable for which a value is to be computed |
| 237 */ | 230 */ |
| 238 void computeValueFor(VariableElement variable) { | 231 void computeValueFor(VariableElement variable) { |
| 239 VariableDeclaration declaration = _declarationMap[variable]; | 232 VariableDeclaration declaration = _declarationMap[variable]; |
| 240 if (declaration == null) { | 233 if (declaration == null) { |
| 241 return; | 234 return; |
| 242 } | 235 } |
| 243 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis
itor()); | 236 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis
itor()); |
| 244 ((variable as VariableElementImpl)).evaluationResult = result; | 237 ((variable as VariableElementImpl)).evaluationResult = result; |
| 245 if (result is ErrorResult) { | 238 if (result is ErrorResult) { |
| 246 List<AnalysisError> errors = new List<AnalysisError>(); | 239 List<AnalysisError> errors = new List<AnalysisError>(); |
| 247 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { | 240 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { |
| 248 ASTNode node2 = data.node; | 241 ASTNode node2 = data.node; |
| 249 Source source2 = variable.getAncestor(CompilationUnitElement).source; | 242 Source source2 = variable.getAncestor(CompilationUnitElement).source; |
| 250 errors.add(new AnalysisError.con2(source2, node2.offset, node2.length, d
ata.errorCode, [])); | 243 errors.add(new AnalysisError.con2(source2, node2.offset, node2.length, d
ata.errorCode, [])); |
| 251 } | 244 } |
| 252 } | 245 } |
| 253 } | 246 } |
| 254 | 247 |
| 255 /** | 248 /** |
| 256 * Generate an error indicating that the given variable is not a valid compile
-time constant | 249 * Generate an error indicating that the given variable is not a valid compile
-time constant |
| 257 * because it references at least one of the variables in the given cycle, eac
h of which directly | 250 * because it references at least one of the variables in the given cycle, eac
h of which directly |
| 258 * or indirectly references the variable. | 251 * or indirectly references the variable. |
| 259 * @param variablesInCycle the variables in the cycle that includes the given
variable | 252 * @param variablesInCycle the variables in the cycle that includes the given
variable |
| 260 * @param variable the variable that is not a valid compile-time constant | 253 * @param variable the variable that is not a valid compile-time constant |
| 261 */ | 254 */ |
| 262 void generateCycleError(List<VariableElement> variablesInCycle, VariableElemen
t variable) { | 255 void generateCycleError(List<VariableElement> variablesInCycle, VariableElemen
t variable) { |
| 263 } | 256 } |
| 264 } | 257 } |
| 265 | |
| 266 /** | 258 /** |
| 267 * Instances of the class {@code ConstantVisitor} evaluate constant expressions
to produce their | 259 * Instances of the class {@code ConstantVisitor} evaluate constant expressions
to produce their |
| 268 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant | 260 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant |
| 269 * expression is one of the following: | 261 * expression is one of the following: |
| 270 * <ul> | 262 * <ul> |
| 271 * <li>A literal number.</li> | 263 * <li>A literal number.</li> |
| 272 * <li>A literal boolean.</li> | 264 * <li>A literal boolean.</li> |
| 273 * <li>A literal string where any interpolated expression is a compile-time cons
tant that evaluates | 265 * <li>A literal string where any interpolated expression is a compile-time cons
tant that evaluates |
| 274 * to a numeric, string or boolean value or to {@code null}.</li> | 266 * to a numeric, string or boolean value or to {@code null}.</li> |
| 275 * <li>{@code null}.</li> | 267 * <li>{@code null}.</li> |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 } | 356 } |
| 365 return error(node, null); | 357 return error(node, null); |
| 366 } | 358 } |
| 367 EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResu
lt(node.value); | 359 EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResu
lt(node.value); |
| 368 EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node
) { | 360 EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node
) { |
| 369 EvaluationResultImpl result = node.expression.accept(this); | 361 EvaluationResultImpl result = node.expression.accept(this); |
| 370 return result.performToString(node); | 362 return result.performToString(node); |
| 371 } | 363 } |
| 372 EvaluationResultImpl visitInterpolationString(InterpolationString node) => new
ValidResult(node.value); | 364 EvaluationResultImpl visitInterpolationString(InterpolationString node) => new
ValidResult(node.value); |
| 373 EvaluationResultImpl visitListLiteral(ListLiteral node) { | 365 EvaluationResultImpl visitListLiteral(ListLiteral node) { |
| 366 if (node.modifier == null) { |
| 367 return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_LI
ST_LITERAL); |
| 368 } |
| 374 ErrorResult result = null; | 369 ErrorResult result = null; |
| 375 for (Expression element in node.elements) { | 370 for (Expression element in node.elements) { |
| 376 result = union(result, element.accept(this)); | 371 result = union(result, element.accept(this)); |
| 377 } | 372 } |
| 378 if (result != null) { | 373 if (result != null) { |
| 379 return result; | 374 return result; |
| 380 } | 375 } |
| 381 return ValidResult.RESULT_OBJECT; | 376 return ValidResult.RESULT_OBJECT; |
| 382 } | 377 } |
| 383 EvaluationResultImpl visitMapLiteral(MapLiteral node) { | 378 EvaluationResultImpl visitMapLiteral(MapLiteral node) { |
| 379 if (node.modifier == null) { |
| 380 return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_MA
P_LITERAL); |
| 381 } |
| 384 ErrorResult result = null; | 382 ErrorResult result = null; |
| 385 for (MapLiteralEntry entry in node.entries) { | 383 for (MapLiteralEntry entry in node.entries) { |
| 386 result = union(result, entry.key.accept(this)); | 384 result = union(result, entry.key.accept(this)); |
| 387 result = union(result, entry.value.accept(this)); | 385 result = union(result, entry.value.accept(this)); |
| 388 } | 386 } |
| 389 if (result != null) { | 387 if (result != null) { |
| 390 return result; | 388 return result; |
| 391 } | 389 } |
| 392 return ValidResult.RESULT_OBJECT; | 390 return ValidResult.RESULT_OBJECT; |
| 393 } | 391 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 EvaluationResultImpl result = null; | 438 EvaluationResultImpl result = null; |
| 441 for (InterpolationElement element in node.elements) { | 439 for (InterpolationElement element in node.elements) { |
| 442 if (result == null) { | 440 if (result == null) { |
| 443 result = element.accept(this); | 441 result = element.accept(this); |
| 444 } else { | 442 } else { |
| 445 result = result.concatenate(node, element.accept(this)); | 443 result = result.concatenate(node, element.accept(this)); |
| 446 } | 444 } |
| 447 } | 445 } |
| 448 return result; | 446 return result; |
| 449 } | 447 } |
| 450 | 448 |
| 451 /** | 449 /** |
| 452 * Return a result object representing an error associated with the given node
. | 450 * Return a result object representing an error associated with the given node
. |
| 453 * @param node the AST node associated with the error | 451 * @param node the AST node associated with the error |
| 454 * @param code the error code indicating the nature of the error | 452 * @param code the error code indicating the nature of the error |
| 455 * @return a result object representing an error associated with the given nod
e | 453 * @return a result object representing an error associated with the given nod
e |
| 456 */ | 454 */ |
| 457 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); | 455 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); |
| 458 | 456 |
| 459 /** | 457 /** |
| 460 * Return the constant value of the static constant represented by the given e
lement. | 458 * Return the constant value of the static constant represented by the given e
lement. |
| 461 * @param node the node to be used if an error needs to be reported | 459 * @param node the node to be used if an error needs to be reported |
| 462 * @param element the element whose value is to be returned | 460 * @param element the element whose value is to be returned |
| 463 * @return the constant value of the static constant | 461 * @return the constant value of the static constant |
| 464 */ | 462 */ |
| 465 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { | 463 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { |
| 466 if (element is PropertyAccessorElement) { | 464 if (element is PropertyAccessorElement) { |
| 467 element = ((element as PropertyAccessorElement)).variable; | 465 element = ((element as PropertyAccessorElement)).variable; |
| 468 } | 466 } |
| 469 if (element is VariableElementImpl) { | 467 if (element is VariableElementImpl) { |
| 470 EvaluationResultImpl value = ((element as VariableElementImpl)).evaluation
Result; | 468 EvaluationResultImpl value = ((element as VariableElementImpl)).evaluation
Result; |
| 471 if (value != null) { | 469 if (value != null) { |
| 472 return value; | 470 return value; |
| 473 } | 471 } |
| 474 } else if (element is ExecutableElement) { | 472 } else if (element is ExecutableElement) { |
| 475 return new ValidResult(element); | 473 return new ValidResult(element); |
| 476 } else if (element is ClassElement) { | 474 } else if (element is ClassElement) { |
| 477 return ValidResult.RESULT_OBJECT; | 475 return ValidResult.RESULT_OBJECT; |
| 478 } | 476 } |
| 479 return error(node, null); | 477 return error(node, null); |
| 480 } | 478 } |
| 481 | 479 |
| 482 /** | 480 /** |
| 483 * Return the union of the errors encoded in the given results. | 481 * Return the union of the errors encoded in the given results. |
| 484 * @param leftResult the first set of errors, or {@code null} if there was no
previous collection | 482 * @param leftResult the first set of errors, or {@code null} if there was no
previous collection |
| 485 * of errors | 483 * of errors |
| 486 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no | 484 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no |
| 487 * errors to be added | 485 * errors to be added |
| 488 * @return the union of the errors encoded in the given results | 486 * @return the union of the errors encoded in the given results |
| 489 */ | 487 */ |
| 490 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { | 488 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { |
| 491 if (rightResult is ErrorResult) { | 489 if (rightResult is ErrorResult) { |
| 492 if (leftResult != null) { | 490 if (leftResult != null) { |
| 493 return new ErrorResult.con2(leftResult, (rightResult as ErrorResult)); | 491 return new ErrorResult.con2(leftResult, (rightResult as ErrorResult)); |
| 494 } else { | 492 } else { |
| 495 return rightResult as ErrorResult; | 493 return rightResult as ErrorResult; |
| 496 } | 494 } |
| 497 } | 495 } |
| 498 return leftResult; | 496 return leftResult; |
| 499 } | 497 } |
| 500 } | 498 } |
| 501 | |
| 502 /** | 499 /** |
| 503 * Instances of the class {@code DirectedGraph} implement a directed graph in wh
ich the nodes are | 500 * Instances of the class {@code DirectedGraph} implement a directed graph in wh
ich the nodes are |
| 504 * arbitrary (client provided) objects and edges are represented implicitly. The
graph will allow an | 501 * arbitrary (client provided) objects and edges are represented implicitly. The
graph will allow an |
| 505 * edge from any node to any other node, including itself, but will not represen
t multiple edges | 502 * edge from any node to any other node, including itself, but will not represen
t multiple edges |
| 506 * between the same pair of nodes. | 503 * between the same pair of nodes. |
| 507 * @param N the type of the nodes in the graph | 504 * @param N the type of the nodes in the graph |
| 508 */ | 505 */ |
| 509 class DirectedGraph<N> { | 506 class DirectedGraph<N> { |
| 510 | 507 |
| 511 /** | 508 /** |
| 512 * The table encoding the edges in the graph. An edge is represented by an ent
ry mapping the head | 509 * The table encoding the edges in the graph. An edge is represented by an ent
ry mapping the head |
| 513 * to a set of tails. Nodes that are not the head of any edge are represented
by an entry mapping | 510 * to a set of tails. Nodes that are not the head of any edge are represented
by an entry mapping |
| 514 * the node to an empty set of tails. | 511 * the node to an empty set of tails. |
| 515 */ | 512 */ |
| 516 Map<N, Set<N>> _edges = new Map<N, Set<N>>(); | 513 Map<N, Set<N>> _edges = new Map<N, Set<N>>(); |
| 517 | 514 |
| 518 /** | 515 /** |
| 519 * Add an edge from the given head node to the given tail node. Both nodes wil
l be a part of the | 516 * Add an edge from the given head node to the given tail node. Both nodes wil
l be a part of the |
| 520 * graph after this method is invoked, whether or not they were before. | 517 * graph after this method is invoked, whether or not they were before. |
| 521 * @param head the node at the head of the edge | 518 * @param head the node at the head of the edge |
| 522 * @param tail the node at the tail of the edge | 519 * @param tail the node at the tail of the edge |
| 523 */ | 520 */ |
| 524 void addEdge(N head, N tail) { | 521 void addEdge(N head, N tail) { |
| 525 Set<N> tails = _edges[tail]; | 522 Set<N> tails = _edges[tail]; |
| 526 if (tails == null) { | 523 if (tails == null) { |
| 527 _edges[tail] = new Set<N>(); | 524 _edges[tail] = new Set<N>(); |
| 528 } | 525 } |
| 529 tails = _edges[head]; | 526 tails = _edges[head]; |
| 530 if (tails == null) { | 527 if (tails == null) { |
| 531 tails = new Set<N>(); | 528 tails = new Set<N>(); |
| 532 _edges[head] = tails; | 529 _edges[head] = tails; |
| 533 } | 530 } |
| 534 javaSetAdd(tails, tail); | 531 javaSetAdd(tails, tail); |
| 535 } | 532 } |
| 536 | 533 |
| 537 /** | 534 /** |
| 538 * Add the given node to the set of nodes in the graph. | 535 * Add the given node to the set of nodes in the graph. |
| 539 * @param node the node to be added | 536 * @param node the node to be added |
| 540 */ | 537 */ |
| 541 void addNode(N node) { | 538 void addNode(N node) { |
| 542 Set<N> tails = _edges[node]; | 539 Set<N> tails = _edges[node]; |
| 543 if (tails == null) { | 540 if (tails == null) { |
| 544 _edges[node] = new Set<N>(); | 541 _edges[node] = new Set<N>(); |
| 545 } | 542 } |
| 546 } | 543 } |
| 547 | 544 |
| 548 /** | 545 /** |
| 549 * Return a list of nodes that form a cycle, or {@code null} if there are no c
ycles in this graph. | 546 * Return a list of nodes that form a cycle, or {@code null} if there are no c
ycles in this graph. |
| 550 * @return a list of nodes that form a cycle | 547 * @return a list of nodes that form a cycle |
| 551 */ | 548 */ |
| 552 List<N> findCycle() => null; | 549 List<N> findCycle() => null; |
| 553 | 550 |
| 554 /** | 551 /** |
| 555 * Return the number of nodes in this graph. | 552 * Return the number of nodes in this graph. |
| 556 * @return the number of nodes in this graph | 553 * @return the number of nodes in this graph |
| 557 */ | 554 */ |
| 558 int get nodeCount => _edges.length; | 555 int get nodeCount => _edges.length; |
| 559 | 556 |
| 560 /** | 557 /** |
| 561 * Return a set containing the tails of edges that have the given node as thei
r head. The set will | 558 * Return a set containing the tails of edges that have the given node as thei
r head. The set will |
| 562 * be empty if there are no such edges or if the node is not part of the graph
. Clients must not | 559 * be empty if there are no such edges or if the node is not part of the graph
. Clients must not |
| 563 * modify the returned set. | 560 * modify the returned set. |
| 564 * @param head the node at the head of all of the edges whose tails are to be
returned | 561 * @param head the node at the head of all of the edges whose tails are to be
returned |
| 565 * @return a set containing the tails of edges that have the given node as the
ir head | 562 * @return a set containing the tails of edges that have the given node as the
ir head |
| 566 */ | 563 */ |
| 567 Set<N> getTails(N head) { | 564 Set<N> getTails(N head) { |
| 568 Set<N> tails = _edges[head]; | 565 Set<N> tails = _edges[head]; |
| 569 if (tails == null) { | 566 if (tails == null) { |
| 570 return new Set<N>(); | 567 return new Set<N>(); |
| 571 } | 568 } |
| 572 return tails; | 569 return tails; |
| 573 } | 570 } |
| 574 | 571 |
| 575 /** | 572 /** |
| 576 * Return {@code true} if this graph is empty. | 573 * Return {@code true} if this graph is empty. |
| 577 * @return {@code true} if this graph is empty | 574 * @return {@code true} if this graph is empty |
| 578 */ | 575 */ |
| 579 bool isEmpty() => _edges.isEmpty; | 576 bool isEmpty() => _edges.isEmpty; |
| 580 | 577 |
| 581 /** | 578 /** |
| 582 * Remove all of the given nodes from this graph. As a consequence, any edges
for which those | 579 * Remove all of the given nodes from this graph. As a consequence, any edges
for which those |
| 583 * nodes were either a head or a tail will also be removed. | 580 * nodes were either a head or a tail will also be removed. |
| 584 * @param nodes the nodes to be removed | 581 * @param nodes the nodes to be removed |
| 585 */ | 582 */ |
| 586 void removeAllNodes(List<N> nodes) { | 583 void removeAllNodes(List<N> nodes) { |
| 587 for (N node in nodes) { | 584 for (N node in nodes) { |
| 588 removeNode(node); | 585 removeNode(node); |
| 589 } | 586 } |
| 590 } | 587 } |
| 591 | 588 |
| 592 /** | 589 /** |
| 593 * Remove the edge from the given head node to the given tail node. If there w
as no such edge then | 590 * Remove the edge from the given head node to the given tail node. If there w
as no such edge then |
| 594 * the graph will be unmodified: the number of edges will be the same and the
set of nodes will be | 591 * the graph will be unmodified: the number of edges will be the same and the
set of nodes will be |
| 595 * the same (neither node will either be added or removed). | 592 * the same (neither node will either be added or removed). |
| 596 * @param head the node at the head of the edge | 593 * @param head the node at the head of the edge |
| 597 * @param tail the node at the tail of the edge | 594 * @param tail the node at the tail of the edge |
| 598 * @return {@code true} if the graph was modified as a result of this operatio
n | 595 * @return {@code true} if the graph was modified as a result of this operatio
n |
| 599 */ | 596 */ |
| 600 void removeEdge(N head, N tail) { | 597 void removeEdge(N head, N tail) { |
| 601 Set<N> tails = _edges[head]; | 598 Set<N> tails = _edges[head]; |
| 602 if (tails != null) { | 599 if (tails != null) { |
| 603 tails.remove(tail); | 600 tails.remove(tail); |
| 604 } | 601 } |
| 605 } | 602 } |
| 606 | 603 |
| 607 /** | 604 /** |
| 608 * Remove the given node from this graph. As a consequence, any edges for whic
h that node was | 605 * Remove the given node from this graph. As a consequence, any edges for whic
h that node was |
| 609 * either a head or a tail will also be removed. | 606 * either a head or a tail will also be removed. |
| 610 * @param node the node to be removed | 607 * @param node the node to be removed |
| 611 */ | 608 */ |
| 612 void removeNode(N node) { | 609 void removeNode(N node) { |
| 613 _edges.remove(node); | 610 _edges.remove(node); |
| 614 for (Set<N> tails in _edges.values) { | 611 for (Set<N> tails in _edges.values) { |
| 615 tails.remove(node); | 612 tails.remove(node); |
| 616 } | 613 } |
| 617 } | 614 } |
| 618 | 615 |
| 619 /** | 616 /** |
| 620 * Find one node (referred to as a sink node) that has no outgoing edges (that
is, for which there | 617 * Find one node (referred to as a sink node) that has no outgoing edges (that
is, for which there |
| 621 * are no edges that have that node as the head of the edge) and remove it fro
m this graph. Return | 618 * are no edges that have that node as the head of the edge) and remove it fro
m this graph. Return |
| 622 * the node that was removed, or {@code null} if there are no such nodes eithe
r because the graph | 619 * the node that was removed, or {@code null} if there are no such nodes eithe
r because the graph |
| 623 * is empty or because every node in the graph has at least one outgoing edge.
As a consequence of | 620 * is empty or because every node in the graph has at least one outgoing edge.
As a consequence of |
| 624 * removing the node from the graph any edges for which that node was a tail w
ill also be removed. | 621 * removing the node from the graph any edges for which that node was a tail w
ill also be removed. |
| 625 * @return the sink node that was removed | 622 * @return the sink node that was removed |
| 626 */ | 623 */ |
| 627 N removeSink() { | 624 N removeSink() { |
| 628 N sink = findSink(); | 625 N sink = findSink(); |
| 629 if (sink == null) { | 626 if (sink == null) { |
| 630 return null; | 627 return null; |
| 631 } | 628 } |
| 632 removeNode(sink); | 629 removeNode(sink); |
| 633 return sink; | 630 return sink; |
| 634 } | 631 } |
| 635 | 632 |
| 636 /** | 633 /** |
| 637 * Return one node that has no outgoing edges (that is, for which there are no
edges that have | 634 * Return one node that has no outgoing edges (that is, for which there are no
edges that have |
| 638 * that node as the head of the edge), or {@code null} if there are no such no
des. | 635 * that node as the head of the edge), or {@code null} if there are no such no
des. |
| 639 * @return a sink node | 636 * @return a sink node |
| 640 */ | 637 */ |
| 641 N findSink() { | 638 N findSink() { |
| 642 for (MapEntry<N, Set<N>> entry in getMapEntrySet(_edges)) { | 639 for (MapEntry<N, Set<N>> entry in getMapEntrySet(_edges)) { |
| 643 if (entry.getValue().isEmpty) { | 640 if (entry.getValue().isEmpty) { |
| 644 return entry.getKey(); | 641 return entry.getKey(); |
| 645 } | 642 } |
| 646 } | 643 } |
| 647 return null; | 644 return null; |
| 648 } | 645 } |
| 649 } | 646 } |
| 650 | |
| 651 /** | 647 /** |
| 652 * Instances of the class {@code ErrorResult} represent the result of evaluating
an expression that | 648 * Instances of the class {@code ErrorResult} represent the result of evaluating
an expression that |
| 653 * is not a valid compile time constant. | 649 * is not a valid compile time constant. |
| 654 */ | 650 */ |
| 655 class ErrorResult extends EvaluationResultImpl { | 651 class ErrorResult extends EvaluationResultImpl { |
| 656 | 652 |
| 657 /** | 653 /** |
| 658 * The errors that prevent the expression from being a valid compile time cons
tant. | 654 * The errors that prevent the expression from being a valid compile time cons
tant. |
| 659 */ | 655 */ |
| 660 List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>(); | 656 List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>(); |
| 661 | 657 |
| 662 /** | 658 /** |
| 663 * Initialize a newly created result representing the error with the given cod
e reported against | 659 * Initialize a newly created result representing the error with the given cod
e reported against |
| 664 * the given node. | 660 * the given node. |
| 665 * @param node the node against which the error should be reported | 661 * @param node the node against which the error should be reported |
| 666 * @param errorCode the error code for the error to be generated | 662 * @param errorCode the error code for the error to be generated |
| 667 */ | 663 */ |
| 668 ErrorResult.con1(ASTNode node, ErrorCode errorCode) { | 664 ErrorResult.con1(ASTNode node, ErrorCode errorCode) { |
| 669 _jtd_constructor_171_impl(node, errorCode); | 665 _jtd_constructor_172_impl(node, errorCode); |
| 670 } | 666 } |
| 671 _jtd_constructor_171_impl(ASTNode node, ErrorCode errorCode) { | 667 _jtd_constructor_172_impl(ASTNode node, ErrorCode errorCode) { |
| 672 _errors.add(new ErrorResult_ErrorData(node, errorCode)); | 668 _errors.add(new ErrorResult_ErrorData(node, errorCode)); |
| 673 } | 669 } |
| 674 | 670 |
| 675 /** | 671 /** |
| 676 * Initialize a newly created result to represent the union of the errors in t
he given result | 672 * Initialize a newly created result to represent the union of the errors in t
he given result |
| 677 * objects. | 673 * objects. |
| 678 * @param firstResult the first set of results being merged | 674 * @param firstResult the first set of results being merged |
| 679 * @param secondResult the second set of results being merged | 675 * @param secondResult the second set of results being merged |
| 680 */ | 676 */ |
| 681 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { | 677 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { |
| 682 _jtd_constructor_172_impl(firstResult, secondResult); | 678 _jtd_constructor_173_impl(firstResult, secondResult); |
| 683 } | 679 } |
| 684 _jtd_constructor_172_impl(ErrorResult firstResult, ErrorResult secondResult) { | 680 _jtd_constructor_173_impl(ErrorResult firstResult, ErrorResult secondResult) { |
| 685 _errors.addAll(firstResult._errors); | 681 _errors.addAll(firstResult._errors); |
| 686 _errors.addAll(secondResult._errors); | 682 _errors.addAll(secondResult._errors); |
| 687 } | 683 } |
| 688 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToError(node, this); | 684 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToError(node, this); |
| 689 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndError(node, this); | 685 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndError(node, this); |
| 690 EvaluationResultImpl bitNot(Expression node) => this; | 686 EvaluationResultImpl bitNot(Expression node) => this; |
| 691 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.bitOrError(node, this); | 687 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.bitOrError(node, this); |
| 692 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitXorError(node, this); | 688 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitXorError(node, this); |
| 693 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp
erand) => rightOperand.concatenateError(node, this); | 689 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp
erand) => rightOperand.concatenateError(node, this); |
| 694 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.divideError(node, this); | 690 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.divideError(node, this); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); | 741 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); |
| 746 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand) => this; | 742 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand) => this; |
| 747 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); | 743 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand) => new ErrorResult.con2(this, leftOperand); |
| 748 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe
rand) => this; | 744 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe
rand) => this; |
| 749 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand) => new ErrorResult.con2(this, leftOperand); | 745 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand) => new ErrorResult.con2(this, leftOperand); |
| 750 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp
erand) => this; | 746 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp
erand) => this; |
| 751 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); | 747 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
) => new ErrorResult.con2(this, leftOperand); |
| 752 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand
) => this; | 748 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand
) => this; |
| 753 } | 749 } |
| 754 class ErrorResult_ErrorData { | 750 class ErrorResult_ErrorData { |
| 755 | 751 |
| 756 /** | 752 /** |
| 757 * The node against which the error should be reported. | 753 * The node against which the error should be reported. |
| 758 */ | 754 */ |
| 759 ASTNode _node; | 755 ASTNode _node; |
| 760 | 756 |
| 761 /** | 757 /** |
| 762 * The error code for the error to be generated. | 758 * The error code for the error to be generated. |
| 763 */ | 759 */ |
| 764 ErrorCode _errorCode; | 760 ErrorCode _errorCode; |
| 765 | 761 |
| 766 /** | 762 /** |
| 767 * Initialize a newly created data holder to represent the error with the give
n code reported | 763 * Initialize a newly created data holder to represent the error with the give
n code reported |
| 768 * against the given node. | 764 * against the given node. |
| 769 * @param node the node against which the error should be reported | 765 * @param node the node against which the error should be reported |
| 770 * @param errorCode the error code for the error to be generated | 766 * @param errorCode the error code for the error to be generated |
| 771 */ | 767 */ |
| 772 ErrorResult_ErrorData(ASTNode node, ErrorCode errorCode) { | 768 ErrorResult_ErrorData(ASTNode node, ErrorCode errorCode) { |
| 773 this._node = node; | 769 this._node = node; |
| 774 this._errorCode = errorCode; | 770 this._errorCode = errorCode; |
| 775 } | 771 } |
| 776 | 772 |
| 777 /** | 773 /** |
| 778 * Return the error code for the error to be generated. | 774 * Return the error code for the error to be generated. |
| 779 * @return the error code for the error to be generated | 775 * @return the error code for the error to be generated |
| 780 */ | 776 */ |
| 781 ErrorCode get errorCode => _errorCode; | 777 ErrorCode get errorCode => _errorCode; |
| 782 | 778 |
| 783 /** | 779 /** |
| 784 * Return the node against which the error should be reported. | 780 * Return the node against which the error should be reported. |
| 785 * @return the node against which the error should be reported | 781 * @return the node against which the error should be reported |
| 786 */ | 782 */ |
| 787 ASTNode get node => _node; | 783 ASTNode get node => _node; |
| 788 } | 784 } |
| 789 | |
| 790 /** | 785 /** |
| 791 * Instances of the class {@code InternalResult} represent the result of attempt
ing to evaluate a | 786 * Instances of the class {@code InternalResult} represent the result of attempt
ing to evaluate a |
| 792 * expression. | 787 * expression. |
| 793 */ | 788 */ |
| 794 abstract class EvaluationResultImpl { | 789 abstract class EvaluationResultImpl { |
| 795 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and); | 790 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and); |
| 796 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand); | 791 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand); |
| 797 EvaluationResultImpl bitNot(Expression node); | 792 EvaluationResultImpl bitNot(Expression node); |
| 798 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp
erand); | 793 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp
erand); |
| 799 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO
perand); | 794 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO
perand); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOper
and); | 845 EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOper
and); |
| 851 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand); | 846 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand); |
| 852 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand); | 847 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand); |
| 853 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand); | 848 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand); |
| 854 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe
rand); | 849 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe
rand); |
| 855 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand); | 850 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand); |
| 856 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp
erand); | 851 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp
erand); |
| 857 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
); | 852 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
); |
| 858 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand
); | 853 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand
); |
| 859 } | 854 } |
| 860 | |
| 861 /** | 855 /** |
| 862 * Instances of the class {@code ReferenceFinder} add reference information for
a given variable to | 856 * Instances of the class {@code ReferenceFinder} add reference information for
a given variable to |
| 863 * the bi-directional mapping used to order the evaluation of constants. | 857 * the bi-directional mapping used to order the evaluation of constants. |
| 864 */ | 858 */ |
| 865 class ReferenceFinder extends RecursiveASTVisitor<Object> { | 859 class ReferenceFinder extends RecursiveASTVisitor<Object> { |
| 866 | 860 |
| 867 /** | 861 /** |
| 868 * The element representing the variable whose initializer will be visited. | 862 * The element representing the variable whose initializer will be visited. |
| 869 */ | 863 */ |
| 870 VariableElement _source; | 864 VariableElement _source; |
| 871 | 865 |
| 872 /** | 866 /** |
| 873 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to | 867 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to |
| 874 * the other constant variables that are referenced in the head's initializer. | 868 * the other constant variables that are referenced in the head's initializer. |
| 875 */ | 869 */ |
| 876 DirectedGraph<VariableElement> _referenceGraph; | 870 DirectedGraph<VariableElement> _referenceGraph; |
| 877 | 871 |
| 878 /** | 872 /** |
| 879 * Initialize a newly created reference finder to find references from the giv
en variable to other | 873 * Initialize a newly created reference finder to find references from the giv
en variable to other |
| 880 * variables and to add those references to the given graph. | 874 * variables and to add those references to the given graph. |
| 881 * @param source the element representing the variable whose initializer will
be visited | 875 * @param source the element representing the variable whose initializer will
be visited |
| 882 * @param referenceGraph a graph recording which variables (heads) reference w
hich other variables | 876 * @param referenceGraph a graph recording which variables (heads) reference w
hich other variables |
| 883 * (tails) in their initializers | 877 * (tails) in their initializers |
| 884 */ | 878 */ |
| 885 ReferenceFinder(VariableElement source, DirectedGraph<VariableElement> referen
ceGraph) { | 879 ReferenceFinder(VariableElement source, DirectedGraph<VariableElement> referen
ceGraph) { |
| 886 this._source = source; | 880 this._source = source; |
| 887 this._referenceGraph = referenceGraph; | 881 this._referenceGraph = referenceGraph; |
| 888 } | 882 } |
| 889 Object visitSimpleIdentifier(SimpleIdentifier node) { | 883 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 890 Element element2 = node.element; | 884 Element element2 = node.element; |
| 891 if (element2 is PropertyAccessorElement) { | 885 if (element2 is PropertyAccessorElement) { |
| 892 element2 = ((element2 as PropertyAccessorElement)).variable; | 886 element2 = ((element2 as PropertyAccessorElement)).variable; |
| 893 } | 887 } |
| 894 if (element2 is VariableElement) { | 888 if (element2 is VariableElement) { |
| 895 VariableElement variable = element2 as VariableElement; | 889 VariableElement variable = element2 as VariableElement; |
| 896 if (variable.isConst()) { | 890 if (variable.isConst()) { |
| 897 _referenceGraph.addEdge(_source, variable); | 891 _referenceGraph.addEdge(_source, variable); |
| 898 } | 892 } |
| 899 } | 893 } |
| 900 return null; | 894 return null; |
| 901 } | 895 } |
| 902 } | 896 } |
| 903 | |
| 904 /** | 897 /** |
| 905 * Instances of the class {@code ValidResult} represent the result of attempting
to evaluate a valid | 898 * Instances of the class {@code ValidResult} represent the result of attempting
to evaluate a valid |
| 906 * compile time constant expression. | 899 * compile time constant expression. |
| 907 */ | 900 */ |
| 908 class ValidResult extends EvaluationResultImpl { | 901 class ValidResult extends EvaluationResultImpl { |
| 909 | 902 |
| 910 /** | 903 /** |
| 911 * A result object representing the value 'false'. | 904 * A result object representing the value 'false'. |
| 912 */ | 905 */ |
| 913 static ValidResult RESULT_FALSE = new ValidResult(false); | 906 static ValidResult RESULT_FALSE = new ValidResult(false); |
| 914 | 907 |
| 915 /** | 908 /** |
| 916 * A result object representing the an object without specific type on which n
o further operations | 909 * A result object representing the an object without specific type on which n
o further operations |
| 917 * can be performed. | 910 * can be performed. |
| 918 */ | 911 */ |
| 919 static ValidResult RESULT_DYNAMIC = new ValidResult(null); | 912 static ValidResult RESULT_DYNAMIC = new ValidResult(null); |
| 920 | 913 |
| 921 /** | 914 /** |
| 922 * A result object representing the an arbitrary integer on which no further o
perations can be | 915 * A result object representing the an arbitrary integer on which no further o
perations can be |
| 923 * performed. | 916 * performed. |
| 924 */ | 917 */ |
| 925 static ValidResult RESULT_INT = new ValidResult(null); | 918 static ValidResult RESULT_INT = new ValidResult(null); |
| 926 | 919 |
| 927 /** | 920 /** |
| 928 * A result object representing the {@code null} value. | 921 * A result object representing the {@code null} value. |
| 929 */ | 922 */ |
| 930 static ValidResult RESULT_NULL = new ValidResult(null); | 923 static ValidResult RESULT_NULL = new ValidResult(null); |
| 931 | 924 |
| 932 /** | 925 /** |
| 933 * A result object representing the an arbitrary numeric on which no further o
perations can be | 926 * A result object representing the an arbitrary numeric on which no further o
perations can be |
| 934 * performed. | 927 * performed. |
| 935 */ | 928 */ |
| 936 static ValidResult RESULT_NUM = new ValidResult(null); | 929 static ValidResult RESULT_NUM = new ValidResult(null); |
| 937 | 930 |
| 938 /** | 931 /** |
| 939 * A result object representing the an arbitrary boolean on which no further o
perations can be | 932 * A result object representing the an arbitrary boolean on which no further o
perations can be |
| 940 * performed. | 933 * performed. |
| 941 */ | 934 */ |
| 942 static ValidResult RESULT_BOOL = new ValidResult(null); | 935 static ValidResult RESULT_BOOL = new ValidResult(null); |
| 943 | 936 |
| 944 /** | 937 /** |
| 945 * A result object representing the an arbitrary object on which no further op
erations can be | 938 * A result object representing the an arbitrary object on which no further op
erations can be |
| 946 * performed. | 939 * performed. |
| 947 */ | 940 */ |
| 948 static ValidResult RESULT_OBJECT = new ValidResult(new Object()); | 941 static ValidResult RESULT_OBJECT = new ValidResult(new Object()); |
| 949 | 942 |
| 950 /** | 943 /** |
| 951 * A result object representing the an arbitrary string on which no further op
erations can be | 944 * A result object representing the an arbitrary string on which no further op
erations can be |
| 952 * performed. | 945 * performed. |
| 953 */ | 946 */ |
| 954 static ValidResult RESULT_STRING = new ValidResult("<string>"); | 947 static ValidResult RESULT_STRING = new ValidResult("<string>"); |
| 955 | 948 |
| 956 /** | 949 /** |
| 957 * A result object representing the value 'true'. | 950 * A result object representing the value 'true'. |
| 958 */ | 951 */ |
| 959 static ValidResult RESULT_TRUE = new ValidResult(true); | 952 static ValidResult RESULT_TRUE = new ValidResult(true); |
| 960 | 953 |
| 961 /** | 954 /** |
| 962 * The value of the expression. | 955 * The value of the expression. |
| 963 */ | 956 */ |
| 964 Object _value; | 957 Object _value; |
| 965 | 958 |
| 966 /** | 959 /** |
| 967 * Initialize a newly created result to represent the given value. | 960 * Initialize a newly created result to represent the given value. |
| 968 * @param value the value of the expression | 961 * @param value the value of the expression |
| 969 */ | 962 */ |
| 970 ValidResult(Object value) { | 963 ValidResult(Object value) { |
| 971 this._value = value; | 964 this._value = value; |
| 972 } | 965 } |
| 973 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToValid(node, this); | 966 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToValid(node, this); |
| 974 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndValid(node, this); | 967 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndValid(node, this); |
| 975 EvaluationResultImpl bitNot(Expression node) { | 968 EvaluationResultImpl bitNot(Expression node) { |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1567 } else if (leftValue is double) { | 1560 } else if (leftValue is double) { |
| 1568 if (_value is int) { | 1561 if (_value is int) { |
| 1569 return valueOf3(((leftValue as double)) * ((_value as int)).toDouble()); | 1562 return valueOf3(((leftValue as double)) * ((_value as int)).toDouble()); |
| 1570 } else if (_value is double) { | 1563 } else if (_value is double) { |
| 1571 return valueOf3(((leftValue as double)) * ((_value as double))); | 1564 return valueOf3(((leftValue as double)) * ((_value as double))); |
| 1572 } | 1565 } |
| 1573 } | 1566 } |
| 1574 return error(node); | 1567 return error(node); |
| 1575 } | 1568 } |
| 1576 bool isNull() => identical(this, RESULT_NULL); | 1569 bool isNull() => identical(this, RESULT_NULL); |
| 1577 | 1570 |
| 1578 /** | 1571 /** |
| 1579 * Return the result of applying boolean conversion to the given value. | 1572 * Return the result of applying boolean conversion to the given value. |
| 1580 * @param node the node against which errors should be reported | 1573 * @param node the node against which errors should be reported |
| 1581 * @param value the value to be converted to a boolean | 1574 * @param value the value to be converted to a boolean |
| 1582 * @return the result of applying boolean conversion to the given value | 1575 * @return the result of applying boolean conversion to the given value |
| 1583 */ | 1576 */ |
| 1584 EvaluationResultImpl booleanConversion(ASTNode node, Object value) { | 1577 EvaluationResultImpl booleanConversion(ASTNode node, Object value) { |
| 1585 if (value is bool) { | 1578 if (value is bool) { |
| 1586 if (((value as bool))) { | 1579 if (((value as bool))) { |
| 1587 return RESULT_TRUE; | 1580 return RESULT_TRUE; |
| 1588 } else { | 1581 } else { |
| 1589 return RESULT_FALSE; | 1582 return RESULT_FALSE; |
| 1590 } | 1583 } |
| 1591 } | 1584 } |
| 1592 return error(node); | 1585 return error(node); |
| 1593 } | 1586 } |
| 1594 ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_C
ONSTANT); | 1587 ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_C
ONSTANT); |
| 1595 | 1588 |
| 1596 /** | 1589 /** |
| 1597 * Return a result object representing an error associated with the given node
. | 1590 * Return a result object representing an error associated with the given node
. |
| 1598 * @param node the AST node associated with the error | 1591 * @param node the AST node associated with the error |
| 1599 * @param code the error code indicating the nature of the error | 1592 * @param code the error code indicating the nature of the error |
| 1600 * @return a result object representing an error associated with the given nod
e | 1593 * @return a result object representing an error associated with the given nod
e |
| 1601 */ | 1594 */ |
| 1602 ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code); | 1595 ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code); |
| 1603 | 1596 |
| 1604 /** | 1597 /** |
| 1605 * Checks if this result has type "bool", with known or unknown value. | 1598 * Checks if this result has type "bool", with known or unknown value. |
| 1606 */ | 1599 */ |
| 1607 bool isAnyBool() => isSomeBool() || identical(this, RESULT_TRUE) || identical(
this, RESULT_FALSE); | 1600 bool isAnyBool() => isSomeBool() || identical(this, RESULT_TRUE) || identical(
this, RESULT_FALSE); |
| 1608 | 1601 |
| 1609 /** | 1602 /** |
| 1610 * Checks if this result has type "int", with known or unknown value. | 1603 * Checks if this result has type "int", with known or unknown value. |
| 1611 */ | 1604 */ |
| 1612 bool isAnyInt() => identical(this, RESULT_INT) || _value is int; | 1605 bool isAnyInt() => identical(this, RESULT_INT) || _value is int; |
| 1613 | 1606 |
| 1614 /** | 1607 /** |
| 1615 * Checks if this result has one of the types - "bool", "num" or "string"; or
may be {@code null}. | 1608 * Checks if this result has one of the types - "bool", "num" or "string"; or
may be {@code null}. |
| 1616 */ | 1609 */ |
| 1617 bool isAnyNullBoolNumString() => isNull() || isAnyBool() || isAnyNum() || _val
ue is String; | 1610 bool isAnyNullBoolNumString() => isNull() || isAnyBool() || isAnyNum() || _val
ue is String; |
| 1618 | 1611 |
| 1619 /** | 1612 /** |
| 1620 * Checks if this result has type "num", with known or unknown value. | 1613 * Checks if this result has type "num", with known or unknown value. |
| 1621 */ | 1614 */ |
| 1622 bool isAnyNum() => isSomeNum() || _value is num; | 1615 bool isAnyNum() => isSomeNum() || _value is num; |
| 1623 | 1616 |
| 1624 /** | 1617 /** |
| 1625 * Checks if this result has type "bool", exact value of which we don't know. | 1618 * Checks if this result has type "bool", exact value of which we don't know. |
| 1626 */ | 1619 */ |
| 1627 bool isSomeBool() => identical(this, RESULT_BOOL); | 1620 bool isSomeBool() => identical(this, RESULT_BOOL); |
| 1628 | 1621 |
| 1629 /** | 1622 /** |
| 1630 * Checks if this result has type "int", exact value of which we don't know. | 1623 * Checks if this result has type "int", exact value of which we don't know. |
| 1631 */ | 1624 */ |
| 1632 bool isSomeInt() => identical(this, RESULT_INT); | 1625 bool isSomeInt() => identical(this, RESULT_INT); |
| 1633 | 1626 |
| 1634 /** | 1627 /** |
| 1635 * Checks if this result has type "num" (or "int"), exact value of which we do
n't know. | 1628 * Checks if this result has type "num" (or "int"), exact value of which we do
n't know. |
| 1636 */ | 1629 */ |
| 1637 bool isSomeNum() => identical(this, RESULT_DYNAMIC) || identical(this, RESULT_
INT) || identical(this, RESULT_NUM); | 1630 bool isSomeNum() => identical(this, RESULT_DYNAMIC) || identical(this, RESULT_
INT) || identical(this, RESULT_NUM); |
| 1638 double toDouble(int value) => value.toDouble(); | 1631 double toDouble(int value) => value.toDouble(); |
| 1639 | 1632 |
| 1640 /** | 1633 /** |
| 1641 * Return an error result that is the union of the two given error results. | 1634 * Return an error result that is the union of the two given error results. |
| 1642 * @param firstError the first error to be combined | 1635 * @param firstError the first error to be combined |
| 1643 * @param secondError the second error to be combined | 1636 * @param secondError the second error to be combined |
| 1644 * @return an error result that is the union of the two given error results | 1637 * @return an error result that is the union of the two given error results |
| 1645 */ | 1638 */ |
| 1646 ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new Erro
rResult.con2(firstError, secondError); | 1639 ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new Erro
rResult.con2(firstError, secondError); |
| 1647 | 1640 |
| 1648 /** | 1641 /** |
| 1649 * Return a result object representing the given value. | 1642 * Return a result object representing the given value. |
| 1650 * @param value the value to be represented as a result object | 1643 * @param value the value to be represented as a result object |
| 1651 * @return a result object representing the given value | 1644 * @return a result object representing the given value |
| 1652 */ | 1645 */ |
| 1653 ValidResult valueOf(int value) => new ValidResult(value); | 1646 ValidResult valueOf(int value) => new ValidResult(value); |
| 1654 | 1647 |
| 1655 /** | 1648 /** |
| 1656 * Return a result object representing the given value. | 1649 * Return a result object representing the given value. |
| 1657 * @param value the value to be represented as a result object | 1650 * @param value the value to be represented as a result object |
| 1658 * @return a result object representing the given value | 1651 * @return a result object representing the given value |
| 1659 */ | 1652 */ |
| 1660 ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE; | 1653 ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE; |
| 1661 | 1654 |
| 1662 /** | 1655 /** |
| 1663 * Return a result object representing the given value. | 1656 * Return a result object representing the given value. |
| 1664 * @param value the value to be represented as a result object | 1657 * @param value the value to be represented as a result object |
| 1665 * @return a result object representing the given value | 1658 * @return a result object representing the given value |
| 1666 */ | 1659 */ |
| 1667 ValidResult valueOf3(double value) => new ValidResult(value); | 1660 ValidResult valueOf3(double value) => new ValidResult(value); |
| 1668 | 1661 |
| 1669 /** | 1662 /** |
| 1670 * Return a result object representing the given value. | 1663 * Return a result object representing the given value. |
| 1671 * @param value the value to be represented as a result object | 1664 * @param value the value to be represented as a result object |
| 1672 * @return a result object representing the given value | 1665 * @return a result object representing the given value |
| 1673 */ | 1666 */ |
| 1674 ValidResult valueOf4(String value) => new ValidResult(value); | 1667 ValidResult valueOf4(String value) => new ValidResult(value); |
| 1675 } | 1668 } |
| OLD | NEW |