From a729b9b4c3d7844a7d44934bf3365f92633c0a60 Mon Sep 17 00:00:00 2001 From: tomlu Date: Thu, 8 Feb 2018 15:32:00 -0800 Subject: Replace path implementation. Path and PathFragment have been replaced with String-based implementations. They are pretty similar, but each method is dissimilar enough that I did not feel sharing code was appropriate. A summary of changes: PATH ==== * Subsumes LocalPath (deleted, its tests repurposed) * Use a simple string to back Path * Path instances are no longer interned; Reference equality will no longer work * Always normalized (same as before) * Some operations will now be slower, like instance compares (which were previously just a reference check) * Multiple identical paths will now consume more memory since they are not interned PATH FRAGMENT ============= * Use a simple string to back PathFragment * No more segment arrays with interned strings * Always normalized * Remove isNormalized * Replace some isNormalizied uses with containsUpLevelReferences() to check if path fragments try to escape their scope * To check if user input is normalized, supply static methods on PathFragment to validate the string before constructing a PathFragment * Because PathFragments are always normalized, we have to replace checks for literal "." from PathFragment#getPathString to PathFragment#getSafePathString. The latter returns "." for the empty string. * The previous implementation supported efficient segment semantics (segment count, iterating over segments). This is now expensive since we do longer have a segment array. ARTIFACT ======== * Remove Path instance. It is instead dynamically constructed on request. This is necessary to avoid this CL becoming a memory regression. RELNOTES: None PiperOrigin-RevId: 185062932 --- .../java/com/google/devtools/build/lib/cmdline/Label.java | 11 ++++++++++- .../google/devtools/build/lib/cmdline/PackageIdentifier.java | 5 +---- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib/cmdline') diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java index 2fbb2a4217..054648dd18 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java +++ b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java @@ -345,8 +345,17 @@ public final class Label return packageIdentifier.getPackageFragment(); } - /** Returns the label as a path fragment, using the package and the label name. */ + /** + * Returns the label as a path fragment, using the package and the label name. + * + *

Make sure that the label refers to a file. Non-file labels do not necessarily have + * PathFragment representations. + */ public PathFragment toPathFragment() { + // PathFragments are normalized, so if we do this on a non-file target named '.' + // then the package would be returned. Detect this and throw. + // A target named '.' can never refer to a file. + Preconditions.checkArgument(!name.equals(".")); return packageIdentifier.getPackageFragment().getRelative(name); } diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java index ac62a3ae96..2067b641f0 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java +++ b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java @@ -87,7 +87,7 @@ public final class PackageIdentifier // TODO(ulfjack): Remove this when kchodorow@'s exec root rearrangement has been rolled out. RepositoryName repository = RepositoryName.create("@" + tofind.getSegment(1)); return PackageIdentifier.create(repository, tofind.subFragment(2)); - } else if (!tofind.normalize().isNormalized()) { + } else if (tofind.containsUplevelReferences()) { RepositoryName repository = RepositoryName.create("@" + tofind.getSegment(1)); return PackageIdentifier.create(repository, tofind.subFragment(2)); } else { @@ -112,9 +112,6 @@ public final class PackageIdentifier private PackageIdentifier(RepositoryName repository, PathFragment pkgName) { this.repository = Preconditions.checkNotNull(repository); - if (!pkgName.isNormalized()) { - pkgName = pkgName.normalize(); - } this.pkgName = Canonicalizer.fragments().intern(Preconditions.checkNotNull(pkgName)); this.hashCode = Objects.hash(repository, pkgName); } -- cgit v1.2.3