| // Copyright (c) 2021, 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 'dart:typed_data'; | |
| import 'package:analyzer/src/binary/binary_reader.dart'; | |
| import 'package:analyzer/src/binary/binary_writer.dart'; | |
| /// Unlinked information about a compilation unit. | |
| class AnalysisDriverUnlinkedUnit { | |
| /// Set of class member names defined by the unit. | |
| final Set<String> definedClassMemberNames; | |
| /// Set of top-level names defined by the unit. | |
| final Set<String> definedTopLevelNames; | |
| /// Set of external names referenced by the unit. | |
| final Set<String> referencedNames; | |
| /// Set of names which are used in `extends`, `with` or `implements` clauses | |
| /// in the file. Import prefixes and type arguments are not included. | |
| final Set<String> subtypedNames; | |
| /// Unlinked information for the unit. | |
| final UnlinkedUnit unit; | |
| AnalysisDriverUnlinkedUnit({ | |
| required this.definedClassMemberNames, | |
| required this.definedTopLevelNames, | |
| required this.referencedNames, | |
| required this.subtypedNames, | |
| required this.unit, | |
| }); | |
| factory AnalysisDriverUnlinkedUnit.fromBytes(Uint8List bytes) { | |
| return AnalysisDriverUnlinkedUnit.read(BinaryReader(bytes)); | |
| } | |
| factory AnalysisDriverUnlinkedUnit.read(BinaryReader reader) { | |
| return AnalysisDriverUnlinkedUnit( | |
| definedClassMemberNames: reader.readStringUtf8Set(), | |
| definedTopLevelNames: reader.readStringUtf8Set(), | |
| referencedNames: reader.readStringUtf8Set(), | |
| subtypedNames: reader.readStringUtf8Set(), | |
| unit: UnlinkedUnit.read(reader), | |
| ); | |
| } | |
| Uint8List toBytes() { | |
| var writer = BinaryWriter(); | |
| write(writer); | |
| return writer.takeBytes(); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeStringUtf8Iterable(definedClassMemberNames); | |
| writer.writeStringUtf8Iterable(definedTopLevelNames); | |
| writer.writeStringUtf8Iterable(referencedNames); | |
| writer.writeStringUtf8Iterable(subtypedNames); | |
| unit.write(writer); | |
| } | |
| } | |
| class UnlinkedCombinator { | |
| final int keywordOffset; | |
| final int endOffset; | |
| final bool isShow; | |
| final List<String> names; | |
| UnlinkedCombinator({ | |
| required this.keywordOffset, | |
| required this.endOffset, | |
| required this.isShow, | |
| required this.names, | |
| }); | |
| factory UnlinkedCombinator.read(BinaryReader reader) { | |
| return UnlinkedCombinator( | |
| keywordOffset: reader.readUint30(), | |
| endOffset: reader.readUint30(), | |
| isShow: reader.readBool(), | |
| names: reader.readStringUtf8List(), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeUint30(keywordOffset); | |
| writer.writeUint30(endOffset); | |
| writer.writeBool(isShow); | |
| writer.writeStringUtf8Iterable(names); | |
| } | |
| } | |
| abstract class UnlinkedConfigurableUriDirective { | |
| final List<UnlinkedNamespaceDirectiveConfiguration> configurations; | |
| final String? uri; | |
| UnlinkedConfigurableUriDirective({ | |
| required this.configurations, | |
| required this.uri, | |
| }); | |
| } | |
| class UnlinkedDartdocTemplate { | |
| final String name; | |
| final String value; | |
| UnlinkedDartdocTemplate({required this.name, required this.value}); | |
| factory UnlinkedDartdocTemplate.read(BinaryReader reader) { | |
| return UnlinkedDartdocTemplate( | |
| name: reader.readStringUtf8(), | |
| value: reader.readStringUtf8(), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeStringUtf8(name); | |
| writer.writeStringUtf8(value); | |
| } | |
| } | |
| class UnlinkedLibraryDirective { | |
| /// `@docImport` directives in the doc comment. | |
| final List<UnlinkedLibraryImportDirective> docImports; | |
| final String? name; | |
| UnlinkedLibraryDirective({required this.docImports, required this.name}); | |
| factory UnlinkedLibraryDirective.read(BinaryReader reader) { | |
| return UnlinkedLibraryDirective( | |
| docImports: reader.readTypedList( | |
| () => UnlinkedLibraryImportDirective.read(reader), | |
| ), | |
| name: reader.readOptionalStringUtf8(), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeList(docImports, (docImport) { | |
| docImport.write(writer); | |
| }); | |
| writer.writeOptionalStringUtf8(name); | |
| } | |
| } | |
| /// Unlinked information about an `export` directive. | |
| class UnlinkedLibraryExportDirective extends UnlinkedNamespaceDirective { | |
| final int exportKeywordOffset; | |
| UnlinkedLibraryExportDirective({ | |
| required super.combinators, | |
| required super.configurations, | |
| required this.exportKeywordOffset, | |
| required super.uri, | |
| }); | |
| factory UnlinkedLibraryExportDirective.read(BinaryReader reader) { | |
| return UnlinkedLibraryExportDirective( | |
| combinators: reader.readTypedList(() => UnlinkedCombinator.read(reader)), | |
| configurations: reader.readTypedList( | |
| () => UnlinkedNamespaceDirectiveConfiguration.read(reader), | |
| ), | |
| exportKeywordOffset: reader.readUint30(), | |
| uri: reader.readOptionalStringUtf8(), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeList<UnlinkedCombinator>(combinators, (x) => x.write(writer)); | |
| writer.writeList<UnlinkedNamespaceDirectiveConfiguration>(configurations, ( | |
| x, | |
| ) { | |
| x.write(writer); | |
| }); | |
| writer.writeUint30(exportKeywordOffset); | |
| writer.writeOptionalStringUtf8(uri); | |
| } | |
| } | |
| /// Unlinked information about an 'import' directive. | |
| class UnlinkedLibraryImportDirective extends UnlinkedNamespaceDirective { | |
| final int importKeywordOffset; | |
| final bool isDocImport; | |
| final bool isSyntheticDartCore; | |
| final UnlinkedLibraryImportPrefix? prefix; | |
| UnlinkedLibraryImportDirective({ | |
| required super.combinators, | |
| required super.configurations, | |
| required this.importKeywordOffset, | |
| required this.isDocImport, | |
| this.isSyntheticDartCore = false, | |
| required this.prefix, | |
| required super.uri, | |
| }); | |
| factory UnlinkedLibraryImportDirective.read(BinaryReader reader) { | |
| return UnlinkedLibraryImportDirective( | |
| combinators: reader.readTypedList(() => UnlinkedCombinator.read(reader)), | |
| configurations: reader.readTypedList( | |
| () => UnlinkedNamespaceDirectiveConfiguration.read(reader), | |
| ), | |
| importKeywordOffset: reader.readUint30() - 1, | |
| isDocImport: reader.readBool(), | |
| isSyntheticDartCore: reader.readBool(), | |
| prefix: reader.readOptionalObject( | |
| () => UnlinkedLibraryImportPrefix.read(reader), | |
| ), | |
| uri: reader.readOptionalStringUtf8(), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeList<UnlinkedCombinator>(combinators, (x) => x.write(writer)); | |
| writer.writeList<UnlinkedNamespaceDirectiveConfiguration>(configurations, ( | |
| x, | |
| ) { | |
| x.write(writer); | |
| }); | |
| writer.writeUint30(1 + importKeywordOffset); | |
| writer.writeBool(isDocImport); | |
| writer.writeBool(isSyntheticDartCore); | |
| writer.writeOptionalObject<UnlinkedLibraryImportPrefix>( | |
| prefix, | |
| (x) => x.write(writer), | |
| ); | |
| writer.writeOptionalStringUtf8(uri); | |
| } | |
| } | |
| class UnlinkedLibraryImportPrefix { | |
| final int? deferredOffset; | |
| final int asOffset; | |
| final int nameOffset; | |
| final UnlinkedLibraryImportPrefixName? name; | |
| UnlinkedLibraryImportPrefix({ | |
| required this.deferredOffset, | |
| required this.asOffset, | |
| required this.nameOffset, | |
| required this.name, | |
| }); | |
| factory UnlinkedLibraryImportPrefix.read(BinaryReader reader) { | |
| return UnlinkedLibraryImportPrefix( | |
| deferredOffset: reader.readOptionalUint30(), | |
| asOffset: reader.readUint30(), | |
| nameOffset: reader.readUint30(), | |
| name: reader.readOptionalObject( | |
| () => UnlinkedLibraryImportPrefixName.read(reader), | |
| ), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeOptionalUint30(deferredOffset); | |
| writer.writeUint30(asOffset); | |
| writer.writeUint30(nameOffset); | |
| writer.writeOptionalObject(name, (name) { | |
| name.write(writer); | |
| }); | |
| } | |
| } | |
| class UnlinkedLibraryImportPrefixName { | |
| final String name; | |
| final int nameOffset; | |
| UnlinkedLibraryImportPrefixName({ | |
| required this.name, | |
| required this.nameOffset, | |
| }); | |
| factory UnlinkedLibraryImportPrefixName.read(BinaryReader reader) { | |
| return UnlinkedLibraryImportPrefixName( | |
| name: reader.readStringUtf8(), | |
| nameOffset: reader.readUint30(), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeStringUtf8(name); | |
| writer.writeUint30(nameOffset); | |
| } | |
| } | |
| abstract class UnlinkedNamespaceDirective | |
| extends UnlinkedConfigurableUriDirective { | |
| final List<UnlinkedCombinator> combinators; | |
| UnlinkedNamespaceDirective({ | |
| required this.combinators, | |
| required super.configurations, | |
| required super.uri, | |
| }); | |
| } | |
| /// Unlinked information about a namespace directive configuration. | |
| class UnlinkedNamespaceDirectiveConfiguration { | |
| /// The name of the declared variable used in the condition. | |
| final String name; | |
| /// The URI to be used if the condition is true. | |
| final String? uri; | |
| /// The value to which the value of the declared variable will be compared, | |
| /// or the empty string if the condition does not include an equality test. | |
| final String value; | |
| UnlinkedNamespaceDirectiveConfiguration({ | |
| required this.name, | |
| required this.uri, | |
| required this.value, | |
| }); | |
| factory UnlinkedNamespaceDirectiveConfiguration.read(BinaryReader reader) { | |
| return UnlinkedNamespaceDirectiveConfiguration( | |
| name: reader.readStringUtf8(), | |
| uri: reader.readOptionalStringUtf8(), | |
| value: reader.readStringUtf8(), | |
| ); | |
| } | |
| String get valueOrTrue { | |
| if (value.isEmpty) { | |
| return 'true'; | |
| } else { | |
| return value; | |
| } | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeStringUtf8(name); | |
| writer.writeOptionalStringUtf8(uri); | |
| writer.writeStringUtf8(value); | |
| } | |
| } | |
| class UnlinkedPartDirective extends UnlinkedConfigurableUriDirective { | |
| final int partKeywordOffset; | |
| UnlinkedPartDirective({ | |
| required super.configurations, | |
| required this.partKeywordOffset, | |
| required super.uri, | |
| }); | |
| factory UnlinkedPartDirective.read(BinaryReader reader) { | |
| return UnlinkedPartDirective( | |
| configurations: reader.readTypedList( | |
| () => UnlinkedNamespaceDirectiveConfiguration.read(reader), | |
| ), | |
| partKeywordOffset: reader.readUint30(), | |
| uri: reader.readOptionalStringUtf8(), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeList<UnlinkedNamespaceDirectiveConfiguration>(configurations, ( | |
| x, | |
| ) { | |
| x.write(writer); | |
| }); | |
| writer.writeUint30(partKeywordOffset); | |
| writer.writeOptionalStringUtf8(uri); | |
| } | |
| } | |
| class UnlinkedPartOfNameDirective { | |
| /// `@docImport` directives in the doc comment. | |
| final List<UnlinkedLibraryImportDirective> docImports; | |
| final String name; | |
| final UnlinkedSourceRange nameRange; | |
| UnlinkedPartOfNameDirective({ | |
| required this.docImports, | |
| required this.name, | |
| required this.nameRange, | |
| }); | |
| factory UnlinkedPartOfNameDirective.read(BinaryReader reader) { | |
| return UnlinkedPartOfNameDirective( | |
| docImports: reader.readTypedList( | |
| () => UnlinkedLibraryImportDirective.read(reader), | |
| ), | |
| name: reader.readStringUtf8(), | |
| nameRange: UnlinkedSourceRange.read(reader), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeList(docImports, (docImport) { | |
| docImport.write(writer); | |
| }); | |
| writer.writeStringUtf8(name); | |
| nameRange.write(writer); | |
| } | |
| } | |
| class UnlinkedPartOfUriDirective { | |
| /// `@docImport` directives in the doc comment. | |
| final List<UnlinkedLibraryImportDirective> docImports; | |
| final String? uri; | |
| final UnlinkedSourceRange uriRange; | |
| UnlinkedPartOfUriDirective({ | |
| required this.docImports, | |
| required this.uri, | |
| required this.uriRange, | |
| }); | |
| factory UnlinkedPartOfUriDirective.read(BinaryReader reader) { | |
| return UnlinkedPartOfUriDirective( | |
| docImports: reader.readTypedList( | |
| () => UnlinkedLibraryImportDirective.read(reader), | |
| ), | |
| uri: reader.readOptionalStringUtf8(), | |
| uriRange: UnlinkedSourceRange.read(reader), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeList(docImports, (docImport) { | |
| docImport.write(writer); | |
| }); | |
| writer.writeOptionalStringUtf8(uri); | |
| uriRange.write(writer); | |
| } | |
| } | |
| class UnlinkedSourceRange { | |
| final int offset; | |
| final int length; | |
| UnlinkedSourceRange({required this.offset, required this.length}) { | |
| RangeError.checkNotNegative(offset); | |
| RangeError.checkNotNegative(length); | |
| } | |
| factory UnlinkedSourceRange.read(BinaryReader reader) { | |
| return UnlinkedSourceRange( | |
| offset: reader.readUint30(), | |
| length: reader.readUint30(), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeUint30(offset); | |
| writer.writeUint30(length); | |
| } | |
| } | |
| /// Unlinked information about a compilation unit. | |
| class UnlinkedUnit { | |
| /// The MD5 hash signature of the API portion of this unit. It depends on all | |
| /// tokens that might affect APIs of declarations in the unit. | |
| // TODO(scheglov): Do we need it? | |
| final Uint8List apiSignature; | |
| /// `export` directives. | |
| final List<UnlinkedLibraryExportDirective> exports; | |
| /// Whether this file has explicit `dart:core` import. | |
| final bool hasDartCoreImport; | |
| /// `import` directives. | |
| final List<UnlinkedLibraryImportDirective> imports; | |
| /// Encoded informative data. | |
| final Uint8List informativeBytes; | |
| /// Whether this file is `dart:core` library. | |
| final bool isDartCore; | |
| /// The `library name;` directive. | |
| final UnlinkedLibraryDirective? libraryDirective; | |
| /// Offsets of the first character of each line in the source code. | |
| final Uint32List lineStarts; | |
| /// `part` directives. | |
| final List<UnlinkedPartDirective> parts; | |
| /// The `part of my.name';` directive. | |
| final UnlinkedPartOfNameDirective? partOfNameDirective; | |
| /// The `part of 'uri';` directive. | |
| final UnlinkedPartOfUriDirective? partOfUriDirective; | |
| /// Top-level declarations of the unit. | |
| final Set<String> topLevelDeclarations; | |
| /// The Dartdoc templates of the unit. | |
| final List<UnlinkedDartdocTemplate> dartdocTemplates; | |
| UnlinkedUnit({ | |
| required this.apiSignature, | |
| required this.exports, | |
| required this.hasDartCoreImport, | |
| required this.imports, | |
| required this.informativeBytes, | |
| required this.isDartCore, | |
| required this.libraryDirective, | |
| required this.lineStarts, | |
| required this.parts, | |
| required this.partOfNameDirective, | |
| required this.partOfUriDirective, | |
| required this.topLevelDeclarations, | |
| required this.dartdocTemplates, | |
| }); | |
| factory UnlinkedUnit.read(BinaryReader reader) { | |
| return UnlinkedUnit( | |
| apiSignature: reader.readUint8List(), | |
| exports: reader.readTypedList( | |
| () => UnlinkedLibraryExportDirective.read(reader), | |
| ), | |
| hasDartCoreImport: reader.readBool(), | |
| imports: reader.readTypedList( | |
| () => UnlinkedLibraryImportDirective.read(reader), | |
| ), | |
| informativeBytes: reader.readUint8List(), | |
| isDartCore: reader.readBool(), | |
| libraryDirective: reader.readOptionalObject( | |
| () => UnlinkedLibraryDirective.read(reader), | |
| ), | |
| lineStarts: reader.readUint30List(), | |
| parts: reader.readTypedList(() => UnlinkedPartDirective.read(reader)), | |
| partOfNameDirective: reader.readOptionalObject( | |
| () => UnlinkedPartOfNameDirective.read(reader), | |
| ), | |
| partOfUriDirective: reader.readOptionalObject( | |
| () => UnlinkedPartOfUriDirective.read(reader), | |
| ), | |
| topLevelDeclarations: reader.readStringUtf8Set(), | |
| dartdocTemplates: reader.readTypedList( | |
| () => UnlinkedDartdocTemplate.read(reader), | |
| ), | |
| ); | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeUint8List(apiSignature); | |
| writer.writeList<UnlinkedLibraryExportDirective>(exports, (x) { | |
| x.write(writer); | |
| }); | |
| writer.writeBool(hasDartCoreImport); | |
| writer.writeList<UnlinkedLibraryImportDirective>(imports, (x) { | |
| x.write(writer); | |
| }); | |
| writer.writeUint8List(informativeBytes); | |
| writer.writeBool(isDartCore); | |
| writer.writeOptionalObject<UnlinkedLibraryDirective>( | |
| libraryDirective, | |
| (x) => x.write(writer), | |
| ); | |
| writer.writeUint30List(lineStarts); | |
| writer.writeList<UnlinkedPartDirective>(parts, (x) { | |
| x.write(writer); | |
| }); | |
| writer.writeOptionalObject<UnlinkedPartOfNameDirective>( | |
| partOfNameDirective, | |
| (x) => x.write(writer), | |
| ); | |
| writer.writeOptionalObject<UnlinkedPartOfUriDirective>( | |
| partOfUriDirective, | |
| (x) => x.write(writer), | |
| ); | |
| writer.writeStringUtf8Iterable(topLevelDeclarations); | |
| writer.writeList(dartdocTemplates, (x) { | |
| x.write(writer); | |
| }); | |
| } | |
| } |