[kernel] Make .function non-nullable on Procedure, Constructor, and LocalFunction

TEST=existing

Change-Id: I4d0ae16291414e58207b7de0466d989d27997619
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195074
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
Johnni Winther
2021-04-14 08:17:28 +00:00
committed by commit-bot@chromium.org
parent 0c22d58a7e
commit d8f2b7cc44
24 changed files with 180 additions and 202 deletions
@@ -141,7 +141,7 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
int charEndOffset,
Member referenceFrom,
[String nativeMethodName])
: _constructor = new Constructor(null,
: _constructor = new Constructor(new FunctionNode(null),
name: new Name(name, compilationUnit.library),
fileUri: compilationUnit.fileUri,
reference: referenceFrom?.reference)
@@ -161,6 +161,8 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
@override
Member get invokeTarget => constructor;
FunctionNode get function => _constructor.function;
@override
Iterable<Member> get exportedMembers => [constructor];
@@ -202,8 +204,7 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
@override
Constructor build(SourceLibraryBuilder libraryBuilder) {
if (!_hasBeenBuilt) {
_constructor.function = buildFunction(libraryBuilder);
_constructor.function.parent = _constructor;
buildFunction(libraryBuilder);
_constructor.function.fileOffset = charOpenParenOffset;
_constructor.function.fileEndOffset = _constructor.fileEndOffset;
_constructor.function.typeParameters = const <TypeParameter>[];
@@ -263,10 +264,10 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
}
@override
FunctionNode buildFunction(SourceLibraryBuilder library) {
void buildFunction(SourceLibraryBuilder library) {
// According to the specification §9.3 the return type of a constructor
// function is its enclosing class.
FunctionNode functionNode = super.buildFunction(library);
super.buildFunction(library);
ClassBuilder enclosingClassBuilder = parent;
Class enclosingClass = enclosingClassBuilder.cls;
List<DartType> typeParameterTypes = <DartType>[];
@@ -276,9 +277,8 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
new TypeParameterType.withDefaultNullabilityForLibrary(
typeParameter, library.library));
}
functionNode.returnType = new InterfaceType(
function.returnType = new InterfaceType(
enclosingClass, library.nonNullable, typeParameterTypes);
return functionNode;
}
@override
@@ -293,9 +293,6 @@ abstract class FunctionBuilderImpl extends MemberBuilderImpl
@override
final String nativeMethodName;
@override
FunctionNode function;
Statement bodyInternal;
@override
@@ -308,18 +305,16 @@ abstract class FunctionBuilderImpl extends MemberBuilderImpl
// }
// }
bodyInternal = newBody;
if (function != null) {
// A forwarding semi-stub is a method that is abstract in the source code,
// but which needs to have a forwarding stub body in order to ensure that
// covariance checks occur. We don't want to replace the forwarding stub
// body with null.
TreeNode parent = function.parent;
if (!(newBody == null &&
parent is Procedure &&
parent.isForwardingSemiStub)) {
function.body = newBody;
newBody?.parent = function;
}
// A forwarding semi-stub is a method that is abstract in the source code,
// but which needs to have a forwarding stub body in order to ensure that
// covariance checks occur. We don't want to replace the forwarding stub
// body with null.
TreeNode parent = function.parent;
if (!(newBody == null &&
parent is Procedure &&
parent.isForwardingSemiStub)) {
function.body = newBody;
newBody?.parent = function;
}
}
@@ -342,9 +337,10 @@ abstract class FunctionBuilderImpl extends MemberBuilderImpl
@override
bool get isNative => nativeMethodName != null;
FunctionNode buildFunction(SourceLibraryBuilder library) {
assert(function == null);
FunctionNode result = new FunctionNode(body, asyncMarker: asyncModifier);
void buildFunction(SourceLibraryBuilder library) {
function.asyncMarker = asyncModifier;
function.body = body;
body?.parent = function;
IncludesTypeParametersNonCovariantly needsCheckVisitor;
if (!isConstructor && !isFactory && parent is ClassBuilder) {
ClassBuilder enclosingClassBuilder = parent;
@@ -360,14 +356,14 @@ abstract class FunctionBuilderImpl extends MemberBuilderImpl
if (typeVariables != null) {
for (TypeVariableBuilder t in typeVariables) {
TypeParameter parameter = t.parameter;
result.typeParameters.add(parameter);
function.typeParameters.add(parameter);
if (needsCheckVisitor != null) {
if (parameter.bound.accept(needsCheckVisitor)) {
parameter.isGenericCovariantImpl = true;
}
}
}
setParents(result.typeParameters, result);
setParents(function.typeParameters, function);
}
if (formals != null) {
for (FormalParameterBuilder formal in formals) {
@@ -379,13 +375,13 @@ abstract class FunctionBuilderImpl extends MemberBuilderImpl
}
}
if (formal.isNamed) {
result.namedParameters.add(parameter);
function.namedParameters.add(parameter);
} else {
result.positionalParameters.add(parameter);
function.positionalParameters.add(parameter);
}
parameter.parent = result;
parameter.parent = function;
if (formal.isRequired) {
result.requiredParameterCount++;
function.requiredParameterCount++;
}
if (library.isNonNullableByDefault) {
@@ -409,14 +405,14 @@ abstract class FunctionBuilderImpl extends MemberBuilderImpl
// assumes that parameters are built, even if illegal in number.
VariableDeclaration parameter =
new VariableDeclarationImpl("#synthetic", 0);
result.positionalParameters.clear();
result.positionalParameters.add(parameter);
parameter.parent = result;
result.namedParameters.clear();
result.requiredParameterCount = 1;
function.positionalParameters.clear();
function.positionalParameters.add(parameter);
parameter.parent = function;
function.namedParameters.clear();
function.requiredParameterCount = 1;
}
if (returnType != null) {
result.returnType = returnType.build(
function.returnType = returnType.build(
library, null, !isConstructor && !isDeclarationInstanceMember);
}
if (!isConstructor && !isDeclarationInstanceMember) {
@@ -444,33 +440,32 @@ abstract class FunctionBuilderImpl extends MemberBuilderImpl
}
Set<TypeParameter> set = typeParameters.toSet();
for (VariableDeclaration parameter in result.positionalParameters) {
for (VariableDeclaration parameter in function.positionalParameters) {
if (containsTypeVariable(parameter.type, set)) {
parameter.type = removeTypeVariables(parameter.type);
}
}
for (VariableDeclaration parameter in result.namedParameters) {
for (VariableDeclaration parameter in function.namedParameters) {
if (containsTypeVariable(parameter.type, set)) {
parameter.type = removeTypeVariables(parameter.type);
}
}
if (containsTypeVariable(result.returnType, set)) {
result.returnType = removeTypeVariables(result.returnType);
if (containsTypeVariable(function.returnType, set)) {
function.returnType = removeTypeVariables(function.returnType);
}
}
}
if (isExtensionInstanceMember) {
ExtensionBuilder extensionBuilder = parent;
_extensionThis = result.positionalParameters.first;
_extensionThis = function.positionalParameters.first;
if (extensionBuilder.typeParameters != null) {
int count = extensionBuilder.typeParameters.length;
_extensionTypeParameters = new List<TypeParameter>.filled(count, null);
for (int index = 0; index < count; index++) {
_extensionTypeParameters[index] = result.typeParameters[index];
_extensionTypeParameters[index] = function.typeParameters[index];
}
}
}
return function = result;
}
@override
@@ -107,15 +107,20 @@ abstract class ProcedureBuilderImpl extends FunctionBuilderImpl
this.isExtensionInstanceMember = isInstanceMember && isExtensionMember,
super(metadata, modifiers, returnType, name, typeVariables, formals,
libraryBuilder, charOffset, nativeMethodName) {
_procedure = new Procedure(procedureNameScheme.getName(kind, name),
isExtensionInstanceMember ? ProcedureKind.Method : kind, null,
fileUri: libraryBuilder.fileUri, reference: procedureReference)
_procedure = new Procedure(
procedureNameScheme.getName(kind, name),
isExtensionInstanceMember ? ProcedureKind.Method : kind,
new FunctionNode(null),
fileUri: libraryBuilder.fileUri,
reference: procedureReference)
..startFileOffset = startCharOffset
..fileOffset = charOffset
..fileEndOffset = charEndOffset
..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault;
}
FunctionNode get function => _procedure.function;
@override
ProcedureBuilder get origin => actualOrigin ?? this;
@@ -136,11 +141,8 @@ abstract class ProcedureBuilderImpl extends FunctionBuilderImpl
@override
void set asyncModifier(AsyncMarker newModifier) {
actualAsyncModifier = newModifier;
if (function != null) {
// No parent, it's an enum.
function.asyncMarker = actualAsyncModifier;
function.dartAsyncMarker = actualAsyncModifier;
}
function.asyncMarker = actualAsyncModifier;
function.dartAsyncMarker = actualAsyncModifier;
}
@override
@@ -266,7 +268,7 @@ class SourceProcedureBuilder extends ProcedureBuilderImpl {
_extensionTearOff ??= new Procedure(
procedureNameScheme.getName(ProcedureKind.Getter, name),
ProcedureKind.Method,
null,
new FunctionNode(null),
isStatic: true,
isExtensionMember: true,
reference: _tearOffReference)
@@ -379,8 +381,7 @@ class SourceProcedureBuilder extends ProcedureBuilderImpl {
@override
Procedure build(SourceLibraryBuilder libraryBuilder) {
_procedure.function = buildFunction(libraryBuilder);
_procedure.function.parent = _procedure;
buildFunction(libraryBuilder);
_procedure.function.fileOffset = charOpenParenOffset;
_procedure.function.fileEndOffset = _procedure.fileEndOffset;
_procedure.isAbstract = isAbstract;
@@ -747,8 +748,7 @@ class RedirectingFactoryBuilder extends ProcedureBuilderImpl {
@override
Procedure build(SourceLibraryBuilder libraryBuilder) {
_procedure.function = buildFunction(libraryBuilder);
_procedure.function.parent = _procedure;
buildFunction(libraryBuilder);
_procedure.function.fileOffset = charOpenParenOffset;
_procedure.function.fileEndOffset = _procedure.fileEndOffset;
_procedure.isAbstract = isAbstract;
@@ -4999,8 +4999,8 @@ class BodyBuilder extends ScopeListener<JumpTarget>
}
push(new FunctionDeclarationImpl(
variable,
// The function node is created later.
null)
// The real function node is created later.
dummyFunctionNode)
..fileOffset = beginToken.charOffset);
declareVariable(variable, scope.parent);
}
@@ -95,7 +95,7 @@ class Covariance {
/// Computes the covariance for the [setter].
factory Covariance.fromSetter(Procedure setter) {
int covariance =
covarianceFromParameter(setter.function!.positionalParameters.first);
covarianceFromParameter(setter.function.positionalParameters.first);
if (covariance == 0) {
return const Covariance.empty();
}
@@ -104,7 +104,7 @@ class Covariance {
/// Computes the covariance for the [procedure].
factory Covariance.fromMethod(Procedure procedure) {
FunctionNode function = procedure.function!;
FunctionNode function = procedure.function;
List<int>? positionalParameters;
if (function.positionalParameters.isNotEmpty) {
for (int index = 0;
@@ -269,7 +269,7 @@ class Covariance {
void applyCovariance(Member member) {
if (isEmpty) return;
if (member is Procedure) {
FunctionNode function = member.function!;
FunctionNode function = member.function;
List<int>? positionalParameters = _positionalParameters;
if (positionalParameters != null) {
for (int index = 0; index < positionalParameters.length; index++) {
+2 -3
View File
@@ -147,7 +147,7 @@ type CanonicalName {
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
UInt32 formatVersion = 60;
UInt32 formatVersion = 61;
Byte[10] shortSdkHash;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
@@ -425,8 +425,7 @@ type Procedure extends Member {
Name name;
List<Expression> annotations;
MemberReference stubTarget; // May be NullReference.
// Can only be absent if abstract, but tag is there anyway.
Option<FunctionNode> function;
FunctionNode function;
}
type RedirectingFactoryConstructor extends Member {
+50 -40
View File
@@ -1988,9 +1988,8 @@ class Constructor extends Member {
int flags = 0;
// TODO(johnniwinther): Make this non-nullable.
@override
FunctionNode? function;
FunctionNode function;
List<Initializer> initializers;
@@ -2004,8 +2003,10 @@ class Constructor extends Member {
Uri? fileUri,
Reference? reference})
: this.initializers = initializers ?? <Initializer>[],
// ignore: unnecessary_null_comparison
assert(function != null),
super(name, fileUri, reference) {
function?.parent = this;
function.parent = this;
setParents(this.initializers, this);
this.isConst = isConst;
this.isExternal = isExternal;
@@ -2082,16 +2083,17 @@ class Constructor extends Member {
visitList(annotations, v);
name.accept(v);
visitList(initializers, v);
function?.accept(v);
function.accept(v);
}
@override
void transformChildren(Transformer v) {
v.transformList(annotations, this);
v.transformList(initializers, this);
// ignore: unnecessary_null_comparison
if (function != null) {
function = v.transform(function!);
function?.parent = this;
function = v.transform(function);
function.parent = this;
}
}
@@ -2099,9 +2101,10 @@ class Constructor extends Member {
void transformOrRemoveChildren(RemovingTransformer v) {
v.transformExpressionList(annotations, this);
v.transformInitializerList(initializers, this);
// ignore: unnecessary_null_comparison
if (function != null) {
function = v.transformOrRemove(function!, dummyFunctionNode);
function?.parent = this;
function = v.transform(function);
function.parent = this;
}
}
@@ -2504,16 +2507,15 @@ class Procedure extends Member {
final ProcedureKind kind;
int flags = 0;
// TODO(johnniwinther): Make this non-nullable.
@override
FunctionNode? function;
FunctionNode function;
// The function node's body might be lazily loaded, meaning that this value
// might not be set correctly yet. Make sure the body is loaded before
// returning anything.
@override
int get transformerFlags {
function?.body;
function.body;
return super.transformerFlags;
}
@@ -2522,7 +2524,7 @@ class Procedure extends Member {
// body now and only set the value afterwards.
@override
void set transformerFlags(int newValue) {
function?.body;
function.body;
super.transformerFlags = newValue;
}
@@ -2536,7 +2538,7 @@ class Procedure extends Member {
ProcedureStubKind stubKind;
Reference? stubTargetReference;
Procedure(Name name, ProcedureKind kind, FunctionNode? function,
Procedure(Name name, ProcedureKind kind, FunctionNode function,
{bool isAbstract: false,
bool isStatic: false,
bool isExternal: false,
@@ -2576,15 +2578,17 @@ class Procedure extends Member {
this.stubTargetReference})
// ignore: unnecessary_null_comparison
: assert(kind != null),
// ignore: unnecessary_null_comparison
assert(function != null),
super(name, fileUri, reference) {
function?.parent = this;
function.parent = this;
this.isAbstract = isAbstract;
this.isStatic = isStatic;
this.isExternal = isExternal;
this.isConst = isConst;
this.isExtensionMember = isExtensionMember;
this.isSynthetic = isSynthetic;
this.transformerFlags = transformerFlags;
setTransformerFlagsWithoutLazyLoading(transformerFlags);
assert(!(isMemberSignature && stubTargetReference == null),
"No member signature origin for member signature $this.");
assert(
@@ -2753,38 +2757,40 @@ class Procedure extends Member {
void visitChildren(Visitor v) {
visitList(annotations, v);
name.accept(v);
function?.accept(v);
function.accept(v);
}
@override
void transformChildren(Transformer v) {
v.transformList(annotations, this);
// ignore: unnecessary_null_comparison
if (function != null) {
function = v.transform(function!);
function?.parent = this;
function = v.transform(function);
function.parent = this;
}
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
v.transformExpressionList(annotations, this);
// ignore: unnecessary_null_comparison
if (function != null) {
function = v.transformOrRemove(function!, dummyFunctionNode);
function?.parent = this;
function = v.transform(function);
function.parent = this;
}
}
@override
DartType get getterType {
return isGetter
? function!.returnType
: function!.computeFunctionType(enclosingLibrary.nonNullable);
? function.returnType
: function.computeFunctionType(enclosingLibrary.nonNullable);
}
@override
DartType get setterType {
return isSetter
? function!.positionalParameters[0].type
? function.positionalParameters[0].type
: const NeverType.nonNullable();
}
@@ -6025,9 +6031,9 @@ class SuperMethodInvocation extends InvocationExpression {
.getTypeArgumentsAsInstanceOf(context.thisType!, superclass);
DartType returnType = Substitution.fromPairs(
superclass.typeParameters, receiverTypeArguments!)
.substituteType(interfaceTarget.function!.returnType);
.substituteType(interfaceTarget.function.returnType);
return Substitution.fromPairs(
interfaceTarget.function!.typeParameters, arguments.types)
interfaceTarget.function.typeParameters, arguments.types)
.substituteType(returnType);
}
@@ -6114,8 +6120,8 @@ class StaticInvocation extends InvocationExpression {
@override
DartType getStaticTypeInternal(StaticTypeContext context) {
return Substitution.fromPairs(
target.function!.typeParameters, arguments.types)
.substituteType(target.function!.returnType);
target.function.typeParameters, arguments.types)
.substituteType(target.function.returnType);
}
@override
@@ -8077,8 +8083,7 @@ class AwaitExpression extends Expression {
/// Common super-interface for [FunctionExpression] and [FunctionDeclaration].
abstract class LocalFunction implements TreeNode {
// TODO(johnniwinther): Make this non-nullable.
FunctionNode? get function;
FunctionNode get function;
}
/// Expression of form `(x,y) => ...` or `(x,y) { ... }`
@@ -10118,11 +10123,13 @@ class FunctionDeclaration extends Statement implements LocalFunction {
VariableDeclaration variable; // Is final and has no initializer.
@override
FunctionNode? function;
FunctionNode function;
FunctionDeclaration(this.variable, this.function) {
FunctionDeclaration(this.variable, this.function)
// ignore: unnecessary_null_comparison
: assert(function != null) {
variable.parent = this;
function?.parent = this;
function.parent = this;
}
@override
@@ -10135,7 +10142,7 @@ class FunctionDeclaration extends Statement implements LocalFunction {
@override
void visitChildren(Visitor v) {
variable.accept(v);
function?.accept(v);
function.accept(v);
}
@override
@@ -10145,9 +10152,10 @@ class FunctionDeclaration extends Statement implements LocalFunction {
variable = v.transform(variable);
variable.parent = this;
}
// ignore: unnecessary_null_comparison
if (function != null) {
function = v.transform(function!);
function?.parent = this;
function = v.transform(function);
function.parent = this;
}
}
@@ -10158,9 +10166,10 @@ class FunctionDeclaration extends Statement implements LocalFunction {
variable = v.transform(variable);
variable.parent = this;
}
// ignore: unnecessary_null_comparison
if (function != null) {
function = v.transformOrRemove(function!, dummyFunctionNode);
function?.parent = this;
function = v.transform(function);
function.parent = this;
}
}
@@ -10171,9 +10180,10 @@ class FunctionDeclaration extends Statement implements LocalFunction {
@override
void toTextInternal(AstPrinter printer) {
// ignore: unnecessary_null_comparison
if (function != null) {
printer.writeFunctionNode(function!, printer.getVariableName(variable));
if (function!.body is ReturnStatement) {
printer.writeFunctionNode(function, printer.getVariableName(variable));
if (function.body is ReturnStatement) {
printer.write(';');
}
}
@@ -12624,7 +12634,7 @@ class TearOffConstant extends Constant {
}
FunctionType getType(StaticTypeContext context) {
return procedure.function!.computeFunctionType(context.nonNullable);
return procedure.function.computeFunctionType(context.nonNullable);
}
}
+17 -23
View File
@@ -499,7 +499,7 @@ class BinaryBuilder {
}
}
List<Expression> readAnnotationList(TreeNode? parent) {
List<Expression> readAnnotationList([TreeNode? parent]) {
int length = readUInt30();
if (length == 0) return const <Expression>[];
return new List<Expression>.generate(
@@ -1493,15 +1493,15 @@ class BinaryBuilder {
int fileEndOffset = readOffset();
int flags = readByte();
Name name = readName();
if (node == null) {
node = new Constructor(null, reference: reference, name: name);
}
List<Expression> annotations = readAnnotationList(node);
List<Expression> annotations = readAnnotationList();
assert(() {
debugPath.add(name.text);
return true;
}());
FunctionNode function = readFunctionNode();
if (node == null) {
node = new Constructor(function, reference: reference, name: name);
}
pushVariableDeclarations(function.positionalParameters);
pushVariableDeclarations(function.namedParameters);
_fillTreeNodeList(node.initializers, (index) => readInitializer(), node);
@@ -1515,6 +1515,7 @@ class BinaryBuilder {
node.name = name;
node.fileUri = fileUri;
node.annotations = annotations;
setParents(annotations, node);
node.function = function..parent = node;
node.transformerFlags = transformerFlags;
return node;
@@ -1538,12 +1539,7 @@ class BinaryBuilder {
ProcedureStubKind stubKind = ProcedureStubKind.values[readByte()];
int flags = readUInt30();
Name name = readName();
if (node == null) {
node = new Procedure(name, kind, null, reference: reference);
} else {
assert(node.kind == kind);
}
List<Expression> annotations = readAnnotationList(node);
List<Expression> annotations = readAnnotationList();
assert(() {
debugPath.add(name.text);
return true;
@@ -1554,8 +1550,13 @@ class BinaryBuilder {
(kind == ProcedureKind.Factory && functionNodeSize <= 50) ||
_disableLazyReading;
Reference? stubTargetReference = readNullableMemberReference();
FunctionNode? function =
readFunctionNodeOption(!readFunctionNodeNow, endOffset);
FunctionNode function = readFunctionNode(
lazyLoadBody: !readFunctionNodeNow, outerEndOffset: endOffset);
if (node == null) {
node = new Procedure(name, kind, function, reference: reference);
} else {
assert(node.kind == kind);
}
int transformerFlags = getAndResetTransformerFlags();
assert(((_) => true)(debugPath.removeLast()));
node.startFileOffset = startFileOffset;
@@ -1565,15 +1566,15 @@ class BinaryBuilder {
node.name = name;
node.fileUri = fileUri;
node.annotations = annotations;
node.function = function;
function?.parent = node;
setParents(annotations, node);
node.function = function..parent = node;
node.setTransformerFlagsWithoutLazyLoading(transformerFlags);
node.stubKind = stubKind;
node.stubTargetReference = stubTargetReference;
assert((node.stubKind == ProcedureStubKind.ConcreteForwardingStub &&
node.stubTargetReference != null) ||
!(node.isForwardingStub && node.function!.body != null));
!(node.isForwardingStub && node.function.body != null));
assert(!(node.isMemberSignature && node.stubTargetReference == null),
"No member signature origin for member signature $node.");
return node;
@@ -1686,13 +1687,6 @@ class BinaryBuilder {
return new AssertInitializer(readStatement() as AssertStatement);
}
FunctionNode? readFunctionNodeOption(bool lazyLoadBody, int outerEndOffset) {
return readAndCheckOptionTag()
? readFunctionNode(
lazyLoadBody: lazyLoadBody, outerEndOffset: outerEndOffset)
: null;
}
FunctionNode readFunctionNode(
{bool lazyLoadBody: false, int outerEndOffset: -1}) {
int tag = readByte();
+7 -16
View File
@@ -488,15 +488,6 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
}
}
void writeOptionalFunctionNode(FunctionNode? node) {
if (node == null) {
writeByte(Tag.Nothing);
} else {
writeByte(Tag.Something);
writeFunctionNode(node);
}
}
void writeLinkTable(Component component) {
_binaryOffsetForLinkTable = getBufferOffset();
writeList(_canonicalNameList, writeCanonicalNameEntry);
@@ -1209,12 +1200,12 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
writeName(node.name);
writeAnnotationList(node.annotations);
assert(node.function!.typeParameters.isEmpty);
writeFunctionNode(node.function!);
assert(node.function.typeParameters.isEmpty);
writeFunctionNode(node.function);
// Parameters are in scope in the initializers.
_variableIndexer ??= new VariableIndexer();
_variableIndexer!.restoreScope(node.function!.positionalParameters.length +
node.function!.namedParameters.length);
_variableIndexer!.restoreScope(node.function.positionalParameters.length +
node.function.namedParameters.length);
writeNodeList(node.initializers);
leaveScope(memberScope: true);
@@ -1273,13 +1264,13 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
writeName(node.name);
writeAnnotationList(node.annotations);
writeNullAllowedReference(node.stubTargetReference);
writeOptionalFunctionNode(node.function);
writeFunctionNode(node.function);
leaveScope(memberScope: true);
_currentlyInNonimplementation = currentlyInNonimplementationSaved;
assert(
(node.concreteForwardingStubTarget != null) ||
!(node.isForwardingStub && node.function!.body != null),
!(node.isForwardingStub && node.function.body != null),
"Invalid forwarding stub $node.");
}
@@ -2251,7 +2242,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
writeByte(Tag.FunctionDeclaration);
writeOffset(node.fileOffset);
writeVariableDeclaration(node.variable);
writeFunctionNode(node.function!);
writeFunctionNode(node.function);
}
@override
+1 -1
View File
@@ -174,7 +174,7 @@ class Tag {
/// Internal version of kernel binary format.
/// Bump it when making incompatible changes in kernel binaries.
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
static const int BinaryFormatVersion = 60;
static const int BinaryFormatVersion = 61;
}
abstract class ConstantTag {
+4 -4
View File
@@ -485,8 +485,8 @@ class CloneVisitorNotMembers implements TreeVisitor<TreeNode> {
// Create the declaration before cloning the body to support recursive
// [LocalFunctionInvocation] nodes.
FunctionDeclaration declaration =
new FunctionDeclaration(newVariable, null);
FunctionNode functionNode = clone(node.function!);
new FunctionDeclaration(newVariable, dummyFunctionNode);
FunctionNode functionNode = clone(node.function);
declaration.function = functionNode..parent = declaration;
return declaration;
}
@@ -757,7 +757,7 @@ class CloneVisitorWithMembers extends CloneVisitorNotMembers {
_activeFileUri = node.fileUri ?? _activeFileUri;
Constructor result = new Constructor(
super.clone(node.function!),
super.clone(node.function),
name: node.name,
isConst: node.isConst,
isExternal: node.isExternal,
@@ -781,7 +781,7 @@ class CloneVisitorWithMembers extends CloneVisitorNotMembers {
final Uri? activeFileUriSaved = _activeFileUri;
_activeFileUri = node.fileUri ?? _activeFileUri;
Procedure result = new Procedure(
node.name, node.kind, super.clone(node.function!),
node.name, node.kind, super.clone(node.function),
reference: reference,
transformerFlags: node.transformerFlags,
fileUri: _activeFileUri,
+6 -5
View File
@@ -1206,13 +1206,13 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
case ProcedureStubKind.ConcreteForwardingStub:
case ProcedureStubKind.NoSuchMethodForwarder:
case ProcedureStubKind.ConcreteMixinStub:
writeFunction(node.function!, name: getMemberName(node));
writeFunction(node.function, name: getMemberName(node));
break;
case ProcedureStubKind.MemberSignature:
case ProcedureStubKind.AbstractMixinStub:
writeFunction(node.function!,
writeFunction(node.function,
name: getMemberName(node), terminateLine: false);
if (node.function!.body is ReturnStatement) {
if (node.function.body is ReturnStatement) {
writeSymbol(';');
}
writeSymbol(' -> ');
@@ -1241,7 +1241,7 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
if (features.isNotEmpty) {
writeWord("/*${features.join(',')}*/");
}
writeFunction(node.function!,
writeFunction(node.function,
name: node.name, initializers: node.initializers);
}
@@ -2289,8 +2289,9 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeAnnotationList(node.variable.annotations);
writeIndentation();
writeWord('function');
// ignore: unnecessary_null_comparison
if (node.function != null) {
writeFunction(node.function!, name: getVariableName(node.variable));
writeFunction(node.function, name: getVariableName(node.variable));
} else {
writeWord(getVariableName(node.variable));
endLine('...;');
+7 -7
View File
@@ -1750,7 +1750,7 @@ TextSerializer<ContinueSwitchStatement> continueSwitchStatementSerializer =
TextSerializer<FunctionDeclaration> functionDeclarationSerializer =
Wrapped<Tuple2<VariableDeclaration, FunctionNode>, FunctionDeclaration>(
(w) => Tuple2(w.variable, w.function!),
(w) => Tuple2(w.variable, w.function),
(u) => FunctionDeclaration(u.first, u.second),
Rebind(variableDeclarationSerializer, functionNodeSerializer));
@@ -1983,7 +1983,7 @@ TextSerializer<Field> immutableFieldSerializer =
TextSerializer<Procedure> methodSerializer =
Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
(w) => Tuple3(w.name, w.flags, w.function!),
(w) => Tuple3(w.name, w.flags, w.function),
(u) =>
Procedure(u.first, ProcedureKind.Method, u.third)..flags = u.second,
Tuple3Serializer(
@@ -1991,7 +1991,7 @@ TextSerializer<Procedure> methodSerializer =
TextSerializer<Procedure> getterSerializer =
Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
(w) => Tuple3(w.name, w.flags, w.function!),
(w) => Tuple3(w.name, w.flags, w.function),
(u) =>
Procedure(u.first, ProcedureKind.Getter, u.third)..flags = u.second,
Tuple3Serializer(
@@ -1999,7 +1999,7 @@ TextSerializer<Procedure> getterSerializer =
TextSerializer<Procedure> setterSerializer =
Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
(w) => Tuple3(w.name, w.flags, w.function!),
(w) => Tuple3(w.name, w.flags, w.function),
(u) =>
Procedure(u.first, ProcedureKind.Setter, u.third)..flags = u.second,
Tuple3Serializer(
@@ -2007,7 +2007,7 @@ TextSerializer<Procedure> setterSerializer =
TextSerializer<Procedure> operatorSerializer =
Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
(w) => Tuple3(w.name, w.flags, w.function!),
(w) => Tuple3(w.name, w.flags, w.function),
(u) => Procedure(u.first, ProcedureKind.Operator, u.third)
..flags = u.second,
Tuple3Serializer(
@@ -2015,7 +2015,7 @@ TextSerializer<Procedure> operatorSerializer =
TextSerializer<Procedure> factorySerializer =
Wrapped<Tuple3<Name, int, FunctionNode>, Procedure>(
(w) => Tuple3(w.name, w.flags, w.function!),
(w) => Tuple3(w.name, w.flags, w.function),
(u) => Procedure(u.first, ProcedureKind.Factory, u.third)
..flags = u.second,
Tuple3Serializer(
@@ -2024,7 +2024,7 @@ TextSerializer<Procedure> factorySerializer =
TextSerializer<Constructor> constructorSerializer = Wrapped<
Tuple3<Name, int, Tuple2<FunctionNode, List<Initializer>?>>,
Constructor>(
(w) => Tuple3(w.name, w.flags, Tuple2(w.function!, w.initializers)),
(w) => Tuple3(w.name, w.flags, Tuple2(w.function, w.initializers)),
(u) =>
Constructor(u.third.first, name: u.first, initializers: u.third.second)
..flags = u.second,
@@ -189,7 +189,7 @@ class RecursiveContinuationRewriter extends RemovingTransformer {
assert(const [
Nullability.nonNullable,
Nullability.legacy
].contains(coreTypes.iterableGetIterator.function!.returnType.nullability));
].contains(coreTypes.iterableGetIterator.function.returnType.nullability));
final DartType elementType = stmt.getElementType(staticTypeContext);
final iteratorType = InterfaceType(
@@ -1144,7 +1144,7 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase {
TreeNode visitFunctionDeclaration(
FunctionDeclaration stmt, TreeNode? removalSentinel) {
stmt.function = transform(stmt.function!)..parent = stmt;
stmt.function = transform(stmt.function)..parent = stmt;
statements.add(stmt);
return removalSentinel ?? EmptyStatement();
}
@@ -138,7 +138,7 @@ class MixinFullResolution {
if (setter != null) {
setters.remove(field.name);
VariableDeclaration parameter =
setter.function!.positionalParameters.first;
setter.function.positionalParameters.first;
clone.isCovariant = parameter.isCovariant;
clone.isGenericCovariantImpl = parameter.isGenericCovariantImpl;
}
@@ -180,8 +180,8 @@ class MixinFullResolution {
var originalProcedure = class_.procedures[i];
if (originalProcedure.name == procedure.name &&
originalProcedure.kind == procedure.kind) {
FunctionNode src = originalProcedure.function!;
FunctionNode dst = procedure.function!;
FunctionNode src = originalProcedure.function;
FunctionNode dst = procedure.function;
if (src.positionalParameters.length !=
dst.positionalParameters.length ||
@@ -200,8 +200,8 @@ class MixinFullResolution {
Procedure clone = cloner.cloneProcedure(procedure, reference);
if (originalIndex != null) {
Procedure originalProcedure = class_.procedures[originalIndex];
FunctionNode src = originalProcedure.function!;
FunctionNode dst = clone.function!;
FunctionNode src = originalProcedure.function;
FunctionNode dst = clone.function;
assert(src.typeParameters.length == dst.typeParameters.length);
for (int j = 0; j < src.typeParameters.length; ++j) {
dst.typeParameters[j].flags = src.typeParameters[j].flags;
@@ -208,7 +208,7 @@ class _WidgetCallSiteTransformer extends Transformer {
return node;
}
_addLocationArgument(node, target.function!, constructedClass,
_addLocationArgument(node, target.function, constructedClass,
isConst: node.isConst);
return node;
}
@@ -234,7 +234,7 @@ class _WidgetCallSiteTransformer extends Transformer {
return node;
}
_addLocationArgument(node, constructor.function!, constructedClass,
_addLocationArgument(node, constructor.function, constructedClass,
isConst: node.isConst);
return node;
}
@@ -252,7 +252,7 @@ class _WidgetCallSiteTransformer extends Transformer {
// constant expression.
!isConst) {
final VariableDeclaration? creationLocationParameter = _getNamedParameter(
_currentFactory!.function!,
_currentFactory!.function,
_creationLocationParameterName,
);
if (creationLocationParameter != null) {
@@ -401,7 +401,7 @@ class WidgetCreatorTracker {
return;
}
assert(!_hasNamedParameter(
constructor.function!,
constructor.function,
_creationLocationParameterName,
));
final VariableDeclaration variable = new VariableDeclaration(
@@ -409,7 +409,7 @@ class WidgetCreatorTracker {
type: new InterfaceType(
_locationClass, clazz.enclosingLibrary.nullable),
initializer: new NullLiteral());
if (!_maybeAddNamedParameter(constructor.function!, variable)) {
if (!_maybeAddNamedParameter(constructor.function, variable)) {
return;
}
@@ -424,7 +424,7 @@ class WidgetCreatorTracker {
}
_maybeAddCreationLocationArgument(
initializer.arguments,
initializer.target.function!,
initializer.target.function,
new VariableGet(variable),
_locationClass,
);
@@ -548,7 +548,7 @@ class WidgetCreatorTracker {
for (Procedure procedure in clazz.procedures) {
if (procedure.isFactory) {
_maybeAddNamedParameter(
procedure.function!,
procedure.function,
new VariableDeclaration(_creationLocationParameterName,
type: new InterfaceType(
_locationClass, clazz.enclosingLibrary.nullable),
@@ -578,12 +578,12 @@ class WidgetCreatorTracker {
_locationClass, clazz.enclosingLibrary.nullable),
initializer: new NullLiteral());
if (_hasNamedParameter(
constructor.function!, _creationLocationParameterName)) {
constructor.function, _creationLocationParameterName)) {
// Constructor was already rewritten.
// TODO(jacobr): is this case actually hit?
return;
}
if (!_maybeAddNamedParameter(constructor.function!, variable)) {
if (!_maybeAddNamedParameter(constructor.function, variable)) {
return;
}
for (Initializer initializer in constructor.initializers) {
@@ -597,7 +597,7 @@ class WidgetCreatorTracker {
_maybeAddCreationLocationArgument(
initializer.arguments,
initializer.target.function!,
initializer.target.function,
new VariableGet(variable),
_locationClass,
);
@@ -605,7 +605,7 @@ class WidgetCreatorTracker {
_isSubclassOfWidget(initializer.target.enclosingClass)) {
_maybeAddCreationLocationArgument(
initializer.arguments,
initializer.target.function!,
initializer.target.function,
new VariableGet(variable),
_locationClass,
);
+2 -2
View File
@@ -363,7 +363,7 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
"Only forwarding stubs can have a forwarding stub super target "
"$node.");
}
node.function!.accept(this);
node.function.accept(this);
classTypeParametersAreInScope = false;
visitList(node.annotations, this);
exitParent(oldParent);
@@ -377,7 +377,7 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
// in scope in the initializer list.
TreeNode? oldParent = enterParent(node);
int stackHeight = enterLocalScope();
visitChildren(node.function!);
visitChildren(node.function);
visitList(node.initializers, this);
if (!isOutline) {
checkInitializers(node);
+2 -2
View File
@@ -258,8 +258,8 @@ main() {
"Incorrect parent pointer on FunctionNode:"
" expected 'Procedure', but found: 'Null'.",
(TestHarness test) {
var procedure =
new Procedure(new Name('bar'), ProcedureKind.Method, null);
var procedure = new Procedure(
new Name('bar'), ProcedureKind.Method, dummyFunctionNode);
procedure.function = new FunctionNode(new EmptyStatement());
test.addNode(procedure);
},
@@ -373,8 +373,8 @@ class _DispatchableInvocation extends _Invocation {
}
/// Marker for noSuchMethod() invocation in the map of invocation targets.
static final Member kNoSuchMethodMarker =
new Procedure(new Name('noSuchMethod&&'), ProcedureKind.Method, null);
static final Member kNoSuchMethodMarker = new Procedure(
new Name('noSuchMethod&&'), ProcedureKind.Method, new FunctionNode(null));
_DispatchableInvocation(Selector selector, Args<Type> args)
: super(selector, args) {
@@ -778,9 +778,7 @@ uint32_t KernelFingerprintHelper::CalculateFunctionFingerprint() {
procedure_helper.SetJustRead(ProcedureHelper::kName);
procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction);
if (ReadTag() == kSomething) {
CalculateFunctionNodeFingerprint();
}
CalculateFunctionNodeFingerprint();
BuildHash(procedure_helper.kind_);
BuildHash(procedure_helper.flags_);
@@ -1116,9 +1116,7 @@ void ProcedureHelper::ReadUntilExcluding(Field field) {
if (++next_read_ == field) return;
FALL_THROUGH;
case kFunction:
if (helper_->ReadTag() == kSomething) {
helper_->SkipFunctionNode(); // read function node.
}
helper_->SkipFunctionNode(); // read function node.
if (++next_read_ == field) return;
FALL_THROUGH;
case kEnd:
@@ -2105,10 +2103,6 @@ void KernelReaderHelper::ReadUntilFunctionNode() {
if (tag == kProcedure) {
ProcedureHelper procedure_helper(this);
procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction);
if (ReadTag() == kNothing) { // read function node tag.
// Running a procedure without a function node doesn't make sense.
UNREACHABLE();
}
// Now at start of FunctionNode.
} else if (tag == kConstructor) {
ConstructorHelper constructor_helper(this);
@@ -512,9 +512,7 @@ void ScopeBuilder::VisitConstructor() {
void ScopeBuilder::VisitProcedure() {
ProcedureHelper procedure_helper(&helper_);
procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction);
if (helper_.ReadTag() == kSomething) {
VisitFunctionNode();
}
VisitFunctionNode();
}
void ScopeBuilder::VisitField() {
+2 -2
View File
@@ -20,8 +20,8 @@ namespace kernel {
static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
// Both version numbers are inclusive.
static const uint32_t kMinSupportedKernelFormatVersion = 60;
static const uint32_t kMaxSupportedKernelFormatVersion = 60;
static const uint32_t kMinSupportedKernelFormatVersion = 61;
static const uint32_t kMaxSupportedKernelFormatVersion = 61;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \
-2
View File
@@ -2032,8 +2032,6 @@ void KernelLoader::LoadProcedure(const Library& library,
procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction);
Tag function_node_tag = helper_.ReadTag();
ASSERT(function_node_tag == kSomething);
FunctionNodeHelper function_node_helper(&helper_);
function_node_helper.ReadUntilIncluding(FunctionNodeHelper::kDartAsyncMarker);
function.set_is_debuggable(function_node_helper.dart_async_marker_ ==