Version 2.15.0-145.0.dev
Merge commit '5e0f4c24c554352fd1da953bf64532c207a04ef3' into 'dev'
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index 2fb02e1..eaad3c1 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -28,7 +28,7 @@
}
expect(
typeArguments.map(
- (arg) => arg.toTypeValue()!.getDisplayString(withNullability: false)),
+ (arg) => arg.toTypeValue()!.getDisplayString(withNullability: true)),
equals(typeArgumentNames),
);
}
@@ -226,100 +226,6 @@
await _assertValueBool(false, "'a' == 'b'");
}
- test_functionReference_explicitTypeArgs_badBound() async {
- var result = await _getExpressionValue("foo<String>", context: '''
-void foo<T extends num>(T a) {}
-''');
- expect(result.isValid, isTrue);
- DartObject value = result.value!;
- assertType(value.type, 'void Function(String)');
- assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
- assertTypeArguments(value, ['String']);
- }
-
- test_functionReference_explicitTypeArgs_differentElements() async {
- var result = await _getExpressionValue("(b ? foo : bar)<int>", context: '''
-const b = true;
-void foo<T>(String a, T b) {}
-void bar<T>(T a, String b) {}
-''');
- expect(result.isValid, isTrue);
- DartObject value = result.value!;
- assertType(value.type, 'void Function(String, int)');
- assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
- assertTypeArguments(value, ['int']);
- }
-
- test_functionReference_explicitTypeArgs_identifier() async {
- // TODO(srawlins): Add test where the type argument is a type variable.
- var result = await _getExpressionValue("foo<int>", context: '''
-void foo<T>(T a) {}
-''');
- expect(result.isValid, isTrue);
- var value = result.value!;
- assertType(value.type, 'void Function(int)');
- assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
- assertTypeArguments(value, ['int']);
- }
-
- test_functionReference_explicitTypeArgs_nonIdentifier() async {
- var result = await _getExpressionValue("(b ? foo : bar)<int>", context: '''
-const b = true;
-void foo<T>(T a) {}
-void bar<T>(T a) {}
-''');
- expect(result.isValid, isTrue);
- var value = result.value!;
- assertType(value.type, 'void Function(int)');
- assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
- assertTypeArguments(value, ['int']);
- }
-
- test_functionReference_explicitTypeArgs_notAType() async {
- var result = await _getExpressionValue("foo<true>", context: '''
-void foo<T>(T a) {}
-''');
- expect(result.isValid, isFalse);
- }
-
- test_functionReference_explicitTypeArgs_tooFew() async {
- var result = await _getExpressionValue("foo<int>", context: '''
-void foo<T, U>(T a) {}
-''');
- expect(result.isValid, isFalse);
- }
-
- test_functionReference_explicitTypeArgs_tooMany() async {
- var result = await _getExpressionValue("foo<int, int>", context: '''
-void foo<T>(T a) {}
-''');
- expect(result.isValid, isFalse);
- }
-
- test_functionReference_uninstantiated_identifier() async {
- var result = await _getExpressionValue("foo", context: '''
-void foo<T>(T a) {}
-''');
- expect(result.isValid, isTrue);
- DartObject value = result.value!;
- assertType(value.type, 'void Function<T>(T)');
- assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
- assertTypeArguments(value, null);
- }
-
- test_functionReference_uninstantiated_nonIdentifier() async {
- var result = await _getExpressionValue("b ? foo : bar", context: '''
-const b = true;
-void foo<T>(T a) {}
-void bar<T>(T a) {}
-''');
- expect(result.isValid, isTrue);
- DartObject value = result.value!;
- assertType(value.type, 'void Function<T>(T)');
- assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
- assertTypeArguments(value, null);
- }
-
test_greaterThan_int_int() async {
await _assertValueBool(false, "2 > 3");
}
@@ -328,51 +234,6 @@
await _assertValueBool(false, "2 >= 3");
}
- test_identical_functionReference_explicitTypeArgs_differentElements() async {
- var result =
- await _getExpressionValue("identical(foo<int>, bar<int>)", context: '''
-void foo<T>(T a) {}
-void bar<T>(T a) {}
-''');
- expect(result.isValid, isTrue);
- DartObject value = result.value!;
- assertType(value.type, 'bool');
- expect(value.toBoolValue(), false);
- }
-
- test_identical_functionReference_explicitTypeArgs_differentTypeArgs() async {
- var result = await _getExpressionValue("identical(foo<int>, foo<String>)",
- context: '''
-void foo<T>(T a) {}
-''');
- expect(result.isValid, isTrue);
- DartObject value = result.value!;
- assertType(value.type, 'bool');
- expect(value.toBoolValue(), false);
- }
-
- test_identical_functionReference_explicitTypeArgs_sameElement() async {
- var result =
- await _getExpressionValue("identical(foo<int>, foo<int>)", context: '''
-void foo<T>(T a) {}
-''');
- expect(result.isValid, isTrue);
- DartObject value = result.value!;
- assertType(value.type, 'bool');
- expect(value.toBoolValue(), true);
- }
-
- test_identical_functionReference_onlyOneHasTypeArgs() async {
- var result =
- await _getExpressionValue("identical(foo<int>, foo)", context: '''
-void foo<T>(T a) {}
-''');
- expect(result.isValid, isTrue);
- DartObject value = result.value!;
- assertType(value.type, 'bool');
- expect(value.toBoolValue(), false);
- }
-
@failingTest
test_identifier_class() async {
var result = await _getExpressionValue("?");
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 69b5497..7b42573 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -120,6 +121,62 @@
);
}
+ test_identical_functionReference_explicitTypeArgs_differentElements() async {
+ await resolveTestCode('''
+void foo<T>(T a) {}
+void bar<T>(T a) {}
+const g = identical(foo<int>, bar<int>);
+''');
+ expect(
+ _evaluateConstant('g'),
+ _boolValue(false),
+ );
+ }
+
+ test_identical_functionReference_explicitTypeArgs_differentTypeArgs() async {
+ await resolveTestCode('''
+void foo<T>(T a) {}
+const g = identical(foo<int>, foo<String>);
+''');
+ expect(
+ _evaluateConstant('g'),
+ _boolValue(false),
+ );
+ }
+
+ test_identical_functionReference_explicitTypeArgs_onlyOneHasTypeArgs() async {
+ await resolveTestCode('''
+void foo<T>(T a) {}
+const g = identical(foo<int>, foo);
+''');
+ expect(
+ _evaluateConstant('g'),
+ _boolValue(false),
+ );
+ }
+
+ test_identical_functionReference_explicitTypeArgs_sameElement() async {
+ await resolveTestCode('''
+void foo<T>(T a) {}
+const g = identical(foo<int>, foo<int>);
+''');
+ expect(
+ _evaluateConstant('g'),
+ _boolValue(true),
+ );
+ }
+
+ test_identical_functionReference_uninstantiated_sameElement() async {
+ await resolveTestCode('''
+void foo<T>(T a) {}
+const g = identical(foo, foo);
+''');
+ expect(
+ _evaluateConstant('g'),
+ _boolValue(true),
+ );
+ }
+
test_visitAsExpression_potentialConstType() async {
await assertNoErrorsInCode('''
const num three = 3;
@@ -223,6 +280,128 @@
expect(result.toIntValue(), 0xFF);
}
+ test_visitFunctionReference_explicitTypeArgs_complexExpression() async {
+ await resolveTestCode('''
+const b = true;
+void foo<T>(T a) {}
+void bar<T>(T a) {}
+const g = (b ? foo : bar)<int>;
+''');
+ var result = _evaluateConstant('g');
+ assertType(result.type, 'void Function(int)');
+ assertElement(result.toFunctionValue(), findElement.topFunction('foo'));
+ _assertTypeArguments(result, ['int']);
+ }
+
+ test_visitFunctionReference_explicitTypeArgs_complexExpression_differentTypes() async {
+ await resolveTestCode('''
+const b = true;
+void foo<T>(String a, T b) {}
+void bar<T>(T a, String b) {}
+const g = (b ? foo : bar)<int>;
+''');
+ var result = _evaluateConstant('g');
+ assertType(result.type, 'void Function(String, int)');
+ assertElement(result.toFunctionValue(), findElement.topFunction('foo'));
+ _assertTypeArguments(result, ['int']);
+ }
+
+ test_visitFunctionReference_explicitTypeArgs_functionName_constantType() async {
+ await resolveTestCode('''
+void f<T>(T a) {}
+const g = f<int>;
+''');
+ var result = _evaluateConstant('g');
+ assertType(result.type, 'void Function(int)');
+ assertElement(result.toFunctionValue(), findElement.topFunction('f'));
+ _assertTypeArguments(result, ['int']);
+ }
+
+ test_visitFunctionReference_explicitTypeArgs_functionName_notMatchingBound() async {
+ await resolveTestCode('''
+void f<T extends num>(T a) {}
+const g = f<String>;
+''');
+ var result = _evaluateConstant('g');
+ assertType(result.type, 'void Function(String)');
+ assertElement(result.toFunctionValue(), findElement.topFunction('f'));
+ _assertTypeArguments(result, ['String']);
+ }
+
+ test_visitFunctionReference_functionName_explicitTypeArgs_notType() async {
+ await resolveTestCode('''
+void foo<T>(T a) {}
+const g = foo<true>;
+''');
+ var result = _evaluateConstantOrNull('g', errorCodes: [
+ CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
+ CompileTimeErrorCode.INVALID_CONSTANT,
+ ]);
+ expect(result, isNull);
+ }
+
+ test_visitFunctionReference_functionName_explicitTypeArgs_tooFew() async {
+ await resolveTestCode('''
+void foo<T, U>(T a, U b) {}
+const g = foo<int>;
+''');
+ var result = _evaluateConstantOrNull('g');
+ // The wrong number of arguments is reported elsewhere. Here, the result is
+ // simply `null`.
+ expect(result, isNull);
+ }
+
+ test_visitFunctionReference_functionName_explicitTypeArgs_tooMany() async {
+ await resolveTestCode('''
+void foo<T>(T a) {}
+const g = foo<int, String>;
+''');
+ var result = _evaluateConstantOrNull('g');
+ // The wrong number of arguments is reported elsewhere. Here, the result is
+ // simply `null`.
+ expect(result, isNull);
+ }
+
+ test_visitFunctionReference_functionName_explicitTypeArgs_typeParameter() async {
+ await resolveTestCode('''
+void f<T>(T a) {}
+
+class C<U> {
+ void m() {
+ static const g = f<U>;
+ }
+}
+''');
+ var result = _evaluateConstantLocal('g')!;
+ assertType(result.type, 'void Function(U)');
+ assertElement(result.toFunctionValue(), findElement.topFunction('f'));
+ _assertTypeArguments(result, ['U']);
+ }
+
+ test_visitFunctionReference_uninstantiated_complexExpression() async {
+ await resolveTestCode('''
+const b = true;
+void foo<T>(T a) {}
+void bar<T>(T a) {}
+const g = b ? foo : bar;
+''');
+ var result = _evaluateConstant('g');
+ assertType(result.type, 'void Function<T>(T)');
+ assertElement(result.toFunctionValue(), findElement.topFunction('foo'));
+ _assertTypeArguments(result, null);
+ }
+
+ test_visitFunctionReference_uninstantiated_functionName() async {
+ await resolveTestCode('''
+void f<T>(T a) {}
+const g = f;
+''');
+ var result = _evaluateConstant('g');
+ assertType(result.type, 'void Function<T>(T)');
+ assertElement(result.toFunctionValue(), findElement.topFunction('f'));
+ _assertTypeArguments(result, null);
+ }
+
test_visitSimpleIdentifier_className() async {
await resolveTestCode('''
const a = C;
@@ -1320,6 +1499,19 @@
}
class ConstantVisitorTestSupport extends PubPackageResolutionTest {
+ void _assertTypeArguments(DartObject value, List<String>? typeArgumentNames) {
+ var typeArguments = (value as DartObjectImpl).typeArguments;
+ if (typeArguments == null) {
+ expect(typeArguments, typeArgumentNames);
+ return;
+ }
+ expect(
+ typeArguments.map(
+ (arg) => arg.toTypeValue()!.getDisplayString(withNullability: true)),
+ equals(typeArgumentNames),
+ );
+ }
+
DartObjectImpl _evaluateConstant(
String name, {
List<ErrorCode>? errorCodes,
@@ -1334,6 +1526,21 @@
)!;
}
+ DartObjectImpl? _evaluateConstantLocal(
+ String name, {
+ List<ErrorCode>? errorCodes,
+ Map<String, String> declaredVariables = const {},
+ Map<String, DartObjectImpl>? lexicalEnvironment,
+ }) {
+ var expression = findNode.variableDeclaration(name).initializer!;
+ return _evaluateExpression(
+ expression,
+ errorCodes: errorCodes,
+ declaredVariables: declaredVariables,
+ lexicalEnvironment: lexicalEnvironment,
+ );
+ }
+
DartObjectImpl? _evaluateConstantOrNull(
String name, {
List<ErrorCode>? errorCodes,
@@ -1341,7 +1548,20 @@
Map<String, DartObjectImpl>? lexicalEnvironment,
}) {
var expression = findNode.topVariableDeclarationByName(name).initializer!;
+ return _evaluateExpression(
+ expression,
+ errorCodes: errorCodes,
+ declaredVariables: declaredVariables,
+ lexicalEnvironment: lexicalEnvironment,
+ );
+ }
+ DartObjectImpl? _evaluateExpression(
+ Expression expression, {
+ List<ErrorCode>? errorCodes,
+ Map<String, String> declaredVariables = const {},
+ Map<String, DartObjectImpl>? lexicalEnvironment,
+ }) {
var unit = this.result.unit;
var source = unit.declaredElement!.source;
var errorListener = GatheringErrorListener();
@@ -1351,7 +1571,7 @@
isNonNullableByDefault: false,
);
- DartObjectImpl? result = expression.accept(
+ var result = expression.accept(
ConstantVisitor(
ConstantEvaluationEngine(
declaredVariables: DeclaredVariables.fromMap(declaredVariables),
diff --git a/tools/VERSION b/tools/VERSION
index fe63169..bf47595 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 144
+PRERELEASE 145
PRERELEASE_PATCH 0
\ No newline at end of file