Add copying of source files in JPS. Add precise method location recognition for JPS diagnostics

This commit is contained in:
Alexey Andreev 2016-04-23 16:15:43 +03:00
parent 0d3d6e883d
commit 9efed77d60
3 changed files with 71 additions and 13 deletions

View File

@ -4,6 +4,9 @@
<root url="jar://$PROJECT_DIR$/tools/idea/jps-plugin/lib/teavm-all.jar!/" /> <root url="jar://$PROJECT_DIR$/tools/idea/jps-plugin/lib/teavm-all.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES>
<root url="file://$PROJECT_DIR$/core/src/main/java" />
<root url="file://$PROJECT_DIR$/tools/core/src/main/java" />
</SOURCES>
</library> </library>
</component> </component>

View File

@ -33,6 +33,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.ModuleBuildTarget; import org.jetbrains.jps.incremental.ModuleBuildTarget;
@ -42,6 +43,7 @@ import org.jetbrains.jps.incremental.messages.ProgressMessage;
import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.JpsProject;
import org.jetbrains.jps.model.java.JpsJavaExtensionService; import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsLibrary;
import org.jetbrains.jps.model.library.JpsLibraryRoot;
import org.jetbrains.jps.model.library.JpsOrderRootType; import org.jetbrains.jps.model.library.JpsOrderRootType;
import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsDependencyElement;
import org.jetbrains.jps.model.module.JpsLibraryDependency; import org.jetbrains.jps.model.module.JpsLibraryDependency;
@ -62,19 +64,23 @@ import org.teavm.model.ValueType;
import org.teavm.tooling.EmptyTeaVMToolLog; import org.teavm.tooling.EmptyTeaVMToolLog;
import org.teavm.tooling.TeaVMTool; import org.teavm.tooling.TeaVMTool;
import org.teavm.tooling.TeaVMToolException; import org.teavm.tooling.TeaVMToolException;
import org.teavm.tooling.sources.DirectorySourceFileProvider;
import org.teavm.tooling.sources.JarSourceFileProvider;
import org.teavm.tooling.sources.SourceFileProvider;
import org.teavm.vm.TeaVMPhase; import org.teavm.vm.TeaVMPhase;
import org.teavm.vm.TeaVMProgressFeedback; import org.teavm.vm.TeaVMProgressFeedback;
import org.teavm.vm.TeaVMProgressListener; import org.teavm.vm.TeaVMProgressListener;
public class TeaVMBuild { public class TeaVMBuild {
private CompileContext context; private final CompileContext context;
private TeaVMStorageProvider storageProvider = new TeaVMStorageProvider(); private final TeaVMStorageProvider storageProvider = new TeaVMStorageProvider();
private List<String> classPathEntries = new ArrayList<>(); private final List<String> classPathEntries = new ArrayList<>();
private List<String> directoryClassPathEntries; private List<String> directoryClassPathEntries;
private TeaVMStorage storage; private TeaVMStorage storage;
private TeaVMBuilderAssistant assistant; private final TeaVMBuilderAssistant assistant;
private Map<String, File> sourceFileCache = new HashMap<>(); private final Map<String, File> sourceFileCache = new HashMap<>();
private Map<File, int[]> fileLineCache = new HashMap<>(); private final Map<File, int[]> fileLineCache = new HashMap<>();
private final List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
public TeaVMBuild(CompileContext context, TeaVMBuilderAssistant assistant) { public TeaVMBuild(CompileContext context, TeaVMBuilderAssistant assistant) {
this.context = context; this.context = context;
@ -102,10 +108,14 @@ public class TeaVMBuild {
tool.setProgressListener(createProgressListener(context)); tool.setProgressListener(createProgressListener(context));
tool.setLog(new EmptyTeaVMToolLog()); tool.setLog(new EmptyTeaVMToolLog());
tool.setMainClass(config.getMainClass()); tool.setMainClass(config.getMainClass());
tool.setSourceMapsFileGenerated(true); tool.setSourceMapsFileGenerated(config.isSourceMapsFileGenerated());
tool.setTargetDirectory(new File(config.getTargetDirectory())); tool.setTargetDirectory(new File(config.getTargetDirectory()));
tool.setClassLoader(buildClassLoader()); tool.setClassLoader(buildClassLoader());
tool.setMinifying(false); tool.setSourceFilesCopied(config.isSourceFilesCopied());
tool.setMinifying(config.isMinifying());
for (SourceFileProvider fileProvider : sourceFileProviders) {
tool.addSourceFileProvider(fileProvider);
}
boolean errorOccurred = false; boolean errorOccurred = false;
try { try {
@ -366,9 +376,15 @@ public class TeaVMBuild {
if (output != null) { if (output != null) {
classPathEntries.add(output.getPath()); classPathEntries.add(output.getPath());
} }
sourceFileProviders.addAll(module.getSourceRoots().stream()
.map(sourceRoot -> new DirectorySourceFileProvider(sourceRoot.getFile()))
.collect(Collectors.toList()));
for (JpsDependencyElement dependency : module.getDependenciesList().getDependencies()) { for (JpsDependencyElement dependency : module.getDependenciesList().getDependencies()) {
if (dependency instanceof JpsModuleDependency) { if (dependency instanceof JpsModuleDependency) {
buildClassPath(((JpsModuleDependency) dependency).getModule(), visited); JpsModuleDependency moduleDependency = (JpsModuleDependency) dependency;
buildClassPath(moduleDependency.getModule(), visited);
} else if (dependency instanceof JpsLibraryDependency) { } else if (dependency instanceof JpsLibraryDependency) {
JpsLibrary library = ((JpsLibraryDependency) dependency).getLibrary(); JpsLibrary library = ((JpsLibraryDependency) dependency).getLibrary();
if (library == null) { if (library == null) {
@ -376,7 +392,32 @@ public class TeaVMBuild {
} }
classPathEntries.addAll(library.getFiles(JpsOrderRootType.COMPILED).stream().map(File::getPath) classPathEntries.addAll(library.getFiles(JpsOrderRootType.COMPILED).stream().map(File::getPath)
.collect(toList())); .collect(toList()));
for (JpsLibraryRoot libraryRoot : library.getRoots(JpsOrderRootType.SOURCES)) {
File file = getFileFromUrl(libraryRoot.getUrl());
if (file != null) {
if (file.isDirectory()) {
sourceFileProviders.add(new DirectorySourceFileProvider(file));
} else {
sourceFileProviders.add(new JarSourceFileProvider(file));
}
}
}
} }
} }
} }
private File getFileFromUrl(String url) {
if (url.startsWith("file://")) {
return new File(url.substring("file://".length()));
} else if (url.startsWith("jar://")) {
int index = url.indexOf('!');
return new File(url.substring("file://".length(), index));
} else if (url.startsWith("jar:file://")) {
int index = url.indexOf('!');
return new File(url.substring("jar:file://".length(), index));
} else {
return null;
}
}
} }

View File

@ -22,7 +22,10 @@ import com.intellij.openapi.project.ProjectManager;
import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope;
import com.siyeh.ig.fixes.MemberSignature;
import java.rmi.AlreadyBoundException; import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException; import java.rmi.NotBoundException;
import java.rmi.RemoteException; import java.rmi.RemoteException;
@ -37,7 +40,7 @@ import org.teavm.idea.jps.remote.TeaVMElementLocation;
public class TeaVMJPSRemoteService extends UnicastRemoteObject implements ApplicationComponent, TeaVMBuilderAssistant { public class TeaVMJPSRemoteService extends UnicastRemoteObject implements ApplicationComponent, TeaVMBuilderAssistant {
private static final int MIN_PORT = 10000; private static final int MIN_PORT = 10000;
private static final int MAX_PORT = 1 << 16; private static final int MAX_PORT = 1 << 16;
private ProjectManager projectManager = ProjectManager.getInstance(); private final ProjectManager projectManager = ProjectManager.getInstance();
private int port; private int port;
private Registry registry; private Registry registry;
@ -99,10 +102,9 @@ public class TeaVMJPSRemoteService extends UnicastRemoteObject implements Applic
} }
for (PsiMethod method : cls.getAllMethods()) { for (PsiMethod method : cls.getAllMethods()) {
if (!method.getName().equals(methodName)) { if (!method.getName().equals(methodName) || !getMethodSignature(method).equals(methodDesc)) {
continue; continue;
} }
// TODO: check method raw signature
resultHolder[0] = getMethodLocation(method); resultHolder[0] = getMethodLocation(method);
return; return;
} }
@ -112,6 +114,18 @@ public class TeaVMJPSRemoteService extends UnicastRemoteObject implements Applic
return resultHolder[0]; return resultHolder[0];
} }
private String getMethodSignature(PsiMethod method) {
StringBuilder sb = new StringBuilder("(");
for (PsiParameter parameter : method.getParameterList().getParameters()) {
sb.append(MemberSignature.createTypeSignature(parameter.getType()));
}
sb.append(")");
PsiType returnType = method.getReturnType();
sb.append(MemberSignature.createTypeSignature(returnType != null ? returnType : PsiType.VOID));
return sb.toString();
}
private TeaVMElementLocation getMethodLocation(PsiMethod method) { private TeaVMElementLocation getMethodLocation(PsiMethod method) {
return new TeaVMElementLocation(method.getTextOffset(), method.getTextOffset() + method.getTextLength(), return new TeaVMElementLocation(method.getTextOffset(), method.getTextOffset() + method.getTextLength(),
-1, -1, method.getContainingFile().getVirtualFile().getPath()); -1, -1, method.getContainingFile().getVirtualFile().getPath());