Add the class NonNullableTypeProvider to access SDK classes in opted-in context
Change-Id: Id0cd7c8cd6f93701a5e603753b10a27236292d41
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102202
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index edb112e..f66ceb7 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -3402,6 +3402,23 @@
}
}
+/// A type provider that returns non-nullable versions of the SDK types.
+class NonNullableTypeProvider extends TypeProviderImpl {
+ NonNullableTypeProvider(
+ LibraryElement coreLibrary, LibraryElement asyncLibrary)
+ : super(coreLibrary, asyncLibrary);
+
+ @override
+ InterfaceType _getType(Namespace namespace, String typeName) {
+ InterfaceType type = super._getType(namespace, typeName);
+ if (type == null) {
+ return null;
+ }
+ return (type as TypeImpl).withNullability(NullabilitySuffix.none)
+ as InterfaceType;
+ }
+}
+
/// Instances of the class `OverrideVerifier` visit all of the declarations in a
/// compilation unit to verify that if they have an override annotation it is
/// being used correctly.
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 5a190a0..3ec7c06 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -44,6 +44,7 @@
defineReflectiveTests(ErrorResolverTest);
defineReflectiveTests(LibraryImportScopeTest);
defineReflectiveTests(LibraryScopeTest);
+ defineReflectiveTests(NonNullableTypeProviderTest);
defineReflectiveTests(PrefixedNamespaceTest);
defineReflectiveTests(ScopeTest);
defineReflectiveTests(StrictModeTest);
@@ -333,6 +334,129 @@
}
@reflectiveTest
+class NonNullableTypeProviderTest extends EngineTestCase {
+ void assertNonNullable(InterfaceType type) {
+ expect((type as TypeImpl).nullabilitySuffix, NullabilitySuffix.none);
+ }
+
+ void test_creation() {
+ //
+ // Create a mock library element with the types expected to be in dart:core.
+ // We cannot use either ElementFactory or TestTypeProvider (which uses
+ // ElementFactory) because we side-effect the elements in ways that would
+ // break other tests.
+ //
+ InterfaceType objectType = _classElement("Object", null).type;
+ InterfaceType boolType = _classElement("bool", objectType).type;
+ InterfaceType numType = _classElement("num", objectType).type;
+ InterfaceType deprecatedType = _classElement('Deprecated', objectType).type;
+ InterfaceType doubleType = _classElement("double", numType).type;
+ InterfaceType functionType = _classElement("Function", objectType).type;
+ InterfaceType futureType = _classElement("Future", objectType, ["T"]).type;
+ InterfaceType futureOrType =
+ _classElement("FutureOr", objectType, ["T"]).type;
+ InterfaceType intType = _classElement("int", numType).type;
+ InterfaceType iterableType =
+ _classElement("Iterable", objectType, ["T"]).type;
+ InterfaceType listType = _classElement("List", objectType, ["E"]).type;
+ InterfaceType mapType = _classElement("Map", objectType, ["K", "V"]).type;
+ InterfaceType nullType = _classElement('Null', objectType).type;
+ InterfaceType setType = _classElement("Set", objectType, ["E"]).type;
+ InterfaceType stackTraceType = _classElement("StackTrace", objectType).type;
+ InterfaceType streamType = _classElement("Stream", objectType, ["T"]).type;
+ InterfaceType stringType = _classElement("String", objectType).type;
+ InterfaceType symbolType = _classElement("Symbol", objectType).type;
+ InterfaceType typeType = _classElement("Type", objectType).type;
+ CompilationUnitElementImpl coreUnit = new CompilationUnitElementImpl();
+ coreUnit.types = <ClassElement>[
+ boolType.element,
+ deprecatedType.element,
+ doubleType.element,
+ functionType.element,
+ intType.element,
+ iterableType.element,
+ listType.element,
+ mapType.element,
+ nullType.element,
+ numType.element,
+ setType.element,
+ objectType.element,
+ stackTraceType.element,
+ stringType.element,
+ symbolType.element,
+ typeType.element
+ ];
+ coreUnit.source = new TestSource('dart:core');
+ coreUnit.librarySource = coreUnit.source;
+ CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
+ asyncUnit.types = <ClassElement>[
+ futureType.element,
+ futureOrType.element,
+ streamType.element
+ ];
+ asyncUnit.source = new TestSource('dart:async');
+ asyncUnit.librarySource = asyncUnit.source;
+ LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
+ null, null, AstTestFactory.libraryIdentifier2(["dart.core"]));
+ coreLibrary.definingCompilationUnit = coreUnit;
+ LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
+ null, null, AstTestFactory.libraryIdentifier2(["dart.async"]));
+ asyncLibrary.definingCompilationUnit = asyncUnit;
+ //
+ // Create a type provider and ensure that it can return the expected types.
+ //
+ TypeProvider provider =
+ new NonNullableTypeProvider(coreLibrary, asyncLibrary);
+ assertNonNullable(provider.boolType);
+ expect(provider.bottomType, isNotNull);
+ assertNonNullable(provider.deprecatedType);
+ assertNonNullable(provider.doubleType);
+ expect(provider.dynamicType, isNotNull);
+ assertNonNullable(provider.functionType);
+ assertNonNullable(provider.futureType);
+ assertNonNullable(provider.futureOrType);
+ assertNonNullable(provider.intType);
+ assertNonNullable(provider.listType);
+ assertNonNullable(provider.mapType);
+ expect(provider.neverType, isNotNull);
+ assertNonNullable(provider.nullType);
+ assertNonNullable(provider.numType);
+ assertNonNullable(provider.objectType);
+ assertNonNullable(provider.stackTraceType);
+ assertNonNullable(provider.streamType);
+ assertNonNullable(provider.stringType);
+ assertNonNullable(provider.symbolType);
+ assertNonNullable(provider.typeType);
+ }
+
+ ClassElement _classElement(String typeName, InterfaceType superclassType,
+ [List<String> parameterNames]) {
+ ClassElementImpl element =
+ new ClassElementImpl.forNode(AstTestFactory.identifier3(typeName));
+ element.supertype = superclassType;
+ if (parameterNames != null) {
+ int count = parameterNames.length;
+ if (count > 0) {
+ List<TypeParameterElementImpl> typeParameters =
+ new List<TypeParameterElementImpl>(count);
+ List<TypeParameterTypeImpl> typeArguments =
+ new List<TypeParameterTypeImpl>(count);
+ for (int i = 0; i < count; i++) {
+ TypeParameterElementImpl typeParameter =
+ new TypeParameterElementImpl.forNode(
+ AstTestFactory.identifier3(parameterNames[i]));
+ typeParameters[i] = typeParameter;
+ typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
+ typeParameter.type = typeArguments[i];
+ }
+ element.typeParameters = typeParameters;
+ }
+ }
+ return element;
+ }
+}
+
+@reflectiveTest
class PrefixedNamespaceTest extends DriverResolutionTest {
void test_lookup_missing() {
ClassElement element = ElementFactory.classElement2('A');