Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(862)

Unified Diff: pkg/analyzer/lib/src/summary/pub_summary.dart

Issue 2227393002: Add support for package cycles linking, more tests. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/pub_summary_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/summary/pub_summary.dart
diff --git a/pkg/analyzer/lib/src/summary/pub_summary.dart b/pkg/analyzer/lib/src/summary/pub_summary.dart
index 21c074db34ed7751bb38b4cd0f54b8aeffefbc55..6f9da57ba975d17dbfa285772a3e7efa129f1628 100644
--- a/pkg/analyzer/lib/src/summary/pub_summary.dart
+++ b/pkg/analyzer/lib/src/summary/pub_summary.dart
@@ -28,6 +28,20 @@ import 'package:analyzer/src/util/fast_uri.dart';
import 'package:path/path.dart' as pathos;
/**
+ * Unlinked and linked information about a [PubPackage].
+ */
+class LinkedPubPackage {
+ final PubPackage package;
+ final PackageBundle unlinked;
+ final PackageBundle linked;
+
+ LinkedPubPackage(this.package, this.unlinked, this.linked);
+
+ @override
+ String toString() => package.toString();
+}
+
+/**
* A package in the pub cache.
*/
class PubPackage {
@@ -51,16 +65,6 @@ class PubPackage {
}
/**
- * Unlinked and linked information about a [PubPackage].
- */
-class LinkedPubPackage {
- final PubPackage package;
- final PackageBundle unlinked;
- final PackageBundle linked;
- LinkedPubPackage(this.package, this.unlinked, this.linked);
-}
-
-/**
* Class that manages summaries for pub packages.
*
* The client should call [getLinkedBundles] after creating a new
@@ -140,13 +144,11 @@ class PubSummaryManager {
// Create graph nodes for packages.
List<_LinkedNode> nodes = <_LinkedNode>[];
- Map<String, _LinkedNode> uriToNode = <String, _LinkedNode>{};
+ Map<String, _LinkedNode> packageToNode = <String, _LinkedNode>{};
unlinkedBundles.forEach((package, unlinked) {
- _LinkedNode node = new _LinkedNode(package, unlinked, uriToNode);
+ _LinkedNode node = new _LinkedNode(package, unlinked, packageToNode);
nodes.add(node);
- for (String uri in unlinked.unlinkedUnitUris) {
- uriToNode[uri] = node;
- }
+ packageToNode[package.name] = node;
});
// Fill the store with unlinked bundles.
@@ -175,6 +177,7 @@ class PubSummaryManager {
}
// TODO(scheglov) compute dependency hashes and write linked bundles.
+ // TODO(scheglov) don't forget to include the SDK API signature.
// Done.
return linkedPackages;
@@ -356,6 +359,23 @@ class PubSummaryManager {
}
/**
+ * If the given [uri] has the `package` scheme, return the names of the
Paul Berry 2016/08/10 11:58:28 s/names/name/
scheglov 2016/08/10 16:08:18 Done.
+ * package that contains the referenced resource. Otherwise return `null`.
+ *
+ * For example `package:foo/bar.dart` => `foo`.
+ */
+ static String getPackageName(String uri) {
+ const String PACKAGE_SCHEME = 'package:';
+ if (uri.startsWith(PACKAGE_SCHEME)) {
+ int index = uri.indexOf('/');
+ if (index != -1) {
+ return uri.substring(PACKAGE_SCHEME.length, index);
+ }
+ }
+ return null;
+ }
+
+ /**
* Return `true` if the given absolute [path] is in the pub cache.
*/
static bool isPathInPubCache(pathos.Context pathContext, String path) {
@@ -378,34 +398,43 @@ class PubSummaryManager {
class _LinkedNode extends Node<_LinkedNode> {
final PubPackage package;
final PackageBundle unlinked;
- final Map<String, _LinkedNode> uriToNode;
+ final Map<String, _LinkedNode> packageToNode;
PackageBundleBuilder linkedBuilder;
bool failed = false;
- _LinkedNode(this.package, this.unlinked, this.uriToNode);
+ _LinkedNode(this.package, this.unlinked, this.packageToNode);
@override
bool get isEvaluated => linkedBuilder != null || failed;
@override
List<_LinkedNode> computeDependencies() {
- Set<String> referencedUris = new Set<String>();
+ Set<_LinkedNode> dependencies = new Set<_LinkedNode>();
for (UnlinkedUnit unit in unlinked.unlinkedUnits) {
for (UnlinkedImport import in unit.imports) {
- String uri = import.isImplicit ? 'dart:core' : import.uri;
- if (uri.startsWith('dart:')) {
- // Ignore SDK imports.
- } else if (uri.startsWith('package:')) {
- referencedUris.add(uri);
+ String uriStr = import.isImplicit ? 'dart:core' : import.uri;
+ Uri uri = FastUri.parse(uriStr);
+ if (!uri.hasScheme) {
+ // A relative path in this package, skip it.
+ } else if (uri.scheme == 'dart') {
+ // SDK is always available.
Paul Berry 2016/08/10 11:58:27 It looks like you're not going with my suggestion
scheglov 2016/08/10 16:08:18 getLinkedBundles() accepts "PackageBundle sdkBundl
Paul Berry 2016/08/10 21:39:37 Ok, based on our discussions, I'm happy landing th
+ // It's API signature is always mixed in.
Paul Berry 2016/08/10 11:58:27 s/It's/Its/
scheglov 2016/08/10 16:08:18 Done.
+ } else if (uriStr.startsWith('package:')) {
+ String package = PubSummaryManager.getPackageName(uriStr);
+ _LinkedNode packageNode = packageToNode[package];
+ if (packageNode == null) {
+ failed = true;
+ return const <_LinkedNode>[];
+ }
+ dependencies.add(packageNode);
} else {
failed = true;
return const <_LinkedNode>[];
}
}
}
- // TODO(scheglov) fail if no corresponding node
- return referencedUris.map((uri) => uriToNode[uri]).toSet().toList();
+ return dependencies.toList();
}
@override
@@ -421,36 +450,72 @@ class _LinkedWalker extends DependencyWalker<_LinkedNode> {
_LinkedWalker(this.store);
@override
- void evaluate(_LinkedNode v) {
- Set<String> libraryUris = v.unlinked.unlinkedUnitUris.toSet();
- Map<String, LinkedLibraryBuilder> map = link(libraryUris, (String absUri) {
- LinkedLibrary dependencyLibrary = store.linkedMap[absUri];
+ void evaluate(_LinkedNode node) {
Paul Berry 2016/08/10 11:58:28 There's a lot of commonality between evaluate() an
scheglov 2016/08/10 16:08:18 Done.
+ Set<String> libraryUris = node.unlinked.unlinkedUnitUris.toSet();
+ Map<String, LinkedLibraryBuilder> linkedLibraries =
+ link(libraryUris, (String absoluteUri) {
+ LinkedLibrary dependencyLibrary = store.linkedMap[absoluteUri];
if (dependencyLibrary == null) {
- // TODO(scheglov) add test
- v.failed = true;
+ node.failed = true;
}
return dependencyLibrary;
- }, (String absUri) {
- UnlinkedUnit unlinkedUnit = store.unlinkedMap[absUri];
+ }, (String absoluteUri) {
+ UnlinkedUnit unlinkedUnit = store.unlinkedMap[absoluteUri];
if (unlinkedUnit == null) {
- // TODO(scheglov) add test
- v.failed = true;
+ node.failed = true;
}
return unlinkedUnit;
}, false);
- if (!v.failed) {
+ // Assemble the linked bundle and put it into the store.
+ if (!node.failed) {
PackageBundleAssembler assembler = new PackageBundleAssembler();
- map.forEach((uri, linkedLibrary) {
+ linkedLibraries.forEach((uri, linkedLibrary) {
assembler.addLinkedLibrary(uri, linkedLibrary);
});
- v.linkedBuilder = assembler.assemble();
- store.addBundle(null, v.linkedBuilder);
+ node.linkedBuilder = assembler.assemble();
+ store.addBundle(null, node.linkedBuilder);
}
}
@override
void evaluateScc(List<_LinkedNode> scc) {
- print('evaluateScc: $scc');
- // TODO(scheglov): implement evaluateScc
+ Map<String, _LinkedNode> uriToNode = <String, _LinkedNode>{};
+ for (_LinkedNode node in scc) {
+ for (String uri in node.unlinked.unlinkedUnitUris) {
+ uriToNode[uri] = node;
+ }
+ }
+ Set<String> libraryUris = uriToNode.keys.toSet();
+ // Perform linking.
+ bool failed = false;
+ Map<String, LinkedLibraryBuilder> linkedLibraries =
+ link(libraryUris, (String absoluteUri) {
+ LinkedLibrary dependencyLibrary = store.linkedMap[absoluteUri];
+ if (dependencyLibrary == null) {
+ failed = true;
+ }
+ return dependencyLibrary;
+ }, (String absoluteUri) {
+ UnlinkedUnit unlinkedUnit = store.unlinkedMap[absoluteUri];
+ if (unlinkedUnit == null) {
+ failed = true;
+ }
+ return unlinkedUnit;
+ }, false);
+ // Assemble linked bundles and put them into the store.
+ if (!failed) {
+ for (_LinkedNode node in scc) {
+ PackageBundleAssembler assembler = new PackageBundleAssembler();
+ linkedLibraries.forEach((uri, linkedLibrary) {
+ if (identical(uriToNode[uri], node)) {
+ assembler.addLinkedLibrary(uri, linkedLibrary);
+ }
+ });
+ node.linkedBuilder = assembler.assemble();
+ store.addBundle(null, node.linkedBuilder);
+ }
+ } else {
+ scc.forEach((node) => node.failed = true);
+ }
}
}
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/pub_summary_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698