| 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 library engine.constant; | 3 library engine.constant; |
| 4 import 'java_core.dart'; | 4 import 'java_core.dart'; |
| 5 import 'source.dart' show Source; | 5 import 'source.dart' show Source; |
| 6 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; | 6 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; |
| 7 import 'scanner.dart' show TokenType; | 7 import 'scanner.dart' show TokenType; |
| 8 import 'ast.dart'; | 8 import 'ast.dart'; |
| 9 import 'element.dart'; | 9 import 'element.dart'; |
| 10 import 'engine.dart' show AnalysisEngine; | 10 import 'engine.dart' show AnalysisEngine; |
| 11 /** | 11 /** |
| 12 * Instances of the class `ConstantEvaluator` evaluate constant expressions to p
roduce their | 12 * Instances of the class `ConstantEvaluator` evaluate constant expressions to p
roduce their |
| 13 * 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 |
| 14 * expression is one of the following: | 14 * expression is one of the following: |
| 15 * | 15 * |
| 16 * * A literal number. | 16 * * A literal number. |
| 17 * * A literal boolean. | 17 * * A literal boolean. |
| 18 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates | 18 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates |
| 19 * to a numeric, string or boolean value or to `null`. | 19 * to a numeric, string or boolean value or to `null`. |
| 20 * * `null`. | 20 * * `null`. |
| 21 * * A reference to a static constant variable. | 21 * * A reference to a static constant variable. |
| 22 * * An identifier expression that denotes a constant variable, a class or a typ
e variable. | 22 * * An identifier expression that denotes a constant variable, a class or a typ
e variable. |
| 23 * * A constant constructor invocation. | 23 * * A constant constructor invocation. |
| 24 * * A constant list literal. | 24 * * A constant list literal. |
| 25 * * A constant map literal. | 25 * * A constant map literal. |
| 26 * * A simple or qualified identifier denoting a top-level function or a static
method. | 26 * * A simple or qualified identifier denoting a top-level function or a static
method. |
| 27 * * A parenthesized expression `(e)` where `e` is a constant expression. | 27 * * A parenthesized expression `(e)` where `e` is a constant expression. |
| 28 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,`e1 != e2
` where `e1` and `e2` are constant expressions that evaluate to a | 28 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`, |
| 29 * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a |
| 29 * numeric, string or boolean value or to `null`. | 30 * numeric, string or boolean value or to `null`. |
| 30 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where`e`,
`e1` and `e2` are constant expressions that evaluate to a boolean value or | 31 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where |
| 32 * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value
or |
| 31 * to `null`. | 33 * to `null`. |
| 32 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,`e1 | e2`, `e1
>> e2` or `e1 << e2`, where `e`, `e1` and `e2`are constant expressions that eva
luate to an integer value or to `null`. | 34 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`, |
| 33 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,`e1 * e2`, `e1
/ e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,`e1 >= e2`, `e1 <= e2` or `e1 % e2`, wh
ere `e`, `e1` and `e2`are constant expressions that evaluate to a numeric value
or to `null`. | 35 * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2` |
| 36 * are constant expressions that evaluate to an integer value or to `null`. |
| 37 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`, |
| 38 * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`, |
| 39 * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2` |
| 40 * are constant expressions that evaluate to a numeric value or to `null`. |
| 34 * | 41 * |
| 35 * </blockquote> The values returned by instances of this class are therefore `n
ull` and | 42 * </blockquote> The values returned by instances of this class are therefore `n
ull` and |
| 36 * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and`Dar
tObject`. | 43 * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and |
| 44 * `DartObject`. |
| 37 * | 45 * |
| 38 * In addition, this class defines several values that can be returned to indica
te various | 46 * In addition, this class defines several values that can be returned to indica
te various |
| 39 * conditions encountered during evaluation. These are documented with the stati
c field that define | 47 * conditions encountered during evaluation. These are documented with the stati
c field that define |
| 40 * those values. | 48 * those values. |
| 41 */ | 49 */ |
| 42 class ConstantEvaluator { | 50 class ConstantEvaluator { |
| 43 | 51 |
| 44 /** | 52 /** |
| 45 * The source containing the expression(s) that will be evaluated. | 53 * The source containing the expression(s) that will be evaluated. |
| 46 */ | 54 */ |
| 47 Source _source; | 55 Source _source; |
| 48 | 56 |
| 49 /** | 57 /** |
| 50 * Initialize a newly created evaluator to evaluate expressions in the given s
ource. | 58 * Initialize a newly created evaluator to evaluate expressions in the given s
ource. |
| 59 * |
| 51 * @param source the source containing the expression(s) that will be evaluate
d | 60 * @param source the source containing the expression(s) that will be evaluate
d |
| 52 */ | 61 */ |
| 53 ConstantEvaluator(Source source) { | 62 ConstantEvaluator(Source source) { |
| 54 this._source = source; | 63 this._source = source; |
| 55 } | 64 } |
| 56 EvaluationResult evaluate(Expression expression) { | 65 EvaluationResult evaluate(Expression expression) { |
| 57 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); | 66 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); |
| 58 if (result is ValidResult) { | 67 if (result is ValidResult) { |
| 59 return EvaluationResult.forValue(((result as ValidResult)).value); | 68 return EvaluationResult.forValue(((result as ValidResult)).value); |
| 60 } | 69 } |
| 61 List<AnalysisError> errors = new List<AnalysisError>(); | 70 List<AnalysisError> errors = new List<AnalysisError>(); |
| 62 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { | 71 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { |
| 63 ASTNode node = data.node; | 72 ASTNode node = data.node; |
| 64 errors.add(new AnalysisError.con2(_source, node.offset, node.length, data.
errorCode, [])); | 73 errors.add(new AnalysisError.con2(_source, node.offset, node.length, data.
errorCode, [])); |
| 65 } | 74 } |
| 66 return EvaluationResult.forErrors(new List.from(errors)); | 75 return EvaluationResult.forErrors(new List.from(errors)); |
| 67 } | 76 } |
| 68 } | 77 } |
| 69 /** | 78 /** |
| 70 * Instances of the class `EvaluationResult` represent the result of attempting
to evaluate an | 79 * Instances of the class `EvaluationResult` represent the result of attempting
to evaluate an |
| 71 * expression. | 80 * expression. |
| 72 */ | 81 */ |
| 73 class EvaluationResult { | 82 class EvaluationResult { |
| 74 | 83 |
| 75 /** | 84 /** |
| 76 * Return an evaluation result representing the result of evaluating an expres
sion that is not a | 85 * Return an evaluation result representing the result of evaluating an expres
sion that is not a |
| 77 * compile-time constant because of the given errors. | 86 * compile-time constant because of the given errors. |
| 87 * |
| 78 * @param errors the errors that should be reported for the expression(s) that
were evaluated | 88 * @param errors the errors that should be reported for the expression(s) that
were evaluated |
| 79 * @return the result of evaluating an expression that is not a compile-time c
onstant | 89 * @return the result of evaluating an expression that is not a compile-time c
onstant |
| 80 */ | 90 */ |
| 81 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio
nResult(null, errors); | 91 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio
nResult(null, errors); |
| 82 | 92 |
| 83 /** | 93 /** |
| 84 * Return an evaluation result representing the result of evaluating an expres
sion that is a | 94 * Return an evaluation result representing the result of evaluating an expres
sion that is a |
| 85 * compile-time constant that evaluates to the given value. | 95 * compile-time constant that evaluates to the given value. |
| 96 * |
| 86 * @param value the value of the expression | 97 * @param value the value of the expression |
| 87 * @return the result of evaluating an expression that is a compile-time const
ant | 98 * @return the result of evaluating an expression that is a compile-time const
ant |
| 88 */ | 99 */ |
| 89 static EvaluationResult forValue(Object value) => new EvaluationResult(value,
null); | 100 static EvaluationResult forValue(Object value) => new EvaluationResult(value,
null); |
| 90 | 101 |
| 91 /** | 102 /** |
| 92 * The value of the expression. | 103 * The value of the expression. |
| 93 */ | 104 */ |
| 94 Object _value; | 105 Object _value; |
| 95 | 106 |
| 96 /** | 107 /** |
| 97 * The errors that should be reported for the expression(s) that were evaluate
d. | 108 * The errors that should be reported for the expression(s) that were evaluate
d. |
| 98 */ | 109 */ |
| 99 List<AnalysisError> _errors; | 110 List<AnalysisError> _errors; |
| 100 | 111 |
| 101 /** | 112 /** |
| 102 * Initialize a newly created result object with the given state. Clients shou
ld use one of the | 113 * Initialize a newly created result object with the given state. Clients shou
ld use one of the |
| 103 * factory methods: [forErrors] and [forValue]. | 114 * factory methods: [forErrors] and [forValue]. |
| 115 * |
| 104 * @param value the value of the expression | 116 * @param value the value of the expression |
| 105 * @param errors the errors that should be reported for the expression(s) that
were evaluated | 117 * @param errors the errors that should be reported for the expression(s) that
were evaluated |
| 106 */ | 118 */ |
| 107 EvaluationResult(Object value, List<AnalysisError> errors) { | 119 EvaluationResult(Object value, List<AnalysisError> errors) { |
| 108 this._value = value; | 120 this._value = value; |
| 109 this._errors = errors; | 121 this._errors = errors; |
| 110 } | 122 } |
| 111 | 123 |
| 112 /** | 124 /** |
| 113 * Return an array containing the errors that should be reported for the expre
ssion(s) that were | 125 * Return an array containing the errors that should be reported for the expre
ssion(s) that were |
| 114 * evaluated. If there are no such errors, the array will be empty. The array
can be empty even if | 126 * evaluated. If there are no such errors, the array will be empty. The array
can be empty even if |
| 115 * the expression is not a valid compile time constant if the errors would hav
e been reported by | 127 * the expression is not a valid compile time constant if the errors would hav
e been reported by |
| 116 * other parts of the analysis engine. | 128 * other parts of the analysis engine. |
| 117 */ | 129 */ |
| 118 List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS :
_errors; | 130 List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS :
_errors; |
| 119 | 131 |
| 120 /** | 132 /** |
| 121 * Return the value of the expression, or `null` if the expression evaluated t
o `null`or if the expression could not be evaluated, either because it was not a
compile-time constant | 133 * Return the value of the expression, or `null` if the expression evaluated t
o `null` |
| 134 * or if the expression could not be evaluated, either because it was not a co
mpile-time constant |
| 122 * expression or because it would throw an exception when evaluated. | 135 * expression or because it would throw an exception when evaluated. |
| 136 * |
| 123 * @return the value of the expression | 137 * @return the value of the expression |
| 124 */ | 138 */ |
| 125 Object get value => _value; | 139 Object get value => _value; |
| 126 | 140 |
| 127 /** | 141 /** |
| 128 * Return `true` if the expression is a compile-time constant expression that
would not | 142 * Return `true` if the expression is a compile-time constant expression that
would not |
| 129 * throw an exception when evaluated. | 143 * throw an exception when evaluated. |
| 144 * |
| 130 * @return `true` if the expression is a valid compile-time constant expressio
n | 145 * @return `true` if the expression is a valid compile-time constant expressio
n |
| 131 */ | 146 */ |
| 132 bool get isValid => _errors == null; | 147 bool get isValid => _errors == null; |
| 133 } | 148 } |
| 134 /** | 149 /** |
| 135 * Instances of the class `ConstantFinder` are used to traverse the AST structur
es of all of | 150 * Instances of the class `ConstantFinder` are used to traverse the AST structur
es of all of |
| 136 * the compilation units being resolved and build a table mapping constant varia
ble elements to the | 151 * the compilation units being resolved and build a table mapping constant varia
ble elements to the |
| 137 * declarations of those variables. | 152 * declarations of those variables. |
| 138 */ | 153 */ |
| 139 class ConstantFinder extends RecursiveASTVisitor<Object> { | 154 class ConstantFinder extends RecursiveASTVisitor<Object> { |
| 140 | 155 |
| 141 /** | 156 /** |
| 142 * A table mapping constant variable elements to the declarations of those var
iables. | 157 * A table mapping constant variable elements to the declarations of those var
iables. |
| 143 */ | 158 */ |
| 144 Map<VariableElement, VariableDeclaration> _variableMap = new Map<VariableEleme
nt, VariableDeclaration>(); | 159 Map<VariableElement, VariableDeclaration> _variableMap = new Map<VariableEleme
nt, VariableDeclaration>(); |
| 145 | 160 |
| 146 /** | 161 /** |
| 147 * Return a table mapping constant variable elements to the declarations of th
ose variables. | 162 * Return a table mapping constant variable elements to the declarations of th
ose variables. |
| 163 * |
| 148 * @return a table mapping constant variable elements to the declarations of t
hose variables | 164 * @return a table mapping constant variable elements to the declarations of t
hose variables |
| 149 */ | 165 */ |
| 150 Map<VariableElement, VariableDeclaration> get variableMap => _variableMap; | 166 Map<VariableElement, VariableDeclaration> get variableMap => _variableMap; |
| 151 Object visitVariableDeclaration(VariableDeclaration node) { | 167 Object visitVariableDeclaration(VariableDeclaration node) { |
| 152 super.visitVariableDeclaration(node); | 168 super.visitVariableDeclaration(node); |
| 153 Expression initializer = node.initializer; | 169 Expression initializer = node.initializer; |
| 154 if (initializer != null && node.isConst) { | 170 if (initializer != null && node.isConst) { |
| 155 VariableElement element = node.element; | 171 VariableElement element = node.element; |
| 156 if (element != null) { | 172 if (element != null) { |
| 157 _variableMap[element] = node; | 173 _variableMap[element] = node; |
| 158 } | 174 } |
| 159 } | 175 } |
| 160 return null; | 176 return null; |
| 161 } | 177 } |
| 162 } | 178 } |
| 163 /** | 179 /** |
| 164 * Instances of the class `ConstantValueComputer` compute the values of constant
variables in | 180 * Instances of the class `ConstantValueComputer` compute the values of constant
variables in |
| 165 * one or more compilation units. The expected usage pattern is for the compilat
ion units to be | 181 * one or more compilation units. The expected usage pattern is for the compilat
ion units to be |
| 166 * added to this computer using the method [add] and then for the method[compute
Values] to invoked exactly once. Any use of an instance after invoking the | 182 * added to this computer using the method [add] and then for the method |
| 183 * [computeValues] to invoked exactly once. Any use of an instance after invokin
g the |
| 167 * method [computeValues] will result in unpredictable behavior. | 184 * method [computeValues] will result in unpredictable behavior. |
| 168 */ | 185 */ |
| 169 class ConstantValueComputer { | 186 class ConstantValueComputer { |
| 170 | 187 |
| 171 /** | 188 /** |
| 172 * The object used to find constant variables in the compilation units that we
re added. | 189 * The object used to find constant variables in the compilation units that we
re added. |
| 173 */ | 190 */ |
| 174 ConstantFinder _constantFinder = new ConstantFinder(); | 191 ConstantFinder _constantFinder = new ConstantFinder(); |
| 175 | 192 |
| 176 /** | 193 /** |
| 177 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to | 194 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to |
| 178 * the other constant variables that are referenced in the head's initializer. | 195 * the other constant variables that are referenced in the head's initializer. |
| 179 */ | 196 */ |
| 180 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle
ment>(); | 197 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle
ment>(); |
| 181 | 198 |
| 182 /** | 199 /** |
| 183 * A table mapping constant variables to the declarations of those variables. | 200 * A table mapping constant variables to the declarations of those variables. |
| 184 */ | 201 */ |
| 185 Map<VariableElement, VariableDeclaration> _declarationMap; | 202 Map<VariableElement, VariableDeclaration> _declarationMap; |
| 186 | 203 |
| 187 /** | 204 /** |
| 188 * Add the constant variables in the given compilation unit to the list of con
stant variables | 205 * Add the constant variables in the given compilation unit to the list of con
stant variables |
| 189 * whose value needs to be computed. | 206 * whose value needs to be computed. |
| 207 * |
| 190 * @param unit the compilation unit defining the constant variables to be adde
d | 208 * @param unit the compilation unit defining the constant variables to be adde
d |
| 191 */ | 209 */ |
| 192 void add(CompilationUnit unit) { | 210 void add(CompilationUnit unit) { |
| 193 unit.accept(_constantFinder); | 211 unit.accept(_constantFinder); |
| 194 } | 212 } |
| 195 | 213 |
| 196 /** | 214 /** |
| 197 * Compute values for all of the constant variables in the compilation units t
hat were added. | 215 * Compute values for all of the constant variables in the compilation units t
hat were added. |
| 198 */ | 216 */ |
| 199 void computeValues() { | 217 void computeValues() { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 219 for (VariableElement variable in variablesInCycle) { | 237 for (VariableElement variable in variablesInCycle) { |
| 220 generateCycleError(variablesInCycle, variable); | 238 generateCycleError(variablesInCycle, variable); |
| 221 } | 239 } |
| 222 _referenceGraph.removeAllNodes(variablesInCycle); | 240 _referenceGraph.removeAllNodes(variablesInCycle); |
| 223 } | 241 } |
| 224 } | 242 } |
| 225 } | 243 } |
| 226 | 244 |
| 227 /** | 245 /** |
| 228 * Compute a value for the given variable. | 246 * Compute a value for the given variable. |
| 247 * |
| 229 * @param variable the variable for which a value is to be computed | 248 * @param variable the variable for which a value is to be computed |
| 230 */ | 249 */ |
| 231 void computeValueFor(VariableElement variable) { | 250 void computeValueFor(VariableElement variable) { |
| 232 VariableDeclaration declaration = _declarationMap[variable]; | 251 VariableDeclaration declaration = _declarationMap[variable]; |
| 233 if (declaration == null) { | 252 if (declaration == null) { |
| 234 return; | 253 return; |
| 235 } | 254 } |
| 236 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis
itor()); | 255 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis
itor()); |
| 237 ((variable as VariableElementImpl)).evaluationResult = result; | 256 ((variable as VariableElementImpl)).evaluationResult = result; |
| 238 if (result is ErrorResult) { | 257 if (result is ErrorResult) { |
| 239 List<AnalysisError> errors = new List<AnalysisError>(); | 258 List<AnalysisError> errors = new List<AnalysisError>(); |
| 240 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { | 259 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { |
| 241 ASTNode node = data.node; | 260 ASTNode node = data.node; |
| 242 Source source = variable.getAncestor(CompilationUnitElement).source; | 261 Source source = variable.getAncestor(CompilationUnitElement).source; |
| 243 errors.add(new AnalysisError.con2(source, node.offset, node.length, data
.errorCode, [])); | 262 errors.add(new AnalysisError.con2(source, node.offset, node.length, data
.errorCode, [])); |
| 244 } | 263 } |
| 245 } | 264 } |
| 246 } | 265 } |
| 247 | 266 |
| 248 /** | 267 /** |
| 249 * Generate an error indicating that the given variable is not a valid compile
-time constant | 268 * Generate an error indicating that the given variable is not a valid compile
-time constant |
| 250 * because it references at least one of the variables in the given cycle, eac
h of which directly | 269 * because it references at least one of the variables in the given cycle, eac
h of which directly |
| 251 * or indirectly references the variable. | 270 * or indirectly references the variable. |
| 271 * |
| 252 * @param variablesInCycle the variables in the cycle that includes the given
variable | 272 * @param variablesInCycle the variables in the cycle that includes the given
variable |
| 253 * @param variable the variable that is not a valid compile-time constant | 273 * @param variable the variable that is not a valid compile-time constant |
| 254 */ | 274 */ |
| 255 void generateCycleError(List<VariableElement> variablesInCycle, VariableElemen
t variable) { | 275 void generateCycleError(List<VariableElement> variablesInCycle, VariableElemen
t variable) { |
| 256 } | 276 } |
| 257 } | 277 } |
| 258 /** | 278 /** |
| 259 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro
duce their | 279 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro
duce their |
| 260 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant | 280 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant |
| 261 * expression is one of the following: | 281 * expression is one of the following: |
| 262 * | 282 * |
| 263 * * A literal number. | 283 * * A literal number. |
| 264 * * A literal boolean. | 284 * * A literal boolean. |
| 265 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates | 285 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates |
| 266 * to a numeric, string or boolean value or to `null`. | 286 * to a numeric, string or boolean value or to `null`. |
| 267 * * `null`. | 287 * * `null`. |
| 268 * * A reference to a static constant variable. | 288 * * A reference to a static constant variable. |
| 269 * * An identifier expression that denotes a constant variable, a class or a typ
e variable. | 289 * * An identifier expression that denotes a constant variable, a class or a typ
e variable. |
| 270 * * A constant constructor invocation. | 290 * * A constant constructor invocation. |
| 271 * * A constant list literal. | 291 * * A constant list literal. |
| 272 * * A constant map literal. | 292 * * A constant map literal. |
| 273 * * A simple or qualified identifier denoting a top-level function or a static
method. | 293 * * A simple or qualified identifier denoting a top-level function or a static
method. |
| 274 * * A parenthesized expression `(e)` where `e` is a constant expression. | 294 * * A parenthesized expression `(e)` where `e` is a constant expression. |
| 275 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,`e1 != e2
` where `e1` and `e2` are constant expressions that evaluate to a | 295 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`, |
| 296 * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a |
| 276 * numeric, string or boolean value or to `null`. | 297 * numeric, string or boolean value or to `null`. |
| 277 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where`e`,
`e1` and `e2` are constant expressions that evaluate to a boolean value or | 298 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where |
| 299 * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value
or |
| 278 * to `null`. | 300 * to `null`. |
| 279 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,`e1 | e2`, `e1
>> e2` or `e1 << e2`, where `e`, `e1` and `e2`are constant expressions that eva
luate to an integer value or to `null`. | 301 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`, |
| 280 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,`e1 * e2`, `e1
/ e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,`e1 >= e2`, `e1 <= e2` or `e1 % e2`, wh
ere `e`, `e1` and `e2`are constant expressions that evaluate to a numeric value
or to `null`. | 302 * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2` |
| 303 * are constant expressions that evaluate to an integer value or to `null`. |
| 304 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`, |
| 305 * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`, |
| 306 * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2` |
| 307 * are constant expressions that evaluate to a numeric value or to `null`. |
| 281 * | 308 * |
| 282 * </blockquote> | 309 * </blockquote> |
| 283 */ | 310 */ |
| 284 class ConstantVisitor extends GeneralizingASTVisitor<EvaluationResultImpl> { | 311 class ConstantVisitor extends GeneralizingASTVisitor<EvaluationResultImpl> { |
| 285 EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) { | 312 EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) { |
| 286 EvaluationResultImpl result = null; | 313 EvaluationResultImpl result = null; |
| 287 for (StringLiteral string in node.strings) { | 314 for (StringLiteral string in node.strings) { |
| 288 if (result == null) { | 315 if (result == null) { |
| 289 result = string.accept(this); | 316 result = string.accept(this); |
| 290 } else { | 317 } else { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 } else if (operatorType == TokenType.TILDE_SLASH) { | 369 } else if (operatorType == TokenType.TILDE_SLASH) { |
| 343 return leftResult.integerDivide(node, rightResult); | 370 return leftResult.integerDivide(node, rightResult); |
| 344 } | 371 } |
| 345 break; | 372 break; |
| 346 } | 373 } |
| 347 return error(node, null); | 374 return error(node, null); |
| 348 } | 375 } |
| 349 EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ?
ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE; | 376 EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ?
ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE; |
| 350 EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult
(node.value); | 377 EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult
(node.value); |
| 351 EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpressio
n node) { | 378 EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpressio
n node) { |
| 379 if (!node.isConst) { |
| 380 return error(node, null); |
| 381 } |
| 352 ConstructorElement constructor = node.element; | 382 ConstructorElement constructor = node.element; |
| 353 if (constructor != null && constructor.isConst) { | 383 if (constructor != null && constructor.isConst) { |
| 354 node.argumentList.accept(this); | 384 node.argumentList.accept(this); |
| 355 return ValidResult.RESULT_OBJECT; | 385 return ValidResult.RESULT_OBJECT; |
| 356 } | 386 } |
| 357 return error(node, null); | 387 return error(node, null); |
| 358 } | 388 } |
| 359 EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResu
lt(node.value); | 389 EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResu
lt(node.value); |
| 360 EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node
) { | 390 EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node
) { |
| 361 EvaluationResultImpl result = node.expression.accept(this); | 391 EvaluationResultImpl result = node.expression.accept(this); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 } | 436 } |
| 407 } | 437 } |
| 408 } | 438 } |
| 409 } | 439 } |
| 410 } | 440 } |
| 411 return error(node, null); | 441 return error(node, null); |
| 412 } | 442 } |
| 413 EvaluationResultImpl visitNode(ASTNode node) => error(node, null); | 443 EvaluationResultImpl visitNode(ASTNode node) => error(node, null); |
| 414 EvaluationResultImpl visitNullLiteral(NullLiteral node) => ValidResult.RESULT_
NULL; | 444 EvaluationResultImpl visitNullLiteral(NullLiteral node) => ValidResult.RESULT_
NULL; |
| 415 EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node
) => node.expression.accept(this); | 445 EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node
) => node.expression.accept(this); |
| 416 EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) => getCo
nstantValue(node, node.element); | 446 EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 447 SimpleIdentifier prefixNode = node.prefix; |
| 448 Element prefixElement = prefixNode.element; |
| 449 if (prefixElement is! PrefixElement) { |
| 450 EvaluationResultImpl prefixResult = prefixNode.accept(this); |
| 451 if (prefixResult is! ValidResult) { |
| 452 return error(node, null); |
| 453 } |
| 454 } |
| 455 return getConstantValue(node, node.element); |
| 456 } |
| 417 EvaluationResultImpl visitPrefixExpression(PrefixExpression node) { | 457 EvaluationResultImpl visitPrefixExpression(PrefixExpression node) { |
| 418 EvaluationResultImpl operand = node.operand.accept(this); | 458 EvaluationResultImpl operand = node.operand.accept(this); |
| 419 if (operand is ValidResult && ((operand as ValidResult)).isNull) { | 459 if (operand is ValidResult && ((operand as ValidResult)).isNull) { |
| 420 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); | 460 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); |
| 421 } | 461 } |
| 422 while (true) { | 462 while (true) { |
| 423 if (node.operator.type == TokenType.BANG) { | 463 if (node.operator.type == TokenType.BANG) { |
| 424 return operand.logicalNot(node); | 464 return operand.logicalNot(node); |
| 425 } else if (node.operator.type == TokenType.TILDE) { | 465 } else if (node.operator.type == TokenType.TILDE) { |
| 426 return operand.bitNot(node); | 466 return operand.bitNot(node); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 441 result = element.accept(this); | 481 result = element.accept(this); |
| 442 } else { | 482 } else { |
| 443 result = result.concatenate(node, element.accept(this)); | 483 result = result.concatenate(node, element.accept(this)); |
| 444 } | 484 } |
| 445 } | 485 } |
| 446 return result; | 486 return result; |
| 447 } | 487 } |
| 448 | 488 |
| 449 /** | 489 /** |
| 450 * Return a result object representing an error associated with the given node
. | 490 * Return a result object representing an error associated with the given node
. |
| 491 * |
| 451 * @param node the AST node associated with the error | 492 * @param node the AST node associated with the error |
| 452 * @param code the error code indicating the nature of the error | 493 * @param code the error code indicating the nature of the error |
| 453 * @return a result object representing an error associated with the given nod
e | 494 * @return a result object representing an error associated with the given nod
e |
| 454 */ | 495 */ |
| 455 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); | 496 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); |
| 456 | 497 |
| 457 /** | 498 /** |
| 458 * Return the constant value of the static constant represented by the given e
lement. | 499 * Return the constant value of the static constant represented by the given e
lement. |
| 500 * |
| 459 * @param node the node to be used if an error needs to be reported | 501 * @param node the node to be used if an error needs to be reported |
| 460 * @param element the element whose value is to be returned | 502 * @param element the element whose value is to be returned |
| 461 * @return the constant value of the static constant | 503 * @return the constant value of the static constant |
| 462 */ | 504 */ |
| 463 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { | 505 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { |
| 464 if (element is PropertyAccessorElement) { | 506 if (element is PropertyAccessorElement) { |
| 465 element = ((element as PropertyAccessorElement)).variable; | 507 element = ((element as PropertyAccessorElement)).variable; |
| 466 } | 508 } |
| 467 if (element is VariableElementImpl) { | 509 if (element is VariableElementImpl) { |
| 468 EvaluationResultImpl value = ((element as VariableElementImpl)).evaluation
Result; | 510 EvaluationResultImpl value = ((element as VariableElementImpl)).evaluation
Result; |
| 469 if (value != null) { | 511 if (value != null) { |
| 470 return value; | 512 return value; |
| 471 } | 513 } |
| 472 } else if (element is ExecutableElement) { | 514 } else if (element is ExecutableElement) { |
| 473 return new ValidResult(element); | 515 if (((element as ExecutableElement)).isStatic) { |
| 516 return new ValidResult(element); |
| 517 } |
| 474 } else if (element is ClassElement) { | 518 } else if (element is ClassElement) { |
| 475 return ValidResult.RESULT_OBJECT; | 519 return ValidResult.RESULT_OBJECT; |
| 476 } | 520 } |
| 477 return error(node, null); | 521 return error(node, null); |
| 478 } | 522 } |
| 479 | 523 |
| 480 /** | 524 /** |
| 481 * Return the union of the errors encoded in the given results. | 525 * Return the union of the errors encoded in the given results. |
| 526 * |
| 482 * @param leftResult the first set of errors, or `null` if there was no previo
us collection | 527 * @param leftResult the first set of errors, or `null` if there was no previo
us collection |
| 483 * of errors | 528 * of errors |
| 484 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no | 529 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no |
| 485 * errors to be added | 530 * errors to be added |
| 486 * @return the union of the errors encoded in the given results | 531 * @return the union of the errors encoded in the given results |
| 487 */ | 532 */ |
| 488 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { | 533 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { |
| 489 if (rightResult is ErrorResult) { | 534 if (rightResult is ErrorResult) { |
| 490 if (leftResult != null) { | 535 if (leftResult != null) { |
| 491 return new ErrorResult.con2(leftResult, (rightResult as ErrorResult)); | 536 return new ErrorResult.con2(leftResult, (rightResult as ErrorResult)); |
| 492 } else { | 537 } else { |
| 493 return rightResult as ErrorResult; | 538 return rightResult as ErrorResult; |
| 494 } | 539 } |
| 495 } | 540 } |
| 496 return leftResult; | 541 return leftResult; |
| 497 } | 542 } |
| 498 } | 543 } |
| 499 /** | 544 /** |
| 500 * Instances of the class `DirectedGraph` implement a directed graph in which th
e nodes are | 545 * Instances of the class `DirectedGraph` implement a directed graph in which th
e nodes are |
| 501 * arbitrary (client provided) objects and edges are represented implicitly. The
graph will allow an | 546 * arbitrary (client provided) objects and edges are represented implicitly. The
graph will allow an |
| 502 * edge from any node to any other node, including itself, but will not represen
t multiple edges | 547 * edge from any node to any other node, including itself, but will not represen
t multiple edges |
| 503 * between the same pair of nodes. | 548 * between the same pair of nodes. |
| 549 * |
| 504 * @param N the type of the nodes in the graph | 550 * @param N the type of the nodes in the graph |
| 505 */ | 551 */ |
| 506 class DirectedGraph<N> { | 552 class DirectedGraph<N> { |
| 507 | 553 |
| 508 /** | 554 /** |
| 509 * The table encoding the edges in the graph. An edge is represented by an ent
ry mapping the head | 555 * The table encoding the edges in the graph. An edge is represented by an ent
ry mapping the head |
| 510 * to a set of tails. Nodes that are not the head of any edge are represented
by an entry mapping | 556 * to a set of tails. Nodes that are not the head of any edge are represented
by an entry mapping |
| 511 * the node to an empty set of tails. | 557 * the node to an empty set of tails. |
| 512 */ | 558 */ |
| 513 Map<N, Set<N>> _edges = new Map<N, Set<N>>(); | 559 Map<N, Set<N>> _edges = new Map<N, Set<N>>(); |
| 514 | 560 |
| 515 /** | 561 /** |
| 516 * Add an edge from the given head node to the given tail node. Both nodes wil
l be a part of the | 562 * Add an edge from the given head node to the given tail node. Both nodes wil
l be a part of the |
| 517 * graph after this method is invoked, whether or not they were before. | 563 * graph after this method is invoked, whether or not they were before. |
| 564 * |
| 518 * @param head the node at the head of the edge | 565 * @param head the node at the head of the edge |
| 519 * @param tail the node at the tail of the edge | 566 * @param tail the node at the tail of the edge |
| 520 */ | 567 */ |
| 521 void addEdge(N head, N tail) { | 568 void addEdge(N head, N tail) { |
| 522 Set<N> tails = _edges[tail]; | 569 Set<N> tails = _edges[tail]; |
| 523 if (tails == null) { | 570 if (tails == null) { |
| 524 _edges[tail] = new Set<N>(); | 571 _edges[tail] = new Set<N>(); |
| 525 } | 572 } |
| 526 tails = _edges[head]; | 573 tails = _edges[head]; |
| 527 if (tails == null) { | 574 if (tails == null) { |
| 528 tails = new Set<N>(); | 575 tails = new Set<N>(); |
| 529 _edges[head] = tails; | 576 _edges[head] = tails; |
| 530 } | 577 } |
| 531 javaSetAdd(tails, tail); | 578 javaSetAdd(tails, tail); |
| 532 } | 579 } |
| 533 | 580 |
| 534 /** | 581 /** |
| 535 * Add the given node to the set of nodes in the graph. | 582 * Add the given node to the set of nodes in the graph. |
| 583 * |
| 536 * @param node the node to be added | 584 * @param node the node to be added |
| 537 */ | 585 */ |
| 538 void addNode(N node) { | 586 void addNode(N node) { |
| 539 Set<N> tails = _edges[node]; | 587 Set<N> tails = _edges[node]; |
| 540 if (tails == null) { | 588 if (tails == null) { |
| 541 _edges[node] = new Set<N>(); | 589 _edges[node] = new Set<N>(); |
| 542 } | 590 } |
| 543 } | 591 } |
| 544 | 592 |
| 545 /** | 593 /** |
| 546 * Return a list of nodes that form a cycle, or `null` if there are no cycles
in this graph. | 594 * Return a list of nodes that form a cycle, or `null` if there are no cycles
in this graph. |
| 595 * |
| 547 * @return a list of nodes that form a cycle | 596 * @return a list of nodes that form a cycle |
| 548 */ | 597 */ |
| 549 List<N> findCycle() => null; | 598 List<N> findCycle() => null; |
| 550 | 599 |
| 551 /** | 600 /** |
| 552 * Return the number of nodes in this graph. | 601 * Return the number of nodes in this graph. |
| 602 * |
| 553 * @return the number of nodes in this graph | 603 * @return the number of nodes in this graph |
| 554 */ | 604 */ |
| 555 int get nodeCount => _edges.length; | 605 int get nodeCount => _edges.length; |
| 556 | 606 |
| 557 /** | 607 /** |
| 558 * Return a set containing the tails of edges that have the given node as thei
r head. The set will | 608 * Return a set containing the tails of edges that have the given node as thei
r head. The set will |
| 559 * be empty if there are no such edges or if the node is not part of the graph
. Clients must not | 609 * be empty if there are no such edges or if the node is not part of the graph
. Clients must not |
| 560 * modify the returned set. | 610 * modify the returned set. |
| 611 * |
| 561 * @param head the node at the head of all of the edges whose tails are to be
returned | 612 * @param head the node at the head of all of the edges whose tails are to be
returned |
| 562 * @return a set containing the tails of edges that have the given node as the
ir head | 613 * @return a set containing the tails of edges that have the given node as the
ir head |
| 563 */ | 614 */ |
| 564 Set<N> getTails(N head) { | 615 Set<N> getTails(N head) { |
| 565 Set<N> tails = _edges[head]; | 616 Set<N> tails = _edges[head]; |
| 566 if (tails == null) { | 617 if (tails == null) { |
| 567 return new Set<N>(); | 618 return new Set<N>(); |
| 568 } | 619 } |
| 569 return tails; | 620 return tails; |
| 570 } | 621 } |
| 571 | 622 |
| 572 /** | 623 /** |
| 573 * Return `true` if this graph is empty. | 624 * Return `true` if this graph is empty. |
| 625 * |
| 574 * @return `true` if this graph is empty | 626 * @return `true` if this graph is empty |
| 575 */ | 627 */ |
| 576 bool get isEmpty => _edges.isEmpty; | 628 bool get isEmpty => _edges.isEmpty; |
| 577 | 629 |
| 578 /** | 630 /** |
| 579 * Remove all of the given nodes from this graph. As a consequence, any edges
for which those | 631 * Remove all of the given nodes from this graph. As a consequence, any edges
for which those |
| 580 * nodes were either a head or a tail will also be removed. | 632 * nodes were either a head or a tail will also be removed. |
| 633 * |
| 581 * @param nodes the nodes to be removed | 634 * @param nodes the nodes to be removed |
| 582 */ | 635 */ |
| 583 void removeAllNodes(List<N> nodes) { | 636 void removeAllNodes(List<N> nodes) { |
| 584 for (N node in nodes) { | 637 for (N node in nodes) { |
| 585 removeNode(node); | 638 removeNode(node); |
| 586 } | 639 } |
| 587 } | 640 } |
| 588 | 641 |
| 589 /** | 642 /** |
| 590 * Remove the edge from the given head node to the given tail node. If there w
as no such edge then | 643 * Remove the edge from the given head node to the given tail node. If there w
as no such edge then |
| 591 * the graph will be unmodified: the number of edges will be the same and the
set of nodes will be | 644 * the graph will be unmodified: the number of edges will be the same and the
set of nodes will be |
| 592 * the same (neither node will either be added or removed). | 645 * the same (neither node will either be added or removed). |
| 646 * |
| 593 * @param head the node at the head of the edge | 647 * @param head the node at the head of the edge |
| 594 * @param tail the node at the tail of the edge | 648 * @param tail the node at the tail of the edge |
| 595 * @return `true` if the graph was modified as a result of this operation | 649 * @return `true` if the graph was modified as a result of this operation |
| 596 */ | 650 */ |
| 597 void removeEdge(N head, N tail) { | 651 void removeEdge(N head, N tail) { |
| 598 Set<N> tails = _edges[head]; | 652 Set<N> tails = _edges[head]; |
| 599 if (tails != null) { | 653 if (tails != null) { |
| 600 tails.remove(tail); | 654 tails.remove(tail); |
| 601 } | 655 } |
| 602 } | 656 } |
| 603 | 657 |
| 604 /** | 658 /** |
| 605 * Remove the given node from this graph. As a consequence, any edges for whic
h that node was | 659 * Remove the given node from this graph. As a consequence, any edges for whic
h that node was |
| 606 * either a head or a tail will also be removed. | 660 * either a head or a tail will also be removed. |
| 661 * |
| 607 * @param node the node to be removed | 662 * @param node the node to be removed |
| 608 */ | 663 */ |
| 609 void removeNode(N node) { | 664 void removeNode(N node) { |
| 610 _edges.remove(node); | 665 _edges.remove(node); |
| 611 for (Set<N> tails in _edges.values) { | 666 for (Set<N> tails in _edges.values) { |
| 612 tails.remove(node); | 667 tails.remove(node); |
| 613 } | 668 } |
| 614 } | 669 } |
| 615 | 670 |
| 616 /** | 671 /** |
| 617 * Find one node (referred to as a sink node) that has no outgoing edges (that
is, for which there | 672 * Find one node (referred to as a sink node) that has no outgoing edges (that
is, for which there |
| 618 * are no edges that have that node as the head of the edge) and remove it fro
m this graph. Return | 673 * are no edges that have that node as the head of the edge) and remove it fro
m this graph. Return |
| 619 * the node that was removed, or `null` if there are no such nodes either beca
use the graph | 674 * the node that was removed, or `null` if there are no such nodes either beca
use the graph |
| 620 * is empty or because every node in the graph has at least one outgoing edge.
As a consequence of | 675 * is empty or because every node in the graph has at least one outgoing edge.
As a consequence of |
| 621 * removing the node from the graph any edges for which that node was a tail w
ill also be removed. | 676 * removing the node from the graph any edges for which that node was a tail w
ill also be removed. |
| 677 * |
| 622 * @return the sink node that was removed | 678 * @return the sink node that was removed |
| 623 */ | 679 */ |
| 624 N removeSink() { | 680 N removeSink() { |
| 625 N sink = findSink(); | 681 N sink = findSink(); |
| 626 if (sink == null) { | 682 if (sink == null) { |
| 627 return null; | 683 return null; |
| 628 } | 684 } |
| 629 removeNode(sink); | 685 removeNode(sink); |
| 630 return sink; | 686 return sink; |
| 631 } | 687 } |
| 632 | 688 |
| 633 /** | 689 /** |
| 634 * Return one node that has no outgoing edges (that is, for which there are no
edges that have | 690 * Return one node that has no outgoing edges (that is, for which there are no
edges that have |
| 635 * that node as the head of the edge), or `null` if there are no such nodes. | 691 * that node as the head of the edge), or `null` if there are no such nodes. |
| 692 * |
| 636 * @return a sink node | 693 * @return a sink node |
| 637 */ | 694 */ |
| 638 N findSink() { | 695 N findSink() { |
| 639 for (N key in _edges.keys) { | 696 for (N key in _edges.keys) { |
| 640 if (_edges[key].isEmpty) return key; | 697 if (_edges[key].isEmpty) return key; |
| 641 } | 698 } |
| 642 return null; | 699 return null; |
| 643 } | 700 } |
| 644 } | 701 } |
| 645 /** | 702 /** |
| 646 * Instances of the class `ErrorResult` represent the result of evaluating an ex
pression that | 703 * Instances of the class `ErrorResult` represent the result of evaluating an ex
pression that |
| 647 * is not a valid compile time constant. | 704 * is not a valid compile time constant. |
| 648 */ | 705 */ |
| 649 class ErrorResult extends EvaluationResultImpl { | 706 class ErrorResult extends EvaluationResultImpl { |
| 650 | 707 |
| 651 /** | 708 /** |
| 652 * The errors that prevent the expression from being a valid compile time cons
tant. | 709 * The errors that prevent the expression from being a valid compile time cons
tant. |
| 653 */ | 710 */ |
| 654 List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>(); | 711 List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>(); |
| 655 | 712 |
| 656 /** | 713 /** |
| 657 * Initialize a newly created result representing the error with the given cod
e reported against | 714 * Initialize a newly created result representing the error with the given cod
e reported against |
| 658 * the given node. | 715 * the given node. |
| 716 * |
| 659 * @param node the node against which the error should be reported | 717 * @param node the node against which the error should be reported |
| 660 * @param errorCode the error code for the error to be generated | 718 * @param errorCode the error code for the error to be generated |
| 661 */ | 719 */ |
| 662 ErrorResult.con1(ASTNode node, ErrorCode errorCode) { | 720 ErrorResult.con1(ASTNode node, ErrorCode errorCode) { |
| 663 _jtd_constructor_172_impl(node, errorCode); | 721 _jtd_constructor_172_impl(node, errorCode); |
| 664 } | 722 } |
| 665 _jtd_constructor_172_impl(ASTNode node, ErrorCode errorCode) { | 723 _jtd_constructor_172_impl(ASTNode node, ErrorCode errorCode) { |
| 666 _errors.add(new ErrorResult_ErrorData(node, errorCode)); | 724 _errors.add(new ErrorResult_ErrorData(node, errorCode)); |
| 667 } | 725 } |
| 668 | 726 |
| 669 /** | 727 /** |
| 670 * Initialize a newly created result to represent the union of the errors in t
he given result | 728 * Initialize a newly created result to represent the union of the errors in t
he given result |
| 671 * objects. | 729 * objects. |
| 730 * |
| 672 * @param firstResult the first set of results being merged | 731 * @param firstResult the first set of results being merged |
| 673 * @param secondResult the second set of results being merged | 732 * @param secondResult the second set of results being merged |
| 674 */ | 733 */ |
| 675 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { | 734 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { |
| 676 _jtd_constructor_173_impl(firstResult, secondResult); | 735 _jtd_constructor_173_impl(firstResult, secondResult); |
| 677 } | 736 } |
| 678 _jtd_constructor_173_impl(ErrorResult firstResult, ErrorResult secondResult) { | 737 _jtd_constructor_173_impl(ErrorResult firstResult, ErrorResult secondResult) { |
| 679 _errors.addAll(firstResult._errors); | 738 _errors.addAll(firstResult._errors); |
| 680 _errors.addAll(secondResult._errors); | 739 _errors.addAll(secondResult._errors); |
| 681 } | 740 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 ASTNode _node; | 813 ASTNode _node; |
| 755 | 814 |
| 756 /** | 815 /** |
| 757 * The error code for the error to be generated. | 816 * The error code for the error to be generated. |
| 758 */ | 817 */ |
| 759 ErrorCode _errorCode; | 818 ErrorCode _errorCode; |
| 760 | 819 |
| 761 /** | 820 /** |
| 762 * Initialize a newly created data holder to represent the error with the give
n code reported | 821 * Initialize a newly created data holder to represent the error with the give
n code reported |
| 763 * against the given node. | 822 * against the given node. |
| 823 * |
| 764 * @param node the node against which the error should be reported | 824 * @param node the node against which the error should be reported |
| 765 * @param errorCode the error code for the error to be generated | 825 * @param errorCode the error code for the error to be generated |
| 766 */ | 826 */ |
| 767 ErrorResult_ErrorData(ASTNode node, ErrorCode errorCode) { | 827 ErrorResult_ErrorData(ASTNode node, ErrorCode errorCode) { |
| 768 this._node = node; | 828 this._node = node; |
| 769 this._errorCode = errorCode; | 829 this._errorCode = errorCode; |
| 770 } | 830 } |
| 771 | 831 |
| 772 /** | 832 /** |
| 773 * Return the error code for the error to be generated. | 833 * Return the error code for the error to be generated. |
| 834 * |
| 774 * @return the error code for the error to be generated | 835 * @return the error code for the error to be generated |
| 775 */ | 836 */ |
| 776 ErrorCode get errorCode => _errorCode; | 837 ErrorCode get errorCode => _errorCode; |
| 777 | 838 |
| 778 /** | 839 /** |
| 779 * Return the node against which the error should be reported. | 840 * Return the node against which the error should be reported. |
| 841 * |
| 780 * @return the node against which the error should be reported | 842 * @return the node against which the error should be reported |
| 781 */ | 843 */ |
| 782 ASTNode get node => _node; | 844 ASTNode get node => _node; |
| 783 } | 845 } |
| 784 /** | 846 /** |
| 785 * Instances of the class `InternalResult` represent the result of attempting to
evaluate a | 847 * Instances of the class `InternalResult` represent the result of attempting to
evaluate a |
| 786 * expression. | 848 * expression. |
| 787 */ | 849 */ |
| 788 abstract class EvaluationResultImpl { | 850 abstract class EvaluationResultImpl { |
| 789 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and); | 851 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 | 927 |
| 866 /** | 928 /** |
| 867 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to | 929 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to |
| 868 * the other constant variables that are referenced in the head's initializer. | 930 * the other constant variables that are referenced in the head's initializer. |
| 869 */ | 931 */ |
| 870 DirectedGraph<VariableElement> _referenceGraph; | 932 DirectedGraph<VariableElement> _referenceGraph; |
| 871 | 933 |
| 872 /** | 934 /** |
| 873 * Initialize a newly created reference finder to find references from the giv
en variable to other | 935 * Initialize a newly created reference finder to find references from the giv
en variable to other |
| 874 * variables and to add those references to the given graph. | 936 * variables and to add those references to the given graph. |
| 937 * |
| 875 * @param source the element representing the variable whose initializer will
be visited | 938 * @param source the element representing the variable whose initializer will
be visited |
| 876 * @param referenceGraph a graph recording which variables (heads) reference w
hich other variables | 939 * @param referenceGraph a graph recording which variables (heads) reference w
hich other variables |
| 877 * (tails) in their initializers | 940 * (tails) in their initializers |
| 878 */ | 941 */ |
| 879 ReferenceFinder(VariableElement source, DirectedGraph<VariableElement> referen
ceGraph) { | 942 ReferenceFinder(VariableElement source, DirectedGraph<VariableElement> referen
ceGraph) { |
| 880 this._source = source; | 943 this._source = source; |
| 881 this._referenceGraph = referenceGraph; | 944 this._referenceGraph = referenceGraph; |
| 882 } | 945 } |
| 883 Object visitSimpleIdentifier(SimpleIdentifier node) { | 946 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 884 Element element = node.element; | 947 Element element = node.element; |
| 885 if (element is PropertyAccessorElement) { | 948 if (element is PropertyAccessorElement) { |
| 886 element = ((element as PropertyAccessorElement)).variable; | 949 element = ((element as PropertyAccessorElement)).variable; |
| 887 } | 950 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 */ | 1014 */ |
| 952 static ValidResult RESULT_TRUE = new ValidResult(true); | 1015 static ValidResult RESULT_TRUE = new ValidResult(true); |
| 953 | 1016 |
| 954 /** | 1017 /** |
| 955 * The value of the expression. | 1018 * The value of the expression. |
| 956 */ | 1019 */ |
| 957 Object _value; | 1020 Object _value; |
| 958 | 1021 |
| 959 /** | 1022 /** |
| 960 * Initialize a newly created result to represent the given value. | 1023 * Initialize a newly created result to represent the given value. |
| 1024 * |
| 961 * @param value the value of the expression | 1025 * @param value the value of the expression |
| 962 */ | 1026 */ |
| 963 ValidResult(Object value) { | 1027 ValidResult(Object value) { |
| 964 this._value = value; | 1028 this._value = value; |
| 965 } | 1029 } |
| 966 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToValid(node, this); | 1030 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToValid(node, this); |
| 967 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndValid(node, this); | 1031 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndValid(node, this); |
| 968 EvaluationResultImpl bitNot(Expression node) { | 1032 EvaluationResultImpl bitNot(Expression node) { |
| 969 if (isSomeInt) { | 1033 if (isSomeInt) { |
| 970 return RESULT_INT; | 1034 return RESULT_INT; |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1349 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); |
| 1286 } | 1350 } |
| 1287 Object leftValue = leftOperand2.value; | 1351 Object leftValue = leftOperand2.value; |
| 1288 if (leftValue == null) { | 1352 if (leftValue == null) { |
| 1289 return error(node.leftOperand); | 1353 return error(node.leftOperand); |
| 1290 } else if (_value == null) { | 1354 } else if (_value == null) { |
| 1291 return error(node.rightOperand); | 1355 return error(node.rightOperand); |
| 1292 } else if (leftValue is int) { | 1356 } else if (leftValue is int) { |
| 1293 if (_value is int) { | 1357 if (_value is int) { |
| 1294 if (((_value as int)) == 0) { | 1358 if (((_value as int)) == 0) { |
| 1295 return valueOf3(((leftValue as int)).toDouble() / ((_value as int)).to
Double()); | 1359 return error2(node, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE); |
| 1296 } | 1360 } |
| 1297 return valueOf(((leftValue as int)) ~/ (_value as int)); | 1361 return valueOf(((leftValue as int)) ~/ (_value as int)); |
| 1298 } else if (_value is double) { | 1362 } else if (_value is double) { |
| 1299 double result = ((leftValue as int)).toDouble() / ((_value as double)); | 1363 double result = ((leftValue as int)).toDouble() / ((_value as double)); |
| 1300 return valueOf(result.toInt()); | 1364 return valueOf(result.toInt()); |
| 1301 } | 1365 } |
| 1302 } else if (leftValue is double) { | 1366 } else if (leftValue is double) { |
| 1303 if (_value is int) { | 1367 if (_value is int) { |
| 1304 double result = ((leftValue as double)) / ((_value as int)).toDouble(); | 1368 double result = ((leftValue as double)) / ((_value as int)).toDouble(); |
| 1305 return valueOf(result.toInt()); | 1369 return valueOf(result.toInt()); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1378 if (leftValue is bool) { | 1442 if (leftValue is bool) { |
| 1379 if (((leftValue as bool))) { | 1443 if (((leftValue as bool))) { |
| 1380 return booleanConversion(node.rightOperand, _value); | 1444 return booleanConversion(node.rightOperand, _value); |
| 1381 } | 1445 } |
| 1382 return RESULT_FALSE; | 1446 return RESULT_FALSE; |
| 1383 } | 1447 } |
| 1384 return error(node); | 1448 return error(node); |
| 1385 } | 1449 } |
| 1386 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; | 1450 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; |
| 1387 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe
rand) { | 1451 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe
rand) { |
| 1452 if (!isAnyBool || !leftOperand.isAnyBool) { |
| 1453 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); |
| 1454 } |
| 1388 if (isSomeBool || leftOperand.isSomeBool) { | 1455 if (isSomeBool || leftOperand.isSomeBool) { |
| 1389 if (isAnyBool && leftOperand.isAnyBool) { | 1456 return RESULT_BOOL; |
| 1390 return RESULT_BOOL; | |
| 1391 } | |
| 1392 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); | |
| 1393 } | 1457 } |
| 1394 Object leftValue = leftOperand.value; | 1458 Object leftValue = leftOperand.value; |
| 1395 if (leftValue is bool && ((leftValue as bool))) { | 1459 if (leftValue is bool && ((leftValue as bool))) { |
| 1396 return RESULT_TRUE; | 1460 return RESULT_TRUE; |
| 1397 } | 1461 } |
| 1398 return booleanConversion(node.rightOperand, _value); | 1462 return booleanConversion(node.rightOperand, _value); |
| 1399 } | 1463 } |
| 1400 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; | 1464 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; |
| 1401 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand
2) { | 1465 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand
2) { |
| 1402 if (isSomeNum || leftOperand2.isSomeNum) { | 1466 if (isSomeNum || leftOperand2.isSomeNum) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1564 } else if (_value is double) { | 1628 } else if (_value is double) { |
| 1565 return valueOf3(((leftValue as double)) * ((_value as double))); | 1629 return valueOf3(((leftValue as double)) * ((_value as double))); |
| 1566 } | 1630 } |
| 1567 } | 1631 } |
| 1568 return error(node); | 1632 return error(node); |
| 1569 } | 1633 } |
| 1570 bool get isNull => identical(this, RESULT_NULL); | 1634 bool get isNull => identical(this, RESULT_NULL); |
| 1571 | 1635 |
| 1572 /** | 1636 /** |
| 1573 * Return the result of applying boolean conversion to the given value. | 1637 * Return the result of applying boolean conversion to the given value. |
| 1638 * |
| 1574 * @param node the node against which errors should be reported | 1639 * @param node the node against which errors should be reported |
| 1575 * @param value the value to be converted to a boolean | 1640 * @param value the value to be converted to a boolean |
| 1576 * @return the result of applying boolean conversion to the given value | 1641 * @return the result of applying boolean conversion to the given value |
| 1577 */ | 1642 */ |
| 1578 EvaluationResultImpl booleanConversion(ASTNode node, Object value) { | 1643 EvaluationResultImpl booleanConversion(ASTNode node, Object value) { |
| 1579 if (value is bool) { | 1644 if (value is bool) { |
| 1580 if (((value as bool))) { | 1645 if (((value as bool))) { |
| 1581 return RESULT_TRUE; | 1646 return RESULT_TRUE; |
| 1582 } else { | 1647 } else { |
| 1583 return RESULT_FALSE; | 1648 return RESULT_FALSE; |
| 1584 } | 1649 } |
| 1585 } | 1650 } |
| 1586 return error(node); | 1651 return error(node); |
| 1587 } | 1652 } |
| 1588 ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_C
ONSTANT); | 1653 ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_C
ONSTANT); |
| 1589 | 1654 |
| 1590 /** | 1655 /** |
| 1591 * Return a result object representing an error associated with the given node
. | 1656 * Return a result object representing an error associated with the given node
. |
| 1657 * |
| 1592 * @param node the AST node associated with the error | 1658 * @param node the AST node associated with the error |
| 1593 * @param code the error code indicating the nature of the error | 1659 * @param code the error code indicating the nature of the error |
| 1594 * @return a result object representing an error associated with the given nod
e | 1660 * @return a result object representing an error associated with the given nod
e |
| 1595 */ | 1661 */ |
| 1596 ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code); | 1662 ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code); |
| 1597 | 1663 |
| 1598 /** | 1664 /** |
| 1599 * Checks if this result has type "bool", with known or unknown value. | 1665 * Checks if this result has type "bool", with known or unknown value. |
| 1600 */ | 1666 */ |
| 1601 bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical(
this, RESULT_FALSE); | 1667 bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical(
this, RESULT_FALSE); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1626 bool get isSomeInt => identical(this, RESULT_INT); | 1692 bool get isSomeInt => identical(this, RESULT_INT); |
| 1627 | 1693 |
| 1628 /** | 1694 /** |
| 1629 * Checks if this result has type "num" (or "int"), exact value of which we do
n't know. | 1695 * Checks if this result has type "num" (or "int"), exact value of which we do
n't know. |
| 1630 */ | 1696 */ |
| 1631 bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESUL
T_INT) || identical(this, RESULT_NUM); | 1697 bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESUL
T_INT) || identical(this, RESULT_NUM); |
| 1632 double toDouble(int value) => value.toDouble(); | 1698 double toDouble(int value) => value.toDouble(); |
| 1633 | 1699 |
| 1634 /** | 1700 /** |
| 1635 * Return an error result that is the union of the two given error results. | 1701 * Return an error result that is the union of the two given error results. |
| 1702 * |
| 1636 * @param firstError the first error to be combined | 1703 * @param firstError the first error to be combined |
| 1637 * @param secondError the second error to be combined | 1704 * @param secondError the second error to be combined |
| 1638 * @return an error result that is the union of the two given error results | 1705 * @return an error result that is the union of the two given error results |
| 1639 */ | 1706 */ |
| 1640 ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new Erro
rResult.con2(firstError, secondError); | 1707 ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new Erro
rResult.con2(firstError, secondError); |
| 1641 | 1708 |
| 1642 /** | 1709 /** |
| 1643 * Return a result object representing the given value. | 1710 * Return a result object representing the given value. |
| 1711 * |
| 1644 * @param value the value to be represented as a result object | 1712 * @param value the value to be represented as a result object |
| 1645 * @return a result object representing the given value | 1713 * @return a result object representing the given value |
| 1646 */ | 1714 */ |
| 1647 ValidResult valueOf(int value) => new ValidResult(value); | 1715 ValidResult valueOf(int value) => new ValidResult(value); |
| 1648 | 1716 |
| 1649 /** | 1717 /** |
| 1650 * Return a result object representing the given value. | 1718 * Return a result object representing the given value. |
| 1719 * |
| 1651 * @param value the value to be represented as a result object | 1720 * @param value the value to be represented as a result object |
| 1652 * @return a result object representing the given value | 1721 * @return a result object representing the given value |
| 1653 */ | 1722 */ |
| 1654 ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE; | 1723 ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE; |
| 1655 | 1724 |
| 1656 /** | 1725 /** |
| 1657 * Return a result object representing the given value. | 1726 * Return a result object representing the given value. |
| 1727 * |
| 1658 * @param value the value to be represented as a result object | 1728 * @param value the value to be represented as a result object |
| 1659 * @return a result object representing the given value | 1729 * @return a result object representing the given value |
| 1660 */ | 1730 */ |
| 1661 ValidResult valueOf3(double value) => new ValidResult(value); | 1731 ValidResult valueOf3(double value) => new ValidResult(value); |
| 1662 | 1732 |
| 1663 /** | 1733 /** |
| 1664 * Return a result object representing the given value. | 1734 * Return a result object representing the given value. |
| 1735 * |
| 1665 * @param value the value to be represented as a result object | 1736 * @param value the value to be represented as a result object |
| 1666 * @return a result object representing the given value | 1737 * @return a result object representing the given value |
| 1667 */ | 1738 */ |
| 1668 ValidResult valueOf4(String value) => new ValidResult(value); | 1739 ValidResult valueOf4(String value) => new ValidResult(value); |
| 1669 } | 1740 } |
| OLD | NEW |