diff --git a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart index 76c675b7dc1..d478a6967f9 100644 --- a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart @@ -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 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 []; @@ -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 typeParameterTypes = []; @@ -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 diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart index 15880c6cda1..7d11b18e6cf 100644 --- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart @@ -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 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.filled(count, null); for (int index = 0; index < count; index++) { - _extensionTypeParameters[index] = result.typeParameters[index]; + _extensionTypeParameters[index] = function.typeParameters[index]; } } } - return function = result; } @override diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart index 498826b12f4..087e96d54ce 100644 --- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart @@ -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; diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index 50db82b756d..1f26ed0385b 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -4999,8 +4999,8 @@ class BodyBuilder extends ScopeListener } 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); } diff --git a/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart b/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart index b33dbcd7881..03c89ce7268 100644 --- a/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart +++ b/pkg/front_end/lib/src/fasta/kernel/member_covariance.dart @@ -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? 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? positionalParameters = _positionalParameters; if (positionalParameters != null) { for (int index = 0; index < positionalParameters.length; index++) { diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md index b5948984f75..20ee23e0296 100644 --- a/pkg/kernel/binary.md +++ b/pkg/kernel/binary.md @@ -147,7 +147,7 @@ type CanonicalName { type ComponentFile { UInt32 magic = 0x90ABCDEF; - UInt32 formatVersion = 60; + UInt32 formatVersion = 61; Byte[10] shortSdkHash; List problemsAsJson; // Described in problems.md. Library[] libraries; @@ -425,8 +425,7 @@ type Procedure extends Member { Name name; List annotations; MemberReference stubTarget; // May be NullReference. - // Can only be absent if abstract, but tag is there anyway. - Option function; + FunctionNode function; } type RedirectingFactoryConstructor extends Member { diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index a81d28faaa4..9e1ce0fe631 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -1988,9 +1988,8 @@ class Constructor extends Member { int flags = 0; - // TODO(johnniwinther): Make this non-nullable. @override - FunctionNode? function; + FunctionNode function; List initializers; @@ -2004,8 +2003,10 @@ class Constructor extends Member { Uri? fileUri, Reference? reference}) : this.initializers = initializers ?? [], + // 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); } } diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index 7c1de525dd8..0d99e602bb0 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart @@ -499,7 +499,7 @@ class BinaryBuilder { } } - List readAnnotationList(TreeNode? parent) { + List readAnnotationList([TreeNode? parent]) { int length = readUInt30(); if (length == 0) return const []; return new List.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 annotations = readAnnotationList(node); + List 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 annotations = readAnnotationList(node); + List 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(); diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index 5652534677d..e7271c54630 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart @@ -488,15 +488,6 @@ class BinaryPrinter implements Visitor, 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, 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, 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, BinarySink { writeByte(Tag.FunctionDeclaration); writeOffset(node.fileOffset); writeVariableDeclaration(node.variable); - writeFunctionNode(node.function!); + writeFunctionNode(node.function); } @override diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart index fca44c61929..523a5a225c2 100644 --- a/pkg/kernel/lib/binary/tag.dart +++ b/pkg/kernel/lib/binary/tag.dart @@ -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 { diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart index 3f09922adc9..6c76c2f73ab 100644 --- a/pkg/kernel/lib/clone.dart +++ b/pkg/kernel/lib/clone.dart @@ -485,8 +485,8 @@ class CloneVisitorNotMembers implements TreeVisitor { // 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, diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart index 3565196e3e4..27edbc162a4 100644 --- a/pkg/kernel/lib/text/ast_to_text.dart +++ b/pkg/kernel/lib/text/ast_to_text.dart @@ -1206,13 +1206,13 @@ class Printer extends Visitor 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 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 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('...;'); diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart index 0899fe860c4..f544010b041 100644 --- a/pkg/kernel/lib/text/text_serializer.dart +++ b/pkg/kernel/lib/text/text_serializer.dart @@ -1750,7 +1750,7 @@ TextSerializer continueSwitchStatementSerializer = TextSerializer functionDeclarationSerializer = Wrapped, 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 immutableFieldSerializer = TextSerializer methodSerializer = Wrapped, 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 methodSerializer = TextSerializer getterSerializer = Wrapped, 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 getterSerializer = TextSerializer setterSerializer = Wrapped, 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 setterSerializer = TextSerializer operatorSerializer = Wrapped, 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 operatorSerializer = TextSerializer factorySerializer = Wrapped, 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 factorySerializer = TextSerializer constructorSerializer = Wrapped< Tuple3?>>, 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, diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart index c477db5eb8a..2404a997679 100644 --- a/pkg/kernel/lib/transformations/continuation.dart +++ b/pkg/kernel/lib/transformations/continuation.dart @@ -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(); } diff --git a/pkg/kernel/lib/transformations/mixin_full_resolution.dart b/pkg/kernel/lib/transformations/mixin_full_resolution.dart index b1a72a8310c..c9b5c39f876 100644 --- a/pkg/kernel/lib/transformations/mixin_full_resolution.dart +++ b/pkg/kernel/lib/transformations/mixin_full_resolution.dart @@ -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; diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart index 7e81c8d62c1..6538a7b4df3 100644 --- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart +++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart @@ -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, ); diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart index a263a040bb5..9431e8eb84a 100644 --- a/pkg/kernel/lib/verifier.dart +++ b/pkg/kernel/lib/verifier.dart @@ -363,7 +363,7 @@ class VerifyingVisitor extends RecursiveResultVisitor { "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 { // 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); diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart index 097200d70e8..f8b17180a69 100644 --- a/pkg/kernel/test/verify_test.dart +++ b/pkg/kernel/test/verify_test.dart @@ -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); }, diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart index c8a530da355..b22fa57e76b 100644 --- a/pkg/vm/lib/transformations/type_flow/analysis.dart +++ b/pkg/vm/lib/transformations/type_flow/analysis.dart @@ -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 args) : super(selector, args) { diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc index ca9ebbf2574..aff6de70333 100644 --- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc +++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc @@ -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_); diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc index c83e6cb922a..4ede221a8a1 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc @@ -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); diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc index f55386b0400..e2be4a97574 100644 --- a/runtime/vm/compiler/frontend/scope_builder.cc +++ b/runtime/vm/compiler/frontend/scope_builder.cc @@ -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() { diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h index 29eae67a0d4..2a78176085f 100644 --- a/runtime/vm/kernel_binary.h +++ b/runtime/vm/kernel_binary.h @@ -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) \ diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc index e5220d1f381..1ac91319ba0 100644 --- a/runtime/vm/kernel_loader.cc +++ b/runtime/vm/kernel_loader.cc @@ -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_ ==