Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
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.java220
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() {

Back to the top