| // Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import '../api.dart'; |
| import 'exception_impls.dart'; |
| import 'introspection_impls.dart'; |
| import 'remote_instance.dart'; |
| import 'serialization.dart'; |
| |
| extension DeserializerExtensions on Deserializer { |
| T expectRemoteInstance<T extends Object>() { |
| int id = expectInt(); |
| |
| // If cached, just return the instance. Only the ID should be sent. |
| RemoteInstance? cached = RemoteInstance.cached(id); |
| if (cached != null) { |
| return cached as T; |
| } |
| |
| moveNext(); |
| RemoteInstanceKind kind = RemoteInstanceKind.values[expectInt()]; |
| final RemoteInstance instance = switch (kind) { |
| RemoteInstanceKind.declarationPhaseIntrospector || |
| RemoteInstanceKind.definitionPhaseIntrospector || |
| RemoteInstanceKind.typePhaseIntrospector => |
| // These are simple wrappers, just pass in the kind |
| RemoteInstanceImpl(id: id, kind: kind), |
| RemoteInstanceKind.classDeclaration => |
| (this..moveNext())._expectClassDeclaration(id), |
| RemoteInstanceKind.constructorMetadataAnnotation => |
| (this..moveNext())._expectConstructorMetadataAnnotation(id), |
| RemoteInstanceKind.enumDeclaration => |
| (this..moveNext())._expectEnumDeclaration(id), |
| RemoteInstanceKind.enumValueDeclaration => |
| (this..moveNext())._expectEnumValueDeclaration(id), |
| RemoteInstanceKind.extensionDeclaration => |
| (this..moveNext())._expectExtensionDeclaration(id), |
| RemoteInstanceKind.extensionTypeDeclaration => |
| (this..moveNext())._expectExtensionTypeDeclaration(id), |
| RemoteInstanceKind.mixinDeclaration => |
| (this..moveNext())._expectMixinDeclaration(id), |
| RemoteInstanceKind.constructorDeclaration => |
| (this..moveNext())._expectConstructorDeclaration(id), |
| RemoteInstanceKind.fieldDeclaration => |
| (this..moveNext())._expectFieldDeclaration(id), |
| RemoteInstanceKind.functionDeclaration => |
| (this..moveNext())._expectFunctionDeclaration(id), |
| RemoteInstanceKind.functionTypeAnnotation => |
| (this..moveNext())._expectFunctionTypeAnnotation(id), |
| RemoteInstanceKind.formalParameter => |
| (this..moveNext())._expectFormalParameter(id), |
| RemoteInstanceKind.identifier => (this..moveNext())._expectIdentifier(id), |
| RemoteInstanceKind.identifierMetadataAnnotation => |
| (this..moveNext())._expectIdentifierMetadataAnnotation(id), |
| RemoteInstanceKind.library => (this..moveNext())._expectLibrary(id), |
| RemoteInstanceKind.methodDeclaration => |
| (this..moveNext())._expectMethodDeclaration(id), |
| RemoteInstanceKind.namedStaticType => |
| (this..moveNext())._expectNamedStaticType(id), |
| RemoteInstanceKind.namedTypeAnnotation => |
| (this..moveNext())._expectNamedTypeAnnotation(id), |
| RemoteInstanceKind.omittedTypeAnnotation => |
| (this..moveNext())._expectOmittedTypeAnnotation(id), |
| RemoteInstanceKind.formalParameterDeclaration => |
| (this..moveNext())._expectFormalParameterDeclaration(id), |
| RemoteInstanceKind.recordField => |
| (this..moveNext())._expectRecordField(id), |
| RemoteInstanceKind.recordTypeAnnotation => |
| (this..moveNext())._expectRecordTypeAnnotation(id), |
| RemoteInstanceKind.staticType => StaticTypeImpl(id), |
| RemoteInstanceKind.typeAliasDeclaration => |
| (this..moveNext())._expectTypeAliasDeclaration(id), |
| RemoteInstanceKind.typeParameter => |
| (this..moveNext())._expectTypeParameter(id), |
| RemoteInstanceKind.typeParameterDeclaration => |
| (this..moveNext())._expectTypeParameterDeclaration(id), |
| RemoteInstanceKind.variableDeclaration => |
| (this..moveNext())._expectVariableDeclaration(id), |
| |
| // Exceptions. |
| RemoteInstanceKind.macroImplementationException || |
| RemoteInstanceKind.macroIntrospectionCycleException || |
| RemoteInstanceKind.unexpectedMacroException => |
| (this..moveNext())._expectException(kind, id), |
| }; |
| RemoteInstance.cache(instance); |
| return instance as T; |
| } |
| |
| Uri expectUri() => Uri.parse(expectString()); |
| |
| /// Reads a list of [RemoteInstance]s. |
| List<T> _expectRemoteInstanceList<T extends RemoteInstance>() { |
| expectList(); |
| return [ |
| for (bool hasNext = moveNext(); hasNext; hasNext = moveNext()) |
| expectRemoteInstance(), |
| ]; |
| } |
| |
| /// Reads a list of [Code]s. |
| List<T> _expectCodeList<T extends Code>() { |
| expectList(); |
| return [ |
| for (bool hasNext = moveNext(); hasNext; hasNext = moveNext()) |
| expectCode(), |
| ]; |
| } |
| |
| /// Reads a `Map<String, T extends Code>`. |
| Map<String, T> _expectStringCodeMap<T extends Code>() { |
| expectList(); |
| return { |
| for (bool hasNext = moveNext(); hasNext; hasNext = moveNext()) |
| expectString(): (this..moveNext()).expectCode(), |
| }; |
| } |
| |
| NamedStaticTypeImpl _expectNamedStaticType(int id) { |
| return NamedStaticTypeImpl( |
| id, |
| declaration: expectRemoteInstance(), |
| typeArguments: (this..moveNext())._expectRemoteInstanceList(), |
| ); |
| } |
| |
| NamedTypeAnnotationImpl _expectNamedTypeAnnotation(int id) => |
| NamedTypeAnnotationImpl( |
| id: id, |
| isNullable: expectBool(), |
| identifier: RemoteInstance.deserialize(this), |
| typeArguments: (this..moveNext())._expectRemoteInstanceList(), |
| ); |
| |
| OmittedTypeAnnotationImpl _expectOmittedTypeAnnotation(int id) { |
| expectBool(); // Always `false`. |
| return OmittedTypeAnnotationImpl( |
| id: id, |
| ); |
| } |
| |
| FunctionTypeAnnotationImpl _expectFunctionTypeAnnotation(int id) => |
| FunctionTypeAnnotationImpl( |
| id: id, |
| isNullable: expectBool(), |
| returnType: RemoteInstance.deserialize(this), |
| positionalParameters: (this..moveNext())._expectRemoteInstanceList(), |
| namedParameters: (this..moveNext())._expectRemoteInstanceList(), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| ); |
| |
| FormalParameterImpl _expectFormalParameter(int id) => |
| FormalParameterImpl.fromBitMask( |
| id: id, |
| bitMask: BitMask(expectInt()), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| name: (this..moveNext()).expectNullableString(), |
| type: RemoteInstance.deserialize(this), |
| ); |
| |
| IdentifierImpl _expectIdentifier(int id) => IdentifierImpl( |
| id: id, |
| name: expectString(), |
| ); |
| |
| FormalParameterDeclarationImpl _expectFormalParameterDeclaration(int id) => |
| FormalParameterDeclarationImpl.fromBitMask( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| bitMask: BitMask((this..moveNext()).expectInt()), |
| style: ParameterStyle.values[(this..moveNext()).expectInt()], |
| type: RemoteInstance.deserialize(this), |
| ); |
| |
| RecordFieldImpl _expectRecordField(int id) => RecordFieldImpl( |
| id: id, |
| name: expectNullableString(), |
| type: (this..moveNext()).expectRemoteInstance()); |
| |
| RecordTypeAnnotationImpl _expectRecordTypeAnnotation(int id) => |
| RecordTypeAnnotationImpl( |
| id: id, |
| isNullable: expectBool(), |
| namedFields: (this..moveNext())._expectRemoteInstanceList(), |
| positionalFields: (this..moveNext())._expectRemoteInstanceList(), |
| ); |
| |
| TypeParameterImpl _expectTypeParameter(int id) => TypeParameterImpl( |
| id: id, |
| bound: checkNull() ? null : expectRemoteInstance(), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| name: (this..moveNext()).expectString(), |
| ); |
| |
| TypeParameterDeclarationImpl _expectTypeParameterDeclaration(int id) => |
| TypeParameterDeclarationImpl( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| bound: (this..moveNext()).checkNull() ? null : expectRemoteInstance(), |
| ); |
| |
| FunctionDeclarationImpl _expectFunctionDeclaration(int id) => |
| FunctionDeclarationImpl.fromBitMask( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| bitMask: BitMask((this..moveNext()).expectInt()), |
| namedParameters: (this..moveNext())._expectRemoteInstanceList(), |
| positionalParameters: (this..moveNext())._expectRemoteInstanceList(), |
| returnType: RemoteInstance.deserialize(this), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| ); |
| |
| MethodDeclarationImpl _expectMethodDeclaration(int id) => |
| MethodDeclarationImpl.fromBitMask( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| bitMask: BitMask((this..moveNext()).expectInt()), |
| namedParameters: (this..moveNext())._expectRemoteInstanceList(), |
| positionalParameters: (this..moveNext())._expectRemoteInstanceList(), |
| returnType: RemoteInstance.deserialize(this), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| definingType: RemoteInstance.deserialize(this), |
| ); |
| |
| ConstructorDeclarationImpl _expectConstructorDeclaration(int id) => |
| ConstructorDeclarationImpl.fromBitMask( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| bitMask: BitMask((this..moveNext()).expectInt()), |
| namedParameters: (this..moveNext())._expectRemoteInstanceList(), |
| positionalParameters: (this..moveNext())._expectRemoteInstanceList(), |
| returnType: RemoteInstance.deserialize(this), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| definingType: RemoteInstance.deserialize(this), |
| ); |
| |
| VariableDeclarationImpl _expectVariableDeclaration(int id) => |
| VariableDeclarationImpl.fromBitMask( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| bitMask: BitMask((this..moveNext()).expectInt()), |
| type: RemoteInstance.deserialize(this), |
| ); |
| |
| FieldDeclarationImpl _expectFieldDeclaration(int id) => |
| FieldDeclarationImpl.fromBitMask( |
| id: id, |
| // Declaration fields. |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| bitMask: BitMask((this..moveNext()).expectInt()), |
| type: RemoteInstance.deserialize(this), |
| // FieldDeclaration fields |
| definingType: RemoteInstance.deserialize(this), |
| ); |
| |
| ClassDeclarationImpl _expectClassDeclaration(int id) => |
| ClassDeclarationImpl.fromBitMask( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| bitMask: BitMask((this..moveNext()).expectInt()), |
| interfaces: (this..moveNext())._expectRemoteInstanceList(), |
| mixins: (this..moveNext())._expectRemoteInstanceList(), |
| superclass: |
| (this..moveNext()).checkNull() ? null : expectRemoteInstance(), |
| ); |
| |
| ConstructorMetadataAnnotationImpl _expectConstructorMetadataAnnotation( |
| int id) => |
| ConstructorMetadataAnnotationImpl( |
| id: id, |
| constructor: expectRemoteInstance(), |
| type: RemoteInstance.deserialize(this), |
| positionalArguments: (this..moveNext())._expectCodeList(), |
| namedArguments: (this..moveNext())._expectStringCodeMap()); |
| |
| IdentifierMetadataAnnotationImpl _expectIdentifierMetadataAnnotation( |
| int id) => |
| IdentifierMetadataAnnotationImpl( |
| id: id, |
| identifier: expectRemoteInstance(), |
| ); |
| |
| EnumDeclarationImpl _expectEnumDeclaration(int id) => EnumDeclarationImpl( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| interfaces: (this..moveNext())._expectRemoteInstanceList(), |
| mixins: (this..moveNext())._expectRemoteInstanceList(), |
| ); |
| |
| MixinDeclarationImpl _expectMixinDeclaration(int id) => MixinDeclarationImpl( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| hasBase: (this..moveNext()).expectBool(), |
| interfaces: (this..moveNext())._expectRemoteInstanceList(), |
| superclassConstraints: (this..moveNext())._expectRemoteInstanceList(), |
| ); |
| |
| EnumValueDeclarationImpl _expectEnumValueDeclaration(int id) => |
| EnumValueDeclarationImpl( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| definingEnum: RemoteInstance.deserialize(this), |
| ); |
| |
| MacroExceptionImpl _expectException(RemoteInstanceKind kind, int id) => |
| MacroExceptionImpl( |
| id: id, |
| kind: kind, |
| message: expectString(), |
| stackTrace: (this..moveNext()).expectNullableString(), |
| ); |
| |
| ExtensionDeclarationImpl _expectExtensionDeclaration(int id) => |
| ExtensionDeclarationImpl( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| onType: RemoteInstance.deserialize(this), |
| ); |
| |
| ExtensionTypeDeclarationImpl _expectExtensionTypeDeclaration(int id) => |
| ExtensionTypeDeclarationImpl( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| representationType: RemoteInstance.deserialize(this), |
| ); |
| |
| TypeAliasDeclarationImpl _expectTypeAliasDeclaration(int id) => |
| TypeAliasDeclarationImpl( |
| id: id, |
| identifier: expectRemoteInstance(), |
| library: RemoteInstance.deserialize(this), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| typeParameters: (this..moveNext())._expectRemoteInstanceList(), |
| aliasedType: RemoteInstance.deserialize(this), |
| ); |
| |
| LibraryImpl _expectLibrary(int id) => LibraryImpl( |
| id: id, |
| languageVersion: |
| LanguageVersionImpl(expectInt(), (this..moveNext()).expectInt()), |
| metadata: (this..moveNext())._expectRemoteInstanceList(), |
| uri: (this..moveNext()).expectUri(), |
| ); |
| |
| List<String> _readStringList() => [ |
| for (bool hasNext = (this |
| ..moveNext() |
| ..expectList()) |
| .moveNext(); |
| hasNext; |
| hasNext = moveNext()) |
| expectString(), |
| ]; |
| |
| List<T> _readCodeList<T extends Code>() => [ |
| for (bool hasNext = (this |
| ..moveNext() |
| ..expectList()) |
| .moveNext(); |
| hasNext; |
| hasNext = moveNext()) |
| expectCode(), |
| ]; |
| |
| List<Object> _readParts() { |
| moveNext(); |
| expectList(); |
| List<Object> parts = []; |
| while (moveNext()) { |
| _CodePartKind partKind = _CodePartKind.values[expectInt()]; |
| moveNext(); |
| switch (partKind) { |
| case _CodePartKind.code: |
| parts.add(expectCode()); |
| break; |
| case _CodePartKind.string: |
| parts.add(expectString()); |
| break; |
| case _CodePartKind.identifier: |
| parts.add(expectRemoteInstance()); |
| break; |
| } |
| } |
| return parts; |
| } |
| |
| T expectCode<T extends Code>() { |
| CodeKind kind = CodeKind.values[expectInt()]; |
| |
| return switch (kind) { |
| CodeKind.raw => RawCode.fromParts(_readParts()) as T, |
| CodeKind.rawTypeAnnotation => |
| RawTypeAnnotationCode.fromParts(_readParts()) as T, |
| CodeKind.comment => CommentCode.fromParts(_readParts()) as T, |
| CodeKind.declaration => DeclarationCode.fromParts(_readParts()) as T, |
| CodeKind.expression => ExpressionCode.fromParts(_readParts()) as T, |
| CodeKind.functionBody => FunctionBodyCode.fromParts(_readParts()) as T, |
| CodeKind.functionTypeAnnotation => FunctionTypeAnnotationCode( |
| namedParameters: _readCodeList(), |
| positionalParameters: _readCodeList(), |
| returnType: (this..moveNext()).expectNullableCode(), |
| typeParameters: _readCodeList()) as T, |
| CodeKind.namedTypeAnnotation => NamedTypeAnnotationCode( |
| name: RemoteInstance.deserialize(this) as Identifier, |
| typeArguments: _readCodeList()) as T, |
| CodeKind.nullableTypeAnnotation => |
| NullableTypeAnnotationCode((this..moveNext()).expectCode()) as T, |
| CodeKind.omittedTypeAnnotation => |
| OmittedTypeAnnotationCode(RemoteInstance.deserialize(this)) as T, |
| CodeKind.parameter => ParameterCode( |
| defaultValue: (this..moveNext()).expectNullableCode(), |
| keywords: _readStringList(), |
| name: (this..moveNext()).expectNullableString(), |
| style: ParameterStyle.values[(this..moveNext()).expectInt()], |
| type: (this..moveNext()).expectNullableCode()) as T, |
| CodeKind.recordField => RecordFieldCode( |
| name: (this..moveNext()).expectNullableString(), |
| type: (this..moveNext()).expectCode()) as T, |
| CodeKind.recordTypeAnnotation => RecordTypeAnnotationCode( |
| namedFields: _readCodeList(), positionalFields: _readCodeList()) as T, |
| CodeKind.typeParameter => TypeParameterCode( |
| bound: (this..moveNext()).expectNullableCode(), |
| name: (this..moveNext()).expectString()) as T, |
| }; |
| } |
| |
| T? expectNullableCode<T extends Code>() { |
| if (checkNull()) return null; |
| return expectCode(); |
| } |
| |
| Diagnostic expectDiagnostic() { |
| expectList(); |
| List<DiagnosticMessage> context = [ |
| for (; moveNext();) expectDiagnosticMessage(), |
| ]; |
| |
| String? correctionMessage = (this..moveNext()).expectNullableString(); |
| DiagnosticMessage message = (this..moveNext()).expectDiagnosticMessage(); |
| Severity severity = Severity.values[(this..moveNext()).expectInt()]; |
| |
| return Diagnostic(message, severity, |
| contextMessages: context, correctionMessage: correctionMessage); |
| } |
| |
| DiagnosticMessage expectDiagnosticMessage() { |
| String message = expectString(); |
| |
| moveNext(); |
| RemoteInstance? target = checkNull() ? null : expectRemoteInstance(); |
| |
| return switch (target) { |
| null => DiagnosticMessage(message), |
| DeclarationImpl() => |
| DiagnosticMessage(message, target: target.asDiagnosticTarget), |
| TypeAnnotationImpl() => |
| DiagnosticMessage(message, target: target.asDiagnosticTarget), |
| MetadataAnnotationImpl() => |
| DiagnosticMessage(message, target: target.asDiagnosticTarget), |
| _ => throw UnsupportedError( |
| 'Unsupported target type ${target.runtimeType}, only Declarations, ' |
| 'TypeAnnotations, and Metadata are allowed.'), |
| }; |
| } |
| } |
| |
| extension SerializeNullable on Serializable? { |
| /// Either serializes a `null` literal or the object. |
| void serializeNullable(Serializer serializer) { |
| Serializable? self = this; |
| if (self == null) { |
| serializer.addNull(); |
| } else { |
| self.serialize(serializer); |
| } |
| } |
| } |
| |
| extension SerializeNullableCode on Code? { |
| /// Either serializes a `null` literal or the code object. |
| void serializeNullable(Serializer serializer) { |
| Code? self = this; |
| if (self == null) { |
| serializer.addNull(); |
| } else { |
| self.serialize(serializer); |
| } |
| } |
| } |
| |
| extension SerializeCode on Code { |
| void serialize(Serializer serializer) { |
| serializer.addInt(kind.index); |
| switch (kind) { |
| case CodeKind.namedTypeAnnotation: |
| NamedTypeAnnotationCode self = this as NamedTypeAnnotationCode; |
| (self.name as IdentifierImpl).serialize(serializer); |
| serializer.startList(); |
| for (TypeAnnotationCode typeArg in self.typeArguments) { |
| typeArg.serialize(serializer); |
| } |
| serializer.endList(); |
| return; |
| case CodeKind.functionTypeAnnotation: |
| FunctionTypeAnnotationCode self = this as FunctionTypeAnnotationCode; |
| serializer.startList(); |
| for (ParameterCode named in self.namedParameters) { |
| named.serialize(serializer); |
| } |
| serializer |
| ..endList() |
| ..startList(); |
| for (ParameterCode positional in self.positionalParameters) { |
| positional.serialize(serializer); |
| } |
| serializer.endList(); |
| self.returnType.serializeNullable(serializer); |
| serializer.startList(); |
| for (TypeParameterCode typeParam in self.typeParameters) { |
| typeParam.serialize(serializer); |
| } |
| serializer.endList(); |
| return; |
| case CodeKind.nullableTypeAnnotation: |
| NullableTypeAnnotationCode self = this as NullableTypeAnnotationCode; |
| self.underlyingType.serialize(serializer); |
| return; |
| case CodeKind.omittedTypeAnnotation: |
| OmittedTypeAnnotationCode self = this as OmittedTypeAnnotationCode; |
| (self.typeAnnotation as OmittedTypeAnnotationImpl) |
| .serialize(serializer); |
| return; |
| case CodeKind.recordField: |
| RecordFieldCode self = this as RecordFieldCode; |
| serializer.addNullableString(self.name); |
| self.type.serialize(serializer); |
| return; |
| case CodeKind.recordTypeAnnotation: |
| RecordTypeAnnotationCode self = this as RecordTypeAnnotationCode; |
| serializer.startList(); |
| for (RecordFieldCode field in self.namedFields) { |
| field.serialize(serializer); |
| } |
| serializer |
| ..endList() |
| ..startList(); |
| for (RecordFieldCode field in self.positionalFields) { |
| field.serialize(serializer); |
| } |
| serializer.endList(); |
| return; |
| case CodeKind.parameter: |
| ParameterCode self = this as ParameterCode; |
| self.defaultValue.serializeNullable(serializer); |
| serializer.startList(); |
| for (String keyword in self.keywords) { |
| serializer.addString(keyword); |
| } |
| serializer |
| ..endList() |
| ..addNullableString(self.name); |
| serializer.addInt(self.style.index); |
| self.type.serializeNullable(serializer); |
| return; |
| case CodeKind.typeParameter: |
| TypeParameterCode self = this as TypeParameterCode; |
| self.bound.serializeNullable(serializer); |
| serializer.addString(self.name); |
| return; |
| case CodeKind.comment: |
| case CodeKind.declaration: |
| case CodeKind.expression: |
| case CodeKind.raw: |
| case CodeKind.rawTypeAnnotation: |
| case CodeKind.functionBody: |
| serializer.startList(); |
| for (Object part in parts) { |
| if (part is String) { |
| serializer |
| ..addInt(_CodePartKind.string.index) |
| ..addString(part); |
| } else if (part is Code) { |
| serializer.addInt(_CodePartKind.code.index); |
| part.serialize(serializer); |
| } else if (part is IdentifierImpl) { |
| serializer.addInt(_CodePartKind.identifier.index); |
| part.serialize(serializer); |
| } else { |
| throw StateError('Unrecognized code part $part'); |
| } |
| } |
| serializer.endList(); |
| return; |
| } |
| } |
| } |
| |
| extension SerializeDiagnostic on Diagnostic { |
| void serialize(Serializer serializer) { |
| serializer.startList(); |
| for (DiagnosticMessage message in contextMessages) { |
| message.serialize(serializer); |
| } |
| serializer.endList(); |
| |
| serializer.addNullableString(correctionMessage); |
| message.serialize(serializer); |
| serializer.addInt(severity.index); |
| } |
| } |
| |
| extension SerializeDiagnosticMessage on DiagnosticMessage { |
| void serialize(Serializer serializer) { |
| serializer.addString(message); |
| switch (target) { |
| case null: |
| serializer.addNull(); |
| case DeclarationDiagnosticTarget target: |
| (target.declaration as DeclarationImpl).serialize(serializer); |
| case TypeAnnotationDiagnosticTarget target: |
| (target.typeAnnotation as TypeAnnotationImpl).serialize(serializer); |
| case MetadataAnnotationDiagnosticTarget target: |
| (target.metadataAnnotation as MetadataAnnotationImpl) |
| .serialize(serializer); |
| } |
| } |
| } |
| |
| extension Helpers on Serializer { |
| void addUri(Uri uri) => addString('$uri'); |
| |
| void addSerializable(Serializable serializable) => |
| serializable.serialize(this); |
| } |
| |
| enum _CodePartKind { |
| string, |
| code, |
| identifier, |
| } |