@@ -343,19 +343,11 @@ class ConstantsTransformer extends Transformer {
343343
344344 tryEvaluateWithContext (TreeNode treeContext, Expression node) {
345345 if (treeContext == node) {
346- try {
347- return constantEvaluator.evaluate (node);
348- } on _AbortCurrentEvaluation catch (_) {
349- return null ;
350- }
346+ return constantEvaluator.evaluate (node);
351347 }
352348
353349 return constantEvaluator.runInsideContext (treeContext, () {
354- try {
355- return constantEvaluator.evaluate (node);
356- } on _AbortCurrentEvaluation catch (_) {
357- return null ;
358- }
350+ return constantEvaluator.evaluate (node);
359351 });
360352 }
361353}
@@ -387,7 +379,18 @@ class ConstantEvaluator extends RecursiveVisitor {
387379 nodeCache = < Node , Constant > {};
388380
389381 /// Evaluates [node] and possibly cache the evaluation result.
382+ /// Returns `null` if expression can't be evaluated.
390383 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) {
391394 if (node == null ) return nullConstant;
392395 if (env.isEmpty) {
393396 // We only try to evaluate the same [node] *once* within an empty
@@ -572,27 +575,30 @@ class ConstantEvaluator extends RecursiveVisitor {
572575 function.positionalParameters[i];
573576 final Constant value = (i < positionalArguments.length)
574577 ? positionalArguments[i]
575- : evaluate (parameter.initializer);
578+ : _evaluateSubexpression (parameter.initializer);
576579 env.addVariableValue (parameter, value);
577580 }
578581 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);
581584 env.addVariableValue (parameter, value);
582585 }
583586
584587 // Step 2) Run all initializers (including super calls) with environment setup.
585588 for (final Field field in klass.fields) {
586589 if (! field.isStatic) {
587- instanceBuilder.setFieldValue (field, evaluate (field.initializer));
590+ instanceBuilder.setFieldValue (
591+ field, _evaluateSubexpression (field.initializer));
588592 }
589593 }
590594 for (final Initializer init in constructor.initializers) {
591595 if (init is FieldInitializer ) {
592- instanceBuilder.setFieldValue (init.field, evaluate (init.value));
596+ instanceBuilder.setFieldValue (
597+ init.field, _evaluateSubexpression (init.value));
593598 } else if (init is LocalInitializer ) {
594599 final VariableDeclaration variable = init.variable;
595- env.addVariableValue (variable, evaluate (variable.initializer));
600+ env.addVariableValue (
601+ variable, _evaluateSubexpression (variable.initializer));
596602 } else if (init is SuperInitializer ) {
597603 handleConstructorInvocation (
598604 init.target,
@@ -653,7 +659,7 @@ class ConstantEvaluator extends RecursiveVisitor {
653659 // We have no support for generic method invocation atm.
654660 assert (node.arguments.named.isEmpty);
655661
656- final Constant receiver = evaluate (node.receiver);
662+ final Constant receiver = _evaluateSubexpression (node.receiver);
657663 final List <Constant > arguments =
658664 evaluatePositionalArguments (node.arguments);
659665
@@ -810,13 +816,13 @@ class ConstantEvaluator extends RecursiveVisitor {
810816 }
811817
812818 visitLogicalExpression (LogicalExpression node) {
813- final Constant left = evaluate (node.left);
819+ final Constant left = _evaluateSubexpression (node.left);
814820 switch (node.operator ) {
815821 case '||' :
816822 if (left is BoolConstant ) {
817823 if (left.value) return trueConstant;
818824
819- final Constant right = evaluate (node.right);
825+ final Constant right = _evaluateSubexpression (node.right);
820826 if (right is BoolConstant ) {
821827 return right;
822828 }
@@ -836,7 +842,7 @@ class ConstantEvaluator extends RecursiveVisitor {
836842 if (left is BoolConstant ) {
837843 if (! left.value) return falseConstant;
838844
839- final Constant right = evaluate (node.right);
845+ final Constant right = _evaluateSubexpression (node.right);
840846 if (right is BoolConstant ) {
841847 return right;
842848 }
@@ -853,7 +859,9 @@ class ConstantEvaluator extends RecursiveVisitor {
853859 contextChain, node, left, '${node .operator }' );
854860 throw const _AbortCurrentEvaluation ();
855861 case '??' :
856- return (left is ! NullConstant ) ? left : evaluate (node.right);
862+ return (left is ! NullConstant )
863+ ? left
864+ : _evaluateSubexpression (node.right);
857865 default :
858866 errorReporter.invalidMethodInvocation (
859867 contextChain, node, left, '${node .operator }' );
@@ -862,11 +870,11 @@ class ConstantEvaluator extends RecursiveVisitor {
862870 }
863871
864872 visitConditionalExpression (ConditionalExpression node) {
865- final Constant constant = evaluate (node.condition);
873+ final Constant constant = _evaluateSubexpression (node.condition);
866874 if (constant == trueConstant) {
867- return evaluate (node.then);
875+ return _evaluateSubexpression (node.then);
868876 } else if (constant == falseConstant) {
869- return evaluate (node.otherwise);
877+ return _evaluateSubexpression (node.otherwise);
870878 } else {
871879 errorReporter.invalidDartType (
872880 contextChain, node, constant, typeEnvironment.boolType);
@@ -885,7 +893,7 @@ class ConstantEvaluator extends RecursiveVisitor {
885893 throw 'Could not evaluate field get ${node .name } on incomplete instance' ;
886894 }
887895
888- final Constant receiver = evaluate (node.receiver);
896+ final Constant receiver = _evaluateSubexpression (node.receiver);
889897 if (receiver is StringConstant && node.name.name == 'length' ) {
890898 return canonicalize (new IntConstant (receiver.value.length));
891899 } else if (receiver is InstanceConstant ) {
@@ -899,7 +907,8 @@ class ConstantEvaluator extends RecursiveVisitor {
899907 }
900908
901909 visitLet (Let node) {
902- env.addVariableValue (node.variable, evaluate (node.variable.initializer));
910+ env.addVariableValue (
911+ node.variable, _evaluateSubexpression (node.variable.initializer));
903912 return node.body.accept (this );
904913 }
905914
@@ -920,7 +929,7 @@ class ConstantEvaluator extends RecursiveVisitor {
920929 return constant;
921930 }
922931 if (variable.isConst) {
923- return evaluate (variable.initializer);
932+ return _evaluateSubexpression (variable.initializer);
924933 }
925934 throw new Exception ('The front-end should ensure we do not encounter a '
926935 'variable get of a non-const variable.' );
@@ -931,7 +940,7 @@ class ConstantEvaluator extends RecursiveVisitor {
931940 final Member target = node.target;
932941 if (target is Field && target.isConst) {
933942 return runInsideContext (target, () {
934- return evaluate (target.initializer);
943+ return _evaluateSubexpression (target.initializer);
935944 });
936945 } else if (target is Procedure ) {
937946 if (target.kind == ProcedureKind .Method ) {
@@ -1021,7 +1030,7 @@ class ConstantEvaluator extends RecursiveVisitor {
10211030 }
10221031
10231032 visitInstantiation (Instantiation node) {
1024- final Constant constant = evaluate (node.expression);
1033+ final Constant constant = _evaluateSubexpression (node.expression);
10251034 if (constant is TearOffConstant ) {
10261035 if (node.typeArguments.length ==
10271036 constant.procedure.function.typeParameters.length) {
0 commit comments