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 } |