Verify that constructor initializers use only potentially constant expressions.
...but don't evaluate them, because they don't have to be constants.
R=brianwilkerson@google.com
Change-Id: I5bc44a02947c1682da85c1f22b3fc28b52b13370
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97549
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index be430e0..cec76ec 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -37,18 +37,9 @@
/// The set of variables declared using '-D' on the command line.
final DeclaredVariables declaredVariables;
- /// The type representing the type 'bool'.
- InterfaceType _boolType;
-
/// The type representing the type 'int'.
InterfaceType _intType;
- /// The type representing the type 'num'.
- InterfaceType _numType;
-
- /// The type representing the type 'string'.
- InterfaceType _stringType;
-
/// The current library that is being analyzed.
final LibraryElement _currentLibrary;
@@ -62,10 +53,7 @@
{bool forAnalysisDriver: false})
: _currentLibrary = currentLibrary,
_typeSystem = currentLibrary.context.typeSystem {
- this._boolType = _typeProvider.boolType;
this._intType = _typeProvider.intType;
- this._numType = _typeProvider.numType;
- this._stringType = _typeProvider.stringType;
this._evaluationEngine = new ConstantEvaluationEngine(
_typeProvider, declaredVariables,
forAnalysisDriver: forAnalysisDriver,
@@ -415,6 +403,29 @@
}
}
+ void _reportNotPotentialConstants(AstNode node) {
+ var notPotentiallyConstants = getNotPotentiallyConstants(node);
+ if (notPotentiallyConstants.isEmpty) return;
+
+ for (var notConst in notPotentiallyConstants) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.INVALID_CONSTANT,
+ notConst,
+ );
+ }
+ }
+
+ /// Validates that all arguments in the [argumentList] are potentially
+ /// constant expressions.
+ void _reportNotPotentialConstantsArguments(ArgumentList argumentList) {
+ if (argumentList == null) {
+ return;
+ }
+ for (Expression argument in argumentList.arguments) {
+ _reportNotPotentialConstants(argument);
+ }
+ }
+
/// Validate that the given expression is a compile time constant. Return the
/// value of the compile time constant, or `null` if the expression is not a
/// compile time constant.
@@ -448,26 +459,20 @@
/// Validates that the expressions of the initializers of the given constant
/// [constructor] are all compile time constants.
void _validateConstructorInitializers(ConstructorDeclaration constructor) {
- List<ParameterElement> parameterElements =
- constructor.parameters.parameterElements;
NodeList<ConstructorInitializer> initializers = constructor.initializers;
for (ConstructorInitializer initializer in initializers) {
if (initializer is AssertInitializer) {
- _validateInitializerExpression(
- parameterElements, initializer.condition);
+ _reportNotPotentialConstants(initializer.condition);
Expression message = initializer.message;
if (message != null) {
- _validateInitializerExpression(parameterElements, message);
+ _reportNotPotentialConstants(message);
}
} else if (initializer is ConstructorFieldInitializer) {
- _validateInitializerExpression(
- parameterElements, initializer.expression);
+ _reportNotPotentialConstants(initializer.expression);
} else if (initializer is RedirectingConstructorInvocation) {
- _validateInitializerInvocationArguments(
- parameterElements, initializer.argumentList);
+ _reportNotPotentialConstantsArguments(initializer.argumentList);
} else if (initializer is SuperConstructorInvocation) {
- _validateInitializerInvocationArguments(
- parameterElements, initializer.argumentList);
+ _reportNotPotentialConstantsArguments(initializer.argumentList);
}
}
}
@@ -540,107 +545,6 @@
}
}
}
-
- /// Validates that the given expression is a compile time constant.
- ///
- /// @param parameterElements the elements of parameters of constant
- /// constructor, they are considered as a valid potentially constant
- /// expressions
- /// @param expression the expression to validate
- void _validateInitializerExpression(
- List<ParameterElement> parameterElements, Expression expression) {
- RecordingErrorListener errorListener = new RecordingErrorListener();
- ErrorReporter subErrorReporter =
- new ErrorReporter(errorListener, _errorReporter.source);
- DartObjectImpl result = expression.accept(
- new _ConstantVerifier_validateInitializerExpression(_typeSystem,
- _evaluationEngine, subErrorReporter, this, parameterElements));
- _reportErrors(errorListener.errors,
- CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER);
- if (result != null) {
- _reportErrorIfFromDeferredLibrary(
- expression,
- CompileTimeErrorCode
- .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY);
- }
- }
-
- /// Validates that all of the arguments of a constructor initializer are
- /// compile time constants.
- ///
- /// @param parameterElements the elements of parameters of constant
- /// constructor, they are considered as a valid potentially constant
- /// expressions
- /// @param argumentList the argument list to validate
- void _validateInitializerInvocationArguments(
- List<ParameterElement> parameterElements, ArgumentList argumentList) {
- if (argumentList == null) {
- return;
- }
- for (Expression argument in argumentList.arguments) {
- _validateInitializerExpression(parameterElements, argument);
- }
- }
-}
-
-class _ConstantVerifier_validateInitializerExpression extends ConstantVisitor {
- final TypeSystem typeSystem;
- final ConstantVerifier verifier;
-
- List<ParameterElement> parameterElements;
-
- _ConstantVerifier_validateInitializerExpression(
- this.typeSystem,
- ConstantEvaluationEngine evaluationEngine,
- ErrorReporter errorReporter,
- this.verifier,
- this.parameterElements)
- : super(evaluationEngine, errorReporter);
-
- @override
- DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) {
- Element element = node.staticElement;
- int length = parameterElements.length;
- for (int i = 0; i < length; i++) {
- ParameterElement parameterElement = parameterElements[i];
- if (identical(parameterElement, element) && parameterElement != null) {
- DartType type = parameterElement.type;
- if (type != null) {
- if (type.isDynamic) {
- return new DartObjectImpl(
- verifier._typeProvider.objectType, DynamicState.DYNAMIC_STATE);
- } else if (typeSystem.isSubtypeOf(type, verifier._boolType)) {
- return new DartObjectImpl(
- verifier._typeProvider.boolType, BoolState.UNKNOWN_VALUE);
- } else if (typeSystem.isSubtypeOf(
- type, verifier._typeProvider.doubleType)) {
- return new DartObjectImpl(
- verifier._typeProvider.doubleType, DoubleState.UNKNOWN_VALUE);
- } else if (typeSystem.isSubtypeOf(type, verifier._intType)) {
- return new DartObjectImpl(
- verifier._typeProvider.intType, IntState.UNKNOWN_VALUE);
- } else if (typeSystem.isSubtypeOf(type, verifier._numType)) {
- return new DartObjectImpl(
- verifier._typeProvider.numType, NumState.UNKNOWN_VALUE);
- } else if (typeSystem.isSubtypeOf(type, verifier._stringType)) {
- return new DartObjectImpl(
- verifier._typeProvider.stringType, StringState.UNKNOWN_VALUE);
- }
- //
- // We don't test for other types of objects (such as List, Map,
- // Function or Type) because there are no operations allowed on such
- // types other than '==' and '!=', which means that we don't need to
- // know the type when there is no specific data about the state of
- // such objects.
- //
- }
- return new DartObjectImpl(
- type is InterfaceType ? type : verifier._typeProvider.objectType,
- GenericState.UNKNOWN_VALUE);
- }
- }
- return super.visitSimpleIdentifier(node);
- }
}
class _ConstLiteralVerifier {
diff --git a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
index 9570f5b..3d091bd 100644
--- a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
+++ b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
@@ -100,6 +100,13 @@
return;
}
+ if (node is AdjacentStrings) {
+ for (var string in node.strings) {
+ collect(string);
+ }
+ return;
+ }
+
if (node is StringInterpolation) {
for (var component in node.elements) {
if (component is InterpolationExpression) {
@@ -133,6 +140,10 @@
return _methodInvocation(node);
}
+ if (node is NamedExpression) {
+ return collect(node.expression);
+ }
+
if (node is BinaryExpression) {
collect(node.leftOperand);
collect(node.rightOperand);
@@ -214,9 +225,10 @@
return;
}
if (element is MethodElement && element.isStatic) {
- if (_isConstantTypeName(node.prefix)) {
- return;
+ if (!_isConstantTypeName(node.prefix)) {
+ nodes.add(node);
}
+ return;
}
}
@@ -250,6 +262,9 @@
if (element is FunctionElement) {
return;
}
+ if (element is MethodElement && element.isStatic) {
+ return;
+ }
nodes.add(node);
}
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index c95f192..ced02d0 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -151,6 +151,10 @@
return _node(search, (n) => n is MixinDeclaration);
}
+ NamedExpression namedExpression(String search) {
+ return _node(search, (n) => n is NamedExpression);
+ }
+
ParenthesizedExpression parenthesized(String search) {
return _node(search, (n) => n is ParenthesizedExpression);
}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 43b69e7..a41a179 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -1046,9 +1046,15 @@
verify([source]);
}
- test_constEvalTypeBool_binary() async {
- await _check_constEvalTypeBool_withParameter_binary("p && ''");
- await _check_constEvalTypeBool_withParameter_binary("p || ''");
+ test_constEvalTypeBool_binary_and() async {
+ Source source = addSource(r'''
+const _ = true && '';
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [
+ CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
+ StaticTypeWarningCode.NON_BOOL_OPERAND,
+ ]);
}
test_constEvalTypeBool_binary_leftTrue() async {
@@ -1059,6 +1065,17 @@
verify([source]);
}
+ test_constEvalTypeBool_binary_or() async {
+ Source source = addSource(r'''
+const _ = false || '';
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [
+ CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
+ StaticTypeWarningCode.NON_BOOL_OPERAND,
+ ]);
+ }
+
test_constEvalTypeBool_logicalOr_trueLeftOperand() async {
Source source = addSource(r'''
class C {
@@ -1077,10 +1094,10 @@
class A {
const A();
}
-class B {
- final a;
- const B(num p) : a = p == const A();
-}''');
+
+const num a = 0;
+const _ = a == const A();
+''');
await computeAnalysisResult(source);
assertErrors(
source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
@@ -1092,10 +1109,10 @@
class A {
const A();
}
-class B {
- final a;
- const B(String p) : a = p != const A();
-}''');
+
+const num a = 0;
+const _ = a != const A();
+''');
await computeAnalysisResult(source);
assertErrors(
source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
@@ -1103,24 +1120,24 @@
}
test_constEvalTypeInt_binary() async {
- await _check_constEvalTypeBoolOrInt_withParameter_binary("p ^ ''");
- await _check_constEvalTypeBoolOrInt_withParameter_binary("p & ''");
- await _check_constEvalTypeBoolOrInt_withParameter_binary("p | ''");
- await _check_constEvalTypeInt_withParameter_binary("p >> ''");
- await _check_constEvalTypeInt_withParameter_binary("p << ''");
+ await _check_constEvalTypeBoolOrInt_binary("a ^ ''");
+ await _check_constEvalTypeBoolOrInt_binary("a & ''");
+ await _check_constEvalTypeBoolOrInt_binary("a | ''");
+ await _check_constEvalTypeInt_binary("a >> ''");
+ await _check_constEvalTypeInt_binary("a << ''");
}
test_constEvalTypeNum_binary() async {
- await _check_constEvalTypeNum_withParameter_binary("p + ''");
- await _check_constEvalTypeNum_withParameter_binary("p - ''");
- await _check_constEvalTypeNum_withParameter_binary("p * ''");
- await _check_constEvalTypeNum_withParameter_binary("p / ''");
- await _check_constEvalTypeNum_withParameter_binary("p ~/ ''");
- await _check_constEvalTypeNum_withParameter_binary("p > ''");
- await _check_constEvalTypeNum_withParameter_binary("p < ''");
- await _check_constEvalTypeNum_withParameter_binary("p >= ''");
- await _check_constEvalTypeNum_withParameter_binary("p <= ''");
- await _check_constEvalTypeNum_withParameter_binary("p % ''");
+ await _check_constEvalTypeNum_binary("a + ''");
+ await _check_constEvalTypeNum_binary("a - ''");
+ await _check_constEvalTypeNum_binary("a * ''");
+ await _check_constEvalTypeNum_binary("a / ''");
+ await _check_constEvalTypeNum_binary("a ~/ ''");
+ await _check_constEvalTypeNum_binary("a > ''");
+ await _check_constEvalTypeNum_binary("a < ''");
+ await _check_constEvalTypeNum_binary("a >= ''");
+ await _check_constEvalTypeNum_binary("a <= ''");
+ await _check_constEvalTypeNum_binary("a % ''");
}
test_constFormalParameter_fieldFormalParameter() async {
@@ -4292,8 +4309,7 @@
const A(int i) : assert(i.isNegative);
}''');
await computeAnalysisResult(source);
- assertErrors(
- source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTANT]);
verify([source]);
}
@@ -4303,64 +4319,7 @@
const A(int i) : assert(i < 0, 'isNegative = ${i.isNegative}');
}''');
await computeAnalysisResult(source);
- assertErrors(
- source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
- verify([source]);
- }
-
- test_nonConstValueInInitializer_binary_notBool_left() async {
- Source source = addSource(r'''
-class A {
- final bool a;
- const A(String p) : a = p && true;
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
- StaticTypeWarningCode.NON_BOOL_OPERAND
- ]);
- verify([source]);
- }
-
- test_nonConstValueInInitializer_binary_notBool_right() async {
- Source source = addSource(r'''
-class A {
- final bool a;
- const A(String p) : a = true && p;
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
- StaticTypeWarningCode.NON_BOOL_OPERAND
- ]);
- verify([source]);
- }
-
- test_nonConstValueInInitializer_binary_notInt() async {
- Source source = addSource(r'''
-class A {
- final int a;
- const A(String p) : a = 5 & p;
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- test_nonConstValueInInitializer_binary_notNum() async {
- Source source = addSource(r'''
-class A {
- final int a;
- const A(String p) : a = 5 + p;
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTANT]);
verify([source]);
}
@@ -4372,8 +4331,7 @@
const A() : a = C;
}''');
await computeAnalysisResult(source);
- assertErrors(
- source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTANT]);
verify([source]);
}
@@ -4391,7 +4349,7 @@
// ought to be suppressed. Or not?
await computeAnalysisResult(source);
assertErrors(source, [
- CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
+ CompileTimeErrorCode.INVALID_CONSTANT,
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION
]);
verify([source]);
@@ -4424,8 +4382,7 @@
const A() : this.named(C);
}''');
await computeAnalysisResult(source);
- assertErrors(
- source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTANT]);
verify([source]);
}
@@ -4439,8 +4396,7 @@
const B() : super(C);
}''');
await computeAnalysisResult(source);
- assertErrors(
- source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+ assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTANT]);
verify([source]);
}
@@ -4457,8 +4413,7 @@
const A() : x = a.c;
}'''
], <ErrorCode>[
- CompileTimeErrorCode
- .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+ CompileTimeErrorCode.INVALID_CONSTANT
]);
}
@@ -4475,8 +4430,7 @@
const A() : x = a.c + 1;
}'''
], <ErrorCode>[
- CompileTimeErrorCode
- .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+ CompileTimeErrorCode.INVALID_CONSTANT
]);
}
@@ -4493,8 +4447,7 @@
const A() : this.named(a.c);
}'''
], <ErrorCode>[
- CompileTimeErrorCode
- .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+ CompileTimeErrorCode.INVALID_CONSTANT
]);
}
@@ -4513,8 +4466,7 @@
const B() : super(a.c);
}'''
], <ErrorCode>[
- CompileTimeErrorCode
- .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+ CompileTimeErrorCode.INVALID_CONSTANT
]);
}
@@ -6169,28 +6121,11 @@
}
}
- Future<void> _check_constEvalTypeBool_withParameter_binary(
- String expr) async {
+ Future<void> _check_constEvalTypeBoolOrInt_binary(String expr) async {
Source source = addSource('''
-class A {
- final a;
- const A(bool p) : a = $expr;
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
- StaticTypeWarningCode.NON_BOOL_OPERAND
- ]);
- verify([source]);
- }
-
- Future<void> _check_constEvalTypeBoolOrInt_withParameter_binary(
- String expr) async {
- Source source = addSource('''
-class A {
- final a;
- const A(int p) : a = $expr;
-}''');
+const int a = 0;
+const _ = $expr;
+''');
await computeAnalysisResult(source);
assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT,
@@ -6199,12 +6134,11 @@
verify([source]);
}
- Future<void> _check_constEvalTypeInt_withParameter_binary(String expr) async {
+ Future<void> _check_constEvalTypeInt_binary(String expr) async {
Source source = addSource('''
-class A {
- final a;
- const A(int p) : a = $expr;
-}''');
+const int a = 0;
+const _ = $expr;
+''');
await computeAnalysisResult(source);
assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
@@ -6213,12 +6147,11 @@
verify([source]);
}
- Future<void> _check_constEvalTypeNum_withParameter_binary(String expr) async {
+ Future<void> _check_constEvalTypeNum_binary(String expr) async {
Source source = addSource('''
-class A {
- final a;
- const A(num p) : a = $expr;
-}''');
+const num a = 0;
+const _ = $expr;
+''');
await computeAnalysisResult(source);
assertErrors(source, [
CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 525f735..b116529 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -2668,17 +2668,15 @@
test_invalid_const_as() async {
addTestFile(r'''
-class A {
- final int a;
- const A(num b) : a = b as int;
-}
+const num a = 1.2;
+const int b = a as int;
''');
await resolveTestFile();
expect(result.errors, isNotEmpty);
- var bRef = findNode.simple('b as int');
- assertElement(bRef, findElement.parameter('b'));
- assertType(bRef, 'num');
+ var aRef = findNode.simple('a as int');
+ assertElement(aRef, findElement.topGet('a'));
+ assertType(aRef, 'num');
assertTypeName(findNode.typeName('int;'), intElement, 'int');
}
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index c93744c..b3a1749 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -284,6 +284,19 @@
expect(result.type, typeProvider.nullType);
}
+ test_visitAsExpression_potentialConst() async {
+ await assertNoErrorsInCode('''
+class A {
+ const A();
+}
+
+class MyClass {
+ final A a;
+ const MyClass(Object o) : a = o as A;
+}
+''');
+ }
+
test_visitBinaryExpression_and_bool_known_known() async {
await _resolveTestCode('''
const c = false & true;
diff --git a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
index c74afb8..c26a62f 100644
--- a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
@@ -139,6 +139,12 @@
@reflectiveTest
class PotentiallyConstantTest extends DriverResolutionTest {
+ test_adjacentStrings() async {
+ await _assertConst(r'''
+var x = 'a' 'b';
+''', () => _xInitializer());
+ }
+
test_asExpression() async {
await _assertConst(r'''
const a = 0;
@@ -385,6 +391,14 @@
''', () => _xInitializer(), () => [findNode.methodInvocation('a.foo()')]);
}
+ test_namedExpression() async {
+ await _assertConst(r'''
+void f({a}) {}
+
+var x = f(a: 0);
+''', () => findNode.namedExpression('a: 0'));
+ }
+
test_parenthesizedExpression_const() async {
await _assertConst(r'''
const a = 0;
@@ -406,16 +420,6 @@
''', () => _xInitializer(), () => [findNode.postfix('a++')]);
}
- test_prefixedIdentifier_importPrefix() async {
- newFile('/test/lib/a.dart', content: r'''
-const a = 0;
-''');
- await _assertConst(r'''
-import 'a.dart' as p;
-var x = p.a + 1;
-''', () => _xInitializer());
- }
-
test_prefixedIdentifier_importPrefix_deferred() async {
newFile('/test/lib/a.dart', content: r'''
const a = 0;
@@ -426,6 +430,26 @@
''', () => _xInitializer(), () => [findNode.prefixed('p.a')]);
}
+ test_prefixedIdentifier_importPrefix_function() async {
+ newFile('/test/lib/a.dart', content: r'''
+void f() {}
+''');
+ await _assertConst(r'''
+import 'a.dart' as p;
+var x = p.f;
+''', () => _xInitializer());
+ }
+
+ test_prefixedIdentifier_importPrefix_topVar() async {
+ newFile('/test/lib/a.dart', content: r'''
+const a = 0;
+''');
+ await _assertConst(r'''
+import 'a.dart' as p;
+var x = p.a + 1;
+''', () => _xInitializer());
+ }
+
test_prefixedIdentifier_length_const() async {
await _assertConst(r'''
const a = 'abc';
@@ -688,6 +712,18 @@
);
}
+ test_simpleIdentifier_method_static() async {
+ await _assertConst(r'''
+class A {
+ static m() {};
+
+ final Object f;
+
+ const A() : f = m; // ref
+}
+''', () => findNode.simple('m; // ref'));
+ }
+
test_simpleIdentifier_parameterOfConstConstructor_inBody() async {
await _assertNotConst(
r'''
@@ -753,6 +789,12 @@
);
}
+ test_stringLiteral() async {
+ await _assertConst(r'''
+var x = 'a';
+''', () => _xInitializer());
+ }
+
_assertConst(String code, AstNode Function() getNode) async {
addTestFile(code);
await resolveTestFile();
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index 4fde7c2..31867db 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -143,7 +143,6 @@
''');
await resolveTestFile();
assertTestErrors([
- CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
CompileTimeErrorCode.CONST_NOT_INITIALIZED,
CompileTimeErrorCode.CONST_NOT_INITIALIZED,
]);