| Index: pkg/analyzer/lib/src/task/dart.dart
|
| diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
|
| index 8821bc4d93011afe13a43f09ec1f6d5b239a5396..09a5803c4c8ef1f60f4feb8d6bb283ed4e36a3e8 100644
|
| --- a/pkg/analyzer/lib/src/task/dart.dart
|
| +++ b/pkg/analyzer/lib/src/task/dart.dart
|
| @@ -1551,28 +1551,43 @@ class BuildLibraryElementTask extends SourceBasedAnalysisTask {
|
| // name as the library.
|
| //
|
| if (context.exists(partSource)) {
|
| - String partLibraryName =
|
| - _getPartLibraryName(partSource, partUnit, directivesToResolve);
|
| - if (partLibraryName == null) {
|
| + _NameOrSource nameOrSource = _getPartLibraryNameOrUri(
|
| + context, partSource, partUnit, directivesToResolve);
|
| + if (nameOrSource == null) {
|
| errors.add(new AnalysisError(
|
| librarySource,
|
| partUri.offset,
|
| partUri.length,
|
| CompileTimeErrorCode.PART_OF_NON_PART,
|
| [partUri.toSource()]));
|
| - } else if (libraryNameNode == null) {
|
| - if (partsLibraryName == _UNKNOWN_LIBRARY_NAME) {
|
| - partsLibraryName = partLibraryName;
|
| - } else if (partsLibraryName != partLibraryName) {
|
| - partsLibraryName = null;
|
| + } else {
|
| + String name = nameOrSource.name;
|
| + if (name != null) {
|
| + if (libraryNameNode == null) {
|
| + if (partsLibraryName == _UNKNOWN_LIBRARY_NAME) {
|
| + partsLibraryName = name;
|
| + } else if (partsLibraryName != name) {
|
| + partsLibraryName = null;
|
| + }
|
| + } else if (libraryNameNode.name != name) {
|
| + errors.add(new AnalysisError(
|
| + librarySource,
|
| + partUri.offset,
|
| + partUri.length,
|
| + StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
|
| + [libraryNameNode.name, name]));
|
| + }
|
| + } else {
|
| + Source source = nameOrSource.source;
|
| + if (source != librarySource) {
|
| + errors.add(new AnalysisError(
|
| + librarySource,
|
| + partUri.offset,
|
| + partUri.length,
|
| + StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
|
| + [librarySource.uri.toString(), source.uri.toString()]));
|
| + }
|
| }
|
| - } else if (libraryNameNode.name != partLibraryName) {
|
| - errors.add(new AnalysisError(
|
| - librarySource,
|
| - partUri.offset,
|
| - partUri.length,
|
| - StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
|
| - [libraryNameNode.name, partLibraryName]));
|
| }
|
| }
|
| if (entryPoint == null) {
|
| @@ -1679,7 +1694,10 @@ class BuildLibraryElementTask extends SourceBasedAnalysisTask {
|
| * Return the name of the library that the given part is declared to be a
|
| * part of, or `null` if the part does not contain a part-of directive.
|
| */
|
| - String _getPartLibraryName(Source partSource, CompilationUnit partUnit,
|
| + _NameOrSource _getPartLibraryNameOrUri(
|
| + AnalysisContext context,
|
| + Source partSource,
|
| + CompilationUnit partUnit,
|
| List<Directive> directivesToResolve) {
|
| NodeList<Directive> directives = partUnit.directives;
|
| int length = directives.length;
|
| @@ -1689,7 +1707,15 @@ class BuildLibraryElementTask extends SourceBasedAnalysisTask {
|
| directivesToResolve.add(directive);
|
| LibraryIdentifier libraryName = directive.libraryName;
|
| if (libraryName != null) {
|
| - return libraryName.name;
|
| + return new _NameOrSource(libraryName.name, null);
|
| + }
|
| + String uri = directive.uri?.stringValue;
|
| + if (uri != null) {
|
| + Source librarySource =
|
| + context.sourceFactory.resolveUri(partSource, uri);
|
| + if (librarySource != null) {
|
| + return new _NameOrSource(null, librarySource);
|
| + }
|
| }
|
| }
|
| }
|
| @@ -4021,6 +4047,7 @@ class ParseDartTask extends SourceBasedAnalysisTask {
|
| parser.parseFunctionBodies =
|
| options.analyzeFunctionBodiesPredicate(_source);
|
| parser.parseGenericMethodComments = options.strongMode;
|
| + parser.enableUriInPartOf = options.enableUriInPartOf;
|
| CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
|
| unit.lineInfo = lineInfo;
|
|
|
| @@ -6380,6 +6407,18 @@ class _ImportSourceClosureTaskInput extends TaskInputImpl<List<Source>> {
|
| }
|
|
|
| /**
|
| + * An object holding either the name or the source associated with a part-of
|
| + * directive.
|
| + */
|
| +class _NameOrSource {
|
| + final String name;
|
| +
|
| + final Source source;
|
| +
|
| + _NameOrSource(this.name, this.source);
|
| +}
|
| +
|
| +/**
|
| * The kind of the source closure to build.
|
| */
|
| enum _SourceClosureKind { IMPORT, EXPORT, IMPORT_EXPORT }
|
|
|