Add preliminary NNBD support to the summary linker.
Change-Id: I256d66333d9715ed720bd6ea87d21fd00e17635a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101900
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 168e9cf..e5cf09c 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -187,7 +187,10 @@
CompilationUnitElementInBuildUnit compilationUnit,
TypeParameterSerializationContext typeParameterContext,
{int slot}) {
- EntityRefBuilder result = new EntityRefBuilder(slot: slot);
+ EntityRefBuilder result = new EntityRefBuilder(
+ slot: slot,
+ nullabilitySuffix:
+ encodeNullabilitySuffix((type as TypeImpl).nullabilitySuffix));
if (type is InterfaceType) {
ClassElementForLink element = type.element;
result.reference = compilationUnit.addReference(element);
@@ -1413,11 +1416,12 @@
return DynamicTypeImpl.instance;
}
}
+ DartType result;
if (entity.paramReference != 0) {
- return context.typeParameterContext
+ result = context.typeParameterContext
.getTypeParameterType(entity.paramReference);
} else if (entity.entityKind == EntityRefKind.genericFunctionType) {
- return new GenericFunctionTypeElementForLink(
+ result = new GenericFunctionTypeElementForLink(
this,
context,
entity.typeParameters,
@@ -1427,13 +1431,13 @@
} else if (entity.syntheticReturnType != null) {
FunctionElementImpl element =
new FunctionElementForLink_Synthetic(this, context, entity);
- return element.type;
+ result = element.type;
} else if (entity.implicitFunctionTypeIndices.isNotEmpty) {
DartType type = resolveRef(entity.reference).asStaticType;
for (int index in entity.implicitFunctionTypeIndices) {
type = (type as FunctionType).parameters[index].type;
}
- return type;
+ result = type;
} else {
ReferenceableElementForLink element = resolveRef(entity.reference);
bool implicitTypeArgumentsInUse = false;
@@ -1452,13 +1456,18 @@
}
}
- var type = element.buildType(
+ result = element.buildType(
getTypeArgument, entity.implicitFunctionTypeIndices);
if (implicitTypeArgumentsInUse) {
- _typesWithImplicitArguments[type] = true;
+ _typesWithImplicitArguments[result] = true;
}
- return type;
}
+ var nullabilitySuffix = decodeNullabilitySuffix(entity.nullabilitySuffix);
+ var resultAsImpl = result as TypeImpl;
+ if (resultAsImpl.nullabilitySuffix != nullabilitySuffix) {
+ result = resultAsImpl.withNullability(nullabilitySuffix);
+ }
+ return result;
}
@override
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index b364311..62665a9 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -31,6 +31,30 @@
*/
final _typesWithImplicitTypeArguments = new Expando();
+NullabilitySuffix decodeNullabilitySuffix(EntityRefNullabilitySuffix suffix) {
+ switch (suffix) {
+ case EntityRefNullabilitySuffix.none:
+ return NullabilitySuffix.none;
+ case EntityRefNullabilitySuffix.question:
+ return NullabilitySuffix.question;
+ case EntityRefNullabilitySuffix.starOrIrrelevant:
+ return NullabilitySuffix.star;
+ }
+ throw new StateError('Unrecognized nullability suffix');
+}
+
+EntityRefNullabilitySuffix encodeNullabilitySuffix(NullabilitySuffix suffix) {
+ switch (suffix) {
+ case NullabilitySuffix.none:
+ return EntityRefNullabilitySuffix.none;
+ case NullabilitySuffix.question:
+ return EntityRefNullabilitySuffix.question;
+ case NullabilitySuffix.star:
+ return EntityRefNullabilitySuffix.starOrIrrelevant;
+ }
+ throw new StateError('Unrecognized nullability suffix');
+}
+
/// An instance of [LibraryResynthesizer] is responsible for resynthesizing the
/// elements in a single library from that library's summary.
abstract class LibraryResynthesizer {
@@ -1376,7 +1400,7 @@
getTypeArgument,
type.implicitFunctionTypeIndices);
}
- var nullabilitySuffix = _translateNullabilitySuffix(type.nullabilitySuffix);
+ var nullabilitySuffix = decodeNullabilitySuffix(type.nullabilitySuffix);
var resultAsImpl = result as TypeImpl;
if (resultAsImpl.nullabilitySuffix != nullabilitySuffix) {
result = resultAsImpl.withNullability(nullabilitySuffix);
@@ -1628,19 +1652,6 @@
return null;
}
- NullabilitySuffix _translateNullabilitySuffix(
- EntityRefNullabilitySuffix suffix) {
- switch (suffix) {
- case EntityRefNullabilitySuffix.none:
- return NullabilitySuffix.none;
- case EntityRefNullabilitySuffix.question:
- return NullabilitySuffix.question;
- case EntityRefNullabilitySuffix.starOrIrrelevant:
- return NullabilitySuffix.star;
- }
- throw new StateError('Unrecognized nullability suffix');
- }
-
/**
* If the given [kind] is a top-level or class member property accessor, and
* the given [name] does not end with `=`, i.e. does not denote a setter,
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 352acf3..14add4a 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -133,6 +133,26 @@
@override
@failingTest
+ test_inferred_type_nullability_class_ref_none() =>
+ super.test_inferred_type_nullability_class_ref_none();
+
+ @override
+ @failingTest
+ test_inferred_type_nullability_class_ref_question() =>
+ super.test_inferred_type_nullability_class_ref_question();
+
+ @override
+ @failingTest
+ test_inferred_type_nullability_function_type_none() =>
+ super.test_inferred_type_nullability_function_type_none();
+
+ @override
+ @failingTest
+ test_inferred_type_nullability_function_type_question() =>
+ super.test_inferred_type_nullability_function_type_question();
+
+ @override
+ @failingTest
test_syntheticFunctionType_genericClosure() async {
// TODO(scheglov) Bug in TypeSystem.getLeastUpperBound().
// LUB(<T>(T) → int, <T>(T) → int) gives `(T) → int`, note absence of `<T>`.
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index c2d13b7..85bcfd2 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -6815,6 +6815,70 @@
''');
}
+ test_inferred_type_nullability_class_ref_none() async {
+ featureSet = enableNnbd;
+ addSource('/a.dart', 'int f() => 0;');
+ var library = await checkLibrary('''
+import 'a.dart';
+var x = f();
+''');
+ checkElementText(
+ library,
+ r'''
+import 'a.dart';
+int x;
+''',
+ annotateNullability: true);
+ }
+
+ test_inferred_type_nullability_class_ref_question() async {
+ featureSet = enableNnbd;
+ addSource('/a.dart', 'int? f() => 0;');
+ var library = await checkLibrary('''
+import 'a.dart';
+var x = f();
+''');
+ checkElementText(
+ library,
+ r'''
+import 'a.dart';
+int? x;
+''',
+ annotateNullability: true);
+ }
+
+ test_inferred_type_nullability_function_type_none() async {
+ featureSet = enableNnbd;
+ addSource('/a.dart', 'void Function() f() => () {};');
+ var library = await checkLibrary('''
+import 'a.dart';
+var x = f();
+''');
+ checkElementText(
+ library,
+ r'''
+import 'a.dart';
+void Function() x;
+''',
+ annotateNullability: true);
+ }
+
+ test_inferred_type_nullability_function_type_question() async {
+ featureSet = enableNnbd;
+ addSource('/a.dart', 'void Function()? f() => () {};');
+ var library = await checkLibrary('''
+import 'a.dart';
+var x = f();
+''');
+ checkElementText(
+ library,
+ r'''
+import 'a.dart';
+void Function()? x;
+''',
+ annotateNullability: true);
+ }
+
test_inferred_type_refers_to_bound_type_param() async {
var library = await checkLibrary('''
class C<T> extends D<int, T> {