Skip to content
Permalink
Browse files

Locate the classes directory in order to relativize classnames (#7853)

### Problem

As described in #7850: `zinc` currently makes assumptions about directory layouts that aren't valid when it is being invoked via `rsc`.

### Solution

Rather than attempting to recognize patterns, get the output directory of the compile to use for relativization.

### Result

A followup PR will be able to confirm that `dep-usage.jvm` works under `rsc`.
  • Loading branch information...
stuhood committed Jun 5, 2019
1 parent 5d44e7e commit e9936fb9f49ddb2d91219f9f5a9b333dbff44ad5
Showing with 19 additions and 13 deletions.
  1. +19 −13 src/scala/org/pantsbuild/zinc/analysis/AnalysisMap.scala
@@ -5,6 +5,7 @@

package org.pantsbuild.zinc.analysis

import java.nio.file.Path
import java.io.{File, IOException}
import java.util.Optional

@@ -65,13 +66,22 @@ class AnalysisMap private[AnalysisMap] (
* Can remove after the sbt jar output patch lands.
*/
def definesClass(classpathEntry: File): DefinesClass = {
getAnalysis(classpathEntry).map { analysis =>
// strongly hold the classNames, and transform them to ensure that they are unlinked from
// the remainder of the analysis
val classNames = analysis.asInstanceOf[Analysis].relations.srcProd.reverseMap.keys.toList.toSet.map(
(f: File) => filePathToClassName(f))
new ClassNamesDefinesClass(classNames)
}.getOrElse {
// If we have analysis with a valid Compilation, use the classnames it refers to.
val analysisDefinesClass =
for (
abstractAnalysis <- getAnalysis(classpathEntry);
analysis = abstractAnalysis.asInstanceOf[Analysis];
compilation <- analysis.compilations.allCompilations.headOption;
singleOutput <- compilation.getOutput.getSingleOutput.asScala;
classesDir = singleOutput.toPath
) yield {
// strongly hold the classNames, and transform them to ensure that they are unlinked from
// the remainder of the analysis
val classNames = analysis.relations.srcProd.reverseMap.keys.toList.toSet.map(
(f: File) => filePathToClassName(classesDir, f))
new ClassNamesDefinesClass(classNames)
}
analysisDefinesClass.getOrElse {
// no analysis: return a function that will scan instead
Locate.definesClass(classpathEntry)
}
@@ -81,12 +91,8 @@ class AnalysisMap private[AnalysisMap] (
override def apply(className: String): Boolean = classes(className)
}

private def filePathToClassName(file: File): String = {
// Extract className from path, for example:
// .../.pants.d/compile/zinc/.../current/classes/org/pantsbuild/example/hello/exe/Exe.class
// => org.pantsbuild.example.hello.exe.Exe
file.getAbsolutePath.split("current/classes")(1).drop(1).replace(".class", "").replaceAll("/", ".")
}
private def filePathToClassName(classesDir: Path, file: File): String =
classesDir.relativize(file.toPath).toString.replace(".class", "").replaceAll("/", ".")

/**
* Gets analysis for a classpath entry (if it exists) by translating its path to a potential

0 comments on commit e9936fb

Please sign in to comment.
You can’t perform that action at this time.