diff --git a/pkg/compiler/lib/src/ir/protobuf_impacts.dart b/pkg/compiler/lib/src/ir/protobuf_impacts.dart index a95d267d13a..387c2ad48c3 100644 --- a/pkg/compiler/lib/src/ir/protobuf_impacts.dart +++ b/pkg/compiler/lib/src/ir/protobuf_impacts.dart @@ -112,6 +112,10 @@ class ProtobufImpactHandler implements ConditionalImpactHandler { _builderInfoAddMethod.getterType as ir.FunctionType, const [ir.NullType()]); + late final ir.Procedure? _builderInfoAddUnusedMethod = _elementMap + .env.libraryIndex + .tryGetProcedure(protobufLibraryUri, 'BuilderInfo', 'addUnused'); + static const String metadataFieldName = '_i'; // All of those methods have the dart field name as second positional @@ -142,25 +146,39 @@ class ProtobufImpactHandler implements ConditionalImpactHandler { ir.InstanceInvocation _buildProtobufMetadataPlaceholder( ir.InstanceInvocation node) { - return ir.InstanceInvocation( - ir.InstanceAccessKind.Instance, - _CloneVisitorLenientVariables().clone(node.receiver), - _builderInfoAddMethod.name, - ir.Arguments( - [ - ir.IntLiteral(0), // tagNumber - ir.NullLiteral(), // name - ir.NullLiteral(), // fieldType - ir.NullLiteral(), // defaultOrMaker - ir.NullLiteral(), // subBuilder - ir.NullLiteral(), // valueOf - ir.NullLiteral(), // enumValues - ], - types: [const ir.NullType()], - ), - interfaceTarget: _builderInfoAddMethod, - functionType: _typeOfBuilderInfoAddOfNull) - ..fileOffset = node.fileOffset; + final addUnusedMethod = _builderInfoAddUnusedMethod; + if (addUnusedMethod == null) { + // Legacy version, call `add` method. + return ir.InstanceInvocation( + ir.InstanceAccessKind.Instance, + _CloneVisitorLenientVariables().clone(node.receiver), + _builderInfoAddMethod.name, + ir.Arguments( + [ + ir.IntLiteral(0), // tagNumber + ir.NullLiteral(), // name + ir.NullLiteral(), // fieldType + ir.NullLiteral(), // defaultOrMaker + ir.NullLiteral(), // subBuilder + ir.NullLiteral(), // valueOf + ir.NullLiteral(), // enumValues + ], + types: [const ir.NullType()], + ), + interfaceTarget: _builderInfoAddMethod, + functionType: _typeOfBuilderInfoAddOfNull) + ..fileOffset = node.fileOffset; + } else { + // New version, call `addUnused` method. + return ir.InstanceInvocation( + ir.InstanceAccessKind.Instance, + _CloneVisitorLenientVariables().clone(node.receiver), + addUnusedMethod.name, + ir.Arguments([]), + interfaceTarget: addUnusedMethod, + functionType: addUnusedMethod.getterType as ir.FunctionType) + ..fileOffset = node.fileOffset; + } } @override diff --git a/pkg/kernel/lib/library_index.dart b/pkg/kernel/lib/library_index.dart index 5bb2f4f41bf..bb4bfb9a0df 100644 --- a/pkg/kernel/lib/library_index.dart +++ b/pkg/kernel/lib/library_index.dart @@ -123,6 +123,11 @@ class LibraryIndex { return _getLibraryIndex(library).getProcedure(containerName, memberName); } + Procedure? tryGetProcedure( + String library, String containerName, String memberName) { + return _getLibraryIndex(library).tryGetProcedure(containerName, memberName); + } + Field getField(String library, String containerName, String memberName) { return _getLibraryIndex(library).getField(containerName, memberName); } @@ -225,6 +230,10 @@ class _ContainerTable { return _getContainerIndex(className).getProcedure(memberName); } + Procedure? tryGetProcedure(String className, String memberName) { + return _getContainerIndex(className).tryGetProcedure(memberName); + } + Field getField(String className, String memberName) { return _getContainerIndex(className).getField(memberName); } @@ -411,6 +420,16 @@ class _MemberTable { return member; } + Procedure? tryGetProcedure(String name) { + Member? member = members[name]; + if (member == null) return null; + if (member is! Procedure) { + throw "Member '$name' in $containerName is not a Procedure: " + "${member} (${member.runtimeType})."; + } + return member; + } + Field getField(String name) { Member member = getMember(name); if (member is! Field) {