Support for AugmentationFileStateKind.
Change-Id: Ib32b7b56739d89118c9a497087dc5066bab177dd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/245680 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
committed by
Commit Bot
parent
b292488a8d
commit
33b6483ad1
@@ -339,7 +339,7 @@ void f() {
|
||||
|
||||
Future<void> test_BUILT_IN_partOf() async {
|
||||
addTestFile('''
|
||||
part of lib;
|
||||
part of my.lib.name;
|
||||
void f() {
|
||||
var part = 1;
|
||||
var of = 2;
|
||||
@@ -613,11 +613,14 @@ export 'dart:math'
|
||||
|
||||
Future<void> test_DIRECTIVE_partOf() async {
|
||||
addTestFile('''
|
||||
part of lib;
|
||||
part of my.lib.name;
|
||||
''');
|
||||
_addLibraryForTestPart();
|
||||
await prepareHighlights();
|
||||
assertHasStringRegion(HighlightRegionType.DIRECTIVE, 'part of lib;');
|
||||
assertHasStringRegion(
|
||||
HighlightRegionType.DIRECTIVE,
|
||||
'part of my.lib.name;',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_DYNAMIC_LOCAL_VARIABLE() async {
|
||||
@@ -1695,7 +1698,7 @@ class HighlightsTestSupport extends PubPackageAnalysisServerTest {
|
||||
|
||||
void _addLibraryForTestPart() {
|
||||
newFile('$testPackageLibPath/my_lib.dart', '''
|
||||
library lib;
|
||||
library my.lib.name;
|
||||
part 'test.dart';
|
||||
''');
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ library my.lib;
|
||||
|
||||
Future<void> test_libraryName_hasPartOfDirective() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library lib;
|
||||
library my.lib;
|
||||
|
||||
part 'test.dart';
|
||||
''');
|
||||
|
||||
@@ -84,7 +84,7 @@ import 'package:meta/meta.dart';
|
||||
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
|
||||
class AnalysisDriver implements AnalysisDriverGeneric {
|
||||
/// The version of data format, should be incremented on every format change.
|
||||
static const int DATA_VERSION = 220;
|
||||
static const int DATA_VERSION = 221;
|
||||
|
||||
/// The number of exception contexts allowed to write. Once this field is
|
||||
/// zero, we stop writing any new exception contexts in this process.
|
||||
@@ -1325,6 +1325,10 @@ class AnalysisDriver implements AnalysisDriverGeneric {
|
||||
}
|
||||
}
|
||||
|
||||
if (file.kind is PartFileStateKind && !library.partedFiles.contains(file)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Prepare the signature and key.
|
||||
String signature = _getResolvedUnitSignature(library, file);
|
||||
String key = _getResolvedUnitKey(signature);
|
||||
|
||||
@@ -43,6 +43,48 @@ import 'package:meta/meta.dart';
|
||||
import 'package:path/path.dart' as package_path;
|
||||
import 'package:pub_semver/pub_semver.dart';
|
||||
|
||||
/// The file has a `library augmentation` directive.
|
||||
abstract class AugmentationFileStateKind extends LibraryOrAugmentationFileKind {
|
||||
final UnlinkedLibraryAugmentationDirective directive;
|
||||
|
||||
AugmentationFileStateKind({
|
||||
required super.file,
|
||||
required this.directive,
|
||||
});
|
||||
}
|
||||
|
||||
/// The URI of the [directive] can be resolved.
|
||||
class AugmentationKnownFileStateKind extends AugmentationFileStateKind {
|
||||
/// The file that is referenced by the [directive].
|
||||
final FileState uriFile;
|
||||
|
||||
AugmentationKnownFileStateKind({
|
||||
required super.file,
|
||||
required super.directive,
|
||||
required this.uriFile,
|
||||
});
|
||||
|
||||
/// If the [uriFile] has `import augment` of this file, returns [uriFile].
|
||||
/// Otherwise, this file is not a valid augmentation, returns `null`.
|
||||
FileState? get augmented {
|
||||
final uriKind = uriFile.kind;
|
||||
if (uriKind is LibraryOrAugmentationFileKind) {
|
||||
if (uriKind.hasAugmentation(this)) {
|
||||
return uriFile;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// The URI of the [directive] can not be resolved.
|
||||
class AugmentationUnknownFileStateKind extends AugmentationFileStateKind {
|
||||
AugmentationUnknownFileStateKind({
|
||||
required super.file,
|
||||
required super.directive,
|
||||
});
|
||||
}
|
||||
|
||||
/// A library from [SummaryDataStore].
|
||||
class ExternalLibrary {
|
||||
final Uri uri;
|
||||
@@ -131,6 +173,7 @@ class FileState {
|
||||
/// Files that reference this file.
|
||||
final List<FileState> referencingFiles = [];
|
||||
|
||||
List<FileState?> _augmentationFiles = [];
|
||||
List<FileState?>? _importedFiles;
|
||||
List<FileState?>? _exportedFiles;
|
||||
List<FileState?> _partedFiles = [];
|
||||
@@ -163,6 +206,11 @@ class FileState {
|
||||
/// The unlinked API signature of the file.
|
||||
Uint8List get apiSignature => _apiSignature!;
|
||||
|
||||
/// The list of imported augmentations.
|
||||
List<FileState?> get augmentationFiles {
|
||||
return _augmentationFiles;
|
||||
}
|
||||
|
||||
/// The content of the file.
|
||||
String get content => _content!;
|
||||
|
||||
@@ -251,7 +299,7 @@ class FileState {
|
||||
/// not processed a library file yet.
|
||||
FileState? get library {
|
||||
final kind = _kind;
|
||||
if (kind is PartKnownFileStateKind) {
|
||||
if (kind is PartFileStateKind) {
|
||||
return kind.library;
|
||||
} else {
|
||||
return null;
|
||||
@@ -395,14 +443,7 @@ class FileState {
|
||||
// Flush exported top-level declarations of all files.
|
||||
if (apiSignatureChanged) {
|
||||
_libraryCycle?.invalidate();
|
||||
|
||||
// If this is a part, invalidate the libraries.
|
||||
final kind = _kind;
|
||||
if (kind is PartKnownFileStateKind) {
|
||||
for (final library in kind._libraries) {
|
||||
library._libraryCycle?.invalidate();
|
||||
}
|
||||
}
|
||||
_invalidatesLibrariesOfThisPart();
|
||||
}
|
||||
|
||||
// It is possible that this file does not reference these files.
|
||||
@@ -417,6 +458,7 @@ class FileState {
|
||||
// Read parts eagerly to link parts to libraries.
|
||||
_updateKind();
|
||||
_updatePartedFiles();
|
||||
_updateAugmentationFiles();
|
||||
|
||||
// Update mapping from subtyped names to files.
|
||||
for (var name in _driverUnlinkedUnit!.subtypedNames) {
|
||||
@@ -499,6 +541,19 @@ class FileState {
|
||||
}
|
||||
}
|
||||
|
||||
/// If this is a part, invalidate the libraries that use it.
|
||||
void _invalidatesLibrariesOfThisPart() {
|
||||
if (_kind is PartFileStateKind) {
|
||||
for (final library in _fsState._pathToFile.values) {
|
||||
if (library._kind is LibraryFileStateKind) {
|
||||
if (library.partedFiles.contains(this)) {
|
||||
library._libraryCycle?.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CompilationUnitImpl _parse(AnalysisErrorListener errorListener) {
|
||||
CharSequenceReader reader = CharSequenceReader(content);
|
||||
Scanner scanner = Scanner(source, reader, errorListener)
|
||||
@@ -555,107 +610,93 @@ class FileState {
|
||||
}
|
||||
}
|
||||
|
||||
removeForOne(_importedFiles);
|
||||
removeForOne(_augmentationFiles);
|
||||
removeForOne(_exportedFiles);
|
||||
removeForOne(_importedFiles);
|
||||
removeForOne(_partedFiles);
|
||||
}
|
||||
|
||||
void _updateAugmentationFiles() {
|
||||
_augmentationFiles = unlinked2.augmentations.map((directive) {
|
||||
return _fileForRelativeUri(directive.uri).map(
|
||||
(augmentation) {
|
||||
augmentation?.referencingFiles.add(this);
|
||||
return augmentation;
|
||||
},
|
||||
(_) => null,
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
void _updateKind() {
|
||||
/// This file is a part (was not part, or no kind at all).
|
||||
/// Now we might be able to update its kind to a known part.
|
||||
void updateLibrariesWithThisPart() {
|
||||
for (final maybeLibrary in _fsState._pathToFile.values) {
|
||||
if (maybeLibrary.kind is LibraryFileStateKind) {
|
||||
if (maybeLibrary.partedFiles.contains(this)) {
|
||||
maybeLibrary._updatePartedFiles();
|
||||
maybeLibrary._libraryCycle?.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_fsState._libraryNameToFiles.remove(_kind);
|
||||
|
||||
final libraryAugmentationDirective = unlinked2.libraryAugmentationDirective;
|
||||
final libraryDirective = unlinked2.libraryDirective;
|
||||
final partOfNameDirective = unlinked2.partOfNameDirective;
|
||||
final partOfUriDirective = unlinked2.partOfUriDirective;
|
||||
if (libraryAugmentationDirective != null) {
|
||||
// TODO(scheglov) This code does not have enough tests.
|
||||
_kind = LibraryAugmentationUnknownFileStateKind(
|
||||
file: this,
|
||||
directive: libraryAugmentationDirective,
|
||||
final uri = libraryAugmentationDirective.uri;
|
||||
final uriFile = _fileForRelativeUri(uri).map(
|
||||
(file) => file,
|
||||
(_) => null,
|
||||
);
|
||||
_fileForRelativeUri(libraryAugmentationDirective.uri);
|
||||
} else if (unlinked2.libraryDirective != null) {
|
||||
if (uriFile != null) {
|
||||
_kind = AugmentationKnownFileStateKind(
|
||||
file: this,
|
||||
directive: libraryAugmentationDirective,
|
||||
uriFile: uriFile,
|
||||
);
|
||||
} else {
|
||||
_kind = AugmentationUnknownFileStateKind(
|
||||
file: this,
|
||||
directive: libraryAugmentationDirective,
|
||||
);
|
||||
}
|
||||
} else if (libraryDirective != null) {
|
||||
_kind = LibraryFileStateKind(
|
||||
file: this,
|
||||
name: libraryDirective.name,
|
||||
);
|
||||
} else if (partOfNameDirective != null) {
|
||||
if (_kind is! PartKnownFileStateKind) {
|
||||
_kind = PartUnknownNameFileStateKind(
|
||||
file: this,
|
||||
directive: partOfNameDirective,
|
||||
);
|
||||
updateLibrariesWithThisPart();
|
||||
}
|
||||
_kind = PartOfNameFileStateKind(
|
||||
file: this,
|
||||
directive: partOfNameDirective,
|
||||
);
|
||||
} else if (partOfUriDirective != null) {
|
||||
if (_kind is! PartKnownFileStateKind) {
|
||||
_kind = PartUnknownUriFileStateKind(
|
||||
final uri = partOfUriDirective.uri;
|
||||
final uriFile = _fileForRelativeUri(uri).map(
|
||||
(file) => file,
|
||||
(_) => null,
|
||||
);
|
||||
if (uriFile != null) {
|
||||
_kind = PartOfUriKnownFileStateKind(
|
||||
file: this,
|
||||
directive: partOfUriDirective,
|
||||
uriFile: uriFile,
|
||||
);
|
||||
} else {
|
||||
_kind = PartOfUriUnknownFileStateKind(
|
||||
file: this,
|
||||
directive: partOfUriDirective,
|
||||
);
|
||||
_fileForRelativeUri(partOfUriDirective.uri);
|
||||
updateLibrariesWithThisPart();
|
||||
}
|
||||
} else {
|
||||
_kind = LibraryFileStateKind(
|
||||
file: this,
|
||||
name: null,
|
||||
);
|
||||
}
|
||||
|
||||
_fsState._libraryNameToFiles.add(_kind);
|
||||
_invalidatesLibrariesOfThisPart();
|
||||
}
|
||||
|
||||
void _updatePartedFiles() {
|
||||
// Disconnect all parts of this library.
|
||||
for (final part in _partedFiles) {
|
||||
if (part != null) {
|
||||
final partKind = part.kind;
|
||||
if (partKind is PartKnownFileStateKind) {
|
||||
partKind._libraries.remove(this);
|
||||
// If no libraries, switch to unknown.
|
||||
if (partKind._libraries.isEmpty) {
|
||||
final partOfNameDirective = part.unlinked2.partOfNameDirective;
|
||||
final partOfUriDirective = part.unlinked2.partOfUriDirective;
|
||||
if (partOfNameDirective != null) {
|
||||
part._kind = PartUnknownNameFileStateKind(
|
||||
file: part,
|
||||
directive: partOfNameDirective,
|
||||
);
|
||||
} else if (partOfUriDirective != null) {
|
||||
part._kind = PartUnknownUriFileStateKind(
|
||||
file: part,
|
||||
directive: partOfUriDirective,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_partedFiles = unlinked2.parts.map((uri) {
|
||||
return _fileForRelativeUri(uri).map(
|
||||
(part) {
|
||||
if (part != null) {
|
||||
part.referencingFiles.add(this);
|
||||
// Either add this as a library, or switch from unknown.
|
||||
final kind = part._kind;
|
||||
if (kind is PartKnownFileStateKind) {
|
||||
kind._libraries.add(this);
|
||||
} else if (kind is PartUnknownNameFileStateKind ||
|
||||
kind is PartUnknownUriFileStateKind) {
|
||||
part._kind = PartKnownFileStateKind(
|
||||
file: part,
|
||||
library: this,
|
||||
);
|
||||
}
|
||||
}
|
||||
part?.referencingFiles.add(this);
|
||||
return part;
|
||||
},
|
||||
(_) => null,
|
||||
@@ -673,6 +714,7 @@ class FileState {
|
||||
UnlinkedLibraryAugmentationDirective? libraryAugmentationDirective;
|
||||
UnlinkedPartOfNameDirective? partOfNameDirective;
|
||||
UnlinkedPartOfUriDirective? partOfUriDirective;
|
||||
var augmentations = <UnlinkedImportAugmentationDirective>[];
|
||||
var exports = <UnlinkedNamespaceDirective>[];
|
||||
var imports = <UnlinkedNamespaceDirective>[];
|
||||
var parts = <String>[];
|
||||
@@ -682,11 +724,19 @@ class FileState {
|
||||
if (directive is ExportDirective) {
|
||||
var builder = _serializeNamespaceDirective(directive);
|
||||
exports.add(builder);
|
||||
} else if (directive is ImportDirective) {
|
||||
var builder = _serializeNamespaceDirective(directive);
|
||||
imports.add(builder);
|
||||
if (builder.uri == 'dart:core') {
|
||||
hasDartCoreImport = true;
|
||||
} else if (directive is ImportDirectiveImpl) {
|
||||
if (directive.augmentKeyword != null) {
|
||||
augmentations.add(
|
||||
UnlinkedImportAugmentationDirective(
|
||||
uri: directive.uri.stringValue ?? '',
|
||||
),
|
||||
);
|
||||
} else {
|
||||
var builder = _serializeNamespaceDirective(directive);
|
||||
imports.add(builder);
|
||||
if (builder.uri == 'dart:core') {
|
||||
hasDartCoreImport = true;
|
||||
}
|
||||
}
|
||||
} else if (directive is LibraryAugmentationDirective) {
|
||||
final uri = directive.uri;
|
||||
@@ -761,6 +811,7 @@ class FileState {
|
||||
}
|
||||
return UnlinkedUnit(
|
||||
apiSignature: Uint8List.fromList(computeUnlinkedApiSignature(unit)),
|
||||
augmentations: augmentations,
|
||||
exports: exports,
|
||||
imports: imports,
|
||||
informativeBytes: writeUnitInformative(unit),
|
||||
@@ -875,6 +926,9 @@ class FileSystemState {
|
||||
/// Mapping from a path to the corresponding [FileState].
|
||||
final Map<String, FileState> _pathToFile = {};
|
||||
|
||||
/// Mapping from a library name to the [LibraryFileStateKind] that have it.
|
||||
final _LibraryNameToFiles _libraryNameToFiles = _LibraryNameToFiles();
|
||||
|
||||
/// The map of subtyped names to files where these names are subtyped.
|
||||
final Map<String, Set<FileState>> _subtypedNameToFiles = {};
|
||||
|
||||
@@ -1070,9 +1124,11 @@ class FileSystemState {
|
||||
_hasUriForPath.clear();
|
||||
_pathToFile.clear();
|
||||
_subtypedNameToFiles.clear();
|
||||
_libraryNameToFiles.clear();
|
||||
}
|
||||
|
||||
FileState _newFile(File resource, String path, Uri uri) {
|
||||
// print('[_newFile][uri: $uri][path: $path]');
|
||||
FileSource uriSource = FileSource(resource, uri);
|
||||
WorkspacePackage? workspacePackage = _workspace?.findPackageFor(path);
|
||||
FeatureSet featureSet = contextFeatureSet(path, uri, workspacePackage);
|
||||
@@ -1152,63 +1208,152 @@ class FileUriProperties {
|
||||
bool get isSrc => (_flags & _isSrc) != 0;
|
||||
}
|
||||
|
||||
class LibraryAugmentationKnownFileStateKind extends FileStateKind {
|
||||
final FileState augmented;
|
||||
class LibraryFileStateKind extends LibraryOrAugmentationFileKind {
|
||||
/// The name of the library from the `library` directive.
|
||||
/// Or `null` if no `library` directive.
|
||||
final String? name;
|
||||
|
||||
LibraryAugmentationKnownFileStateKind({
|
||||
required super.file,
|
||||
required this.augmented,
|
||||
});
|
||||
}
|
||||
|
||||
/// A library augmentation when the augmented target is unknown, e.g.
|
||||
/// the provided URI cannot be resolved.
|
||||
class LibraryAugmentationUnknownFileStateKind extends FileStateKind {
|
||||
final UnlinkedLibraryAugmentationDirective directive;
|
||||
|
||||
LibraryAugmentationUnknownFileStateKind({
|
||||
required super.file,
|
||||
required this.directive,
|
||||
});
|
||||
}
|
||||
|
||||
class LibraryFileStateKind extends FileStateKind {
|
||||
LibraryFileStateKind({
|
||||
required super.file,
|
||||
required this.name,
|
||||
});
|
||||
}
|
||||
|
||||
class PartKnownFileStateKind extends FileStateKind {
|
||||
final List<FileState> _libraries = [];
|
||||
|
||||
PartKnownFileStateKind({
|
||||
required super.file,
|
||||
required FileState library,
|
||||
}) {
|
||||
_libraries.add(library);
|
||||
bool hasPart(PartFileStateKind part) {
|
||||
return file.partedFiles.contains(part.file);
|
||||
}
|
||||
|
||||
FileState get library => _libraries.first;
|
||||
}
|
||||
|
||||
/// The file is a part, but its library is unknown.
|
||||
/// We don't know the library with this name.
|
||||
class PartUnknownNameFileStateKind extends FileStateKind {
|
||||
abstract class LibraryOrAugmentationFileKind extends FileStateKind {
|
||||
LibraryOrAugmentationFileKind({
|
||||
required super.file,
|
||||
});
|
||||
|
||||
bool hasAugmentation(AugmentationFileStateKind augmentation) {
|
||||
return file.augmentationFiles.contains(augmentation.file);
|
||||
}
|
||||
}
|
||||
|
||||
/// The file has `part of` directive.
|
||||
abstract class PartFileStateKind extends FileStateKind {
|
||||
PartFileStateKind({
|
||||
required super.file,
|
||||
});
|
||||
|
||||
/// Returns the library in which this part should be analyzed.
|
||||
FileState? get library;
|
||||
}
|
||||
|
||||
/// The file has `part of name` directive.
|
||||
class PartOfNameFileStateKind extends PartFileStateKind {
|
||||
final UnlinkedPartOfNameDirective directive;
|
||||
|
||||
PartUnknownNameFileStateKind({
|
||||
PartOfNameFileStateKind({
|
||||
required super.file,
|
||||
required this.directive,
|
||||
});
|
||||
|
||||
/// Libraries with the same name as in [directive].
|
||||
List<LibraryFileStateKind> get libraries {
|
||||
final files = file._fsState._libraryNameToFiles;
|
||||
return files[directive.name] ?? [];
|
||||
}
|
||||
|
||||
/// If there are libraries that include this file as a part, return the
|
||||
/// first one as if sorted by path.
|
||||
@override
|
||||
FileState? get library {
|
||||
LibraryFileStateKind? result;
|
||||
for (final library in libraries) {
|
||||
if (library.hasPart(this)) {
|
||||
if (result == null) {
|
||||
result = library;
|
||||
} else if (library.file.path.compareTo(result.file.path) < 0) {
|
||||
result = library;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result?.file;
|
||||
}
|
||||
}
|
||||
|
||||
/// The file is a part, but its library is unknown.
|
||||
/// When we don't understand the URI.
|
||||
class PartUnknownUriFileStateKind extends FileStateKind {
|
||||
/// The file has `part of URI` directive.
|
||||
abstract class PartOfUriFileStateKind extends PartFileStateKind {
|
||||
final UnlinkedPartOfUriDirective directive;
|
||||
|
||||
PartUnknownUriFileStateKind({
|
||||
PartOfUriFileStateKind({
|
||||
required super.file,
|
||||
required this.directive,
|
||||
});
|
||||
}
|
||||
|
||||
/// The file has `part of URI` directive, and the URI can be resolved.
|
||||
class PartOfUriKnownFileStateKind extends PartOfUriFileStateKind {
|
||||
final FileState uriFile;
|
||||
|
||||
PartOfUriKnownFileStateKind({
|
||||
required super.file,
|
||||
required super.directive,
|
||||
required this.uriFile,
|
||||
});
|
||||
|
||||
@override
|
||||
FileState? get library {
|
||||
final uriKind = uriFile.kind;
|
||||
if (uriKind is LibraryFileStateKind) {
|
||||
if (uriKind.hasPart(this)) {
|
||||
return uriFile;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// The file has `part of URI` directive, and the URI cannot be resolved.
|
||||
class PartOfUriUnknownFileStateKind extends PartOfUriFileStateKind {
|
||||
PartOfUriUnknownFileStateKind({
|
||||
required super.file,
|
||||
required super.directive,
|
||||
});
|
||||
|
||||
@override
|
||||
FileState? get library => null;
|
||||
}
|
||||
|
||||
class _LibraryNameToFiles {
|
||||
final Map<String, List<LibraryFileStateKind>> _map = {};
|
||||
|
||||
List<LibraryFileStateKind>? operator [](String name) {
|
||||
return _map[name];
|
||||
}
|
||||
|
||||
/// If [kind] is a named library, register it.
|
||||
void add(FileStateKind? kind) {
|
||||
if (kind is LibraryFileStateKind) {
|
||||
final name = kind.name;
|
||||
if (name != null) {
|
||||
final libraries = _map[name] ??= [];
|
||||
libraries.add(kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_map.clear();
|
||||
}
|
||||
|
||||
/// If [kind] is a named library, unregister it.
|
||||
void remove(FileStateKind? kind) {
|
||||
if (kind is LibraryFileStateKind) {
|
||||
final name = kind.name;
|
||||
if (name != null) {
|
||||
final libraries = _map[name];
|
||||
if (libraries != null) {
|
||||
libraries.remove(kind);
|
||||
if (libraries.isEmpty) {
|
||||
_map.remove(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,26 @@ class MacroClass {
|
||||
}
|
||||
}
|
||||
|
||||
class UnlinkedImportAugmentationDirective {
|
||||
final String uri;
|
||||
|
||||
UnlinkedImportAugmentationDirective({
|
||||
required this.uri,
|
||||
});
|
||||
|
||||
factory UnlinkedImportAugmentationDirective.read(
|
||||
SummaryDataReader reader,
|
||||
) {
|
||||
return UnlinkedImportAugmentationDirective(
|
||||
uri: reader.readStringUtf8(),
|
||||
);
|
||||
}
|
||||
|
||||
void write(BufferedSink sink) {
|
||||
sink.writeStringUtf8(uri);
|
||||
}
|
||||
}
|
||||
|
||||
class UnlinkedLibraryAugmentationDirective {
|
||||
final String uri;
|
||||
final UnlinkedSourceRange uriRange;
|
||||
@@ -285,6 +305,9 @@ class UnlinkedUnit {
|
||||
/// TODO(scheglov) Do we need it?
|
||||
final Uint8List apiSignature;
|
||||
|
||||
/// `import augmentation` directives.
|
||||
final List<UnlinkedImportAugmentationDirective> augmentations;
|
||||
|
||||
/// URIs of `export` directives.
|
||||
final List<UnlinkedNamespaceDirective> exports;
|
||||
|
||||
@@ -317,6 +340,7 @@ class UnlinkedUnit {
|
||||
|
||||
UnlinkedUnit({
|
||||
required this.apiSignature,
|
||||
required this.augmentations,
|
||||
required this.exports,
|
||||
required this.imports,
|
||||
required this.informativeBytes,
|
||||
@@ -332,6 +356,9 @@ class UnlinkedUnit {
|
||||
factory UnlinkedUnit.read(SummaryDataReader reader) {
|
||||
return UnlinkedUnit(
|
||||
apiSignature: reader.readUint8List(),
|
||||
augmentations: reader.readTypedList(
|
||||
() => UnlinkedImportAugmentationDirective.read(reader),
|
||||
),
|
||||
exports: reader.readTypedList(
|
||||
() => UnlinkedNamespaceDirective.read(reader),
|
||||
),
|
||||
@@ -361,6 +388,9 @@ class UnlinkedUnit {
|
||||
|
||||
void write(BufferedSink sink) {
|
||||
sink.writeUint8List(apiSignature);
|
||||
sink.writeList<UnlinkedImportAugmentationDirective>(augmentations, (x) {
|
||||
x.write(sink);
|
||||
});
|
||||
sink.writeList<UnlinkedNamespaceDirective>(exports, (x) {
|
||||
x.write(sink);
|
||||
});
|
||||
|
||||
@@ -904,6 +904,7 @@ class _FileStateUnlinked {
|
||||
UnlinkedLibraryAugmentationDirective? libraryAugmentationDirective;
|
||||
UnlinkedPartOfNameDirective? partOfNameDirective;
|
||||
UnlinkedPartOfUriDirective? partOfUriDirective;
|
||||
var augmentations = <UnlinkedImportAugmentationDirective>[];
|
||||
var exports = <UnlinkedNamespaceDirective>[];
|
||||
var imports = <UnlinkedNamespaceDirective>[];
|
||||
var parts = <String>[];
|
||||
@@ -912,11 +913,19 @@ class _FileStateUnlinked {
|
||||
if (directive is ExportDirective) {
|
||||
var builder = _serializeNamespaceDirective(directive);
|
||||
exports.add(builder);
|
||||
} else if (directive is ImportDirective) {
|
||||
var builder = _serializeNamespaceDirective(directive);
|
||||
imports.add(builder);
|
||||
if (builder.uri == 'dart:core') {
|
||||
hasDartCoreImport = true;
|
||||
} else if (directive is ImportDirectiveImpl) {
|
||||
if (directive.augmentKeyword != null) {
|
||||
augmentations.add(
|
||||
UnlinkedImportAugmentationDirective(
|
||||
uri: directive.uri.stringValue ?? '',
|
||||
),
|
||||
);
|
||||
} else {
|
||||
var builder = _serializeNamespaceDirective(directive);
|
||||
imports.add(builder);
|
||||
if (builder.uri == 'dart:core') {
|
||||
hasDartCoreImport = true;
|
||||
}
|
||||
}
|
||||
} else if (directive is LibraryAugmentationDirective) {
|
||||
final uri = directive.uri;
|
||||
@@ -995,6 +1004,7 @@ class _FileStateUnlinked {
|
||||
|
||||
var unlinkedUnit = UnlinkedUnit(
|
||||
apiSignature: computeUnlinkedApiSignature(unit),
|
||||
augmentations: augmentations,
|
||||
exports: exports,
|
||||
imports: imports,
|
||||
informativeBytes: writeUnitInformative(unit),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 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 'package:analyzer/dart/analysis/results.dart';
|
||||
import 'package:analyzer/dart/element/nullability_suffix.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
@@ -396,10 +397,13 @@ C<int Function()> c;
|
||||
}
|
||||
|
||||
test_invalidPart_withPart() async {
|
||||
await _assertCanBeAnalyzed('''
|
||||
newFile(testFilePath, '''
|
||||
part of a;
|
||||
part 'test.dart';
|
||||
''');
|
||||
final analysisSession = contextFor(testFile.path).currentSession;
|
||||
final result = await analysisSession.getResolvedUnit(testFile.path);
|
||||
result as PartWithoutLibraryResult;
|
||||
}
|
||||
|
||||
test_issue_48688() async {
|
||||
|
||||
@@ -2548,7 +2548,7 @@ class A {}
|
||||
expect(driver.knownFiles, contains(p));
|
||||
}
|
||||
|
||||
test_part_getErrors_afterLibrary() async {
|
||||
test_partOfName_getErrors_afterLibrary() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
@@ -2584,7 +2584,7 @@ var b = new B();
|
||||
}
|
||||
}
|
||||
|
||||
test_part_getErrors_beforeLibrary() async {
|
||||
test_partOfName_getErrors_beforeLibrary() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
@@ -2614,7 +2614,7 @@ var b = new B();
|
||||
}
|
||||
}
|
||||
|
||||
test_part_getResult_afterLibrary() async {
|
||||
test_partOfName_getResult_afterLibrary() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
@@ -2653,7 +2653,7 @@ var b = new B();
|
||||
}
|
||||
}
|
||||
|
||||
test_part_getResult_beforeLibrary() async {
|
||||
test_partOfName_getResult_beforeLibrary() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
@@ -2684,7 +2684,7 @@ var b = new B();
|
||||
_assertTopLevelVarType(result.unit, 'b', 'B');
|
||||
}
|
||||
|
||||
test_part_getResult_changePart_invalidatesLibraryCycle() async {
|
||||
test_partOfName_getResult_changePart_invalidatesLibraryCycle() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
newFile(a, r'''
|
||||
@@ -2710,7 +2710,26 @@ Future<int> f;
|
||||
expect(result.errors, isEmpty);
|
||||
}
|
||||
|
||||
test_part_getResult_noLibrary() async {
|
||||
test_partOfName_getResult_hasLibrary_noPart() async {
|
||||
final a = newFile('/test/lib/a.dart', r'''
|
||||
library my.lib;
|
||||
''');
|
||||
|
||||
final c = newFile('/test/lib/c.dart', r'''
|
||||
part of my.lib;
|
||||
class C {}
|
||||
''');
|
||||
|
||||
// Discover the library.
|
||||
driver.getFileSync(a.path);
|
||||
|
||||
// There is no library which c.dart is a part of, so invalid result.
|
||||
final result = await driver.getResult(c.path);
|
||||
result as PartWithoutLibraryResult;
|
||||
expect(result.path, c.path);
|
||||
}
|
||||
|
||||
test_partOfName_getResult_noLibrary() async {
|
||||
final c = newFile('/test/lib/c.dart', r'''
|
||||
part of a;
|
||||
class C {}
|
||||
@@ -2722,7 +2741,7 @@ class C {}
|
||||
expect(result.path, c.path);
|
||||
}
|
||||
|
||||
test_part_getUnitElement_afterLibrary() async {
|
||||
test_partOfName_getUnitElement_afterLibrary() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
@@ -2762,7 +2781,7 @@ var b = new B();
|
||||
}
|
||||
}
|
||||
|
||||
test_part_getUnitElement_beforeLibrary() async {
|
||||
test_partOfName_getUnitElement_beforeLibrary() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
@@ -2799,7 +2818,7 @@ var b = new B();
|
||||
}
|
||||
}
|
||||
|
||||
test_part_getUnitElement_noLibrary() async {
|
||||
test_partOfName_getUnitElement_noLibrary() async {
|
||||
final c = newFile('/test/lib/c.dart', r'''
|
||||
part of a;
|
||||
''');
|
||||
@@ -2810,7 +2829,7 @@ part of a;
|
||||
expect(result.path, c.path);
|
||||
}
|
||||
|
||||
test_part_results_afterLibrary() async {
|
||||
test_partOfName_results_afterLibrary() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
@@ -2859,7 +2878,7 @@ var b = new B();
|
||||
}
|
||||
}
|
||||
|
||||
test_part_results_beforeLibrary() async {
|
||||
test_partOfName_results_beforeLibrary() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
@@ -2894,7 +2913,7 @@ var b = new B();
|
||||
expect(result.errors, isEmpty);
|
||||
}
|
||||
|
||||
test_part_results_noLibrary() async {
|
||||
test_partOfName_results_noLibrary() async {
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
newFile(c, r'''
|
||||
part of a;
|
||||
@@ -2913,7 +2932,7 @@ var b = new B();
|
||||
.lastWhere((result) => result.path == c);
|
||||
}
|
||||
|
||||
test_part_results_noLibrary_priority() async {
|
||||
test_partOfName_results_noLibrary_priority() async {
|
||||
var c = newFile('/test/lib/c.dart', r'''
|
||||
part of a;
|
||||
class C {}
|
||||
@@ -2932,7 +2951,7 @@ var b = new B();
|
||||
.lastWhere((result) => result.path == c.path);
|
||||
}
|
||||
|
||||
test_part_results_priority_beforeLibrary() async {
|
||||
test_partOfName_results_priority_beforeLibrary() async {
|
||||
var a = convertPath('/test/lib/a.dart');
|
||||
var b = convertPath('/test/lib/b.dart');
|
||||
var c = convertPath('/test/lib/c.dart');
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user