diff options
Diffstat (limited to 'org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java')
-rw-r--r-- | org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java | 220 |
1 files changed, 183 insertions, 37 deletions
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java index dd203a1a8b..74d59e83f9 100644 --- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java +++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java @@ -5,6 +5,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * IBM Corporation - fix for 342936 @@ -19,17 +23,24 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.nio.charset.Charset; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import javax.annotation.processing.Processor; +import javax.lang.model.SourceVersion; import javax.tools.Diagnostic; import javax.tools.DiagnosticListener; import javax.tools.JavaFileManager; +import javax.tools.JavaFileManager.Location; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; @@ -46,12 +57,14 @@ import org.eclipse.jdt.internal.compiler.batch.ClasspathJsr199; import org.eclipse.jdt.internal.compiler.batch.CompilationUnit; import org.eclipse.jdt.internal.compiler.batch.FileSystem; import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.batch.Main; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit; import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; +import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.Messages; import org.eclipse.jdt.internal.compiler.util.SuffixConstants; import org.eclipse.jdt.internal.compiler.util.Util; @@ -62,6 +75,8 @@ public class EclipseCompilerImpl extends Main { Iterable<? extends JavaFileObject> compilationUnits; public JavaFileManager fileManager; protected Processor[] processors; + // TODO: This is not yet used anywhere + protected String[] modules; public DiagnosticListener<? super JavaFileObject> diagnosticListener; public EclipseCompilerImpl(PrintWriter out, PrintWriter err, boolean systemExitWhenFinished) { @@ -70,6 +85,7 @@ public class EclipseCompilerImpl extends Main { public boolean call() { try { + handleLocations(); if (this.proceed) { this.globalProblemsCount = 0; this.globalErrorsCount = 0; @@ -87,6 +103,7 @@ public class EclipseCompilerImpl extends Main { } return false; } catch (RuntimeException e) { // internal compiler failure + e.printStackTrace(); this.logger.logException(e); return false; } finally { @@ -112,31 +129,60 @@ public class EclipseCompilerImpl extends Main { @Override public CompilationUnit[] getCompilationUnits() { + // This method is largely a copy of Main#getCompilationUnits() if (this.compilationUnits == null) return EclipseCompilerImpl.NO_UNITS; + Map<String,CompilationUnit> pathToModCU = new HashMap<>(); + HashtableOfObject knownFileNames = new HashtableOfObject(); ArrayList<CompilationUnit> units = new ArrayList<>(); - for (final JavaFileObject javaFileObject : this.compilationUnits) { - if (javaFileObject.getKind() != JavaFileObject.Kind.SOURCE) { - throw new IllegalArgumentException(); - } - String name = javaFileObject.getName(); - CompilationUnit compilationUnit = new CompilationUnit(null, - name, - null, - null, - shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, name.toCharArray()), null) { + for (int round = 0; round < 2; round++) { + int i = 0; + for (final JavaFileObject javaFileObject : this.compilationUnits) { + String name = javaFileObject.getName(); + char[] charName = name.toCharArray(); + boolean isModuleInfo = CharOperation.endsWith(charName, TypeConstants.MODULE_INFO_FILE_NAME); + if (isModuleInfo == (round==0)) { // 1st round: modules, 2nd round others (to ensure populating pathToModCU well in time) + if (knownFileNames.get(charName) != null) + throw new IllegalArgumentException(this.bind("unit.more", name)); //$NON-NLS-1$ + knownFileNames.put(charName, charName); + File file = new File(name); + if (!file.exists()) + throw new IllegalArgumentException(this.bind("unit.missing", name)); //$NON-NLS-1$ + CompilationUnit cu = new CompilationUnit(null, + name, + null, + this.destinationPaths[i], + shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, name.toCharArray()), this.modNames[i]) { - @Override - public char[] getContents() { - try { - return javaFileObject.getCharContent(true).toString().toCharArray(); - } catch(IOException e) { - e.printStackTrace(); - throw new AbortCompilationUnit(null, e, null); - } + @Override + public char[] getContents() { + try { + return javaFileObject.getCharContent(true).toString().toCharArray(); + } catch(IOException e) { + e.printStackTrace(); + throw new AbortCompilationUnit(null, e, null); + } + } + }; + units.add(cu); + this.javaFileObjectMap.put(cu, javaFileObject); + if (isModuleInfo) { + int lastSlash = CharOperation.lastIndexOf(File.separatorChar, cu.fileName); + if (lastSlash != -1) { + pathToModCU.put(String.valueOf(CharOperation.subarray(cu.fileName, 0, lastSlash)), cu); + } + } else { + for (Entry<String, CompilationUnit> entry : pathToModCU.entrySet()) { + Path modPath = Paths.get(entry.getKey()); + Path cuPath = Paths.get(name); + while (cuPath != null && cuPath.startsWith(modPath)) { + cu.setModule(entry.getValue()); + break; + } + } + } } - }; - units.add(compilationUnit); - this.javaFileObjectMap.put(compilationUnit, javaFileObject); + i++; + } } CompilationUnit[] result = new CompilationUnit[units.size()]; units.toArray(result); @@ -339,8 +385,10 @@ public class EclipseCompilerImpl extends Main { if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) { ClassFile[] classFiles = unitResult.getClassFiles(); boolean generateClasspathStructure = this.fileManager.hasLocation(StandardLocation.CLASS_OUTPUT); - String currentDestinationPath = this.destinationPath; File outputLocation = null; + String currentDestinationPath = unitResult.getCompilationUnit().getDestinationPath(); + if (currentDestinationPath == null) + currentDestinationPath = this.destinationPath; if (currentDestinationPath != null) { outputLocation = new File(currentDestinationPath); outputLocation.mkdirs(); @@ -365,9 +413,20 @@ public class EclipseCompilerImpl extends Main { })); } try { + char[] modName = unitResult.compilationUnit.getModuleName(); + Location location = null; + if (modName == null) { + location = StandardLocation.CLASS_OUTPUT; + } else { + // TODO: Still possible to end up with a non-null module name without JDK 9 in build path + System.out.println("module name:" + new String(modName)); //$NON-NLS-1$ + System.out.println("CU:" + new String(unitResult.compilationUnit.getFileName())); //$NON-NLS-1$ + location = this.fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT, new String(modName)); + System.out.println("Location from getLocationForModule(): " + location); //$NON-NLS-1$ + } JavaFileObject javaFileForOutput = this.fileManager.getJavaFileForOutput( - StandardLocation.CLASS_OUTPUT, + location, new String(filename), JavaFileObject.Kind.CLASS, this.javaFileObjectMap.get(unitResult.compilationUnit)); @@ -419,7 +478,11 @@ public class EclipseCompilerImpl extends Main { ArrayList<String> extdirsClasspaths, ArrayList<String> endorsedDirClasspaths, String customEncoding) { + // Sometimes this gets called too early there by losing locations set after that point. + // The code is now moved to handleLocations() which is invoked just before compilation + } + protected void handleLocations() { ArrayList<FileSystem.Classpath> fileSystemClasspaths = new ArrayList<>(); EclipseFileManager eclipseJavaFileManager = null; StandardJavaFileManager standardJavaFileManager = null; @@ -440,13 +503,27 @@ public class EclipseCompilerImpl extends Main { fileSystemClasspaths.addAll(this.handleEndorseddirs(null)); } } - Iterable<? extends File> location = null; + Iterable<? extends File> locationFiles = null; if (standardJavaFileManager != null) { - location = standardJavaFileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH); - if (location != null) { - for (File file : location) { + locationFiles = standardJavaFileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH); + if (locationFiles != null) { + for (File file : locationFiles) { if (file.isDirectory()) { - setPlatformLocations(fileSystemClasspaths, file); + List<Classpath> platformLocations = getPlatformLocations(fileSystemClasspaths, file); + if (standardJavaFileManager instanceof EclipseFileManager) { + if (platformLocations.size() == 1) { + Classpath jrt = platformLocations.get(0); + if (jrt instanceof ClasspathJrt) { + // TODO: double check, should it be platform or system module? + try { + ((EclipseFileManager) standardJavaFileManager).locationHandler.newSystemLocation(StandardLocation.SYSTEM_MODULES, (ClasspathJrt) jrt); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + fileSystemClasspaths.addAll(platformLocations); break; // Only possible scenario is, we have one and only entry representing the Java home. } else { Classpath classpath = FileSystem.getClasspath( @@ -479,9 +556,9 @@ public class EclipseCompilerImpl extends Main { } } if (standardJavaFileManager != null) { - location = standardJavaFileManager.getLocation(StandardLocation.SOURCE_PATH); - if (location != null) { - for (File file : location) { + locationFiles = standardJavaFileManager.getLocation(StandardLocation.SOURCE_PATH); + if (locationFiles != null) { + for (File file : locationFiles) { Classpath classpath = FileSystem.getClasspath( file.getAbsolutePath(), null, @@ -491,9 +568,9 @@ public class EclipseCompilerImpl extends Main { } } } - location = standardJavaFileManager.getLocation(StandardLocation.CLASS_PATH); - if (location != null) { - for (File file : location) { + locationFiles = standardJavaFileManager.getLocation(StandardLocation.CLASS_PATH); + if (locationFiles != null) { + for (File file : locationFiles) { Classpath classpath = FileSystem.getClasspath( file.getAbsolutePath(), null, @@ -504,12 +581,81 @@ public class EclipseCompilerImpl extends Main { } } } + if (SourceVersion.latest().compareTo(SourceVersion.RELEASE_8) > 0) { + try { + Iterable<? extends Path> locationAsPaths = standardJavaFileManager.getLocationAsPaths(StandardLocation.MODULE_SOURCE_PATH); + if (locationAsPaths != null) { + for (Path path : locationAsPaths) { + ArrayList<Classpath> modulepaths = handleModuleSourcepath(path.toFile().getCanonicalPath()); + for (Classpath classpath : modulepaths) { + Collection<String> moduleNames = classpath.getModuleNames(null); + for (String modName : moduleNames) { + Path p = Paths.get(classpath.getPath()); + standardJavaFileManager.setLocationForModule(StandardLocation.MODULE_SOURCE_PATH, modName, + Collections.singletonList(p)); + p = Paths.get(classpath.getDestinationPath()); + standardJavaFileManager.setLocationForModule(StandardLocation.CLASS_OUTPUT, modName, + Collections.singletonList(p)); + } + } + fileSystemClasspaths.addAll(modulepaths); + } + } + } catch (Exception e) { + // TODO: Revisit when JRE 9 no longer throws IllegalStateException for getLocation. + } + try { + locationFiles = standardJavaFileManager.getLocation(StandardLocation.MODULE_PATH); + if (locationFiles != null) { + for (File file : locationFiles) { + try { + ArrayList<Classpath> modulepaths = handleModulepath(file.getCanonicalPath()); + for (Classpath classpath : modulepaths) { + Collection<String> moduleNames = classpath.getModuleNames(null); + for (String string : moduleNames) { + Path path = Paths.get(classpath.getPath()); + standardJavaFileManager.setLocationForModule(StandardLocation.MODULE_PATH, string, + Collections.singletonList(path)); + } + } + fileSystemClasspaths.addAll(modulepaths); + } catch (IOException e) { + throw new AbortCompilationUnit(null, e, null); + } + } + } + } catch (Exception e) { + // TODO: Revisit when JRE 9 no longer throws IllegalStateException for getLocation. + } + } } else if (javaFileManager != null) { Classpath classpath = null; if (this.fileManager.hasLocation(StandardLocation.SOURCE_PATH)) { classpath = new ClasspathJsr199(this.fileManager, StandardLocation.SOURCE_PATH); fileSystemClasspaths.add(classpath); } + if (SourceVersion.latest().compareTo(SourceVersion.RELEASE_8) > 0) { + // Add the locations to search for in specific order + if (this.fileManager.hasLocation(StandardLocation.UPGRADE_MODULE_PATH)) { + classpath = new ClasspathJsr199(this.fileManager, StandardLocation.UPGRADE_MODULE_PATH); + } + if (this.fileManager.hasLocation(StandardLocation.SYSTEM_MODULES)) { + classpath = new ClasspathJsr199(this.fileManager, StandardLocation.SYSTEM_MODULES); + fileSystemClasspaths.add(classpath); + } + if (this.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) { + classpath = new ClasspathJsr199(this.fileManager, StandardLocation.PATCH_MODULE_PATH); + fileSystemClasspaths.add(classpath); + } + if (this.fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) { + classpath = new ClasspathJsr199(this.fileManager, StandardLocation.MODULE_SOURCE_PATH); + fileSystemClasspaths.add(classpath); + } + if (this.fileManager.hasLocation(StandardLocation.MODULE_PATH)) { + classpath = new ClasspathJsr199(this.fileManager, StandardLocation.MODULE_PATH); + fileSystemClasspaths.add(classpath); + } + } classpath = new ClasspathJsr199(this.fileManager, StandardLocation.CLASS_PATH); fileSystemClasspaths.add(classpath); haveClassPaths = true; @@ -533,9 +679,9 @@ public class EclipseCompilerImpl extends Main { } } - protected void setPlatformLocations(ArrayList<FileSystem.Classpath> fileSystemClasspaths, File file) { + protected List<Classpath> getPlatformLocations(ArrayList<FileSystem.Classpath> fileSystemClasspaths, File file) { List<Classpath> platformLibraries = Util.collectPlatformLibraries(file); - fileSystemClasspaths.addAll(platformLibraries); + return platformLibraries; } @Override protected void loggingExtraProblems() { |