Skip to content

Commit 41a8b79

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Use the inferred type of const lists/maps to for constant evaluation.
This addresses one of the root causes of #33304. Note that when a constant list or map is recorded in a summary, we don't encode enough information in the summary to resynthesize its inferred type correctly, so this only fixes cases where the constant is used in the same build unit as its declaration. Change-Id: Id0034f481cb82f18c77bbe2ee8ebec7e8b244caa Reviewed-on: https://dart-review.googlesource.com/60203 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Paul Berry <[email protected]>
1 parent 2972ca6 commit 41a8b79

File tree

7 files changed

+88
-21
lines changed

7 files changed

+88
-21
lines changed

pkg/analyzer/lib/src/dart/constant/evaluation.dart

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,14 +1409,11 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
14091409
if (errorOccurred) {
14101410
return null;
14111411
}
1412-
DartType elementType = _typeProvider.dynamicType;
1413-
NodeList<TypeAnnotation> typeArgs = node.typeArguments?.arguments;
1414-
if (typeArgs?.length == 1) {
1415-
DartType type = visitTypeAnnotation(typeArgs[0])?.toTypeValue();
1416-
if (type != null) {
1417-
elementType = type;
1418-
}
1419-
}
1412+
var nodeType = node.staticType;
1413+
DartType elementType =
1414+
nodeType is InterfaceType && nodeType.typeArguments.isNotEmpty
1415+
? nodeType.typeArguments[0]
1416+
: _typeProvider.dynamicType;
14201417
InterfaceType listType = _typeProvider.listType.instantiate([elementType]);
14211418
return new DartObjectImpl(listType, new ListState(elements));
14221419
}
@@ -1445,17 +1442,12 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
14451442
}
14461443
DartType keyType = _typeProvider.dynamicType;
14471444
DartType valueType = _typeProvider.dynamicType;
1448-
NodeList<TypeAnnotation> typeArgs = node.typeArguments?.arguments;
1449-
if (typeArgs?.length == 2) {
1450-
DartType keyTypeCandidate =
1451-
visitTypeAnnotation(typeArgs[0])?.toTypeValue();
1452-
if (keyTypeCandidate != null) {
1453-
keyType = keyTypeCandidate;
1454-
}
1455-
DartType valueTypeCandidate =
1456-
visitTypeAnnotation(typeArgs[1])?.toTypeValue();
1457-
if (valueTypeCandidate != null) {
1458-
valueType = valueTypeCandidate;
1445+
var nodeType = node.staticType;
1446+
if (nodeType is InterfaceType) {
1447+
var typeArguments = nodeType.typeArguments;
1448+
if (typeArguments.length >= 2) {
1449+
keyType = typeArguments[0];
1450+
valueType = typeArguments[1];
14591451
}
14601452
}
14611453
InterfaceType mapType =

pkg/analyzer/lib/src/dart/constant/utilities.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class ConstantAstCloner extends AstCloner {
8383
@override
8484
ListLiteral visitListLiteral(ListLiteral node) {
8585
ListLiteral literal = super.visitListLiteral(node);
86+
literal.staticType = node.staticType;
8687
if (previewDart2 && node.constKeyword == null && node.isConst) {
8788
literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
8889
}
@@ -92,6 +93,7 @@ class ConstantAstCloner extends AstCloner {
9293
@override
9394
MapLiteral visitMapLiteral(MapLiteral node) {
9495
MapLiteral literal = super.visitMapLiteral(node);
96+
literal.staticType = node.staticType;
9597
if (previewDart2 && node.constKeyword == null && node.isConst) {
9698
literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
9799
}

pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,18 @@ var v = const A(null);''');
492492
verify([source]);
493493
}
494494

495+
test_listLiteral_inferredElementType() async {
496+
resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
497+
Source source = addSource('''
498+
const Object x = [1];
499+
const List<String> y = x;
500+
''');
501+
await computeAnalysisResult(source);
502+
assertErrors(
503+
source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
504+
verify([source]);
505+
}
506+
495507
test_mapKeyTypeNotAssignable() async {
496508
Source source = addSource("var v = const <String, int > {1 : 2};");
497509
await computeAnalysisResult(source);
@@ -502,6 +514,30 @@ var v = const A(null);''');
502514
verify([source]);
503515
}
504516

517+
test_mapLiteral_inferredKeyType() async {
518+
resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
519+
Source source = addSource('''
520+
const Object x = {1: 1};
521+
const Map<String, dynamic> y = x;
522+
''');
523+
await computeAnalysisResult(source);
524+
assertErrors(
525+
source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
526+
verify([source]);
527+
}
528+
529+
test_mapLiteral_inferredValueType() async {
530+
resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
531+
Source source = addSource('''
532+
const Object x = {1: 1};
533+
const Map<dynamic, String> y = x;
534+
''');
535+
await computeAnalysisResult(source);
536+
assertErrors(
537+
source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
538+
verify([source]);
539+
}
540+
505541
test_mapValueTypeNotAssignable() async {
506542
Source source = addSource("var v = const <String, String> {'a' : 2};");
507543
await computeAnalysisResult(source);

pkg/analyzer/test/src/summary/resynthesize_ast_test.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,13 @@ class ResynthesizeAstStrongTest extends _ResynthesizeAstTest {
183183

184184
@failingTest // See dartbug.com/32290
185185
test_const_constructor_inferred_args() =>
186-
test_const_constructor_inferred_args();
186+
super.test_const_constructor_inferred_args();
187+
188+
@failingTest // See dartbug.com/33441
189+
test_const_list_inferredType() => super.test_const_list_inferredType();
190+
191+
@failingTest // See dartbug.com/33441
192+
test_const_map_inferredType() => super.test_const_map_inferredType();
187193

188194
@override
189195
@failingTest

pkg/analyzer/test/src/summary/resynthesize_common.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3297,6 +3297,35 @@ const dynamic v =
32973297
}
32983298
}
32993299

3300+
test_const_list_inferredType() async {
3301+
if (!isStrongMode) return;
3302+
// The summary needs to contain enough information so that when the constant
3303+
// is resynthesized, the constant value can get the type that was computed
3304+
// by type inference.
3305+
var library = await checkLibrary('''
3306+
const Object x = const [1];
3307+
''');
3308+
checkElementText(library, '''
3309+
const Object x = const <
3310+
int/*location: dart:core;int*/>[1];
3311+
''');
3312+
}
3313+
3314+
test_const_map_inferredType() async {
3315+
if (!isStrongMode) return;
3316+
// The summary needs to contain enough information so that when the constant
3317+
// is resynthesized, the constant value can get the type that was computed
3318+
// by type inference.
3319+
var library = await checkLibrary('''
3320+
const Object x = const {1: 1.0};
3321+
''');
3322+
checkElementText(library, '''
3323+
const Object x = const <
3324+
int/*location: dart:core;int*/,
3325+
double/*location: dart:core;double*/>{1: 1.0};
3326+
''');
3327+
}
3328+
33003329
test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
33013330
var library = await checkLibrary(r'''
33023331
class C {

pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ class C {
147147

148148
@failingTest // See dartbug.com/32290
149149
test_const_constructor_inferred_args() =>
150-
test_const_constructor_inferred_args();
150+
super.test_const_constructor_inferred_args();
151151

152152
@failingTest
153153
@FastaProblem('https://github.com/dart-lang/sdk/issues/30258')

pkg/analyzer/test/src/task/strong/checker_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ test() {
349349
''');
350350
}
351351

352+
@failingTest // See dartbug.com/33440
352353
test_constantGenericTypeArg_explicit() async {
353354
// Regression test for https://github.com/dart-lang/sdk/issues/26141
354355
await checkFile('''
@@ -375,6 +376,7 @@ main() {
375376
''');
376377
}
377378

379+
@failingTest // See dartbug.com/32918
378380
test_constantGenericTypeArg_infer() async {
379381
// Regression test for https://github.com/dart-lang/sdk/issues/26141
380382
await checkFile('''

0 commit comments

Comments
 (0)