@@ -343,19 +343,11 @@ class ConstantsTransformer extends Transformer {
343
343
344
344
tryEvaluateWithContext (TreeNode treeContext, Expression node) {
345
345
if (treeContext == node) {
346
- try {
347
- return constantEvaluator.evaluate (node);
348
- } on _AbortCurrentEvaluation catch (_) {
349
- return null ;
350
- }
346
+ return constantEvaluator.evaluate (node);
351
347
}
352
348
353
349
return constantEvaluator.runInsideContext (treeContext, () {
354
- try {
355
- return constantEvaluator.evaluate (node);
356
- } on _AbortCurrentEvaluation catch (_) {
357
- return null ;
358
- }
350
+ return constantEvaluator.evaluate (node);
359
351
});
360
352
}
361
353
}
@@ -387,7 +379,18 @@ class ConstantEvaluator extends RecursiveVisitor {
387
379
nodeCache = < Node , Constant > {};
388
380
389
381
/// Evaluates [node] and possibly cache the evaluation result.
382
+ /// Returns `null` if expression can't be evaluated.
390
383
Constant evaluate (Expression node) {
384
+ try {
385
+ return _evaluateSubexpression (node);
386
+ } on _AbortCurrentEvaluation catch (_) {
387
+ return null ;
388
+ }
389
+ }
390
+
391
+ /// Evaluates [node] and possibly cache the evaluation result.
392
+ /// @throws _AbortCurrentEvaluation if expression can't be evaluated.
393
+ Constant _evaluateSubexpression (Expression node) {
391
394
if (node == null ) return nullConstant;
392
395
if (env.isEmpty) {
393
396
// We only try to evaluate the same [node] *once* within an empty
@@ -572,27 +575,30 @@ class ConstantEvaluator extends RecursiveVisitor {
572
575
function.positionalParameters[i];
573
576
final Constant value = (i < positionalArguments.length)
574
577
? positionalArguments[i]
575
- : evaluate (parameter.initializer);
578
+ : _evaluateSubexpression (parameter.initializer);
576
579
env.addVariableValue (parameter, value);
577
580
}
578
581
for (final VariableDeclaration parameter in function.namedParameters) {
579
- final Constant value =
580
- namedArguments[parameter.name] ?? evaluate (parameter.initializer);
582
+ final Constant value = namedArguments[parameter.name] ??
583
+ _evaluateSubexpression (parameter.initializer);
581
584
env.addVariableValue (parameter, value);
582
585
}
583
586
584
587
// Step 2) Run all initializers (including super calls) with environment setup.
585
588
for (final Field field in klass.fields) {
586
589
if (! field.isStatic) {
587
- instanceBuilder.setFieldValue (field, evaluate (field.initializer));
590
+ instanceBuilder.setFieldValue (
591
+ field, _evaluateSubexpression (field.initializer));
588
592
}
589
593
}
590
594
for (final Initializer init in constructor.initializers) {
591
595
if (init is FieldInitializer ) {
592
- instanceBuilder.setFieldValue (init.field, evaluate (init.value));
596
+ instanceBuilder.setFieldValue (
597
+ init.field, _evaluateSubexpression (init.value));
593
598
} else if (init is LocalInitializer ) {
594
599
final VariableDeclaration variable = init.variable;
595
- env.addVariableValue (variable, evaluate (variable.initializer));
600
+ env.addVariableValue (
601
+ variable, _evaluateSubexpression (variable.initializer));
596
602
} else if (init is SuperInitializer ) {
597
603
handleConstructorInvocation (
598
604
init.target,
@@ -653,7 +659,7 @@ class ConstantEvaluator extends RecursiveVisitor {
653
659
// We have no support for generic method invocation atm.
654
660
assert (node.arguments.named.isEmpty);
655
661
656
- final Constant receiver = evaluate (node.receiver);
662
+ final Constant receiver = _evaluateSubexpression (node.receiver);
657
663
final List <Constant > arguments =
658
664
evaluatePositionalArguments (node.arguments);
659
665
@@ -810,13 +816,13 @@ class ConstantEvaluator extends RecursiveVisitor {
810
816
}
811
817
812
818
visitLogicalExpression (LogicalExpression node) {
813
- final Constant left = evaluate (node.left);
819
+ final Constant left = _evaluateSubexpression (node.left);
814
820
switch (node.operator ) {
815
821
case '||' :
816
822
if (left is BoolConstant ) {
817
823
if (left.value) return trueConstant;
818
824
819
- final Constant right = evaluate (node.right);
825
+ final Constant right = _evaluateSubexpression (node.right);
820
826
if (right is BoolConstant ) {
821
827
return right;
822
828
}
@@ -836,7 +842,7 @@ class ConstantEvaluator extends RecursiveVisitor {
836
842
if (left is BoolConstant ) {
837
843
if (! left.value) return falseConstant;
838
844
839
- final Constant right = evaluate (node.right);
845
+ final Constant right = _evaluateSubexpression (node.right);
840
846
if (right is BoolConstant ) {
841
847
return right;
842
848
}
@@ -853,7 +859,9 @@ class ConstantEvaluator extends RecursiveVisitor {
853
859
contextChain, node, left, '${node .operator }' );
854
860
throw const _AbortCurrentEvaluation ();
855
861
case '??' :
856
- return (left is ! NullConstant ) ? left : evaluate (node.right);
862
+ return (left is ! NullConstant )
863
+ ? left
864
+ : _evaluateSubexpression (node.right);
857
865
default :
858
866
errorReporter.invalidMethodInvocation (
859
867
contextChain, node, left, '${node .operator }' );
@@ -862,11 +870,11 @@ class ConstantEvaluator extends RecursiveVisitor {
862
870
}
863
871
864
872
visitConditionalExpression (ConditionalExpression node) {
865
- final Constant constant = evaluate (node.condition);
873
+ final Constant constant = _evaluateSubexpression (node.condition);
866
874
if (constant == trueConstant) {
867
- return evaluate (node.then);
875
+ return _evaluateSubexpression (node.then);
868
876
} else if (constant == falseConstant) {
869
- return evaluate (node.otherwise);
877
+ return _evaluateSubexpression (node.otherwise);
870
878
} else {
871
879
errorReporter.invalidDartType (
872
880
contextChain, node, constant, typeEnvironment.boolType);
@@ -885,7 +893,7 @@ class ConstantEvaluator extends RecursiveVisitor {
885
893
throw 'Could not evaluate field get ${node .name } on incomplete instance' ;
886
894
}
887
895
888
- final Constant receiver = evaluate (node.receiver);
896
+ final Constant receiver = _evaluateSubexpression (node.receiver);
889
897
if (receiver is StringConstant && node.name.name == 'length' ) {
890
898
return canonicalize (new IntConstant (receiver.value.length));
891
899
} else if (receiver is InstanceConstant ) {
@@ -899,7 +907,8 @@ class ConstantEvaluator extends RecursiveVisitor {
899
907
}
900
908
901
909
visitLet (Let node) {
902
- env.addVariableValue (node.variable, evaluate (node.variable.initializer));
910
+ env.addVariableValue (
911
+ node.variable, _evaluateSubexpression (node.variable.initializer));
903
912
return node.body.accept (this );
904
913
}
905
914
@@ -920,7 +929,7 @@ class ConstantEvaluator extends RecursiveVisitor {
920
929
return constant;
921
930
}
922
931
if (variable.isConst) {
923
- return evaluate (variable.initializer);
932
+ return _evaluateSubexpression (variable.initializer);
924
933
}
925
934
throw new Exception ('The front-end should ensure we do not encounter a '
926
935
'variable get of a non-const variable.' );
@@ -931,7 +940,7 @@ class ConstantEvaluator extends RecursiveVisitor {
931
940
final Member target = node.target;
932
941
if (target is Field && target.isConst) {
933
942
return runInsideContext (target, () {
934
- return evaluate (target.initializer);
943
+ return _evaluateSubexpression (target.initializer);
935
944
});
936
945
} else if (target is Procedure ) {
937
946
if (target.kind == ProcedureKind .Method ) {
@@ -1021,7 +1030,7 @@ class ConstantEvaluator extends RecursiveVisitor {
1021
1030
}
1022
1031
1023
1032
visitInstantiation (Instantiation node) {
1024
- final Constant constant = evaluate (node.expression);
1033
+ final Constant constant = _evaluateSubexpression (node.expression);
1025
1034
if (constant is TearOffConstant ) {
1026
1035
if (node.typeArguments.length ==
1027
1036
constant.procedure.function.typeParameters.length) {
0 commit comments