4545import com .google .common .base .Splitter ;
4646import com .google .common .base .Verify ;
4747import com .google .common .collect .ImmutableList ;
48+ import com .google .common .collect .ImmutableMap ;
4849import com .google .common .collect .ImmutableSet ;
4950import com .google .common .collect .Iterables ;
5051import com .google .common .collect .Lists ;
110111import com .sun .tools .javac .util .JCDiagnostic ;
111112import com .sun .tools .javac .util .Options ;
112113import com .sun .tools .javac .util .Position ;
114+ import java .io .File ;
113115import java .io .IOException ;
114116import java .io .UncheckedIOException ;
115117import java .lang .annotation .Target ;
116118import java .net .JarURLConnection ;
117119import java .net .URI ;
120+ import java .nio .file .Path ;
118121import java .util .ArrayDeque ;
119122import java .util .ArrayList ;
120123import java .util .Arrays ;
121124import java .util .Collection ;
122125import java .util .Comparator ;
123126import java .util .Deque ;
124127import java .util .EnumSet ;
128+ import java .util .HashMap ;
125129import java .util .HashSet ;
126130import java .util .Iterator ;
127131import java .util .List ;
146150import javax .lang .model .util .SimpleTypeVisitor8 ;
147151import javax .tools .Diagnostic ;
148152import javax .tools .DiagnosticCollector ;
153+ import javax .tools .FileObject ;
154+ import javax .tools .ForwardingJavaFileManager ;
149155import javax .tools .JavaFileManager ;
156+ import javax .tools .JavaFileManager .Location ;
150157import javax .tools .JavaFileObject ;
151158import javax .tools .JavaFileObject .Kind ;
152159import javax .tools .SimpleJavaFileObject ;
160+ import javax .tools .StandardJavaFileManager ;
153161import org .jspecify .annotations .Nullable ;
154162
155163/** Factories for constructing {@link Fix}es. */
@@ -1447,23 +1455,46 @@ public static final class FixCompiler {
14471455 private final List <JavaFileObject > fileObjects ;
14481456 private final VisitorState state ;
14491457 private final BasicJavacTask javacTask ;
1458+ private final ImmutableMap <URI , JavaFileObject > speculativeFiles ;
14501459
14511460 private FixCompiler (
1452- List <JavaFileObject > fileObjects , VisitorState state , BasicJavacTask javacTask ) {
1461+ List <JavaFileObject > fileObjects ,
1462+ VisitorState state ,
1463+ BasicJavacTask javacTask ,
1464+ Map <URI , JavaFileObject > speculativeFiles ) {
14531465 this .fileObjects = fileObjects ;
14541466 this .state = state ;
14551467 this .javacTask = javacTask ;
1468+ this .speculativeFiles = ImmutableMap .copyOf (speculativeFiles );
14561469 }
14571470
14581471 public Result compile (ImmutableList <String > extraOptions ) {
14591472 DiagnosticCollector <JavaFileObject > diagnosticListener = new DiagnosticCollector <>();
14601473 Context context = createContext ();
14611474 Arguments arguments = Arguments .instance (javacTask .getContext ());
1475+ JavaFileManager originalFileManager = state .context .get (JavaFileManager .class );
1476+ JavaFileManager fileManager = originalFileManager ;
1477+ if (originalFileManager instanceof StandardJavaFileManager standardFileManager ) {
1478+ fileManager =
1479+ new StandardForwardingFileManager (standardFileManager ) {
1480+ @ Override
1481+ public boolean contains (Location location , FileObject fo ) throws IOException {
1482+ JavaFileObject underlying = speculativeFiles .get (fo .toUri ());
1483+ return super .contains (location , underlying != null ? underlying : fo );
1484+ }
1485+
1486+ @ Override
1487+ public Path asPath (FileObject fo ) {
1488+ JavaFileObject underlying = speculativeFiles .get (fo .toUri ());
1489+ return super .asPath (underlying != null ? underlying : fo );
1490+ }
1491+ };
1492+ }
14621493 JavacTask newTask =
14631494 JavacTool .create ()
14641495 .getTask (
14651496 CharStreams .nullWriter (),
1466- state . context . get ( JavaFileManager . class ) ,
1497+ fileManager ,
14671498 diagnosticListener ,
14681499 extraOptions ,
14691500 arguments .getClassNames (),
@@ -1511,11 +1542,16 @@ public static FixCompiler create(Fix fix, VisitorState state) throws IOException
15111542 }
15121543 Arguments arguments = Arguments .instance (javacTask .getContext ());
15131544 ArrayList <JavaFileObject > fileObjects = new ArrayList <>(arguments .getFileObjects ());
1514- applyFix (fix , state , fileObjects );
1515- return new FixCompiler (fileObjects , state , javacTask );
1545+ Map <URI , JavaFileObject > speculativeFiles = new HashMap <>();
1546+ applyFix (fix , state , fileObjects , speculativeFiles );
1547+ return new FixCompiler (fileObjects , state , javacTask , speculativeFiles );
15161548 }
15171549
1518- private static void applyFix (Fix fix , VisitorState state , ArrayList <JavaFileObject > fileObjects )
1550+ private static void applyFix (
1551+ Fix fix ,
1552+ VisitorState state ,
1553+ ArrayList <JavaFileObject > fileObjects ,
1554+ Map <URI , JavaFileObject > speculativeFiles )
15191555 throws IOException {
15201556
15211557 JCCompilationUnit compilationUnit = (JCCompilationUnit ) state .getPath ().getCompilationUnit ();
@@ -1535,14 +1571,16 @@ private static void applyFix(Fix fix, VisitorState state, ArrayList<JavaFileObje
15351571 diff .handleFix (fix );
15361572 SourceFile fixSource = new SourceFile (modifiedFile .getName (), modifiedFileContent );
15371573 diff .applyDifferences (fixSource );
1538- fileObjects .set (
1539- i ,
1574+ JavaFileObject originalFile = fileObjects .get ( i );
1575+ SimpleJavaFileObject speculativeFile =
15401576 new SimpleJavaFileObject (sourceURI (modifiedFile .toUri ()), Kind .SOURCE ) {
15411577 @ Override
15421578 public CharSequence getCharContent (boolean ignoreEncodingErrors ) {
15431579 return fixSource .getAsSequence ();
15441580 }
1545- });
1581+ };
1582+ fileObjects .set (i , speculativeFile );
1583+ speculativeFiles .put (speculativeFile .toUri (), originalFile );
15461584 });
15471585 }
15481586
@@ -1924,5 +1962,91 @@ public String avoidShadowing(String name) {
19241962 }
19251963 }
19261964
1965+ private static class StandardForwardingFileManager
1966+ extends ForwardingJavaFileManager <StandardJavaFileManager >
1967+ implements StandardJavaFileManager {
1968+ StandardForwardingFileManager (StandardJavaFileManager delegate ) {
1969+ super (delegate );
1970+ }
1971+
1972+ @ Override
1973+ public Iterable <? extends JavaFileObject > getJavaFileObjectsFromFiles (
1974+ Iterable <? extends File > files ) {
1975+ return fileManager .getJavaFileObjectsFromFiles (files );
1976+ }
1977+
1978+ @ Override
1979+ public Iterable <? extends JavaFileObject > getJavaFileObjectsFromPaths (
1980+ Collection <? extends Path > paths ) {
1981+ return fileManager .getJavaFileObjectsFromPaths (paths );
1982+ }
1983+
1984+ // Implementing StandardJavaFileManager
1985+ @ SuppressWarnings ({"deprecation" , "IterablePathParameter" })
1986+ @ Override
1987+ public Iterable <? extends JavaFileObject > getJavaFileObjectsFromPaths (
1988+ Iterable <? extends Path > paths ) {
1989+ return fileManager .getJavaFileObjectsFromPaths (paths );
1990+ }
1991+
1992+ @ Override
1993+ public Iterable <? extends JavaFileObject > getJavaFileObjects (File ... files ) {
1994+ return fileManager .getJavaFileObjects (files );
1995+ }
1996+
1997+ @ Override
1998+ public Iterable <? extends JavaFileObject > getJavaFileObjects (Path ... paths ) {
1999+ return fileManager .getJavaFileObjects (paths );
2000+ }
2001+
2002+ @ Override
2003+ public Iterable <? extends JavaFileObject > getJavaFileObjects (String ... names ) {
2004+ return fileManager .getJavaFileObjects (names );
2005+ }
2006+
2007+ @ Override
2008+ public Iterable <? extends JavaFileObject > getJavaFileObjectsFromStrings (
2009+ Iterable <String > names ) {
2010+ return fileManager .getJavaFileObjectsFromStrings (names );
2011+ }
2012+
2013+ @ Override
2014+ public void setLocation (Location location , Iterable <? extends File > files ) throws IOException {
2015+ fileManager .setLocation (location , files );
2016+ }
2017+
2018+ @ Override
2019+ public void setLocationFromPaths (Location location , Collection <? extends Path > paths )
2020+ throws IOException {
2021+ fileManager .setLocationFromPaths (location , paths );
2022+ }
2023+
2024+ @ Override
2025+ public void setLocationForModule (
2026+ Location location , String moduleName , Collection <? extends Path > paths ) throws IOException {
2027+ fileManager .setLocationForModule (location , moduleName , paths );
2028+ }
2029+
2030+ @ Override
2031+ public Iterable <? extends File > getLocation (Location location ) {
2032+ return fileManager .getLocation (location );
2033+ }
2034+
2035+ @ Override
2036+ public Iterable <? extends Path > getLocationAsPaths (Location location ) {
2037+ return fileManager .getLocationAsPaths (location );
2038+ }
2039+
2040+ @ Override
2041+ public Path asPath (FileObject file ) {
2042+ return fileManager .asPath (file );
2043+ }
2044+
2045+ @ Override
2046+ public void setPathFactory (PathFactory f ) {
2047+ fileManager .setPathFactory (f );
2048+ }
2049+ }
2050+
19272051 private SuggestedFixes () {}
19282052}
0 commit comments