Support for 'nullabilitySuffix' in linked types.
R=brianwilkerson@google.com
Change-Id: I08853e2a699cc2270f120247424503a2c5a7cac3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100924
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index 8624b44..d73ab28 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -361,7 +361,12 @@
if (this.useCounter == before) return type;
- return FunctionTypeBuilder(typeFormals, parameters, returnType);
+ return FunctionTypeBuilder(
+ typeFormals,
+ parameters,
+ returnType,
+ type.nullabilitySuffix,
+ );
}
@override
@@ -391,7 +396,11 @@
return type;
}
- return new NamedTypeBuilder(type.element, arguments);
+ return new NamedTypeBuilder(
+ type.element,
+ arguments,
+ type.nullabilitySuffix,
+ );
}
@override
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index ff3d13e..8458072 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -19482,6 +19482,7 @@
int _interfaceClass;
List<LinkedNodeTypeBuilder> _interfaceTypeArguments;
idl.LinkedNodeTypeKind _kind;
+ idl.EntityRefNullabilitySuffix _nullabilitySuffix;
int _typeParameterElement;
int _typeParameterId;
@@ -19550,6 +19551,14 @@
}
@override
+ idl.EntityRefNullabilitySuffix get nullabilitySuffix =>
+ _nullabilitySuffix ??= idl.EntityRefNullabilitySuffix.starOrIrrelevant;
+
+ set nullabilitySuffix(idl.EntityRefNullabilitySuffix value) {
+ this._nullabilitySuffix = value;
+ }
+
+ @override
int get typeParameterElement => _typeParameterElement ??= 0;
set typeParameterElement(int value) {
@@ -19574,6 +19583,7 @@
int interfaceClass,
List<LinkedNodeTypeBuilder> interfaceTypeArguments,
idl.LinkedNodeTypeKind kind,
+ idl.EntityRefNullabilitySuffix nullabilitySuffix,
int typeParameterElement,
int typeParameterId})
: _functionFormalParameters = functionFormalParameters,
@@ -19584,6 +19594,7 @@
_interfaceClass = interfaceClass,
_interfaceTypeArguments = interfaceTypeArguments,
_kind = kind,
+ _nullabilitySuffix = nullabilitySuffix,
_typeParameterElement = typeParameterElement,
_typeParameterId = typeParameterId;
@@ -19637,6 +19648,8 @@
x?.collectApiSignature(signature);
}
}
+ signature.addInt(
+ this._nullabilitySuffix == null ? 0 : this._nullabilitySuffix.index);
}
fb.Offset finish(fb.Builder fbBuilder) {
@@ -19693,6 +19706,10 @@
if (_kind != null && _kind != idl.LinkedNodeTypeKind.bottom) {
fbBuilder.addUint8(5, _kind.index);
}
+ if (_nullabilitySuffix != null &&
+ _nullabilitySuffix != idl.EntityRefNullabilitySuffix.starOrIrrelevant) {
+ fbBuilder.addUint8(10, _nullabilitySuffix.index);
+ }
if (_typeParameterElement != null && _typeParameterElement != 0) {
fbBuilder.addUint32(6, _typeParameterElement);
}
@@ -19727,6 +19744,7 @@
int _interfaceClass;
List<idl.LinkedNodeType> _interfaceTypeArguments;
idl.LinkedNodeTypeKind _kind;
+ idl.EntityRefNullabilitySuffix _nullabilitySuffix;
int _typeParameterElement;
int _typeParameterId;
@@ -19794,6 +19812,13 @@
}
@override
+ idl.EntityRefNullabilitySuffix get nullabilitySuffix {
+ _nullabilitySuffix ??= const _EntityRefNullabilitySuffixReader().vTableGet(
+ _bc, _bcOffset, 10, idl.EntityRefNullabilitySuffix.starOrIrrelevant);
+ return _nullabilitySuffix;
+ }
+
+ @override
int get typeParameterElement {
_typeParameterElement ??=
const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
@@ -19832,6 +19857,8 @@
interfaceTypeArguments.map((_value) => _value.toJson()).toList();
if (kind != idl.LinkedNodeTypeKind.bottom)
_result["kind"] = kind.toString().split('.')[1];
+ if (nullabilitySuffix != idl.EntityRefNullabilitySuffix.starOrIrrelevant)
+ _result["nullabilitySuffix"] = nullabilitySuffix.toString().split('.')[1];
if (typeParameterElement != 0)
_result["typeParameterElement"] = typeParameterElement;
if (typeParameterId != 0) _result["typeParameterId"] = typeParameterId;
@@ -19848,6 +19875,7 @@
"interfaceClass": interfaceClass,
"interfaceTypeArguments": interfaceTypeArguments,
"kind": kind,
+ "nullabilitySuffix": nullabilitySuffix,
"typeParameterElement": typeParameterElement,
"typeParameterId": typeParameterId,
};
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 9afbf14..ad1b299 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -2003,6 +2003,8 @@
kind:LinkedNodeTypeKind (id: 5);
+ nullabilitySuffix:EntityRefNullabilitySuffix (id: 10);
+
typeParameterElement:uint (id: 6);
typeParameterId:uint (id: 7);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 73bba33..171389f 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -2614,6 +2614,9 @@
@Id(5)
LinkedNodeTypeKind get kind;
+ @Id(10)
+ EntityRefNullabilitySuffix get nullabilitySuffix;
+
@Id(6)
int get typeParameterElement;
diff --git a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
index 4abe8d6..17c0845 100644
--- a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// 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' as ast;
import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -330,6 +331,7 @@
linker.elementFactory,
element,
unitReference,
+ linker.contextFeatures.isEnabled(Feature.non_nullable),
libraryScope,
);
unitContext.unit.accept(resolver);
diff --git a/pkg/analyzer/lib/src/summary2/function_type_builder.dart b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
index 608e192..39425e6 100644
--- a/pkg/analyzer/lib/src/summary2/function_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
@@ -18,6 +18,7 @@
final List<TypeParameterElement> typeFormals;
final List<ParameterElement> parameters;
final DartType returnType;
+ final NullabilitySuffix nullabilitySuffix;
/// The node for which this builder is created, or `null` if the builder
/// was detached from its node, e.g. during computing default types for
@@ -33,11 +34,15 @@
FunctionTypeBuilder(
this.typeFormals,
this.parameters,
- this.returnType, {
+ this.returnType,
+ this.nullabilitySuffix, {
this.node,
});
- factory FunctionTypeBuilder.of(GenericFunctionType node) {
+ factory FunctionTypeBuilder.of(
+ GenericFunctionType node,
+ NullabilitySuffix nullabilitySuffix,
+ ) {
return FunctionTypeBuilder(
node.typeParameters?.typeParameters
?.map((n) => n.declaredElement as TypeParameterElement)
@@ -52,6 +57,7 @@
);
}).toList(),
_getNodeType(node.returnType),
+ nullabilitySuffix,
node: node,
);
}
@@ -77,6 +83,7 @@
e.parameterKind,
);
}).toList(),
+ nullabilitySuffix: nullabilitySuffix,
);
if (node != null) {
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 66b6e74..b2958f6 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
import 'package:analyzer/dart/element/element.dart';
@@ -84,6 +85,10 @@
);
}
+ FeatureSet get contextFeatures {
+ return analysisContext.analysisOptions.contextFeatures;
+ }
+
void link(List<LinkedNodeBundle> inputBundles,
List<LinkInputLibrary> inputLibraries) {
for (var input in inputBundles) {
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index bc93069..35cdd00 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -947,28 +947,33 @@
_typeParameters.remove(--_nextSyntheticTypeParameterId);
}
+ var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
+
return FunctionTypeImpl.synthetic(
returnType,
typeParameters,
formalParameters,
- );
+ ).withNullability(nullabilitySuffix);
} else if (kind == LinkedNodeTypeKind.interface) {
var element = bundleContext.elementOfIndex(linkedType.interfaceClass);
+ var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
return InterfaceTypeImpl.explicit(
element,
linkedType.interfaceTypeArguments.map(readType).toList(),
+ nullabilitySuffix: nullabilitySuffix,
);
} else if (kind == LinkedNodeTypeKind.typeParameter) {
+ TypeParameterElement element;
var id = linkedType.typeParameterId;
if (id != 0) {
- var element = _typeParameters[id];
+ element = _typeParameters[id];
assert(element != null);
- return TypeParameterTypeImpl(element);
} else {
var index = linkedType.typeParameterElement;
- var element = bundleContext.elementOfIndex(index);
- return TypeParameterTypeImpl(element);
+ element = bundleContext.elementOfIndex(index);
}
+ var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
+ return TypeParameterTypeImpl(element).withNullability(nullabilitySuffix);
} else if (kind == LinkedNodeTypeKind.void_) {
return VoidTypeImpl.instance;
} else {
@@ -1145,6 +1150,19 @@
}
return typeParameterList?.typeParameterList_typeParameters;
}
+
+ static NullabilitySuffix _nullabilitySuffix(EntityRefNullabilitySuffix data) {
+ switch (data) {
+ case EntityRefNullabilitySuffix.starOrIrrelevant:
+ return NullabilitySuffix.star;
+ case EntityRefNullabilitySuffix.question:
+ return NullabilitySuffix.question;
+ case EntityRefNullabilitySuffix.none:
+ return NullabilitySuffix.none;
+ default:
+ throw StateError('$data');
+ }
+ }
}
/// Ensure that all [GenericFunctionType] and [TypeParameter] nodes are read,
diff --git a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
index c151916..75e6617 100644
--- a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
@@ -94,6 +94,7 @@
kind: LinkedNodeTypeKind.interface,
interfaceClass: indexOfElement(type.element),
interfaceTypeArguments: type.typeArguments.map(writeType).toList(),
+ nullabilitySuffix: _nullabilitySuffix(type),
);
} else if (type is TypeParameterType) {
TypeParameterElementImpl element = type.element;
@@ -101,12 +102,14 @@
if (id != null) {
return LinkedNodeTypeBuilder(
kind: LinkedNodeTypeKind.typeParameter,
+ nullabilitySuffix: _nullabilitySuffix(type),
typeParameterId: id,
);
} else {
var index = indexOfElement(element);
return LinkedNodeTypeBuilder(
kind: LinkedNodeTypeKind.typeParameter,
+ nullabilitySuffix: _nullabilitySuffix(type),
typeParameterElement: index,
);
}
@@ -177,6 +180,7 @@
.toList(),
functionReturnType: writeType(type.returnType),
functionTypeParameters: typeParameterBuilders,
+ nullabilitySuffix: _nullabilitySuffix(type),
);
for (var typeParameter in typeParameters) {
@@ -186,4 +190,18 @@
return result;
}
+
+ static EntityRefNullabilitySuffix _nullabilitySuffix(DartType type) {
+ var nullabilitySuffix = (type as TypeImpl).nullabilitySuffix;
+ switch (nullabilitySuffix) {
+ case NullabilitySuffix.question:
+ return EntityRefNullabilitySuffix.question;
+ case NullabilitySuffix.star:
+ return EntityRefNullabilitySuffix.starOrIrrelevant;
+ case NullabilitySuffix.none:
+ return EntityRefNullabilitySuffix.none;
+ default:
+ throw StateError('$nullabilitySuffix');
+ }
+ }
}
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index 44d637a..683e7c9 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -16,6 +16,7 @@
final Element element;
final List<DartType> arguments;
+ final NullabilitySuffix nullabilitySuffix;
/// The node for which this builder is created, or `null` if the builder
/// was detached from its node, e.g. during computing default types for
@@ -28,9 +29,14 @@
/// and set for the [node].
DartType _type;
- NamedTypeBuilder(this.element, this.arguments, {this.node});
+ NamedTypeBuilder(this.element, this.arguments, this.nullabilitySuffix,
+ {this.node});
- factory NamedTypeBuilder.of(Element element, TypeName node) {
+ factory NamedTypeBuilder.of(
+ TypeName node,
+ Element element,
+ NullabilitySuffix nullabilitySuffix,
+ ) {
List<DartType> arguments;
var argumentList = node.typeArguments;
if (argumentList != null) {
@@ -39,7 +45,7 @@
arguments = <DartType>[];
}
- return NamedTypeBuilder(element, arguments, node: node);
+ return NamedTypeBuilder(element, arguments, nullabilitySuffix, node: node);
}
@override
@@ -52,10 +58,15 @@
if (element is ClassElement) {
var parameters = element.typeParameters;
if (parameters.isEmpty) {
- _type = element.type;
+ var rawType = element.type;
+ _type = (rawType as TypeImpl).withNullability(nullabilitySuffix);
} else {
var arguments = _buildArguments(parameters);
- _type = InterfaceTypeImpl.explicit(element, arguments);
+ _type = InterfaceTypeImpl.explicit(
+ element,
+ arguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
}
} else if (element is GenericTypeAliasElement) {
// Break a possible recursion.
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 83b68c8..4b7cd9f 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -520,6 +520,7 @@
final LinkedElementFactory elementFactory;
final LibraryElement _libraryElement;
final Reference unitReference;
+ final bool nnbd;
Reference reference;
Scope scope;
@@ -530,6 +531,7 @@
this.elementFactory,
this._libraryElement,
this.unitReference,
+ this.nnbd,
this.scope,
) : reference = unitReference;
@@ -771,7 +773,8 @@
node.typeParameters?.accept(this);
node.parameters.accept(this);
- var builder = FunctionTypeBuilder.of(node);
+ var nullabilitySuffix = _getNullabilitySuffix(node.question != null);
+ var builder = FunctionTypeBuilder.of(node, nullabilitySuffix);
(node as GenericFunctionTypeImpl).type = builder;
nodesToBuildType.addTypeBuilder(builder);
@@ -905,10 +908,18 @@
node.typeArguments?.accept(this);
+ var nullabilitySuffix = _getNullabilitySuffix(node.question != null);
if (element is TypeParameterElement) {
- node.type = TypeParameterTypeImpl(element);
+ node.type = TypeParameterTypeImpl(
+ element,
+ nullabilitySuffix: nullabilitySuffix,
+ );
} else {
- var builder = NamedTypeBuilder.of(element, node);
+ var builder = NamedTypeBuilder.of(
+ node,
+ element,
+ nullabilitySuffix,
+ );
node.type = builder;
nodesToBuildType.addTypeBuilder(builder);
}
@@ -956,4 +967,16 @@
_createTypeParameterElement(typeParameter);
}
}
+
+ NullabilitySuffix _getNullabilitySuffix(bool hasQuestion) {
+ if (nnbd) {
+ if (hasQuestion) {
+ return NullabilitySuffix.question;
+ } else {
+ return NullabilitySuffix.none;
+ }
+ } else {
+ return NullabilitySuffix.star;
+ }
+ }
}