mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
[cfe] Eliminate Nullability.legacy in transformers
Nullability.legacy is replaced with an appropriate invocation of a method on Library to retrieve the appropriate nullability. Only transformers in pkg/kernel and pkg/front_end are affected. The inference transformers are excluded from the scope of this CL. Change-Id: I691c4343def913388a1277227b760fd7e1aa194c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/125666 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
539b0093e1
commit
f692a2fbb8
11 changed files with 217 additions and 63 deletions
|
@ -238,7 +238,7 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
|
|||
Not wrapper = new Not(initializer);
|
||||
SourceLoader loader = library.loader;
|
||||
loader.transformPostInference(wrapper, bodyBuilder.transformSetLiterals,
|
||||
bodyBuilder.transformCollections);
|
||||
bodyBuilder.transformCollections, library.library);
|
||||
initializer = wrapper.operand;
|
||||
}
|
||||
buildBody(initializer);
|
||||
|
|
|
@ -184,8 +184,11 @@ class FormalParameterBuilder extends ModifierBuilderImpl
|
|||
variable.initializer = initializer..parent = variable;
|
||||
if (library.loader is SourceLoader) {
|
||||
SourceLoader loader = library.loader;
|
||||
loader.transformPostInference(variable,
|
||||
bodyBuilder.transformSetLiterals, bodyBuilder.transformCollections);
|
||||
loader.transformPostInference(
|
||||
variable,
|
||||
bodyBuilder.transformSetLiterals,
|
||||
bodyBuilder.transformCollections,
|
||||
library.library);
|
||||
}
|
||||
initializerWasInferred = true;
|
||||
bodyBuilder.resolveRedirectingFactoryTargets();
|
||||
|
|
|
@ -553,8 +553,8 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
void inferAnnotations(TreeNode parent, List<Expression> annotations) {
|
||||
if (annotations != null) {
|
||||
typeInferrer?.inferMetadata(this, parent, annotations);
|
||||
libraryBuilder.loader.transformListPostInference(
|
||||
annotations, transformSetLiterals, transformCollections);
|
||||
libraryBuilder.loader.transformListPostInference(annotations,
|
||||
transformSetLiterals, transformCollections, libraryBuilder.library);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,7 +692,10 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
// transformations need a parent relation.
|
||||
Not wrapper = new Not(initializer);
|
||||
libraryBuilder.loader.transformPostInference(
|
||||
wrapper, transformSetLiterals, transformCollections);
|
||||
wrapper,
|
||||
transformSetLiterals,
|
||||
transformCollections,
|
||||
libraryBuilder.library);
|
||||
initializer = wrapper.operand;
|
||||
}
|
||||
fieldBuilder.buildBody(initializer);
|
||||
|
@ -869,7 +872,10 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
this, initializer, originParameter.type);
|
||||
originParameter.initializer = initializer..parent = originParameter;
|
||||
libraryBuilder.loader.transformPostInference(
|
||||
originParameter, transformSetLiterals, transformCollections);
|
||||
originParameter,
|
||||
transformSetLiterals,
|
||||
transformCollections,
|
||||
libraryBuilder.library);
|
||||
}
|
||||
|
||||
VariableDeclaration extensionTearOffParameter =
|
||||
|
@ -882,7 +888,8 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
libraryBuilder.loader.transformPostInference(
|
||||
extensionTearOffParameter,
|
||||
transformSetLiterals,
|
||||
transformCollections);
|
||||
transformCollections,
|
||||
libraryBuilder.library);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -894,8 +901,8 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
asyncModifier,
|
||||
builder.member.function,
|
||||
body);
|
||||
libraryBuilder.loader.transformPostInference(
|
||||
body, transformSetLiterals, transformCollections);
|
||||
libraryBuilder.loader.transformPostInference(body, transformSetLiterals,
|
||||
transformCollections, libraryBuilder.library);
|
||||
}
|
||||
|
||||
if (builder.returnType != null) {
|
||||
|
@ -1351,8 +1358,8 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
constructor.initializers.add(initializer);
|
||||
}
|
||||
setParents(constructor.initializers, constructor);
|
||||
libraryBuilder.loader.transformListPostInference(
|
||||
constructor.initializers, transformSetLiterals, transformCollections);
|
||||
libraryBuilder.loader.transformListPostInference(constructor.initializers,
|
||||
transformSetLiterals, transformCollections, libraryBuilder.library);
|
||||
if (constructor.function.body == null) {
|
||||
/// >If a generative constructor c is not a redirecting constructor
|
||||
/// >and no body is provided, then c implicitly has an empty body {}.
|
||||
|
|
|
@ -24,6 +24,7 @@ import 'package:kernel/ast.dart'
|
|||
IfStatement,
|
||||
InterfaceType,
|
||||
Let,
|
||||
Library,
|
||||
ListConcatenation,
|
||||
ListLiteral,
|
||||
MapConcatenation,
|
||||
|
@ -32,7 +33,6 @@ import 'package:kernel/ast.dart'
|
|||
MethodInvocation,
|
||||
Name,
|
||||
Not,
|
||||
Nullability,
|
||||
NullLiteral,
|
||||
Procedure,
|
||||
PropertyGet,
|
||||
|
@ -85,6 +85,12 @@ class CollectionTransformer extends Transformer {
|
|||
final Field mapEntryValue;
|
||||
final SourceLoaderDataForTesting dataForTesting;
|
||||
|
||||
/// Library that contains the transformed nodes.
|
||||
///
|
||||
/// The transformation of the nodes is affected by the NNBD opt-in status of
|
||||
/// the library.
|
||||
Library _currentLibrary;
|
||||
|
||||
static Procedure _findSetFactory(CoreTypes coreTypes) {
|
||||
Procedure factory = coreTypes.index.getMember('dart:core', 'Set', '');
|
||||
RedirectingFactoryBody body = factory?.function?.body;
|
||||
|
@ -132,13 +138,13 @@ class CollectionTransformer extends Transformer {
|
|||
new StaticInvocation(
|
||||
setFactory, new Arguments([], types: [elementType])),
|
||||
type: new InterfaceType(
|
||||
coreTypes.setClass, Nullability.legacy, [elementType]),
|
||||
coreTypes.setClass, _currentLibrary.nonNullable, [elementType]),
|
||||
isFinal: true);
|
||||
} else {
|
||||
result = new VariableDeclaration.forValue(
|
||||
new ListLiteral([], typeArgument: elementType),
|
||||
type: new InterfaceType(
|
||||
coreTypes.listClass, Nullability.legacy, [elementType]),
|
||||
coreTypes.listClass, _currentLibrary.nonNullable, [elementType]),
|
||||
isFinal: true);
|
||||
}
|
||||
List<Statement> body = [result];
|
||||
|
@ -335,7 +341,7 @@ class CollectionTransformer extends Transformer {
|
|||
// Build a block expression and create an empty map.
|
||||
VariableDeclaration result = new VariableDeclaration.forValue(
|
||||
new MapLiteral([], keyType: node.keyType, valueType: node.valueType),
|
||||
type: new InterfaceType(coreTypes.mapClass, Nullability.legacy,
|
||||
type: new InterfaceType(coreTypes.mapClass, _currentLibrary.nonNullable,
|
||||
[node.keyType, node.valueType]),
|
||||
isFinal: true);
|
||||
List<Statement> body = [result];
|
||||
|
@ -448,14 +454,16 @@ class CollectionTransformer extends Transformer {
|
|||
}
|
||||
|
||||
DartType entryType = new InterfaceType(
|
||||
mapEntryClass, Nullability.legacy, <DartType>[keyType, valueType]);
|
||||
mapEntryClass,
|
||||
_currentLibrary.nullableIfTrue(entry.isNullAware),
|
||||
<DartType>[keyType, valueType]);
|
||||
VariableDeclaration elt;
|
||||
Statement loopBody;
|
||||
if (entry.entryType == null ||
|
||||
!typeEnvironment.isSubtypeOf(entry.entryType, entryType,
|
||||
SubtypeCheckMode.ignoringNullabilities)) {
|
||||
elt = new VariableDeclaration(null,
|
||||
type: new InterfaceType(mapEntryClass, Nullability.legacy,
|
||||
type: new InterfaceType(mapEntryClass, _currentLibrary.nonNullable,
|
||||
<DartType>[const DynamicType(), const DynamicType()]),
|
||||
isFinal: true);
|
||||
VariableDeclaration keyVar = new VariableDeclaration.forValue(
|
||||
|
@ -653,4 +661,18 @@ class CollectionTransformer extends Transformer {
|
|||
return new MapConcatenation(parts,
|
||||
keyType: node.keyType, valueType: node.valueType);
|
||||
}
|
||||
|
||||
void enterLibrary(Library library) {
|
||||
assert(
|
||||
_currentLibrary == null,
|
||||
"Attempting to enter library '${library.fileUri}' "
|
||||
"without having exited library '${_currentLibrary.fileUri}'.");
|
||||
_currentLibrary = library;
|
||||
}
|
||||
|
||||
void exitLibrary() {
|
||||
assert(_currentLibrary != null,
|
||||
"Attempting to exit a library without having entered one.");
|
||||
_currentLibrary = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@ import 'package:kernel/ast.dart'
|
|||
Expression,
|
||||
InterfaceType,
|
||||
Let,
|
||||
Library,
|
||||
MethodInvocation,
|
||||
Name,
|
||||
Nullability,
|
||||
Procedure,
|
||||
SetLiteral,
|
||||
StaticInvocation,
|
||||
|
@ -36,6 +36,12 @@ class SetLiteralTransformer extends Transformer {
|
|||
final Procedure setFactory;
|
||||
final Procedure addMethod;
|
||||
|
||||
/// Library that contains the transformed nodes.
|
||||
///
|
||||
/// The transformation of the nodes is affected by the NNBD opt-in status of
|
||||
/// the library.
|
||||
Library _currentLibrary;
|
||||
|
||||
static Procedure _findSetFactory(CoreTypes coreTypes) {
|
||||
Procedure factory = coreTypes.index.getMember('dart:core', 'Set', '');
|
||||
RedirectingFactoryBody body = factory?.function?.body;
|
||||
|
@ -58,8 +64,8 @@ class SetLiteralTransformer extends Transformer {
|
|||
VariableDeclaration setVar = new VariableDeclaration.forValue(
|
||||
new StaticInvocation(
|
||||
setFactory, new Arguments([], types: [node.typeArgument])),
|
||||
type: new InterfaceType(
|
||||
coreTypes.setClass, Nullability.legacy, [node.typeArgument]));
|
||||
type: new InterfaceType(coreTypes.setClass, _currentLibrary.nonNullable,
|
||||
[node.typeArgument]));
|
||||
// Innermost body of let chain: setVar
|
||||
Expression setExp = new VariableGet(setVar);
|
||||
for (int i = node.expressions.length - 1; i >= 0; i--) {
|
||||
|
@ -75,4 +81,18 @@ class SetLiteralTransformer extends Transformer {
|
|||
}
|
||||
return new Let(setVar, setExp);
|
||||
}
|
||||
|
||||
void enterLibrary(Library library) {
|
||||
assert(
|
||||
_currentLibrary == null,
|
||||
"Attempting to enter library '${library.fileUri}' "
|
||||
"without having exited library '${_currentLibrary.fileUri}'.");
|
||||
_currentLibrary = library;
|
||||
}
|
||||
|
||||
void exitLibrary() {
|
||||
assert(_currentLibrary != null,
|
||||
"Attempting to exit a library without having entered one.");
|
||||
_currentLibrary = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1046,31 +1046,44 @@ class SourceLoader extends Loader {
|
|||
ticker.logMs("Performed top level inference");
|
||||
}
|
||||
|
||||
void transformPostInference(
|
||||
TreeNode node, bool transformSetLiterals, bool transformCollections) {
|
||||
void transformPostInference(TreeNode node, bool transformSetLiterals,
|
||||
bool transformCollections, Library clientLibrary) {
|
||||
if (transformCollections) {
|
||||
node.accept(collectionTransformer ??= new CollectionTransformer(this));
|
||||
collectionTransformer ??= new CollectionTransformer(this);
|
||||
collectionTransformer.enterLibrary(clientLibrary);
|
||||
node.accept(collectionTransformer);
|
||||
collectionTransformer.exitLibrary();
|
||||
}
|
||||
if (transformSetLiterals) {
|
||||
node.accept(setLiteralTransformer ??= new SetLiteralTransformer(this));
|
||||
setLiteralTransformer ??= new SetLiteralTransformer(this);
|
||||
setLiteralTransformer.enterLibrary(clientLibrary);
|
||||
node.accept(setLiteralTransformer);
|
||||
setLiteralTransformer.exitLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
void transformListPostInference(List<TreeNode> list,
|
||||
bool transformSetLiterals, bool transformCollections) {
|
||||
void transformListPostInference(
|
||||
List<TreeNode> list,
|
||||
bool transformSetLiterals,
|
||||
bool transformCollections,
|
||||
Library clientLibrary) {
|
||||
if (transformCollections) {
|
||||
CollectionTransformer transformer =
|
||||
collectionTransformer ??= new CollectionTransformer(this);
|
||||
transformer.enterLibrary(clientLibrary);
|
||||
for (int i = 0; i < list.length; ++i) {
|
||||
list[i] = list[i].accept(transformer);
|
||||
}
|
||||
transformer.exitLibrary();
|
||||
}
|
||||
if (transformSetLiterals) {
|
||||
SetLiteralTransformer transformer =
|
||||
setLiteralTransformer ??= new SetLiteralTransformer(this);
|
||||
transformer.enterLibrary(clientLibrary);
|
||||
for (int i = 0; i < list.length; ++i) {
|
||||
list[i] = list[i].accept(transformer);
|
||||
}
|
||||
transformer.exitLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ advances
|
|||
advancing
|
||||
advice
|
||||
affect
|
||||
affected
|
||||
affects
|
||||
after
|
||||
again
|
||||
|
|
|
@ -78,7 +78,18 @@ class ExpressionLifter extends Transformer {
|
|||
final VariableDeclaration asyncResult = new VariableDeclaration(':result');
|
||||
final List<VariableDeclaration> variables = <VariableDeclaration>[];
|
||||
|
||||
ExpressionLifter(this.continuationRewriter);
|
||||
/// Library that contains the transformed nodes.
|
||||
///
|
||||
/// The transformation of the nodes is affected by the NNBD opt-in status of
|
||||
/// the library.
|
||||
Library _currentLibrary;
|
||||
|
||||
ExpressionLifter(this.continuationRewriter, this._currentLibrary) {
|
||||
assert(
|
||||
_currentLibrary != null,
|
||||
"Attempting to create an expression lifter "
|
||||
"without the client library.");
|
||||
}
|
||||
|
||||
Block blockOf(List<Statement> statements) {
|
||||
return new Block(statements.reversed.toList());
|
||||
|
@ -506,7 +517,10 @@ class ExpressionLifter extends Transformer {
|
|||
visitFunctionNode(FunctionNode node) {
|
||||
var nestedRewriter =
|
||||
new RecursiveContinuationRewriter(continuationRewriter.helper);
|
||||
return node.accept(nestedRewriter);
|
||||
nestedRewriter.enterLibrary(_currentLibrary);
|
||||
TreeNode result = node.accept(nestedRewriter);
|
||||
nestedRewriter.exitLibrary();
|
||||
return result;
|
||||
}
|
||||
|
||||
TreeNode visitBlockExpression(BlockExpression expr) {
|
||||
|
|
|
@ -45,7 +45,10 @@ Procedure transformProcedure(CoreTypes coreTypes, Procedure procedure,
|
|||
{bool productMode}) {
|
||||
var helper = new HelperNodes.fromCoreTypes(coreTypes, productMode);
|
||||
var rewriter = new RecursiveContinuationRewriter(helper);
|
||||
return rewriter.visitProcedure(procedure);
|
||||
rewriter.enterLibrary(procedure.enclosingLibrary);
|
||||
Procedure result = rewriter.visitProcedure(procedure);
|
||||
rewriter.exitLibrary();
|
||||
return result;
|
||||
}
|
||||
|
||||
class RecursiveContinuationRewriter extends Transformer {
|
||||
|
@ -57,6 +60,12 @@ class RecursiveContinuationRewriter extends Transformer {
|
|||
final VariableDeclaration asyncContextVariable =
|
||||
new VariableDeclaration(ContinuationVariables.awaitContextVar);
|
||||
|
||||
/// Library that contains the transformed nodes.
|
||||
///
|
||||
/// The transformation of the nodes is affected by the NNBD opt-in status of
|
||||
/// the library.
|
||||
Library _currentLibrary;
|
||||
|
||||
RecursiveContinuationRewriter(this.helper);
|
||||
|
||||
Component rewriteComponent(Component node) {
|
||||
|
@ -67,26 +76,54 @@ class RecursiveContinuationRewriter extends Transformer {
|
|||
return node.accept<TreeNode>(this);
|
||||
}
|
||||
|
||||
@override
|
||||
visitLibrary(Library node) {
|
||||
enterLibrary(node);
|
||||
Library result = super.visitLibrary(node);
|
||||
exitLibrary();
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
visitProcedure(Procedure node) {
|
||||
return node.isAbstract ? node : super.visitProcedure(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitFunctionNode(FunctionNode node) {
|
||||
switch (node.asyncMarker) {
|
||||
case AsyncMarker.Sync:
|
||||
case AsyncMarker.SyncYielding:
|
||||
node.transformChildren(new RecursiveContinuationRewriter(helper));
|
||||
node.transformChildren(new RecursiveContinuationRewriter(helper)
|
||||
..enterLibrary(_currentLibrary));
|
||||
return node;
|
||||
case AsyncMarker.SyncStar:
|
||||
return new SyncStarFunctionRewriter(helper, node).rewrite();
|
||||
return new SyncStarFunctionRewriter(helper, node, _currentLibrary)
|
||||
.rewrite();
|
||||
case AsyncMarker.Async:
|
||||
return new AsyncFunctionRewriter(helper, node).rewrite();
|
||||
return new AsyncFunctionRewriter(helper, node, _currentLibrary)
|
||||
.rewrite();
|
||||
case AsyncMarker.AsyncStar:
|
||||
return new AsyncStarFunctionRewriter(helper, node).rewrite();
|
||||
return new AsyncStarFunctionRewriter(helper, node, _currentLibrary)
|
||||
.rewrite();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void enterLibrary(Library library) {
|
||||
assert(
|
||||
_currentLibrary == null,
|
||||
"Attempting to enter library '${library.fileUri}' "
|
||||
"without having exited library '${_currentLibrary.fileUri}'.");
|
||||
_currentLibrary = library;
|
||||
}
|
||||
|
||||
void exitLibrary() {
|
||||
assert(_currentLibrary != null,
|
||||
"Attempting to exit a library without having entered one.");
|
||||
_currentLibrary = null;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter {
|
||||
|
@ -97,8 +134,15 @@ abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter {
|
|||
int capturedTryDepth = 0; // Deepest yield point within a try-block.
|
||||
int capturedCatchDepth = 0; // Deepest yield point within a catch-block.
|
||||
|
||||
ContinuationRewriterBase(HelperNodes helper, this.enclosingFunction)
|
||||
: super(helper);
|
||||
ContinuationRewriterBase(
|
||||
HelperNodes helper, this.enclosingFunction, Library enclosingLibrary)
|
||||
: super(helper) {
|
||||
assert(
|
||||
enclosingLibrary != null,
|
||||
"Attempting to create a continuation rewriter "
|
||||
"without the client library.");
|
||||
_currentLibrary = enclosingLibrary;
|
||||
}
|
||||
|
||||
/// Given a container [type], which is an instantiation of the given
|
||||
/// [containerClass] extract its element type.
|
||||
|
@ -184,14 +228,15 @@ abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter {
|
|||
class SyncStarFunctionRewriter extends ContinuationRewriterBase {
|
||||
final VariableDeclaration iteratorVariable;
|
||||
|
||||
SyncStarFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction)
|
||||
SyncStarFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction,
|
||||
Library enclosingLibrary)
|
||||
: iteratorVariable = new VariableDeclaration(':iterator')
|
||||
..type =
|
||||
new InterfaceType(helper.syncIteratorClass, Nullability.legacy, [
|
||||
..type = new InterfaceType(
|
||||
helper.syncIteratorClass, enclosingLibrary.nullable, [
|
||||
ContinuationRewriterBase.elementTypeFrom(
|
||||
helper.iterableClass, enclosingFunction.returnType)
|
||||
]),
|
||||
super(helper, enclosingFunction);
|
||||
super(helper, enclosingFunction, enclosingLibrary);
|
||||
|
||||
FunctionNode rewrite() {
|
||||
// :sync_op(:iterator) {
|
||||
|
@ -286,11 +331,12 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase {
|
|||
|
||||
ExpressionLifter expressionRewriter;
|
||||
|
||||
AsyncRewriterBase(HelperNodes helper, FunctionNode enclosingFunction)
|
||||
: super(helper, enclosingFunction) {}
|
||||
AsyncRewriterBase(HelperNodes helper, FunctionNode enclosingFunction,
|
||||
Library enclosingLibrary)
|
||||
: super(helper, enclosingFunction, enclosingLibrary);
|
||||
|
||||
void setupAsyncContinuations(List<Statement> statements) {
|
||||
expressionRewriter = new ExpressionLifter(this);
|
||||
expressionRewriter = new ExpressionLifter(this, _currentLibrary);
|
||||
|
||||
// var :async_stack_trace;
|
||||
statements.add(stackTraceVariable);
|
||||
|
@ -751,7 +797,7 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase {
|
|||
new Arguments(<Expression>[new VariableGet(streamVariable)],
|
||||
types: [valueVariable.type])),
|
||||
type: new InterfaceType(helper.streamIteratorClass,
|
||||
Nullability.legacy, [valueVariable.type]));
|
||||
_currentLibrary.nullable, [valueVariable.type]));
|
||||
|
||||
// await :for-iterator.moveNext()
|
||||
var condition = new AwaitExpression(new MethodInvocation(
|
||||
|
@ -905,8 +951,9 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase {
|
|||
class AsyncStarFunctionRewriter extends AsyncRewriterBase {
|
||||
VariableDeclaration controllerVariable;
|
||||
|
||||
AsyncStarFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction)
|
||||
: super(helper, enclosingFunction);
|
||||
AsyncStarFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction,
|
||||
Library enclosingLibrary)
|
||||
: super(helper, enclosingFunction, enclosingLibrary);
|
||||
|
||||
FunctionNode rewrite() {
|
||||
var statements = <Statement>[];
|
||||
|
@ -916,7 +963,7 @@ class AsyncStarFunctionRewriter extends AsyncRewriterBase {
|
|||
// _AsyncStarStreamController<T> :controller;
|
||||
controllerVariable = new VariableDeclaration(":controller",
|
||||
type: new InterfaceType(helper.asyncStarStreamControllerClass,
|
||||
Nullability.legacy, [elementType]));
|
||||
_currentLibrary.nullable, [elementType]));
|
||||
statements.add(controllerVariable);
|
||||
|
||||
// dynamic :controller_stream;
|
||||
|
@ -1022,8 +1069,9 @@ class AsyncFunctionRewriter extends AsyncRewriterBase {
|
|||
VariableDeclaration completerVariable;
|
||||
VariableDeclaration returnVariable;
|
||||
|
||||
AsyncFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction)
|
||||
: super(helper, enclosingFunction);
|
||||
AsyncFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction,
|
||||
Library enclosingLibrary)
|
||||
: super(helper, enclosingFunction, enclosingLibrary);
|
||||
|
||||
FunctionNode rewrite() {
|
||||
var statements = <Statement>[];
|
||||
|
@ -1038,11 +1086,11 @@ class AsyncFunctionRewriter extends AsyncRewriterBase {
|
|||
valueType = elementTypeFromReturnType(helper.futureOrClass);
|
||||
}
|
||||
final DartType returnType = new InterfaceType(
|
||||
helper.futureOrClass, Nullability.legacy, <DartType>[valueType]);
|
||||
helper.futureOrClass, _currentLibrary.nullable, <DartType>[valueType]);
|
||||
var completerTypeArguments = <DartType>[valueType];
|
||||
|
||||
final completerType = new InterfaceType(helper.asyncAwaitCompleterClass,
|
||||
Nullability.legacy, completerTypeArguments);
|
||||
_currentLibrary.nonNullable, completerTypeArguments);
|
||||
// final Completer<T> :async_completer = new _AsyncAwaitCompleter<T>();
|
||||
completerVariable = new VariableDeclaration(":async_completer",
|
||||
initializer: new ConstructorInvocation(
|
||||
|
|
|
@ -129,6 +129,12 @@ class _WidgetCallSiteTransformer extends Transformer {
|
|||
|
||||
WidgetCreatorTracker _tracker;
|
||||
|
||||
/// Library that contains the transformed call sites.
|
||||
///
|
||||
/// The transformation of the call sites is affected by the NNBD opt-in status
|
||||
/// of the library.
|
||||
Library _currentLibrary;
|
||||
|
||||
_WidgetCallSiteTransformer(
|
||||
{@required Class widgetClass,
|
||||
@required Class locationClass,
|
||||
|
@ -271,11 +277,26 @@ class _WidgetCallSiteTransformer extends Transformer {
|
|||
location,
|
||||
parameterLocations: new ListLiteral(
|
||||
parameterLocations,
|
||||
typeArgument: new InterfaceType(_locationClass, Nullability.legacy),
|
||||
typeArgument:
|
||||
new InterfaceType(_locationClass, _currentLibrary.nonNullable),
|
||||
isConst: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void enterLibrary(Library library) {
|
||||
assert(
|
||||
_currentLibrary == null,
|
||||
"Attempting to enter library '${library.fileUri}' "
|
||||
"without having exited library '${_currentLibrary.fileUri}'.");
|
||||
_currentLibrary = library;
|
||||
}
|
||||
|
||||
void exitLibrary() {
|
||||
assert(_currentLibrary != null,
|
||||
"Attempting to exit a library without having entered one.");
|
||||
_currentLibrary = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Rewrites all widget constructors and constructor invocations to add a
|
||||
|
@ -345,7 +366,8 @@ class WidgetCreatorTracker {
|
|||
_hasCreationLocationClass.enclosingLibrary,
|
||||
);
|
||||
final Field locationField = new Field(fieldName,
|
||||
type: new InterfaceType(_locationClass, Nullability.legacy),
|
||||
type: new InterfaceType(
|
||||
_locationClass, clazz.enclosingLibrary.nonNullable),
|
||||
isFinal: true,
|
||||
reference: clazz.reference.canonicalName
|
||||
?.getChildFromFieldWithName(fieldName)
|
||||
|
@ -365,7 +387,8 @@ class WidgetCreatorTracker {
|
|||
));
|
||||
final VariableDeclaration variable = new VariableDeclaration(
|
||||
_creationLocationParameterName,
|
||||
type: new InterfaceType(_locationClass, Nullability.legacy),
|
||||
type: new InterfaceType(
|
||||
_locationClass, clazz.enclosingLibrary.nonNullable),
|
||||
);
|
||||
if (!_maybeAddNamedParameter(constructor.function, variable)) {
|
||||
return;
|
||||
|
@ -458,7 +481,9 @@ class WidgetCreatorTracker {
|
|||
if (library.isExternal) {
|
||||
continue;
|
||||
}
|
||||
callsiteTransformer.enterLibrary(library);
|
||||
library.transformChildren(callsiteTransformer);
|
||||
callsiteTransformer.exitLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -497,10 +522,10 @@ class WidgetCreatorTracker {
|
|||
if (procedure.isFactory) {
|
||||
_maybeAddNamedParameter(
|
||||
procedure.function,
|
||||
new VariableDeclaration(
|
||||
_creationLocationParameterName,
|
||||
type: new InterfaceType(_locationClass, Nullability.legacy),
|
||||
),
|
||||
new VariableDeclaration(_creationLocationParameterName,
|
||||
type: new InterfaceType(
|
||||
_locationClass, clazz.enclosingLibrary.nonNullable),
|
||||
isRequired: clazz.enclosingLibrary.isNonNullableByDefault),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -521,9 +546,10 @@ class WidgetCreatorTracker {
|
|||
}
|
||||
|
||||
final VariableDeclaration variable = new VariableDeclaration(
|
||||
_creationLocationParameterName,
|
||||
type: new InterfaceType(_locationClass, Nullability.legacy),
|
||||
);
|
||||
_creationLocationParameterName,
|
||||
type: new InterfaceType(
|
||||
_locationClass, clazz.enclosingLibrary.nonNullable),
|
||||
isRequired: clazz.enclosingLibrary.isNonNullableByDefault);
|
||||
if (_hasNamedParameter(
|
||||
constructor.function, _creationLocationParameterName)) {
|
||||
// Constructor was already rewritten. TODO(jacobr): is this case actually hit?
|
||||
|
|
|
@ -438,7 +438,7 @@ class TypeCheckingVisitor
|
|||
handleCall(arguments, target.function.thisFunctionType,
|
||||
typeParameters: class_.typeParameters);
|
||||
return new InterfaceType(
|
||||
target.enclosingClass, Nullability.legacy, arguments.types);
|
||||
target.enclosingClass, currentLibrary.nonNullable, arguments.types);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -748,7 +748,7 @@ class TypeCheckingVisitor
|
|||
checkAssignable(node, fieldType, valueType);
|
||||
});
|
||||
return new InterfaceType(
|
||||
node.classNode, Nullability.legacy, node.typeArguments);
|
||||
node.classNode, currentLibrary.nonNullable, node.typeArguments);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
Loading…
Reference in a new issue