[cfe] Move SourceLibraryBuilder.parts to SourceCompilationUnitImpl

Change-Id: Id3f4ec4bb107169c8a95b9cc6b8bf8032545c360
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371687
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2024-06-17 08:26:10 +00:00 committed by Commit Queue
parent 17af09ff47
commit 47a69d9db6
9 changed files with 289 additions and 263 deletions

View file

@ -196,6 +196,9 @@ abstract class SourceCompilationUnit implements CompilationUnit {
void addDependencies(Library library, Set<SourceLibraryBuilder> seen);
void includeParts(SourceLibraryBuilder libraryBuilder,
List<SourceCompilationUnit> includedParts, Set<Uri> usedParts);
void validatePart(SourceLibraryBuilder? library, Set<Uri>? usedParts);
void addScriptToken(int charOffset);

View file

@ -16,7 +16,7 @@ import 'import.dart' show Import;
import 'dill/dill_library_builder.dart' show DillLibraryBuilder;
import 'source/source_library_builder.dart' show Part, SourceLibraryBuilder;
import 'source/source_library_builder.dart' show SourceLibraryBuilder;
import 'incremental_compiler.dart' show getPartUri;
@ -52,8 +52,8 @@ class BuilderGraph implements Graph<Uri> {
neighbors.add(uri);
}
}
for (Part part in libraryBuilder.parts) {
Uri uri = part.compilationUnit.importUri;
for (SourceCompilationUnit part in libraryBuilder.parts) {
Uri uri = part.importUri;
if (libraryBuilders.containsKey(uri)) {
neighbors.add(uri);
}

View file

@ -29,7 +29,7 @@ class Export {
/// The [LibraryDependency] node corresponding to this import.
///
/// This set in [SourceLibraryBuilder.addDependencies].
/// This set in [SourceLibraryBuilder._addDependencies].
late final LibraryDependency libraryDependency;
bool addToExportScope(String name, Builder member) {

View file

@ -49,7 +49,7 @@ class Import {
/// The [LibraryDependency] node corresponding to this import.
///
/// This set in [SourceLibraryBuilder.addDependencies].
/// This set in [SourceLibraryBuilder._addDependencies].
LibraryDependency? libraryDependency;
Import(

View file

@ -101,7 +101,7 @@ import 'source/source_library_builder.dart'
import 'source/source_loader.dart';
import 'ticker.dart' show Ticker;
import 'uri_translator.dart' show UriTranslator;
import 'uris.dart' show dartCore;
import 'uris.dart' show MALFORMED_URI_SCHEME, dartCore;
import 'util/error_reporter_file_copier.dart' show saveAsGzip;
import 'util/experiment_environment_getter.dart'
show enableIncrementalCompilerBenchmarking, getExperimentEnvironment;
@ -2268,7 +2268,7 @@ class _ExtensionTypeFinder extends VisitorDefault<void> with VisitorVoidMixin {
/// Uri.parse("file://path/to/parent.dart"),
/// new LibraryPart([], ":hello")
/// ),
/// new Uri(scheme: SourceLibraryBuilder.MALFORMED_URI_SCHEME,
/// new Uri(scheme: MALFORMED_URI_SCHEME,
/// query: Uri.encodeQueryComponent(":hello"))
/// )
/// ```
@ -2278,7 +2278,7 @@ Uri getPartUri(Uri parentUri, LibraryPart part) {
} on FormatException {
// This is also done in [SourceLibraryBuilder.resolve]
return new Uri(
scheme: SourceLibraryBuilder.MALFORMED_URI_SCHEME,
scheme: MALFORMED_URI_SCHEME,
query: Uri.encodeQueryComponent(part.partUri));
}
}

View file

@ -71,6 +71,7 @@ import '../modifier.dart'
staticMask;
import '../operator.dart' show Operator;
import '../problems.dart' show unhandled;
import '../uris.dart';
import 'offset_map.dart';
import 'source_enum_builder.dart';
import 'source_library_builder.dart'
@ -876,7 +877,7 @@ class OutlineBuilder extends StackListenerImpl {
} else {
Token beginToken = pop() as Token;
int charOffset = beginToken.charOffset;
push("${SourceLibraryBuilder.MALFORMED_URI_SCHEME}:bad${charOffset}");
push("${MALFORMED_URI_SCHEME}:bad${charOffset}");
push(charOffset);
// Point to dollar sign
int interpolationOffset = charOffset + beginToken.lexeme.length;

View file

@ -102,6 +102,7 @@ import '../modifier.dart'
staticMask;
import '../problems.dart' show unexpected, unhandled;
import '../scope.dart';
import '../uris.dart';
import '../util/helpers.dart';
import 'class_declaration.dart';
import 'name_scheme.dart';
@ -130,6 +131,9 @@ class SourceCompilationUnitImpl implements SourceCompilationUnit {
/// This is meant to be written once and read once.
OffsetMap? _offsetMap;
/// The part directives in this compilation unit.
final List<Part> _parts = [];
SourceCompilationUnitImpl(this._sourceLibraryBuilder);
@override
@ -352,10 +356,267 @@ class SourceCompilationUnitImpl implements SourceCompilationUnit {
List<NamedTypeBuilder> get unresolvedNamedTypes =>
_sourceLibraryBuilder.unresolvedNamedTypes;
@override
void includeParts(SourceLibraryBuilder libraryBuilder,
List<SourceCompilationUnit> includedParts, Set<Uri> usedParts) {
Set<Uri> seenParts = new Set<Uri>();
int index = 0;
while (index < _parts.length) {
Part part = _parts[index];
bool keepPart = true;
// TODO(johnniwinther): Use [part.offset] in messages.
if (part.compilationUnit == this) {
addProblem(messagePartOfSelf, -1, noLength, fileUri);
keepPart = false;
} else if (seenParts.add(part.compilationUnit.fileUri)) {
if (part.compilationUnit.partOfLibrary != null) {
addProblem(messagePartOfTwoLibraries, -1, noLength,
part.compilationUnit.fileUri,
context: [
messagePartOfTwoLibrariesContext.withLocation(
part.compilationUnit.partOfLibrary!.fileUri, -1, noLength),
messagePartOfTwoLibrariesContext.withLocation(
fileUri, -1, noLength)
]);
keepPart = false;
} else {
usedParts.add(part.compilationUnit.importUri);
keepPart = _includePart(libraryBuilder, this, includedParts,
part.compilationUnit, usedParts, part.offset);
}
} else {
addProblem(
templatePartTwice.withArguments(part.compilationUnit.fileUri),
-1,
noLength,
fileUri);
keepPart = false;
}
if (keepPart) {
index++;
} else {
// TODO(johnniwinther): Stop removing parts.
_parts.removeAt(index);
}
}
}
bool _includePart(
SourceLibraryBuilder libraryBuilder,
SourceCompilationUnit parentCompilationUnit,
List<SourceCompilationUnit> includedParts,
CompilationUnit part,
Set<Uri> usedParts,
int partOffset) {
switch (part) {
case SourceCompilationUnit():
if (part.partOfUri != null) {
if (isNotMalformedUriScheme(part.partOfUri!) &&
part.partOfUri != parentCompilationUnit.importUri) {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
parentCompilationUnit.addProblem(
templatePartOfUriMismatch.withArguments(part.fileUri,
parentCompilationUnit.importUri, part.partOfUri!),
partOffset,
noLength,
parentCompilationUnit.fileUri);
return false;
}
} else if (part.partOfName != null) {
if (parentCompilationUnit.name != null) {
if (part.partOfName != parentCompilationUnit.name) {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
parentCompilationUnit.addProblem(
templatePartOfLibraryNameMismatch.withArguments(part.fileUri,
parentCompilationUnit.name!, part.partOfName!),
partOffset,
noLength,
parentCompilationUnit.fileUri);
return false;
}
} else {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
parentCompilationUnit.addProblem(
templatePartOfUseUri.withArguments(part.fileUri,
parentCompilationUnit.fileUri, part.partOfName!),
partOffset,
noLength,
parentCompilationUnit.fileUri);
return false;
}
} else {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
assert(!part.isPart);
if (isNotMalformedUriScheme(part.fileUri)) {
parentCompilationUnit.addProblem(
templateMissingPartOf.withArguments(part.fileUri),
partOffset,
noLength,
parentCompilationUnit.fileUri);
}
return false;
}
// Language versions have to match. Except if (at least) one of them is
// invalid in which case we've already gotten an error about this.
if (parentCompilationUnit.languageVersion != part.languageVersion &&
parentCompilationUnit.languageVersion.valid &&
part.languageVersion.valid) {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
List<LocatedMessage> context = <LocatedMessage>[];
if (parentCompilationUnit.languageVersion.isExplicit) {
context.add(messageLanguageVersionLibraryContext.withLocation(
parentCompilationUnit.languageVersion.fileUri!,
parentCompilationUnit.languageVersion.charOffset,
parentCompilationUnit.languageVersion.charCount));
}
if (part.languageVersion.isExplicit) {
context.add(messageLanguageVersionPartContext.withLocation(
part.languageVersion.fileUri!,
part.languageVersion.charOffset,
part.languageVersion.charCount));
}
parentCompilationUnit.addProblem(messageLanguageVersionMismatchInPart,
partOffset, noLength, parentCompilationUnit.fileUri,
context: context);
}
part.validatePart(libraryBuilder, usedParts);
NameIterator partDeclarations = part.localMembersNameIterator;
while (partDeclarations.moveNext()) {
String name = partDeclarations.name;
Builder declaration = partDeclarations.current;
if (declaration.next != null) {
List<Builder> duplicated = <Builder>[];
while (declaration.next != null) {
duplicated.add(declaration);
partDeclarations.moveNext();
declaration = partDeclarations.current;
}
duplicated.add(declaration);
// Handle duplicated declarations in the part.
//
// Duplicated declarations are handled by creating a linked list
// using the `next` field. This is preferred over making all scope
// entries be a `List<Declaration>`.
//
// We maintain the linked list so that the last entry is easy to
// recognize (it's `next` field is null). This means that it is
// reversed with respect to source code order. Since kernel doesn't
// allow duplicated declarations, we ensure that we only add the
// first declaration to the kernel tree.
//
// Since the duplicated declarations are stored in reverse order, we
// iterate over them in reverse order as this is simpler and
// normally not a problem. However, in this case we need to call
// [addBuilder] in source order as it would otherwise create cycles.
//
// We also need to be careful preserving the order of the links. The
// part library still keeps these declarations in its scope so that
// DietListener can find them.
for (int i = duplicated.length; i > 0; i--) {
Builder declaration = duplicated[i - 1];
// No reference: There should be no duplicates when using
// references.
libraryBuilder.addBuilder(
name, declaration, declaration.charOffset);
}
} else {
// No reference: The part is in the same loader so the reference
// - if needed - was already added.
libraryBuilder.addBuilder(
name, declaration, declaration.charOffset);
}
}
libraryBuilder.unresolvedNamedTypes.addAll(part.unresolvedNamedTypes);
libraryBuilder.constructorReferences.addAll(part.constructorReferences);
part.libraryName.reference =
parentCompilationUnit.libraryName.reference;
part.partOfLibrary = libraryBuilder;
part.scope.becomePartOf(libraryBuilder.scope);
// TODO(ahe): Include metadata from part?
// Recovery: Take on all exporters (i.e. if a library has erroneously
// exported the part it has (in validatePart) been recovered to import
// the main library (this) instead --- to make it complete (and set up
// scopes correctly) the exporters in this has to be updated too).
libraryBuilder.exporters.addAll(part.exporters);
libraryBuilder.nativeMethods.addAll(part.nativeMethods);
libraryBuilder.unboundNominalVariables
.addAll(part.unboundNominalVariables);
libraryBuilder.unboundStructuralVariables
.addAll(part.unboundStructuralVariables);
// Check that the targets are different. This is not normally a problem
// but is for augmentation libraries.
if (libraryBuilder.library != part.library &&
part.library.problemsAsJson != null) {
(libraryBuilder.library.problemsAsJson ??= <String>[])
.addAll(part.library.problemsAsJson!);
}
part.collectInferableTypes(libraryBuilder._inferableTypes!);
part.takeMixinApplications(libraryBuilder._mixinApplications!);
if (libraryBuilder.library != part.library) {
// Mark the part library as synthetic as it's not an actual library
// (anymore).
part.library.isSynthetic = true;
}
includedParts.add(part);
return true;
case DillCompilationUnit():
// Trying to add a dill library builder as a part means that it exists
// as a stand-alone library in the dill file.
// This means, that it's not a part (if it had been it would be been
// "merged in" to the real library and thus not been a library on its
// own) so we behave like if it's a library with a missing "part of"
// declaration (i.e. as it was a SourceLibraryBuilder without a
// "part of" declaration).
if (isNotMalformedUriScheme(part.fileUri)) {
parentCompilationUnit.addProblem(
templateMissingPartOf.withArguments(part.fileUri),
partOffset,
noLength,
parentCompilationUnit.fileUri);
}
return false;
}
}
@override
void validatePart(SourceLibraryBuilder? library, Set<Uri>? usedParts) {
_libraryBuilder = library ?? _sourceLibraryBuilder;
_sourceLibraryBuilder.validatePart(library, usedParts);
if (library != null && _parts.isNotEmpty) {
// If [library] is null, we have already reported a problem that this
// part is orphaned.
List<LocatedMessage> context = <LocatedMessage>[
messagePartInPartLibraryContext.withLocation(library.fileUri, -1, 1),
];
for (Part part in _parts) {
addProblem(messagePartInPart, part.offset, noLength, fileUri,
context: context);
}
for (Part part in _parts) {
// Mark this part as used so we don't report it as orphaned.
usedParts!.add(part.compilationUnit.importUri);
}
}
_parts.clear();
if (exporters.isNotEmpty) {
List<LocatedMessage> context = <LocatedMessage>[
messagePartExportContext.withLocation(fileUri, -1, 1),
];
for (Export export in exporters) {
export.exporter.addProblem(
messagePartExport, export.charOffset, "export".length, null,
context: context);
}
}
}
@override
@ -375,7 +636,7 @@ class SourceCompilationUnitImpl implements SourceCompilationUnit {
fileUri: newFileUri,
accessor: this,
isPatch: isAugmenting);
_sourceLibraryBuilder.parts.add(new Part(charOffset, compilationUnit));
_parts.add(new Part(charOffset, compilationUnit));
// TODO(ahe): [metadata] should be stored, evaluated, and added to [part].
LibraryPart part = new LibraryPart(<Expression>[], uri)
@ -2357,8 +2618,6 @@ class SourceCompilationUnitImpl implements SourceCompilationUnit {
}
class SourceLibraryBuilder extends LibraryBuilderImpl {
static const String MALFORMED_URI_SCHEME = "org-dartlang-malformed-uri";
late final SourceCompilationUnit compilationUnit =
new SourceCompilationUnitImpl(this);
@ -2371,7 +2630,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
final List<ConstructorReferenceBuilder> constructorReferences =
<ConstructorReferenceBuilder>[];
final List<Part> parts = [];
final List<SourceCompilationUnit> _parts = [];
final List<Import> imports = <Import>[];
@ -2708,6 +2967,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
isPatch: isPatch,
omittedTypes: omittedTypes);
Iterable<SourceCompilationUnit> get parts => _parts;
@override
bool get isPart => partOfName != null || partOfUri != null;
@ -2854,8 +3115,6 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
_languageVersion.isFinal = true;
}
bool uriIsValid(Uri uri) => !uri.isScheme(MALFORMED_URI_SCHEME);
// TODO(johnniwinther): Move this to [SourceCompilationUnitImpl].
Uri resolve(Uri baseUri, String? uri, int uriOffset, {isPart = false}) {
if (uri == null) {
@ -3171,241 +3430,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
return library;
}
void validatePart(SourceLibraryBuilder? library, Set<Uri>? usedParts) {
if (library != null && parts.isNotEmpty) {
// If [library] is null, we have already reported a problem that this
// part is orphaned.
List<LocatedMessage> context = <LocatedMessage>[
messagePartInPartLibraryContext.withLocation(library.fileUri, -1, 1),
];
for (Part part in parts) {
addProblem(messagePartInPart, part.offset, noLength, fileUri,
context: context);
}
for (Part part in parts) {
// Mark this part as used so we don't report it as orphaned.
usedParts!.add(part.compilationUnit.importUri);
}
}
parts.clear();
if (exporters.isNotEmpty) {
List<LocatedMessage> context = <LocatedMessage>[
messagePartExportContext.withLocation(fileUri, -1, 1),
];
for (Export export in exporters) {
export.exporter.addProblem(
messagePartExport, export.charOffset, "export".length, null,
context: context);
}
}
}
void includeParts(Set<Uri> usedParts) {
Set<Uri> seenParts = new Set<Uri>();
int index = 0;
while (index < parts.length) {
Part part = parts[index];
bool keepPart = true;
// TODO(johnniwinther): Use [part.offset] in messages.
if (part.compilationUnit == compilationUnit) {
addProblem(messagePartOfSelf, -1, noLength, fileUri);
keepPart = false;
} else if (seenParts.add(part.compilationUnit.fileUri)) {
if (part.compilationUnit.partOfLibrary != null) {
addProblem(messagePartOfTwoLibraries, -1, noLength,
part.compilationUnit.fileUri,
context: [
messagePartOfTwoLibrariesContext.withLocation(
part.compilationUnit.partOfLibrary!.fileUri, -1, noLength),
messagePartOfTwoLibrariesContext.withLocation(
this.fileUri, -1, noLength)
]);
keepPart = false;
} else {
usedParts.add(part.compilationUnit.importUri);
keepPart = _includePart(part.compilationUnit, usedParts, part.offset);
}
} else {
addProblem(
templatePartTwice.withArguments(part.compilationUnit.fileUri),
-1,
noLength,
fileUri);
keepPart = false;
}
if (keepPart) {
index++;
} else {
parts.removeAt(index);
}
}
}
bool _includePart(CompilationUnit part, Set<Uri> usedParts, int partOffset) {
switch (part) {
case SourceCompilationUnit():
if (part.partOfUri != null) {
if (uriIsValid(part.partOfUri!) && part.partOfUri != importUri) {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
addProblem(
templatePartOfUriMismatch.withArguments(
part.fileUri, importUri, part.partOfUri!),
partOffset,
noLength,
fileUri);
return false;
}
} else if (part.partOfName != null) {
if (name != null) {
if (part.partOfName != name) {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
addProblem(
templatePartOfLibraryNameMismatch.withArguments(
part.fileUri, name!, part.partOfName!),
partOffset,
noLength,
fileUri);
return false;
}
} else {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
addProblem(
templatePartOfUseUri.withArguments(
part.fileUri, fileUri, part.partOfName!),
partOffset,
noLength,
fileUri);
return false;
}
} else {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
assert(!part.isPart);
if (uriIsValid(part.fileUri)) {
addProblem(templateMissingPartOf.withArguments(part.fileUri),
partOffset, noLength, fileUri);
}
return false;
}
// Language versions have to match. Except if (at least) one of them is
// invalid in which case we've already gotten an error about this.
if (languageVersion != part.languageVersion &&
languageVersion.valid &&
part.languageVersion.valid) {
// This is an error, but the part is not removed from the list of
// parts, so that metadata annotations can be associated with it.
List<LocatedMessage> context = <LocatedMessage>[];
if (languageVersion.isExplicit) {
context.add(messageLanguageVersionLibraryContext.withLocation(
languageVersion.fileUri!,
languageVersion.charOffset,
languageVersion.charCount));
}
if (part.languageVersion.isExplicit) {
context.add(messageLanguageVersionPartContext.withLocation(
part.languageVersion.fileUri!,
part.languageVersion.charOffset,
part.languageVersion.charCount));
}
addProblem(messageLanguageVersionMismatchInPart, partOffset, noLength,
fileUri,
context: context);
}
part.validatePart(this, usedParts);
NameIterator partDeclarations = part.localMembersNameIterator;
while (partDeclarations.moveNext()) {
String name = partDeclarations.name;
Builder declaration = partDeclarations.current;
if (declaration.next != null) {
List<Builder> duplicated = <Builder>[];
while (declaration.next != null) {
duplicated.add(declaration);
partDeclarations.moveNext();
declaration = partDeclarations.current;
}
duplicated.add(declaration);
// Handle duplicated declarations in the part.
//
// Duplicated declarations are handled by creating a linked list
// using the `next` field. This is preferred over making all scope
// entries be a `List<Declaration>`.
//
// We maintain the linked list so that the last entry is easy to
// recognize (it's `next` field is null). This means that it is
// reversed with respect to source code order. Since kernel doesn't
// allow duplicated declarations, we ensure that we only add the
// first declaration to the kernel tree.
//
// Since the duplicated declarations are stored in reverse order, we
// iterate over them in reverse order as this is simpler and
// normally not a problem. However, in this case we need to call
// [addBuilder] in source order as it would otherwise create cycles.
//
// We also need to be careful preserving the order of the links. The
// part library still keeps these declarations in its scope so that
// DietListener can find them.
for (int i = duplicated.length; i > 0; i--) {
Builder declaration = duplicated[i - 1];
// No reference: There should be no duplicates when using
// references.
addBuilder(name, declaration, declaration.charOffset);
}
} else {
// No reference: The part is in the same loader so the reference
// - if needed - was already added.
addBuilder(name, declaration, declaration.charOffset);
}
}
unresolvedNamedTypes.addAll(part.unresolvedNamedTypes);
constructorReferences.addAll(part.constructorReferences);
part.libraryName.reference = libraryName.reference;
part.partOfLibrary = this;
part.scope.becomePartOf(scope);
// TODO(ahe): Include metadata from part?
// Recovery: Take on all exporters (i.e. if a library has erroneously
// exported the part it has (in validatePart) been recovered to import
// the main library (this) instead --- to make it complete (and set up
// scopes correctly) the exporters in this has to be updated too).
exporters.addAll(part.exporters);
nativeMethods.addAll(part.nativeMethods);
unboundNominalVariables.addAll(part.unboundNominalVariables);
unboundStructuralVariables.addAll(part.unboundStructuralVariables);
// Check that the targets are different. This is not normally a problem
// but is for augmentation libraries.
if (library != part.library && part.library.problemsAsJson != null) {
(library.problemsAsJson ??= <String>[])
.addAll(part.library.problemsAsJson!);
}
part.collectInferableTypes(_inferableTypes!);
part.takeMixinApplications(_mixinApplications!);
if (library != part.library) {
// Mark the part library as synthetic as it's not an actual library
// (anymore).
part.library.isSynthetic = true;
}
return true;
case DillCompilationUnit():
// Trying to add a dill library builder as a part means that it exists
// as a stand-alone library in the dill file.
// This means, that it's not a part (if it had been it would be been
// "merged in" to the real library and thus not been a library on its
// own) so we behave like if it's a library with a missing "part of"
// declaration (i.e. as it was a SourceLibraryBuilder without a
// "part of" declaration).
if (uriIsValid(part.fileUri)) {
addProblem(templateMissingPartOf.withArguments(part.fileUri),
partOffset, noLength, fileUri);
}
return false;
}
compilationUnit.includeParts(this, _parts, usedParts);
}
void buildInitialScopes() {
@ -4212,11 +4238,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
}
}
for (Part part in parts) {
CompilationUnit compilationUnit = part.compilationUnit;
if (compilationUnit is SourceCompilationUnit) {
compilationUnit.addDependencies(library, seen);
}
for (SourceCompilationUnit part in parts) {
part.addDependencies(library, seen);
}
}

View file

@ -93,7 +93,6 @@ import 'source_library_builder.dart'
InvalidLanguageVersion,
LanguageVersion,
LibraryAccess,
Part,
SourceLibraryBuilder;
import 'source_procedure_builder.dart';
import 'stack_listener_impl.dart' show offsetForToken;
@ -903,7 +902,7 @@ severity: $severity
templateInternalProblemUriMissingScheme.withArguments(fileUri),
-1,
libraryBuilder.importUri);
} else if (fileUri.isScheme(SourceLibraryBuilder.MALFORMED_URI_SCHEME)) {
} else if (fileUri.isScheme(MALFORMED_URI_SCHEME)) {
libraryBuilder.addProblemAtAccessors(messageExpectedUri);
bytes = synthesizeSourceForMissingFile(libraryBuilder.importUri, null);
}
@ -1211,11 +1210,7 @@ severity: $severity
DietParser parser = new DietParser(listener,
allowPatterns: library.libraryFeatures.patterns.isEnabled);
parser.parseUnit(tokens);
for (Part part in library.parts) {
assert(part.compilationUnit.partOfLibrary == library,
"Part ${part.compilationUnit} is not part of ${library}.");
SourceCompilationUnit compilationUnit =
part.compilationUnit as SourceCompilationUnit;
for (SourceCompilationUnit compilationUnit in library.parts) {
Token tokens =
await tokenize(compilationUnit, suppressLexicalErrors: true);
DietListener listener =
@ -1365,7 +1360,7 @@ severity: $severity
} else {
part.addProblem(messagePartOrphan, 0, 1, part.fileUri);
SourceLibraryBuilder sourceLibraryBuilder = part.createLibrary();
sourceLibraryBuilder.validatePart(null, null);
part.validatePart(null, null);
sourceLibraries.add(sourceLibraryBuilder);
_loadedLibraryBuilders[uri] = sourceLibraryBuilder;
}

View file

@ -4,3 +4,7 @@
final Uri dartCore = Uri.parse('dart:core');
final Uri missingUri = Uri.parse('org-dartlang-internal:missing');
const String MALFORMED_URI_SCHEME = "org-dartlang-malformed-uri";
bool isNotMalformedUriScheme(Uri uri) => !uri.isScheme(MALFORMED_URI_SCHEME);