mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
don't load AST transformations from the same module and (temporarily) on stub generation (IDEADEV-41244)
This commit is contained in:
@@ -24,6 +24,7 @@ import org.codehaus.groovy.tools.javac.JavaAwareResolveVisitor;
|
||||
import org.codehaus.groovy.tools.javac.JavaStubGenerator;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.*;
|
||||
@@ -39,6 +40,7 @@ public class GroovycRunner {
|
||||
public static final String PATCHERS = "patchers";
|
||||
public static final String ENCODING = "encoding";
|
||||
public static final String OUTPUTPATH = "outputpath";
|
||||
public static final String FINAL_OUTPUTPATH = "final_outputpath";
|
||||
public static final String END = "end";
|
||||
|
||||
public static final String SRC_FILE = "src_file";
|
||||
@@ -112,11 +114,12 @@ public class GroovycRunner {
|
||||
final List srcFiles = new ArrayList();
|
||||
final Map class2File = new HashMap();
|
||||
|
||||
fillFromArgsFile(argsFile, compilerConfiguration, patchers, compilerMessages, srcFiles, class2File);
|
||||
final String[] finalOutput = new String[1];
|
||||
fillFromArgsFile(argsFile, compilerConfiguration, patchers, compilerMessages, srcFiles, class2File, finalOutput);
|
||||
if (srcFiles.isEmpty()) return;
|
||||
|
||||
System.out.println(PRESENTABLE_MESSAGE + "Groovy compiler: loading sources...");
|
||||
final CompilationUnit unit = createCompilationUnit(forStubs, compilerConfiguration);
|
||||
final CompilationUnit unit = createCompilationUnit(forStubs, compilerConfiguration, finalOutput[0]);
|
||||
addSources(forStubs, srcFiles, unit);
|
||||
runPatchers(patchers, compilerMessages, class2File, unit);
|
||||
|
||||
@@ -165,7 +168,7 @@ public class GroovycRunner {
|
||||
}
|
||||
|
||||
private static String fillFromArgsFile(File argsFile, CompilerConfiguration compilerConfiguration, List patchers, List compilerMessages,
|
||||
List srcFiles, Map class2File) {
|
||||
List srcFiles, Map class2File, String[] finalOutput) {
|
||||
String moduleClasspath = null;
|
||||
|
||||
BufferedReader reader = null;
|
||||
@@ -207,14 +210,15 @@ public class GroovycRunner {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (line.startsWith(ENCODING)) {
|
||||
else if (line.startsWith(ENCODING)) {
|
||||
compilerConfiguration.setSourceEncoding(reader.readLine());
|
||||
}
|
||||
|
||||
if (line.startsWith(OUTPUTPATH)) {
|
||||
else if (line.startsWith(OUTPUTPATH)) {
|
||||
compilerConfiguration.setTargetDirectory(reader.readLine());
|
||||
}
|
||||
else if (line.startsWith(FINAL_OUTPUTPATH)) {
|
||||
finalOutput[0] = reader.readLine();
|
||||
}
|
||||
|
||||
line = reader.readLine();
|
||||
}
|
||||
@@ -324,11 +328,40 @@ public class GroovycRunner {
|
||||
compilerMessages.add(new CompilerMessage(CompilerMessage.WARNING, message + ":\n" + writer, "<exception>", -1, -1));
|
||||
}
|
||||
|
||||
private static CompilationUnit createCompilationUnit(final boolean forStubs, final CompilerConfiguration config) {
|
||||
private static CompilationUnit createCompilationUnit(final boolean forStubs, final CompilerConfiguration config, String finalOutput) {
|
||||
config.setClasspathList(Collections.EMPTY_LIST);
|
||||
|
||||
final GroovyClassLoader classLoader = buildClassLoaderFor(config);
|
||||
final CompilationUnit unit = new CompilationUnit(config, null, classLoader) {
|
||||
|
||||
final String localGlobalTransforms = new File(finalOutput + File.separator +
|
||||
"META-INF" + File.separator +
|
||||
"services" + File.separator +
|
||||
"org.codehaus.groovy.transform.ASTTransformation")
|
||||
.getAbsolutePath();
|
||||
|
||||
final GroovyClassLoader transformLoader = new GroovyClassLoader(classLoader) {
|
||||
public Enumeration getResources(String name) throws IOException {
|
||||
if (name.endsWith("org.codehaus.groovy.transform.ASTTransformation")) {
|
||||
if (forStubs) {
|
||||
//commenting the next line (it shouldn't be there) will result in GroovyCompilerTest failure
|
||||
//meaning that stub generation for some module (A) may require already compiled classes from another module (B)
|
||||
//where A depends on B, of course
|
||||
return Collections.enumeration(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
final Enumeration resources = super.getResources(name);
|
||||
final ArrayList list = Collections.list(resources);
|
||||
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
|
||||
if (localGlobalTransforms.equals(((URL)iterator.next()).getFile())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return Collections.enumeration(list);
|
||||
}
|
||||
return super.getResources(name);
|
||||
}
|
||||
};
|
||||
final CompilationUnit unit = new CompilationUnit(config, null, classLoader, transformLoader) {
|
||||
|
||||
public void gotoPhase(int phase) throws CompilationFailedException {
|
||||
super.gotoPhase(phase);
|
||||
|
||||
@@ -57,9 +57,8 @@ public class GroovyCompiler extends GroovyCompilerBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compileFiles(CompileContext compileContext, Module module, List<VirtualFile> toCompile, VirtualFile outputDir, OutputSink sink,
|
||||
boolean tests) {
|
||||
runGroovycCompiler(compileContext, module, toCompile, false, outputDir, sink, tests);
|
||||
protected void compileFiles(CompileContext compileContext, Module module, List<VirtualFile> toCompile, OutputSink sink, boolean tests) {
|
||||
runGroovycCompiler(compileContext, module, toCompile, false, getMainOutput(compileContext, module, tests), sink, tests);
|
||||
}
|
||||
|
||||
public boolean validateConfiguration(CompileScope compileScope) {
|
||||
|
||||
@@ -57,7 +57,6 @@ import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.PathsList;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.groovy.compiler.rt.CompilerMessage;
|
||||
import org.jetbrains.groovy.compiler.rt.GroovycRunner;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
@@ -67,7 +66,6 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -75,8 +73,6 @@ import java.util.regex.Pattern;
|
||||
public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.compiler.GroovyCompilerBase");
|
||||
protected final Project myProject;
|
||||
@NonNls private static final String GROOVYC_RUNNER_REQUIRED = ".*(groovy|asm|antlr|junit|jline|ant|commons).*\\.jar";
|
||||
private static final Pattern NONTRADITIONAL_GROOVYC_RUNNER_REQUIRED = Pattern.compile(".*(groovy|junit|jline|ant).*\\.jar");
|
||||
|
||||
public GroovyCompilerBase(Project project) {
|
||||
myProject = project;
|
||||
@@ -142,7 +138,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
|
||||
try {
|
||||
File fileWithParameters = File.createTempFile("toCompile", "");
|
||||
fillFileWithGroovycParameters(toCompile, fileWithParameters, outputDir, patchers);
|
||||
fillFileWithGroovycParameters(toCompile, fileWithParameters, outputDir, patchers, getMainOutput(compileContext, module, tests));
|
||||
|
||||
commandLine.addParameter(forStubs ? "stubs" : "groovyc");
|
||||
commandLine.addParameter(fileWithParameters.getPath());
|
||||
@@ -211,6 +207,10 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
protected static VirtualFile getMainOutput(CompileContext compileContext, Module module, boolean tests) {
|
||||
return tests ? compileContext.getModuleOutputDirectoryForTests(module) : compileContext.getModuleOutputDirectory(module);
|
||||
}
|
||||
|
||||
private static CompilerMessageCategory getMessageCategory(CompilerMessage compilerMessage) {
|
||||
String category;
|
||||
category = compilerMessage.getCategory();
|
||||
@@ -223,7 +223,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
return CompilerMessageCategory.ERROR;
|
||||
}
|
||||
|
||||
private void fillFileWithGroovycParameters(List<VirtualFile> virtualFiles, File f, VirtualFile outputDir, final List<String> patchers) {
|
||||
private void fillFileWithGroovycParameters(List<VirtualFile> virtualFiles, File f, VirtualFile outputDir, final List<String> patchers, VirtualFile finalOutputDir) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Running groovyc on: " + virtualFiles.toString());
|
||||
}
|
||||
@@ -269,9 +269,13 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
printer.println(ideCharset.name());
|
||||
}
|
||||
|
||||
//production output
|
||||
printer.println(GroovycRunner.OUTPUTPATH);
|
||||
printer.println(PathUtil.getLocalPath(outputDir));
|
||||
|
||||
printer.println(GroovycRunner.FINAL_OUTPUTPATH);
|
||||
printer.println(PathUtil.getLocalPath(finalOutputDir));
|
||||
|
||||
|
||||
printer.close();
|
||||
}
|
||||
|
||||
@@ -314,10 +318,10 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
}
|
||||
|
||||
if (!toCompile.isEmpty()) {
|
||||
compileFiles(compileContext, module, toCompile, compileContext.getModuleOutputDirectory(module), sink, false);
|
||||
compileFiles(compileContext, module, toCompile, sink, false);
|
||||
}
|
||||
if (!toCompileTests.isEmpty()) {
|
||||
compileFiles(compileContext, module, toCompileTests, compileContext.getModuleOutputDirectoryForTests(module), sink, true);
|
||||
compileFiles(compileContext, module, toCompileTests, sink, true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -325,9 +329,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
}
|
||||
|
||||
protected abstract void compileFiles(CompileContext compileContext, Module module,
|
||||
List<VirtualFile> toCompile,
|
||||
VirtualFile outputDir,
|
||||
OutputSink sink, boolean tests);
|
||||
List<VirtualFile> toCompile, OutputSink sink, boolean tests);
|
||||
|
||||
public boolean isCompilableFile(VirtualFile file, CompileContext context) {
|
||||
final boolean result = GroovyFileType.GROOVY_FILE_TYPE.equals(file.getFileType());
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ public class GroovycStubGenerator extends GroovyCompilerBase {
|
||||
|
||||
@Override
|
||||
protected void compileFiles(CompileContext compileContext, Module module,
|
||||
final List<VirtualFile> toCompile, VirtualFile outputDir, OutputSink sink, boolean tests) {
|
||||
final List<VirtualFile> toCompile, OutputSink sink, boolean tests) {
|
||||
boolean hasGroovy = false;
|
||||
boolean hasJava = false;
|
||||
for (final VirtualFile file : toCompile) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.plugins.groovy.lang;
|
||||
|
||||
import com.intellij.compiler.CompilerConfiguration;
|
||||
import com.intellij.compiler.CompilerManagerImpl;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.Executor;
|
||||
@@ -38,17 +39,18 @@ import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.roots.CompilerModuleExtension;
|
||||
import com.intellij.openapi.roots.ContentEntry;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.module.ModifiableModuleModel;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.StdModuleTypes;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.util.JDOMExternalizable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.testFramework.fixtures.TempDirTestFixture;
|
||||
import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl;
|
||||
@@ -77,6 +79,17 @@ public class GroovyCompilerTest extends JavaCodeInsightFixtureTestCase {
|
||||
super.setUp();
|
||||
getProject().getComponent(GroovyCompilerLoader.class).projectOpened();
|
||||
CompilerManagerImpl.testSetup();
|
||||
|
||||
CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(myMainOutput.findOrCreateDir("out").getUrl());
|
||||
|
||||
addGroovyLibrary(myModule);
|
||||
}
|
||||
|
||||
private static void addGroovyLibrary(final Module to) {
|
||||
final String root = PathManager.getHomePath() + "/community/lib/";
|
||||
final File[] groovyJars = GroovyUtils.getFilesInDirectoryByPattern(root, GroovyConfigUtils.GROOVY_ALL_JAR_PATTERN);
|
||||
assert groovyJars.length == 1;
|
||||
PsiTestUtil.addLibrary(to, "groovy", root, groovyJars[0].getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,17 +99,6 @@ public class GroovyCompilerTest extends JavaCodeInsightFixtureTestCase {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) throws Exception {
|
||||
super.tuneFixture(moduleBuilder);
|
||||
moduleBuilder.setOutputPath(myMainOutput.getTempDirPath() + "/out/production");
|
||||
moduleBuilder.setTestOutputPath(myMainOutput.getTempDirPath() + "/out/tests");
|
||||
final File[] groovyJars = GroovyUtils.getFilesInDirectoryByPattern(PathManager.getHomePath() + "/community/lib", GroovyConfigUtils.GROOVY_ALL_JAR_PATTERN);
|
||||
assert groovyJars.length == 1;
|
||||
moduleBuilder.addLibrary("Groovy", groovyJars[0].getPath());
|
||||
//moduleBuilder.addJdk(CompilerConfigurationImpl.getTestsExternalCompilerHome());
|
||||
}
|
||||
|
||||
public void testPlainGroovy() throws Throwable {
|
||||
myFixture.addFileToProject("A.groovy", "println '239'");
|
||||
assertEmpty(make());
|
||||
@@ -298,6 +300,85 @@ public class GroovyCompilerTest extends JavaCodeInsightFixtureTestCase {
|
||||
assertEmpty(make());
|
||||
}
|
||||
|
||||
public void testDontApplyTransformsFromSameModule() throws Exception {
|
||||
addTransform();
|
||||
|
||||
myFixture.addClass("public class JavaClassToGenerateStubs {}");
|
||||
|
||||
assertEmpty(make());
|
||||
|
||||
}
|
||||
|
||||
private void addTransform() throws IOException {
|
||||
myFixture.addFileToProject("Transf.groovy",
|
||||
"import org.codehaus.groovy.ast.*\n" +
|
||||
"import org.codehaus.groovy.control.*\n" +
|
||||
"import org.codehaus.groovy.transform.*\n" +
|
||||
"@GroovyASTTransformation(phase = CompilePhase.CONVERSION)\n" +
|
||||
"public class Transf implements ASTTransformation {\n" +
|
||||
" void visit(ASTNode[] nodes, SourceUnit sourceUnit) {\n" +
|
||||
" ModuleNode module = nodes[0]\n" +
|
||||
" for (clazz in module.classes) {\n" +
|
||||
" if (clazz.name.contains('Bar')) " +
|
||||
" module.addStaticImportClass('Foo', ClassHelper.makeWithoutCaching(Foo.class));\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
|
||||
myFixture.addFileToProject("Foo.groovy", "class Foo {\n" +
|
||||
"static def autoImported() { 239 }\n" +
|
||||
"}");
|
||||
|
||||
CompilerConfiguration.getInstance(getProject()).addResourceFilePattern("*.ASTTransformation");
|
||||
|
||||
myFixture.addFileToProject("META-INF/services/org.codehaus.groovy.transform.ASTTransformation", "Transf");
|
||||
}
|
||||
|
||||
public void testApplyTransformsFromDependencies() throws Exception {
|
||||
addTransform();
|
||||
|
||||
myFixture.addFileToProject("dependent/Bar.groovy", "class Bar {\n" +
|
||||
" static Object zzz = autoImported()\n" +
|
||||
" static void main(String[] args) {\n" +
|
||||
" println zzz\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
|
||||
myFixture.addFileToProject("dependent/AJavaClass.java", "class AJavaClass {}");
|
||||
|
||||
Module dep = addDependentModule();
|
||||
|
||||
addGroovyLibrary(dep);
|
||||
|
||||
assertEmpty(make());
|
||||
assertOutput("Bar", "239", dep);
|
||||
}
|
||||
|
||||
private Module addDependentModule() {
|
||||
Module dep = new WriteCommandAction<Module>(getProject()) {
|
||||
@Override
|
||||
protected void run(Result<Module> result) throws Throwable {
|
||||
final ModifiableModuleModel moduleModel = ModuleManager.getInstance(getProject()).getModifiableModel();
|
||||
moduleModel.newModule("dependent/dependent.iml", StdModuleTypes.JAVA);
|
||||
moduleModel.commit();
|
||||
|
||||
final Module dep = ModuleManager.getInstance(getProject()).findModuleByName("dependent");
|
||||
final ModifiableRootModel model = ModuleRootManager.getInstance(dep).getModifiableModel();
|
||||
model.addModuleOrderEntry(myModule);
|
||||
final VirtualFile depRoot = myFixture.getTempDirFixture().getFile("dependent");
|
||||
final ContentEntry entry = model.addContentEntry(depRoot);
|
||||
entry.addSourceFolder(depRoot, false);
|
||||
model.setSdk(ModuleRootManager.getInstance(myModule).getSdk());
|
||||
|
||||
//model.getModuleExtension(CompilerModuleExtension.class).inheritCompilerOutputPath(true);
|
||||
|
||||
model.commit();
|
||||
result.setResult(dep);
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
return dep;
|
||||
}
|
||||
|
||||
private void deleteClassFile(final String className) throws IOException {
|
||||
new WriteCommandAction(getProject()) {
|
||||
protected void run(Result result) throws Throwable {
|
||||
@@ -349,9 +430,13 @@ public class GroovyCompilerTest extends JavaCodeInsightFixtureTestCase {
|
||||
*/
|
||||
|
||||
private void assertOutput(String className, String output) throws ExecutionException {
|
||||
assertOutput(className, output, myModule);
|
||||
}
|
||||
|
||||
private void assertOutput(String className, String output, final Module module) throws ExecutionException {
|
||||
final ApplicationConfiguration configuration =
|
||||
new ApplicationConfiguration("app", getProject(), ApplicationConfigurationType.getInstance());
|
||||
configuration.setModule(myModule);
|
||||
configuration.setModule(module);
|
||||
configuration.setMainClassName(className);
|
||||
final DefaultRunExecutor extension = Executor.EXECUTOR_EXTENSION_NAME.findExtension(DefaultRunExecutor.class);
|
||||
final ExecutionEnvironment environment = new ExecutionEnvironment(configuration, new RunnerSettings<JDOMExternalizable>(null, null),null, DataManager.getInstance().getDataContext());
|
||||
|
||||
Reference in New Issue
Block a user