From 856c4431146239559e44e736b9fb977f2e16eac8 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 9 Dec 2009 15:40:45 +0300 Subject: [PATCH 01/10] "Build All artifacts" action added --- .../actions/BuildAllArtifactsAction.java | 57 +++++++++++++++++++ .../actions/BuildArtifactActionGroup.java | 10 ++-- .../src/messages/ActionsBundle.properties | 3 +- resources/src/idea/IdeaActions.xml | 2 + 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 java/compiler/impl/src/com/intellij/compiler/actions/BuildAllArtifactsAction.java diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/BuildAllArtifactsAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/BuildAllArtifactsAction.java new file mode 100644 index 000000000000..e21e4183ed7f --- /dev/null +++ b/java/compiler/impl/src/com/intellij/compiler/actions/BuildAllArtifactsAction.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.compiler.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.compiler.CompilerManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.artifacts.ArtifactManager; +import com.intellij.packaging.impl.compiler.ArtifactCompileScope; + +import java.util.ArrayList; +import java.util.List; + +/** +* @author nik +*/ +public class BuildAllArtifactsAction extends AnAction { + public BuildAllArtifactsAction() { + super("Build All Artifacts", "Build all configured artifacts", null); + } + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(e.getData(PlatformDataKeys.PROJECT) != null); + } + + @Override + public void actionPerformed(AnActionEvent e) { + final Project project = e.getData(PlatformDataKeys.PROJECT); + if (project == null) return; + + List toBuild = new ArrayList(); + for (Artifact artifact : ArtifactManager.getInstance(project).getSortedArtifacts()) { + if (!StringUtil.isEmpty(artifact.getOutputPath())) { + toBuild.add(artifact); + } + } + CompilerManager.getInstance(project).make(ArtifactCompileScope.createArtifactsScope(project, toBuild), null); + } +} diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactActionGroup.java b/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactActionGroup.java index cae981933a70..521e1d2dbbaa 100644 --- a/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactActionGroup.java +++ b/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactActionGroup.java @@ -15,10 +15,7 @@ */ package com.intellij.compiler.actions; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.artifacts.Artifact; @@ -50,6 +47,11 @@ public class BuildArtifactActionGroup extends ActionGroup { actions.add(new BuildArtifactAction(project, artifact)); } } + if (actions.size() > 1) { + actions.add(0, new BuildAllArtifactsAction()); + actions.add(1, Separator.getInstance()); + } return actions.toArray(new AnAction[actions.size()]); } + } diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index f865108d50b6..c7471702fe8a 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -556,9 +556,8 @@ action.RunAPT.text=Process {0} _Annotations action.RunAPT.description=Run Annotation Processors on the selected scope action.GenerateAntBuild.text=_Generate Ant Build... action.GenerateAntBuild.description=Generate Ant Build File from the Project +action.BuildAllArtifacts.text=Build All Artifacts group.BuildArtifactsGroup.text=Build Artifact -action.BuildJar.text=Build _Jars... -action.BuildJar.description=Archive module output directories into jar files group.RunMenu.text=R_un group.RunnerActions.text=Run/Debug action.editRunConfigurations.text=Edit Configu_rations diff --git a/resources/src/idea/IdeaActions.xml b/resources/src/idea/IdeaActions.xml index eb8474183030..25b0ceb66668 100644 --- a/resources/src/idea/IdeaActions.xml +++ b/resources/src/idea/IdeaActions.xml @@ -182,6 +182,8 @@ + + From 61558d19677e2e9598f3dd35f7970e1c12ffa80d Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Dec 2009 13:42:59 +0000 Subject: [PATCH 02/10] accept Grails sdk paths entered manually (IDEADEV-40075) --- .../groovy/config/ui/GroovyFacetEditor.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ui/GroovyFacetEditor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ui/GroovyFacetEditor.java index 644d4dfb25b1..4033da5fcca7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ui/GroovyFacetEditor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ui/GroovyFacetEditor.java @@ -27,8 +27,8 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.DocumentAdapter; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,7 +37,6 @@ import org.jetbrains.plugins.groovy.config.LibraryManager; import org.jetbrains.plugins.groovy.util.GroovyUtils; import javax.swing.*; -import javax.swing.event.DocumentEvent; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -66,7 +65,6 @@ public class GroovyFacetEditor { private JComboBox myComboBox; private JRadioButton myExistingSdk; private JRadioButton myNewSdk; - private AbstractGroovyLibraryManager myChosenManager; private final Class myAcceptableManager; public GroovyFacetEditor(@Nullable Project project) { @@ -165,7 +163,15 @@ public class GroovyFacetEditor { @Nullable public AbstractGroovyLibraryManager getChosenManager() { if (addNewSdk()) { - return myChosenManager; + final String path = getNewSdkPath(); + if (path != null) { + final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(FileUtil.toSystemIndependentName(path)); + if (file != null && file.isDirectory()) { + return findManager(file); + } + } + + return null; } final Object selectedItem = myComboBox.getSelectedItem(); if (selectedItem != null && selectedItem instanceof Pair) { @@ -179,13 +185,6 @@ public class GroovyFacetEditor { } private void configureSdkPathField(@Nullable final Project project) { - mySdkPath.getTextField().getDocument().addDocumentListener(new DocumentAdapter() { - @Override - protected void textChanged(DocumentEvent e) { - myChosenManager = null; - } - }); - mySdkPath.getButton().addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { @@ -203,7 +202,6 @@ public class GroovyFacetEditor { if (files.length > 0) { final VirtualFile dir = files[0]; mySdkPath.setText(FileUtil.toSystemDependentName(dir.getPath())); - myChosenManager = findManager(dir); } } }); From d90dec9aceae0f3753e45c95a4093077915e44bc Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Dec 2009 15:09:06 +0000 Subject: [PATCH 03/10] use our groovy stub generator by default, give an UI option to switch to groovyc's one for perverts (IDEADEV-42045) --- .../compiler/GroovyCompilerConfigurable.form | 10 +++++++- .../compiler/GroovyCompilerConfigurable.java | 7 +++++- .../compiler/GroovyCompilerConfiguration.java | 20 ++++++++++------ .../groovy/compiler/GroovyCompilerLoader.java | 16 ++++++------- .../generator/GroovyToJavaGenerator.java | 4 ++++ .../generator/GroovycStubGenerator.java | 24 +++++++++++++++---- 6 files changed, 59 insertions(+), 22 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfigurable.form b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfigurable.form index 1eaf3812dfd2..90a9f505b22f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfigurable.form +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfigurable.form @@ -8,7 +8,7 @@ - + @@ -37,6 +37,14 @@ + + + + + + + + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfigurable.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfigurable.java index 54df775d2767..1af3db22ef53 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfigurable.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfigurable.java @@ -43,6 +43,7 @@ public class GroovyCompilerConfigurable implements SearchableConfigurable, Compi private JTextField myHeapSize; private JPanel myMainPanel; private JPanel myExcludesPanel; + private JCheckBox myUseGroovycStubs; private ExcludedEntriesConfigurable myExcludes; private final GroovyCompilerConfiguration myConfig; @@ -100,16 +101,20 @@ public class GroovyCompilerConfigurable implements SearchableConfigurable, Compi } public boolean isModified() { - return !Comparing.equal(myConfig.getHeapSize(), myHeapSize.getText()) || myExcludes.isModified(); + return !Comparing.equal(myConfig.getHeapSize(), myHeapSize.getText()) || + myExcludes.isModified() || + myConfig.isUseGroovycStubs() != myUseGroovycStubs.isSelected(); } public void apply() throws ConfigurationException { myExcludes.apply(); myConfig.setHeapSize(myHeapSize.getText()); + myConfig.setUseGroovycStubs(myUseGroovycStubs.isSelected()); } public void reset() { myHeapSize.setText(myConfig.getHeapSize()); + myUseGroovycStubs.setSelected(myConfig.isUseGroovycStubs()); myExcludes.reset(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfiguration.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfiguration.java index 41b602735a4b..dfc2534355c8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfiguration.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerConfiguration.java @@ -36,11 +36,13 @@ import org.jdom.Element; ) public class GroovyCompilerConfiguration implements PersistentStateComponent, Disposable { private String myHeapSize = "400"; + private boolean myUseGroovycStubs = false; private final ExcludedEntriesConfiguration myExcludeFromStubGeneration = new ExcludedEntriesConfiguration(); public MyStateBean getState() { final MyStateBean bean = new MyStateBean(); bean.heapSize = myHeapSize; + bean.useGroovycStubs = myUseGroovycStubs; myExcludeFromStubGeneration.writeExternal(bean.excludes); return bean; } @@ -55,11 +57,7 @@ public class GroovyCompilerConfiguration implements PersistentStateComponent(Arrays.asList(GroovyFileType.GROOVY_FILE_TYPE, StdFileTypes.JAVA)), - new HashSet(Arrays.asList(StdFileTypes.JAVA))); - } else { - GroovyToJavaGenerator generator = new GroovyToJavaGenerator(myProject); - compilerManager.addCompiler(generator); - compilerManager.addCompilationStatusListener(generator); - } + compilerManager.addTranslatingCompiler(new GroovycStubGenerator(myProject), + new HashSet(Arrays.asList(GroovyFileType.GROOVY_FILE_TYPE, StdFileTypes.JAVA)), + new HashSet(Arrays.asList(StdFileTypes.JAVA))); + + GroovyToJavaGenerator generator = new GroovyToJavaGenerator(myProject); + compilerManager.addCompiler(generator); + compilerManager.addCompilationStatusListener(generator); compilerManager.addTranslatingCompiler(new GroovyCompiler(myProject), new HashSet(Arrays.asList(GroovyFileType.GROOVY_FILE_TYPE, StdFileTypes.CLASS)), diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java index 8241a74a4773..d30851a9e138 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java @@ -114,6 +114,10 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat } public GenerationItem[] getGenerationItems(CompileContext context) { + if (GroovyCompilerConfiguration.getInstance(myProject).isUseGroovycStubs()) { + return new GenerationItem[0]; + } + myContext = context; List generationItems = new ArrayList(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java index a02a2b9ec3b6..235964624085 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java @@ -24,9 +24,9 @@ import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompilerPaths; import com.intellij.openapi.compiler.ex.CompileContextEx; import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -47,7 +47,6 @@ import java.util.List; * @author peter */ public class GroovycStubGenerator extends GroovyCompilerBase { - private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.compiler.generator.GroovycStubGenerator"); public GroovycStubGenerator(Project project) { super(project); @@ -55,8 +54,26 @@ public class GroovycStubGenerator extends GroovyCompilerBase { @Override public void compile(CompileContext compileContext, Chunk moduleChunk, VirtualFile[] virtualFiles, OutputSink sink) { + if (!GroovyCompilerConfiguration.getInstance(myProject).isUseGroovycStubs()) { + return; + } + final CompileScope scope = compileContext.getCompileScope(); - if (scope.getFiles(StdFileTypes.JAVA, true).length == 0) { + final VirtualFile[] javaFiles = scope.getFiles(StdFileTypes.JAVA, true); + if (javaFiles.length == 0) { + return; + } + + boolean hasJava = false; + for (VirtualFile javaFile : javaFiles) { + final Module module = ModuleUtil.findModuleForFile(javaFile, myProject); + if (module != null && moduleChunk.containsNode(module)) { + hasJava = true; + break; + } + } + + if (!hasJava) { return; } @@ -103,7 +120,6 @@ public class GroovycStubGenerator extends GroovyCompilerBase { if (!hasJava) { //always pass groovyc stub generator at least 1 java file, or it won't generate stubs - //todo not needed anymore with groovy 1.7? toCompile.add(createMockJavaFile(rootPath)); } From dbab6926ba68c570c1b2cafdf251046a4ad2a397 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Dec 2009 15:10:41 +0000 Subject: [PATCH 04/10] test for compiling groovy class extending another abstract groovy class --- .../groovy/lang/GroovyCompilerTest.groovy | 282 +++++++++ .../groovy/lang/GroovyCompilerTest.java | 534 ------------------ 2 files changed, 282 insertions(+), 534 deletions(-) create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy delete mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.java diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy new file mode 100644 index 000000000000..b79dbed29bb1 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy @@ -0,0 +1,282 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.plugins.groovy.lang; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import junit.framework.AssertionFailedError; + +/** + * @author peter + */ +public class GroovyCompilerTest extends GroovyCompilerTestCase { + + public void testPlainGroovy() throws Throwable { + myFixture.addFileToProject("A.groovy", "println '239'"); + assertEmpty(make()); + assertOutput("A", "239"); + } + + public void testJavaDependsOnGroovy() throws Throwable { + myFixture.addClass("public class Foo {" + + "public static void main(String[] args) { " + + " System.out.println(new Bar().foo());" + + "}" + + "}"); + myFixture.addFileToProject("Bar.groovy", "class Bar {" + + " def foo() {" + + " 239" + + " }" + + "}"); + assertEmpty(make()); + assertOutput("Foo", "239"); + } + + public void testCorrectFailAndCorrect() throws Exception { + myFixture.addClass("public class Foo {" + + "public static void main(String[] args) { " + + " System.out.println(new Bar().foo());" + + "}" + + "}"); + final String barText = "class Bar {" + " def foo() { 239 }" + "}"; + final PsiFile file = myFixture.addFileToProject("Bar.groovy", barText); + assertEmpty(make()); + assertOutput("Foo", "239"); + + setFileText(file, "class Bar {}"); + try { + make(); + fail("Make should fail"); + } + catch (RuntimeException e) { + if (!(e.getCause() instanceof AssertionFailedError)) { + throw e; + } + } + + setFileText(file, barText); + assertEmpty(make()); + assertOutput("Foo", "239"); + } + + public void testRenameToJava() throws Throwable { + myFixture.addClass("public class Foo {" + + "public static void main(String[] args) { " + + " System.out.println(new Bar().foo());" + + "}" + + "}"); + + final PsiFile bar = + myFixture.addFileToProject("Bar.groovy", "public class Bar {" + "public int foo() { " + " return 239;" + "}" + "}"); + + assertEmpty(make()); + assertOutput("Foo", "239"); + + setFileName bar, "Bar.java" + + assertEmpty(make()); + assertOutput("Foo", "239"); + } + + public void testTransitiveJavaDependency() throws Throwable { + final VirtualFile ifoo = myFixture.addClass("public interface IFoo { int foo(); }").getContainingFile().getVirtualFile(); + myFixture.addClass("public class Foo implements IFoo {" + + " public int foo() { return 239; }" + + "}"); + final PsiFile bar = myFixture.addFileToProject("Bar.groovy", "class Bar {" + + "Foo foo\n" + + "public static void main(String[] args) { " + + " System.out.println(new Foo().foo());" + + "}" + + "}"); + assertEmpty(make()); + assertOutput("Bar", "239"); + + touch(ifoo); + touch(bar.getVirtualFile()); + + //assertTrue(assertOneElement(make()).contains("WARNING: Groovyc stub generation failed")); + assertEmpty make() + assertOutput("Bar", "239"); + } + + public void testTransitiveJavaDependencyThroughGroovy() throws Throwable { + myFixture.addClass("public class IFoo { void foo() {} }").getContainingFile().getVirtualFile(); + myFixture.addFileToProject("Foo.groovy", "class Foo {\n" + + " static IFoo f\n" + + " public int foo() { return 239; }\n" + + "}"); + final PsiFile bar = myFixture.addFileToProject("Bar.groovy", "class Bar extends Foo {" + + "public static void main(String[] args) { " + + " System.out.println(new Foo().foo());" + + "}" + + "}"); + assertEmpty(make()); + assertOutput("Bar", "239"); + + deleteClassFile("IFoo"); + touch(bar.getVirtualFile()); + + //assertTrue(assertOneElement(make()).contains("WARNING: Groovyc error")); + assertEmpty make() + assertOutput("Bar", "239"); + } + + public void testDeleteTransitiveJavaClass() throws Throwable { + myFixture.addClass("public interface IFoo { int foo(); }"); + myFixture.addClass("public class Foo implements IFoo {" + + " public int foo() { return 239; }" + + "}"); + final PsiFile bar = myFixture.addFileToProject("Bar.groovy", "class Bar {" + + "Foo foo\n" + + "public static void main(String[] args) { " + + " System.out.println(new Foo().foo());" + + "}" + + "}"); + assertEmpty(make()); + assertOutput("Bar", "239"); + + deleteClassFile("IFoo"); + touch(bar.getVirtualFile()); + + //assertTrue(assertOneElement(make()).contains("WARNING: Groovyc stub generation failed")); + assertEmpty make() + assertOutput("Bar", "239"); + } + + public void testGroovyDependsOnGroovy() throws Throwable { + myFixture.addClass("public class JustToMakeGroovyGenerateStubs {}"); + myFixture.addFileToProject("Foo.groovy", "class Foo { }"); + final PsiFile bar = myFixture.addFileToProject("Bar.groovy", "class Bar {" + + "def foo(Foo f) {}\n" + + "public static void main(String[] args) { " + + " System.out.println(239);" + + "}" + + "}"); + assertEmpty(make()); + assertOutput("Bar", "239"); + + touch(bar.getVirtualFile()); + + assertEmpty(make()); + assertOutput("Bar", "239"); + } + + public void testMakeInTests() throws Throwable { + setupTestSources(); + myFixture.addFileToProject("tests/Super.groovy", "class Super {}"); + assertEmpty(make()); + + myFixture.addFileToProject("tests/Sub.groovy", "class Sub {\n" + + " Super xxx() {}\n" + + " static void main(String[] args) {" + + " println 'hello'" + + " }" + + "}"); + myFixture.addFileToProject("tests/Java.java", "public class Java {}"); + assertEmpty(make()); + assertOutput("Sub", "hello"); + } + + public void testTestsDependOnProduction() throws Throwable { + setupTestSources(); + myFixture.addFileToProject("src/com/Bar.groovy", "package com\n" + + "class Bar {}"); + myFixture.addFileToProject("src/com/ToGenerateStubs.java", "package com;\n" + + "public class ToGenerateStubs {}"); + myFixture.addFileToProject("tests/com/BarTest.groovy", "package com\n" + + "class BarTest extends Bar {}"); + assertEmpty(make()); + } + + public void testStubForGroovyExtendingJava() throws Exception { + myFixture.addClass("public class Foo {}"); + myFixture.addFileToProject("Bar.groovy", "class Bar extends Foo {}"); + myFixture.addClass("public class Goo extends Bar {}"); + + 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); + } + + public void testExtendFromGroovyAbstractClass() throws Exception { + myFixture.addFileToProject "Super.groovy", "abstract class Super {}" + myFixture.addFileToProject "AJava.java", "public class AJava {}" + assertEmpty make() + + myFixture.addFileToProject "Sub.groovy", "class Sub extends Super {}" + assertEmpty make() + } + + +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.java deleted file mode 100644 index 479f3cb94422..000000000000 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.java +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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; -import com.intellij.execution.application.ApplicationConfiguration; -import com.intellij.execution.application.ApplicationConfigurationType; -import com.intellij.execution.configurations.RunnerSettings; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.impl.DefaultJavaProgramRunner; -import com.intellij.execution.process.ProcessAdapter; -import com.intellij.execution.process.ProcessEvent; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.process.ProcessOutputTypes; -import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.ProgramRunner; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.ide.DataManager; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; -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.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.PsiTestUtil; -import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; -import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; -import com.intellij.testFramework.fixtures.TempDirTestFixture; -import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl; -import com.intellij.util.ObjectUtils; -import com.intellij.util.concurrency.Semaphore; -import junit.framework.AssertionFailedError; -import org.jetbrains.plugins.groovy.compiler.GroovyCompilerLoader; -import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; -import org.jetbrains.plugins.groovy.util.GroovyUtils; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * @author peter - */ -public class GroovyCompilerTest extends JavaCodeInsightFixtureTestCase { - private TempDirTestFixture myMainOutput; - - @Override - protected void setUp() throws Exception { - myMainOutput = new TempDirTestFixtureImpl(); - myMainOutput.setUp(); - super.setUp(); - getProject().getComponent(GroovyCompilerLoader.class).projectOpened(); - CompilerManagerImpl.testSetup(); - - CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(myMainOutput.findOrCreateDir("out").getUrl()); - - addGroovyLibrary(myModule); - } - - @Override - protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) throws Exception { - moduleBuilder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15); - super.tuneFixture(moduleBuilder); - } - - 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 - protected void tearDown() throws Exception { - myMainOutput.tearDown(); - myMainOutput = null; - super.tearDown(); - } - - public void testPlainGroovy() throws Throwable { - myFixture.addFileToProject("A.groovy", "println '239'"); - assertEmpty(make()); - assertOutput("A", "239"); - } - - public void testJavaDependsOnGroovy() throws Throwable { - myFixture.addClass("public class Foo {" + - "public static void main(String[] args) { " + - " System.out.println(new Bar().foo());" + - "}" + - "}"); - myFixture.addFileToProject("Bar.groovy", "class Bar {" + - " def foo() {" + - " 239" + - " }" + - "}"); - assertEmpty(make()); - assertOutput("Foo", "239"); - } - - public void testCorrectFailAndCorrect() throws Exception { - myFixture.addClass("public class Foo {" + - "public static void main(String[] args) { " + - " System.out.println(new Bar().foo());" + - "}" + - "}"); - final String barText = "class Bar {" + " def foo() { 239 }" + "}"; - final PsiFile file = myFixture.addFileToProject("Bar.groovy", barText); - assertEmpty(make()); - assertOutput("Foo", "239"); - - setFileText(file, "class Bar {}"); - try { - make(); - fail("Make should fail"); - } - catch (RuntimeException e) { - if (!(e.getCause() instanceof AssertionFailedError)) { - throw e; - } - } - - setFileText(file, barText); - assertEmpty(make()); - assertOutput("Foo", "239"); - } - - public void testRenameToJava() throws Throwable { - myFixture.addClass("public class Foo {" + - "public static void main(String[] args) { " + - " System.out.println(new Bar().foo());" + - "}" + - "}"); - - final PsiFile bar = - myFixture.addFileToProject("Bar.groovy", "public class Bar {" + "public int foo() { " + " return 239;" + "}" + "}"); - - assertEmpty(make()); - assertOutput("Foo", "239"); - - new WriteCommandAction(getProject()) { - protected void run(Result result) throws Throwable { - bar.setName("Bar.java"); - } - }.execute(); - - assertEmpty(make()); - assertOutput("Foo", "239"); - } - - public void testTransitiveJavaDependency() throws Throwable { - final VirtualFile ifoo = myFixture.addClass("public interface IFoo { int foo(); }").getContainingFile().getVirtualFile(); - myFixture.addClass("public class Foo implements IFoo {" + - " public int foo() { return 239; }" + - "}"); - final PsiFile bar = myFixture.addFileToProject("Bar.groovy", "class Bar {" + - "Foo foo\n" + - "public static void main(String[] args) { " + - " System.out.println(new Foo().foo());" + - "}" + - "}"); - assertEmpty(make()); - assertOutput("Bar", "239"); - - touch(ifoo); - touch(bar.getVirtualFile()); - - assertTrue(assertOneElement(make()).contains("WARNING: Groovyc stub generation failed")); - assertOutput("Bar", "239"); - } - - public void testTransitiveJavaDependencyThroughGroovy() throws Throwable { - myFixture.addClass("public class IFoo { void foo() {} }").getContainingFile().getVirtualFile(); - myFixture.addFileToProject("Foo.groovy", "class Foo {\n" + - " static IFoo f\n" + - " public int foo() { return 239; }\n" + - "}"); - final PsiFile bar = myFixture.addFileToProject("Bar.groovy", "class Bar extends Foo {" + - "public static void main(String[] args) { " + - " System.out.println(new Foo().foo());" + - "}" + - "}"); - assertEmpty(make()); - assertOutput("Bar", "239"); - - deleteClassFile("IFoo"); - touch(bar.getVirtualFile()); - - assertTrue(assertOneElement(make()).contains("WARNING: Groovyc error")); - assertOutput("Bar", "239"); - } - - public void testDeleteTransitiveJavaClass() throws Throwable { - myFixture.addClass("public interface IFoo { int foo(); }"); - myFixture.addClass("public class Foo implements IFoo {" + - " public int foo() { return 239; }" + - "}"); - final PsiFile bar = myFixture.addFileToProject("Bar.groovy", "class Bar {" + - "Foo foo\n" + - "public static void main(String[] args) { " + - " System.out.println(new Foo().foo());" + - "}" + - "}"); - assertEmpty(make()); - assertOutput("Bar", "239"); - - deleteClassFile("IFoo"); - touch(bar.getVirtualFile()); - - assertTrue(assertOneElement(make()).contains("WARNING: Groovyc stub generation failed")); - assertOutput("Bar", "239"); - } - - public void testGroovyDependsOnGroovy() throws Throwable { - myFixture.addClass("public class JustToMakeGroovyGenerateStubs {}"); - myFixture.addFileToProject("Foo.groovy", "class Foo { }"); - final PsiFile bar = myFixture.addFileToProject("Bar.groovy", "class Bar {" + - "def foo(Foo f) {}\n" + - "public static void main(String[] args) { " + - " System.out.println(239);" + - "}" + - "}"); - assertEmpty(make()); - assertOutput("Bar", "239"); - - touch(bar.getVirtualFile()); - - assertEmpty(make()); - assertOutput("Bar", "239"); - } - - public void testMakeInTests() throws Throwable { - setupTestSources(); - myFixture.addFileToProject("tests/Super.groovy", "class Super {}"); - assertEmpty(make()); - - myFixture.addFileToProject("tests/Sub.groovy", "class Sub {\n" + - " Super xxx() {}\n" + - " static void main(String[] args) {" + - " println 'hello'" + - " }" + - "}"); - myFixture.addFileToProject("tests/Java.java", "public class Java {}"); - assertEmpty(make()); - assertOutput("Sub", "hello"); - } - - public void testTestsDependOnProduction() throws Throwable { - setupTestSources(); - myFixture.addFileToProject("src/com/Bar.groovy", "package com\n" + - "class Bar {}"); - myFixture.addFileToProject("src/com/ToGenerateStubs.java", "package com;\n" + - "public class ToGenerateStubs {}"); - myFixture.addFileToProject("tests/com/BarTest.groovy", "package com\n" + - "class BarTest extends Bar {}"); - assertEmpty(make()); - } - - private void setupTestSources() { - new WriteCommandAction(getProject()) { - protected void run(Result result) throws Throwable { - final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule); - final ModifiableRootModel rootModel = rootManager.getModifiableModel(); - final ContentEntry entry = rootModel.getContentEntries()[0]; - entry.removeSourceFolder(entry.getSourceFolders()[0]); - entry.addSourceFolder(myFixture.getTempDirFixture().findOrCreateDir("src"), false); - entry.addSourceFolder(myFixture.getTempDirFixture().findOrCreateDir("tests"), true); - rootModel.commit(); - } - }.execute(); - } - - public void testStubForGroovyExtendingJava() throws Exception { - myFixture.addClass("public class Foo {}"); - myFixture.addFileToProject("Bar.groovy", "class Bar extends Foo {}"); - myFixture.addClass("public class Goo extends Bar {}"); - - 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("Transf.java", - "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" + - " public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {\n" + - " ModuleNode module = (ModuleNode) nodes[0];\n" + - " for (ClassNode clazz : module.getClasses()) {\n" + - " if (clazz.getName().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(getProject()) { - @Override - protected void run(Result 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 { - final CompilerModuleExtension extension = ModuleRootManager.getInstance(myModule).getModuleExtension(CompilerModuleExtension.class); - //noinspection ConstantConditions - extension.getCompilerOutputPath().findChild(className + ".class").delete(this); - } - }.execute(); - } - - private static void touch(VirtualFile file) throws IOException { - file.setBinaryContent(file.contentsToByteArray(), file.getModificationStamp() + 1, file.getTimeStamp() + 1); - } - - private static void setFileText(final PsiFile file, final String barText) throws IOException { - Runnable runnable = new Runnable() { - public void run() { - try { - VfsUtil.saveText(ObjectUtils.assertNotNull(file.getVirtualFile()), barText); - } - catch (IOException e) { - throw new RuntimeException(e); - } - } - }; - ApplicationManager.getApplication().invokeAndWait(runnable, ModalityState.NON_MODAL); - - } - - private List make() { - final Semaphore semaphore = new Semaphore(); - semaphore.down(); - final ErrorReportingCallback callback = new ErrorReportingCallback(semaphore); - CompilerManager.getInstance(getProject()).make(callback); - semaphore.waitFor(); - callback.throwException(); - return callback.getMessages(); - } - - /* - private void compile(VirtualFile... files) { - final Semaphore semaphore = new Semaphore(); - semaphore.down(); - final ErrorReportingCallback callback = new ErrorReportingCallback(semaphore); - CompilerManager.getInstance(getProject()).compile(files, new ErrorReportingCallback(semaphore), false); - semaphore.waitFor(); - callback.throwException(); - } - */ - - 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(module); - configuration.setMainClassName(className); - final DefaultRunExecutor extension = Executor.EXECUTOR_EXTENSION_NAME.findExtension(DefaultRunExecutor.class); - final ExecutionEnvironment environment = new ExecutionEnvironment(configuration, new RunnerSettings(null, null),null, DataManager.getInstance().getDataContext()); - final DefaultJavaProgramRunner runner = ProgramRunner.PROGRAM_RUNNER_EP.findExtension(DefaultJavaProgramRunner.class); - final StringBuffer sb = new StringBuffer(); - final Semaphore semaphore = new Semaphore(); - semaphore.down(); - runner.execute(extension, environment, new ProgramRunner.Callback() { - public void processStarted(RunContentDescriptor descriptor) { - final ProcessHandler handler = descriptor.getProcessHandler(); - - assert handler != null; - handler.addProcessListener(new ProcessAdapter() { - public void onTextAvailable(ProcessEvent event, Key outputType) { - if (ProcessOutputTypes.SYSTEM != outputType) { - sb.append(event.getText()); - } - } - - @Override - public void processTerminated(ProcessEvent event) { - semaphore.up(); - } - }); - } - }); - semaphore.waitFor(); - assertEquals(output.trim(), StringUtil.convertLineSeparators(sb.toString().trim())); - } - - private static class ErrorReportingCallback implements CompileStatusNotification { - private final Semaphore mySemaphore; - private Throwable myError; - private List myMessages = new ArrayList(); - - public ErrorReportingCallback(Semaphore semaphore) { - mySemaphore = semaphore; - } - - public void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext) { - try { - assertFalse("Code did not compile!", aborted); - for (CompilerMessageCategory category : CompilerMessageCategory.values()) { - for (CompilerMessage message : compileContext.getMessages(category)) { - final String msg = message.getMessage(); - if (category != CompilerMessageCategory.INFORMATION || !msg.startsWith("Compilation completed successfully")) { - myMessages.add(category + ": " + msg); - } - } - } - if (errors > 0) { - fail("Compiler errors occurred! " + StringUtil.join(myMessages, "\n")); - } - } - catch (Throwable t) { - myError = t; - } - finally { - mySemaphore.up(); - } - } - - void throwException() { - if (myError != null) { - throw new RuntimeException(myError); - } - } - - public List getMessages() { - return myMessages; - } - } -} From 15452b12b3af9446f3c5b6e0fe8dbde9e84fd1a7 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Dec 2009 15:13:53 +0000 Subject: [PATCH 05/10] forgotten --- .../groovy/lang/GroovyCompilerTestCase.java | 258 ++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java new file mode 100644 index 000000000000..1478526fa023 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java @@ -0,0 +1,258 @@ +package org.jetbrains.plugins.groovy.lang; + +import com.intellij.compiler.CompilerManagerImpl; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.application.ApplicationConfiguration; +import com.intellij.execution.application.ApplicationConfigurationType; +import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.impl.DefaultJavaProgramRunner; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.ide.DataManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +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.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.PsiTestUtil; +import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; +import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; +import com.intellij.testFramework.fixtures.TempDirTestFixture; +import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl; +import com.intellij.util.ObjectUtils; +import com.intellij.util.concurrency.Semaphore; +import org.jetbrains.plugins.groovy.compiler.GroovyCompilerLoader; +import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; +import org.jetbrains.plugins.groovy.util.GroovyUtils; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author peter + */ +public class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestCase { + private TempDirTestFixture myMainOutput; + + @Override + protected void setUp() throws Exception { + myMainOutput = new TempDirTestFixtureImpl(); + myMainOutput.setUp(); + super.setUp(); + getProject().getComponent(GroovyCompilerLoader.class).projectOpened(); + CompilerManagerImpl.testSetup(); + + CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(myMainOutput.findOrCreateDir("out").getUrl()); + + addGroovyLibrary(myModule); + } + + @Override + protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) throws Exception { + moduleBuilder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15); + super.tuneFixture(moduleBuilder); + } + + protected 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 + protected void tearDown() throws Exception { + myMainOutput.tearDown(); + myMainOutput = null; + super.tearDown(); + } + + protected void setupTestSources() { + new WriteCommandAction(getProject()) { + protected void run(Result result) throws Throwable { + final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule); + final ModifiableRootModel rootModel = rootManager.getModifiableModel(); + final ContentEntry entry = rootModel.getContentEntries()[0]; + entry.removeSourceFolder(entry.getSourceFolders()[0]); + entry.addSourceFolder(myFixture.getTempDirFixture().findOrCreateDir("src"), false); + entry.addSourceFolder(myFixture.getTempDirFixture().findOrCreateDir("tests"), true); + rootModel.commit(); + } + }.execute(); + } + + protected Module addDependentModule() { + Module dep = new WriteCommandAction(getProject()) { + @Override + protected void run(Result 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; + } + + protected void deleteClassFile(final String className) throws IOException { + new WriteCommandAction(getProject()) { + protected void run(Result result) throws Throwable { + final CompilerModuleExtension extension = ModuleRootManager.getInstance(myModule).getModuleExtension(CompilerModuleExtension.class); + //noinspection ConstantConditions + extension.getCompilerOutputPath().findChild(className + ".class").delete(this); + } + }.execute(); + } + + protected static void touch(VirtualFile file) throws IOException { + file.setBinaryContent(file.contentsToByteArray(), file.getModificationStamp() + 1, file.getTimeStamp() + 1); + } + + protected static void setFileText(final PsiFile file, final String barText) throws IOException { + Runnable runnable = new Runnable() { + public void run() { + try { + VfsUtil.saveText(ObjectUtils.assertNotNull(file.getVirtualFile()), barText); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }; + ApplicationManager.getApplication().invokeAndWait(runnable, ModalityState.NON_MODAL); + + } + + protected void setFileName(final PsiFile bar, final String name) { + new WriteCommandAction(getProject()) { + protected void run(Result result) throws Throwable { + bar.setName(name); + } + }.execute(); + } + + protected List make() { + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + final ErrorReportingCallback callback = new ErrorReportingCallback(semaphore); + CompilerManager.getInstance(getProject()).make(callback); + semaphore.waitFor(); + callback.throwException(); + return callback.getMessages(); + } + + protected void assertOutput(String className, String output) throws ExecutionException { + assertOutput(className, output, myModule); + } + + protected void assertOutput(String className, String output, final Module module) throws ExecutionException { + final ApplicationConfiguration configuration = + new ApplicationConfiguration("app", getProject(), ApplicationConfigurationType.getInstance()); + configuration.setModule(module); + configuration.setMainClassName(className); + final DefaultRunExecutor extension = Executor.EXECUTOR_EXTENSION_NAME.findExtension(DefaultRunExecutor.class); + final ExecutionEnvironment environment = new ExecutionEnvironment(configuration, new RunnerSettings(null, null),null, DataManager + .getInstance().getDataContext()); + final DefaultJavaProgramRunner runner = ProgramRunner.PROGRAM_RUNNER_EP.findExtension(DefaultJavaProgramRunner.class); + final StringBuffer sb = new StringBuffer(); + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + runner.execute(extension, environment, new ProgramRunner.Callback() { + public void processStarted(RunContentDescriptor descriptor) { + final ProcessHandler handler = descriptor.getProcessHandler(); + + assert handler != null; + handler.addProcessListener(new ProcessAdapter() { + public void onTextAvailable(ProcessEvent event, Key outputType) { + if (ProcessOutputTypes.SYSTEM != outputType) { + sb.append(event.getText()); + } + } + + @Override + public void processTerminated(ProcessEvent event) { + semaphore.up(); + } + }); + } + }); + semaphore.waitFor(); + assertEquals(output.trim(), StringUtil.convertLineSeparators(sb.toString().trim())); + } + + private static class ErrorReportingCallback implements CompileStatusNotification { + private final Semaphore mySemaphore; + private Throwable myError; + private List myMessages = new ArrayList(); + + public ErrorReportingCallback(Semaphore semaphore) { + mySemaphore = semaphore; + } + + public void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext) { + try { + assertFalse("Code did not compile!", aborted); + for (CompilerMessageCategory category : CompilerMessageCategory.values()) { + for (CompilerMessage message : compileContext.getMessages(category)) { + final String msg = message.getMessage(); + if (category != CompilerMessageCategory.INFORMATION || !msg.startsWith("Compilation completed successfully")) { + myMessages.add(category + ": " + msg); + } + } + } + if (errors > 0) { + fail("Compiler errors occurred! " + StringUtil.join(myMessages, "\n")); + } + } + catch (Throwable t) { + myError = t; + } + finally { + mySemaphore.up(); + } + } + + void throwException() { + if (myError != null) { + throw new RuntimeException(myError); + } + } + + public List getMessages() { + return myMessages; + } + } +} From b3f56d57ba18f88813a35558bd517871a73a1ef6 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 21 Dec 2009 17:38:42 +0300 Subject: [PATCH 06/10] correct product name in dialog, restart instead of shutdown if possible --- .../project/impl/ProjectManagerImpl.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index f956a0ff901a..bda7f3265ef6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -19,17 +19,16 @@ import com.intellij.ide.AppLifecycleListener; import com.intellij.ide.highlighter.WorkspaceFileType; import com.intellij.ide.impl.ProjectUtil; import com.intellij.ide.startup.impl.StartupManagerImpl; -import com.intellij.notification.*; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; -import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.*; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.application.impl.ApplicationImpl; import com.intellij.openapi.components.ExportableApplicationComponent; import com.intellij.openapi.components.StateStorage; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; -import com.intellij.openapi.components.impl.stores.*; +import com.intellij.openapi.components.impl.stores.IComponentStore; +import com.intellij.openapi.components.impl.stores.IProjectStore; +import com.intellij.openapi.components.impl.stores.StorageUtil; +import com.intellij.openapi.components.impl.stores.XmlElementStorage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.ProcessCanceledException; @@ -45,7 +44,6 @@ import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileEvent; @@ -66,7 +64,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; -import javax.swing.event.HyperlinkEvent; import java.io.File; import java.io.IOException; import java.util.*; @@ -597,7 +594,10 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt for (String component : components) { message += component + "\n"; } - message += "Shutdown IDEA?"; + + final boolean canRestart = ApplicationManager.getApplication().isRestartCapable(); + message += "Would you like to " + (canRestart ? "restart " : "shutdown "); + message += ApplicationNamesInfo.getInstance().getProductName() + "?"; if (Messages.showYesNoDialog(message, "Application Configuration Reload", Messages.getQuestionIcon()) == 0) { @@ -607,9 +607,13 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt ((XmlElementStorage)stateStorage).disableSaving(); } } - ApplicationManagerEx.getApplicationEx().exit(true); + if (canRestart) { + ApplicationManagerEx.getApplicationEx().restart(); + } + else { + ApplicationManagerEx.getApplicationEx().exit(true); + } } - } return reloadOk[0]; From facae3a168c83425c971cb1ab18f67695b566ca1 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 21 Dec 2009 18:10:25 +0300 Subject: [PATCH 07/10] Fix IDEADEV-42046: beforeRunTasks settings are reset --- .../execution/impl/RunManagerImpl.java | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java index a6abff4db540..b7ebeeca4082 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java @@ -231,7 +231,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, setBeforeRunTasks(configuration, tasks); } - void checkRecentsLimit() { + void checkRecentsLimit() { while (getTempConfigurations().length > getConfig().getRecentsLimit()) { for (Iterator> it = myConfigurations.entrySet().iterator(); it.hasNext();) { Map.Entry entry = it.next(); @@ -351,7 +351,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, continue; } } - + addConfigurationElement(parentNode, runnerAndConfigurationSettings); } @@ -440,17 +440,33 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, public void readExternal(final Element parentNode) throws InvalidDataException { clear(); + final Comparator comparator = new Comparator() { + public int compare(Element a, Element b) { + final boolean aDefault = Boolean.valueOf(a.getAttributeValue("default", "false")); + final boolean bDefault = Boolean.valueOf(b.getAttributeValue("default", "false")); + return aDefault == bDefault ? 0 : aDefault ? -1 : 1; + } + }; + final List children = parentNode.getChildren(); + final List sortedElements = new ArrayList(); for (final Object aChildren : children) { final Element element = (Element)aChildren; - if (loadConfiguration(element, false) == null && Comparing.strEqual(element.getName(), CONFIGURATION)) { + if (Comparing.strEqual(element.getName(), CONFIGURATION)) { + sortedElements.add(element); + } + } + + Collections.sort(sortedElements, comparator); // ensure templates are loaded first! + + for (final Element element : sortedElements) { + if (loadConfiguration(element, false) == null) { if (myUnloadedElements == null) myUnloadedElements = new ArrayList(2); myUnloadedElements.add(element); } } myOrder.readExternal(parentNode); - mySelectedConfig = parentNode.getAttributeValue(SELECTED_ATTR); } @@ -551,7 +567,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, @Nullable private static ConfigurationFactory findFactoryOfTypeByName(final ConfigurationType type, final String factoryName) { if (factoryName == null) return null; - + if (type instanceof UnknownConfigurationType) { return type.getConfigurationFactories()[0]; } From 170768a70031ffe21dd17d095fcddacf2fd27593 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Dec 2009 17:22:01 +0000 Subject: [PATCH 08/10] diagnostics for missing output directory in IDEADEV-42054 NPE during compilation of Groovy code --- .../plugins/groovy/compiler/GroovyCompilerBase.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java index 16cc3970e105..6c429fdebf05 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java @@ -56,6 +56,8 @@ 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.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.groovy.compiler.rt.CompilerMessage; import org.jetbrains.groovy.compiler.rt.GroovycRunner; import org.jetbrains.plugins.groovy.GroovyFileType; @@ -137,7 +139,9 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { try { File fileWithParameters = File.createTempFile("toCompile", ""); - fillFileWithGroovycParameters(toCompile, fileWithParameters, outputDir, patchers, getMainOutput(compileContext, module, tests)); + final VirtualFile finalOutputDir = getMainOutput(compileContext, module, tests); + LOG.assertTrue(finalOutputDir != null, "No output directory for module " + module.getName() + (tests ? " tests" : " production")); + fillFileWithGroovycParameters(toCompile, fileWithParameters, outputDir, patchers, finalOutputDir); commandLine.addParameter(forStubs ? "stubs" : "groovyc"); commandLine.addParameter(fileWithParameters.getPath()); @@ -206,6 +210,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { } } + @Nullable protected static VirtualFile getMainOutput(CompileContext compileContext, Module module, boolean tests) { return tests ? compileContext.getModuleOutputDirectoryForTests(module) : compileContext.getModuleOutputDirectory(module); } @@ -222,7 +227,8 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { return CompilerMessageCategory.ERROR; } - private void fillFileWithGroovycParameters(List virtualFiles, File f, VirtualFile outputDir, final List patchers, VirtualFile finalOutputDir) { + private void fillFileWithGroovycParameters(List virtualFiles, File f, VirtualFile outputDir, final List patchers, + @NotNull VirtualFile finalOutputDir) { if (LOG.isDebugEnabled()) { LOG.debug("Running groovyc on: " + virtualFiles.toString()); } From 8f6b0fb01d16e8bd3743df20e70f2125c122d0c7 Mon Sep 17 00:00:00 2001 From: irengrig Date: Tue, 22 Dec 2009 01:45:00 +0300 Subject: [PATCH 09/10] SVN: authentication for free-read-access repositories to work also --- .../openapi/vcs/impl/GenericNotifierImpl.java | 8 ++++ .../idea/svn/SvnAuthenticationNotifier.java | 39 +++++++++++++++---- .../svn/SvnBranchConfigurationManager.java | 2 +- .../jetbrains/idea/svn/SvnConfiguration.java | 8 ++++ .../src/org/jetbrains/idea/svn/SvnVcs.java | 2 +- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java index 9007383485aa..e0d9a9e7498e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java @@ -131,6 +131,14 @@ public abstract class GenericNotifierImpl { } } + @Nullable + protected T getObj(final Key key) { + synchronized (myLock) { + final MyNotification notification = myState.get(key); + return notification == null ? null : notification.getObj(); + } + } + protected static class MyNotification extends Notification { private T myObj; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java index f08e31f0768b..5008f1e6818e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java @@ -28,11 +28,13 @@ import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier; import com.intellij.openapi.vcs.impl.GenericNotifierImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.dialogs.SvnInteractiveAuthenticationProvider; import org.tmatesoft.svn.core.SVNAuthenticationException; import org.tmatesoft.svn.core.SVNCancelException; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; +import org.tmatesoft.svn.core.auth.SVNAuthentication; import org.tmatesoft.svn.core.internal.util.SVNURLUtil; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc.SVNWCClient; @@ -59,7 +61,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl resultRef = new Ref(); final boolean done = ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { public void run() { - final boolean result = interactiveValidation(obj.myProject, obj.getUrl()); + final boolean result = interactiveValidation(obj.myProject, obj.getUrl(), obj.getRealm(), obj.getKind()); log("ask result for: " + obj.getUrl() + " is: " + result); resultRef.set(result); if (result) { @@ -76,7 +78,8 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl Date: Tue, 22 Dec 2009 02:32:03 +0300 Subject: [PATCH 10/10] IDEA-26932 (CVS connection is performed from the UI thread (hangs IDEA)) --- .../cvsSupport2/cvsoperations/common/CvsCommandOperation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/common/CvsCommandOperation.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/common/CvsCommandOperation.java index f19f785f6750..b2cbb8dfb7c1 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/common/CvsCommandOperation.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/common/CvsCommandOperation.java @@ -244,7 +244,7 @@ public abstract class CvsCommandOperation extends CvsOperation implements IFileI } catch (AuthenticationException e) { if (! root.isOffline()) { - ApplicationManager.getApplication().invokeLater(new Runnable() { + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { public void run() { final LoginPerformer.MyForRootProvider performer = new LoginPerformer.MyForRootProvider(Collections.singletonList(root), new Consumer() { @@ -257,6 +257,7 @@ public abstract class CvsCommandOperation extends CvsOperation implements IFileI performer.loginAll(ModalityContextImpl.NON_MODAL); } }); + return; } throw root.processException(new CommandException(e, "Authentication problem")); }