Merge branch 'idea90' of git.labs.intellij.net:idea/community into idea90

This commit is contained in:
Dmitry Avdeev
2009-12-22 14:27:14 +03:00
23 changed files with 770 additions and 603 deletions
@@ -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<Artifact> toBuild = new ArrayList<Artifact>();
for (Artifact artifact : ArtifactManager.getInstance(project).getSortedArtifacts()) {
if (!StringUtil.isEmpty(artifact.getOutputPath())) {
toBuild.add(artifact);
}
}
CompilerManager.getInstance(project).make(ArtifactCompileScope.createArtifactsScope(project, toBuild), null);
}
}
@@ -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()]);
}
}
@@ -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<Map.Entry<String, RunnerAndConfigurationSettingsImpl>> it = myConfigurations.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, RunnerAndConfigurationSettingsImpl> 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<Element> comparator = new Comparator<Element>() {
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<Element> sortedElements = new ArrayList<Element>();
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<Element>(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];
}
@@ -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];
@@ -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
@@ -131,6 +131,14 @@ public abstract class GenericNotifierImpl<T, Key> {
}
}
@Nullable
protected T getObj(final Key key) {
synchronized (myLock) {
final MyNotification<T> notification = myState.get(key);
return notification == null ? null : notification.getObj();
}
}
protected static class MyNotification<T> extends Notification {
private T myObj;
@@ -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<VcsException>() {
@@ -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"));
}
@@ -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<VirtualFile> virtualFiles, File f, VirtualFile outputDir, final List<String> patchers, VirtualFile finalOutputDir) {
private void fillFileWithGroovycParameters(List<VirtualFile> virtualFiles, File f, VirtualFile outputDir, final List<String> patchers,
@NotNull VirtualFile finalOutputDir) {
if (LOG.isDebugEnabled()) {
LOG.debug("Running groovyc on: " + virtualFiles.toString());
}
@@ -8,7 +8,7 @@
<properties/>
<border type="none"/>
<children>
<grid id="838f2" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="838f2" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -37,6 +37,14 @@
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="cb8cb" class="javax.swing.JCheckBox" binding="myUseGroovycStubs">
<constraints>
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Use groovyc's native &amp;stub generator"/>
</properties>
</component>
</children>
</grid>
<grid id="4e3dc" binding="myExcludesPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
@@ -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();
}
@@ -36,11 +36,13 @@ import org.jdom.Element;
)
public class GroovyCompilerConfiguration implements PersistentStateComponent<GroovyCompilerConfiguration.MyStateBean>, 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<Gro
public void loadState(MyStateBean state) {
myHeapSize = state.heapSize;
final Element oldStyle = state.option.getChild("ExcludedEntriesConfiguration");
if (oldStyle != null) {
myExcludeFromStubGeneration.readExternal(oldStyle);
return;
}
myUseGroovycStubs = state.useGroovycStubs;
myExcludeFromStubGeneration.readExternal(state.excludes);
}
@@ -76,6 +74,14 @@ public class GroovyCompilerConfiguration implements PersistentStateComponent<Gro
myHeapSize = heapSize;
}
public boolean isUseGroovycStubs() {
return myUseGroovycStubs;
}
public void setUseGroovycStubs(boolean useGroovycStubs) {
myUseGroovycStubs = useGroovycStubs;
}
public void dispose() {
Disposer.dispose(myExcludeFromStubGeneration);
}
@@ -85,7 +91,7 @@ public class GroovyCompilerConfiguration implements PersistentStateComponent<Gro
@Tag("excludes") public Element excludes = new Element("aaa");
//todo remove after Maia beta
@Tag("option") public Element option = new Element("bbb");
public boolean useGroovycStubs = false;
}
}
@@ -41,15 +41,13 @@ public class GroovyCompilerLoader extends AbstractProjectComponent {
CompilerManager compilerManager = CompilerManager.getInstance(myProject);
compilerManager.addCompilableFileType(GroovyFileType.GROOVY_FILE_TYPE);
if (System.getProperty("use.groovyc.stub.generator", "true").equals("true")) {
compilerManager.addTranslatingCompiler(new GroovycStubGenerator(myProject),
new HashSet<FileType>(Arrays.asList(GroovyFileType.GROOVY_FILE_TYPE, StdFileTypes.JAVA)),
new HashSet<FileType>(Arrays.asList(StdFileTypes.JAVA)));
} else {
GroovyToJavaGenerator generator = new GroovyToJavaGenerator(myProject);
compilerManager.addCompiler(generator);
compilerManager.addCompilationStatusListener(generator);
}
compilerManager.addTranslatingCompiler(new GroovycStubGenerator(myProject),
new HashSet<FileType>(Arrays.asList(GroovyFileType.GROOVY_FILE_TYPE, StdFileTypes.JAVA)),
new HashSet<FileType>(Arrays.asList(StdFileTypes.JAVA)));
GroovyToJavaGenerator generator = new GroovyToJavaGenerator(myProject);
compilerManager.addCompiler(generator);
compilerManager.addCompilationStatusListener(generator);
compilerManager.addTranslatingCompiler(new GroovyCompiler(myProject),
new HashSet<FileType>(Arrays.asList(GroovyFileType.GROOVY_FILE_TYPE, StdFileTypes.CLASS)),
@@ -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<GenerationItem> generationItems = new ArrayList<GenerationItem>();
@@ -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<Module> 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));
}
@@ -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<? extends LibraryManager> 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);
}
}
});
@@ -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()
}
}
@@ -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<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 {
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<String> 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<JDOMExternalizable>(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<String> myMessages = new ArrayList<String>();
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<String> getMessages() {
return myMessages;
}
}
}
@@ -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<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;
}
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<String> 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<JDOMExternalizable>(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<String> myMessages = new ArrayList<String>();
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<String> getMessages() {
return myMessages;
}
}
}
@@ -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<SvnAuthentica
final Ref<Boolean> resultRef = new Ref<Boolean>();
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<SvnAuthentica
for (SVNURL key : keys) {
final SVNURL commonURLAncestor = SVNURLUtil.getCommonURLAncestor(key, obj.getUrl());
if ((! StringUtil.isEmptyOrSpaces(commonURLAncestor.getHost())) && (! StringUtil.isEmptyOrSpaces(commonURLAncestor.getPath()))) {
if (passiveValidation(myVcs.getProject(), key)) {
final AuthenticationRequest currObj = getObj(key);
if ((currObj != null) && passiveValidation(myVcs.getProject(), key, true, currObj.getRealm(), currObj.getKind())) {
outdatedRequests.add(key);
}
}
@@ -179,20 +182,22 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
LOG.debug(s);
}
public static boolean passiveValidation(final Project project, final SVNURL url) {
public static boolean passiveValidation(final Project project, final SVNURL url, final boolean checkWrite,
final String realm, final String kind) {
final SvnConfiguration configuration = SvnConfiguration.getInstance(project);
final ISVNAuthenticationManager passiveManager = configuration.getPassiveAuthenticationManager();
return validationImpl(project, url, configuration, passiveManager);
return validationImpl(project, url, configuration, passiveManager, checkWrite, realm, kind);
}
public static boolean interactiveValidation(final Project project, final SVNURL url) {
public static boolean interactiveValidation(final Project project, final SVNURL url, final String realm, final String kind) {
final SvnConfiguration configuration = SvnConfiguration.getInstance(project);
final ISVNAuthenticationManager passiveManager = configuration.getInteractiveManager(SvnVcs.getInstance(project));
return validationImpl(project, url, configuration, passiveManager);
return validationImpl(project, url, configuration, passiveManager, true, realm, kind);
}
private static boolean validationImpl(final Project project, final SVNURL url,
final SvnConfiguration configuration, final ISVNAuthenticationManager manager) {
final SvnConfiguration configuration, final ISVNAuthenticationManager manager,
final boolean checkWrite, final String realm, final String kind) {
try {
new SVNWCClient(manager, configuration.getOptions(project)).doInfo(url, SVNRevision.UNDEFINED, SVNRevision.HEAD);
} catch (SVNAuthenticationException e) {
@@ -207,8 +212,26 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
return false;
}
LOG.info("some other exc", e);
}
if ((! checkWrite) || configuration.haveCredentialsFor(kind, realm)) {
return true;
}
return true;
final SvnVcs svnVcs = SvnVcs.getInstance(project);
if (svnVcs.getAuthNotifier().getObj(url) != null) return false;
final SvnInteractiveAuthenticationProvider provider = new SvnInteractiveAuthenticationProvider(svnVcs);
final SVNAuthentication svnAuthentication = provider.requestClientAuthentication(kind, url, realm, null, null, true);
if (svnAuthentication != null) {
try {
configuration.getAuthenticationManager(svnVcs).acknowledgeAuthentication(true, kind, realm, null, svnAuthentication);
}
catch (SVNException e) {
LOG.info(e);
// acknowledge at least in runtime
configuration.acknowledge(kind, realm, svnAuthentication);
}
return true;
}
return false;
}
}
@@ -150,7 +150,7 @@ public class SvnBranchConfigurationManager implements PersistentStateComponent<S
final WorkingCopy wcRoot = rootsToWorkingCopies.getWcRoot(myRoot);
if (wcRoot == null) return;
final boolean validated = SvnAuthenticationNotifier.passiveValidation(myProject, wcRoot.getUrl());
final boolean validated = SvnAuthenticationNotifier.passiveValidation(myProject, wcRoot.getUrl(), false, null, null);
if (! validated) return;
for (String newBranchUrl : next.getBranchUrls()) {
@@ -443,4 +443,12 @@ public class SvnConfiguration implements ProjectComponent, JDOMExternalizable {
}, "button.text.clear.authentication.cache", false, myProject);
}
}
public boolean haveCredentialsFor(final String kind, final String realm) {
return RUNTIME_AUTH_CACHE.getData(kind, realm) != null;
}
public void acknowledge(final String kind, final String realm, final Object object) {
RUNTIME_AUTH_CACHE.putData(kind, realm, object);
}
}
@@ -166,8 +166,8 @@ public class SvnVcs extends AbstractVcs {
super(project, VCS_NAME);
LOG.debug("ct");
myRootsToWorkingCopies = new RootsToWorkingCopies(myProject);
myAuthNotifier = new SvnAuthenticationNotifier(this);
myConfiguration = svnConfiguration;
myAuthNotifier = new SvnAuthenticationNotifier(this);
dumpFileStatus(FileStatus.ADDED);
dumpFileStatus(FileStatus.DELETED);
+2
View File
@@ -182,6 +182,8 @@
<add-to-group group-id="RefactoringMenu" anchor="after" relative-to-action="ReplaceMethodWithMethodObject"/>
</action>
<action id="BuildAllArtifacts" class="com.intellij.compiler.actions.BuildAllArtifactsAction"/>
<group id="BuildMenu" popup="true">
<action id="CompileDirty" class="com.intellij.compiler.actions.CompileDirtyAction" icon="/actions/compile.png"/>
<action id="MakeModule" class="com.intellij.compiler.actions.MakeModuleAction"/>