From 5d19c56af2845b1d384ad4096cf7c478c9ae729f Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 16 Oct 2012 11:36:06 +0200 Subject: [PATCH 01/57] remove hard-coded non-standard jvm options --- .../impl/src/com/intellij/compiler/server/BuildManager.java | 4 ++-- .../com/intellij/compiler/CompilerWorkspaceConfiguration.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 50cd59e5b758..5c4f66307ede 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -720,8 +720,8 @@ public class BuildManager implements ApplicationComponent{ final GeneralCommandLine cmdLine = new GeneralCommandLine(); final String vmExecutablePath = ((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk); cmdLine.setExePath(vmExecutablePath); - cmdLine.addParameter("-XX:MaxPermSize=150m"); - cmdLine.addParameter("-XX:ReservedCodeCacheSize=64m"); + //cmdLine.addParameter("-XX:MaxPermSize=150m"); + //cmdLine.addParameter("-XX:ReservedCodeCacheSize=64m"); final int heapSize = config.COMPILER_PROCESS_HEAP_SIZE; final int xms = heapSize / 2; if (xms > 32) { diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java index 903bf499fb1b..520af37478f5 100644 --- a/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java +++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java @@ -39,7 +39,7 @@ public class CompilerWorkspaceConfiguration implements PersistentStateComponent< public boolean MAKE_PROJECT_ON_SAVE = false; public boolean PARALLEL_COMPILATION = false; public int COMPILER_PROCESS_HEAP_SIZE = 700; - public String COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS = ""; + public String COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS = "-XX:MaxPermSize=150m"; public static CompilerWorkspaceConfiguration getInstance(Project project) { return ServiceManager.getService(project, CompilerWorkspaceConfiguration.class); From 5433f475e90cb3ef4751bcb765b083fe725deecf Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 16 Oct 2012 11:36:54 +0200 Subject: [PATCH 02/57] default directory for generated stuff --- jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java index c3078ed4789d..ba752157c796 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java +++ b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java @@ -174,7 +174,7 @@ public class ProjectPaths { if (parentFile == null) { return null; } - return new File(parentFile, outputDir.getName() + "_" + DEFAULT_GENERATED_DIR_NAME); + return new File(parentFile, DEFAULT_GENERATED_DIR_NAME); } private enum ClasspathPart {WHOLE, BEFORE_JDK, AFTER_JDK} From 5b5aa87a9bd22942478278d45c7e878b1fdae7bb Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Tue, 16 Oct 2012 15:30:11 +0400 Subject: [PATCH 03/57] RUBY-10872: CapturingProcessAdapter should set process exit code to ProcessOutput --- .../intellij/execution/process/CapturingProcessAdapter.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/platform-api/src/com/intellij/execution/process/CapturingProcessAdapter.java b/platform/platform-api/src/com/intellij/execution/process/CapturingProcessAdapter.java index d0fc159abad1..c3de67d40927 100644 --- a/platform/platform-api/src/com/intellij/execution/process/CapturingProcessAdapter.java +++ b/platform/platform-api/src/com/intellij/execution/process/CapturingProcessAdapter.java @@ -16,6 +16,7 @@ package com.intellij.execution.process; import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; /** * @author traff @@ -41,6 +42,11 @@ public class CapturingProcessAdapter extends ProcessAdapter { } } + @Override + public void processTerminated(@NotNull final ProcessEvent event) { + myOutput.setExitCode(event.getExitCode()); + } + public ProcessOutput getOutput() { return myOutput; } From e20b54bc7cbcfb243262621eddb0a34557753204 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Tue, 16 Oct 2012 15:31:50 +0400 Subject: [PATCH 04/57] RUBY-10872: fixed ProcessOutput.checkSuccess() to be compliant with its javadoc --- .../src/com/intellij/execution/process/ProcessOutput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/execution/process/ProcessOutput.java b/platform/platform-api/src/com/intellij/execution/process/ProcessOutput.java index 8260200733c5..6fb27bccacea 100644 --- a/platform/platform-api/src/com/intellij/execution/process/ProcessOutput.java +++ b/platform/platform-api/src/com/intellij/execution/process/ProcessOutput.java @@ -90,7 +90,7 @@ public class ProcessOutput { * @return true iff exit code is zero */ public boolean checkSuccess(@NotNull final Logger logger) { - if (getExitCode() != 0) { + if (getExitCode() != 0 || isTimeout()) { logger.info(getStderr() + (isTimeout()? "\nTimed out" : "\nExit code " + getExitCode())); return false; } From 1bb0a61340720d2416d03395ef0cd7f7d2b78b25 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 16 Oct 2012 15:39:10 +0400 Subject: [PATCH 05/57] avoid ModuleBuilder duplication (seemingly fixes Maven and Android problem) --- .../newProjectWizard/modes/CreateFromScratchMode.java | 10 ++++++---- .../newProjectWizard/modes/CreateFromTemplateMode.java | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java index 1874404a7fbb..14ca759786ee 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java @@ -35,6 +35,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; +import java.util.List; import java.util.Map; public class CreateFromScratchMode extends WizardMode { @@ -53,19 +54,20 @@ public class CreateFromScratchMode extends WizardMode { @Nullable protected StepSequence createSteps(final WizardContext context, @NotNull final ModulesProvider modulesProvider) { - for (ModuleBuilder builder : ModuleBuilder.getAllBuilders()) { + List builders = ModuleBuilder.getAllBuilders(); + for (ModuleBuilder builder : builders) { myBuildersMap.put(builder.getBuilderId(), builder); } myBuildersMap.put(ModuleType.EMPTY.getId(), new EmptyModuleBuilder()); - return addSteps(context, modulesProvider, this, new StepSequence()); + return addSteps(context, modulesProvider, this, new StepSequence(), builders); } static StepSequence addSteps(WizardContext context, ModulesProvider modulesProvider, WizardMode mode, - StepSequence sequence) { + StepSequence sequence, List builders) { sequence.addCommonStep(new ProjectNameWithTypeStep(context, sequence, mode)); - for (ModuleBuilder builder : ModuleBuilder.getAllBuilders()) { + for (ModuleBuilder builder : builders) { addModuleBuilder(builder, context, modulesProvider, sequence); } return sequence; diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java index ec5e18e76afc..221400e9a58c 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java @@ -56,7 +56,7 @@ public class CreateFromTemplateMode extends WizardMode { StepSequence sequence = new StepSequence(); mySelectTemplateStep = new SelectTemplateStep(context, sequence); sequence.addCommonStep(mySelectTemplateStep); - return CreateFromScratchMode.addSteps(context, modulesProvider, this, sequence); + return CreateFromScratchMode.addSteps(context, modulesProvider, this, sequence, ModuleBuilder.getAllBuilders()); } @Nullable From 0bfcc29db78b5990340f8262b734bdc1faac8a9e Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 16 Oct 2012 15:58:41 +0400 Subject: [PATCH 06/57] jps model: run configurations supported --- .../org/jetbrains/jps/model/JpsProject.java | 10 + .../model/java/JpsJavaExtensionService.java | 5 + ...ApplicationRunConfigurationProperties.java | 11 ++ .../JpsApplicationRunConfigurationState.java | 8 + .../JpsApplicationRunConfigurationType.java | 13 ++ .../runConfiguration/JpsRunConfiguration.java | 14 ++ .../JpsRunConfigurationType.java | 10 + .../JpsTypedRunConfiguration.java | 17 ++ .../jps/model/impl/JpsProjectImpl.java | 24 +++ .../JpsRunConfigurationImpl.java | 43 +++++ .../impl/JpsJavaExtensionServiceImpl.java | 9 + ...icationRunConfigurationPropertiesImpl.java | 39 ++++ .../JpsModelSerializerExtension.java | 6 + .../model/serialization/JpsProjectLoader.java | 29 ++- ...ApplicationRunConfigurationSerializer.java | 32 +++ .../library/JpsLibraryTableSerializer.java | 2 +- ...sRunConfigurationPropertiesSerializer.java | 20 ++ .../JpsRunConfigurationSerializer.java | 46 +++++ .../run-configurations-dir/.idea/misc.xml | 7 + .../run-configurations-dir/.idea/modules.xml | 9 + .../.idea/runConfigurations/shared.xml | 17 ++ .../.idea/runConfigurations/test.xml | 23 +++ .../.idea/workspace.xml | 182 ++++++++++++++++++ .../run-configurations.iml | 12 ++ .../run-configurations/run-configurations.iml | 12 ++ .../run-configurations/run-configurations.ipr | 50 +++++ .../run-configurations/run-configurations.iws | 169 ++++++++++++++++ ....serialization.JpsModelSerializerExtension | 1 + ...JpsRunConfigurationsSerializationTest.java | 36 ++++ .../JpsTestSerializerExtension.java | 19 ++ 30 files changed, 872 insertions(+), 3 deletions(-) create mode 100644 jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationProperties.java create mode 100644 jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationState.java create mode 100644 jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java create mode 100644 jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfiguration.java create mode 100644 jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java create mode 100644 jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsTypedRunConfiguration.java create mode 100644 jps/model-impl/src/org/jetbrains/jps/model/impl/runConfiguration/JpsRunConfigurationImpl.java create mode 100644 jps/model-impl/src/org/jetbrains/jps/model/java/impl/runConfiguration/JpsApplicationRunConfigurationPropertiesImpl.java create mode 100644 jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsApplicationRunConfigurationSerializer.java create mode 100644 jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationPropertiesSerializer.java create mode 100644 jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java create mode 100644 jps/model-serialization/testData/run-configurations-dir/.idea/misc.xml create mode 100644 jps/model-serialization/testData/run-configurations-dir/.idea/modules.xml create mode 100644 jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/shared.xml create mode 100644 jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/test.xml create mode 100644 jps/model-serialization/testData/run-configurations-dir/.idea/workspace.xml create mode 100644 jps/model-serialization/testData/run-configurations-dir/run-configurations.iml create mode 100644 jps/model-serialization/testData/run-configurations/run-configurations.iml create mode 100644 jps/model-serialization/testData/run-configurations/run-configurations.ipr create mode 100644 jps/model-serialization/testData/run-configurations/run-configurations.iws create mode 100644 jps/model-serialization/testSrc/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension create mode 100644 jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsRunConfigurationsSerializationTest.java create mode 100644 jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsTestSerializerExtension.java diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java b/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java index 35e55502bf85..709bdab57eed 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java @@ -8,6 +8,8 @@ import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleType; import org.jetbrains.jps.model.module.JpsSdkReferencesTable; import org.jetbrains.jps.model.module.JpsTypedModule; +import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType; +import org.jetbrains.jps.model.runConfiguration.JpsTypedRunConfiguration; import java.util.List; @@ -38,4 +40,12 @@ public interface JpsProject extends JpsCompositeElement, JpsReferenceableElement @NotNull JpsSdkReferencesTable getSdkReferencesTable(); + + @NotNull +

+ Iterable> getRunConfigurations(JpsRunConfigurationType

type); + + @NotNull +

+ JpsTypedRunConfiguration

addRunConfiguration(@NotNull String name, @NotNull JpsRunConfigurationType

type, @NotNull P properties); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java index 8484a678ebfa..63e3d0534db0 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java @@ -6,6 +6,8 @@ import org.jetbrains.jps.model.JpsDummyElement; import org.jetbrains.jps.model.JpsGlobal; import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationProperties; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationState; import org.jetbrains.jps.model.library.JpsTypedLibrary; import org.jetbrains.jps.model.library.sdk.JpsSdk; import org.jetbrains.jps.model.library.sdk.JpsSdkReference; @@ -95,4 +97,7 @@ public abstract class JpsJavaExtensionService { @NotNull public abstract JpsSdkReference createWrappedJavaSdkReference(@NotNull JpsJavaSdkTypeWrapper sdkType, @NotNull JpsSdkReference wrapperReference); + + @NotNull + public abstract JpsApplicationRunConfigurationProperties createRunConfigurationProperties(JpsApplicationRunConfigurationState state); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationProperties.java b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationProperties.java new file mode 100644 index 000000000000..d7e5c43e366f --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationProperties.java @@ -0,0 +1,11 @@ +package org.jetbrains.jps.model.java.runConfiguration; + +import org.jetbrains.jps.model.JpsElement; + +/** + * @author nik + */ +public interface JpsApplicationRunConfigurationProperties extends JpsElement { + String getMainClass(); + void setMainClass(String value); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationState.java b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationState.java new file mode 100644 index 000000000000..2aca5634df18 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationState.java @@ -0,0 +1,8 @@ +package org.jetbrains.jps.model.java.runConfiguration; + +/** +* @author nik +*/ +public class JpsApplicationRunConfigurationState { + public String MAIN_CLASS_NAME; +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java new file mode 100644 index 000000000000..be6913abeb7b --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/runConfiguration/JpsApplicationRunConfigurationType.java @@ -0,0 +1,13 @@ +package org.jetbrains.jps.model.java.runConfiguration; + +import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType; + +/** + * @author nik + */ +public class JpsApplicationRunConfigurationType extends JpsRunConfigurationType { + public static final JpsApplicationRunConfigurationType INSTANCE = new JpsApplicationRunConfigurationType(); + + private JpsApplicationRunConfigurationType() { + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfiguration.java b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfiguration.java new file mode 100644 index 000000000000..76174fd3d51d --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfiguration.java @@ -0,0 +1,14 @@ +package org.jetbrains.jps.model.runConfiguration; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.JpsNamedElement; + +/** + * @author nik + */ +public interface JpsRunConfiguration extends JpsNamedElement, JpsCompositeElement { + @NotNull + JpsElement getProperties(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java new file mode 100644 index 000000000000..aff1b8759e2e --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsRunConfigurationType.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model.runConfiguration; + +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.JpsElementType; + +/** + * @author nik + */ +public abstract class JpsRunConfigurationType

extends JpsElementType

{ +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsTypedRunConfiguration.java b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsTypedRunConfiguration.java new file mode 100644 index 000000000000..ac93c8a5f5c7 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/runConfiguration/JpsTypedRunConfiguration.java @@ -0,0 +1,17 @@ +package org.jetbrains.jps.model.runConfiguration; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.JpsTypedElement; + +/** + * @author nik + */ +public interface JpsTypedRunConfiguration

extends JpsRunConfiguration, JpsTypedElement

{ + @NotNull + @Override + P getProperties(); + + @Override + JpsRunConfigurationType

getType(); +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java index 0bece2444bc1..9c8b7dfaf880 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.*; import org.jetbrains.jps.model.ex.JpsElementChildRoleBase; import org.jetbrains.jps.model.ex.JpsElementCollectionRole; +import org.jetbrains.jps.model.impl.runConfiguration.JpsRunConfigurationImpl; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsLibraryCollection; import org.jetbrains.jps.model.library.JpsLibraryType; @@ -16,6 +17,9 @@ import org.jetbrains.jps.model.module.JpsTypedModule; import org.jetbrains.jps.model.module.impl.JpsModuleImpl; import org.jetbrains.jps.model.module.impl.JpsModuleRole; import org.jetbrains.jps.model.module.impl.JpsSdkReferencesTableImpl; +import org.jetbrains.jps.model.runConfiguration.JpsRunConfiguration; +import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType; +import org.jetbrains.jps.model.runConfiguration.JpsTypedRunConfiguration; import java.util.List; @@ -25,6 +29,7 @@ import java.util.List; public class JpsProjectImpl extends JpsRootElementBase implements JpsProject { private static final JpsElementCollectionRole> EXTERNAL_REFERENCES_COLLECTION_ROLE = JpsElementCollectionRole.create(JpsElementChildRoleBase.>create("external reference")); + private static final JpsElementCollectionRole RUN_CONFIGURATIONS_ROLE = JpsElementCollectionRole.create(JpsElementChildRoleBase.create("run configuration")); private final JpsLibraryCollection myLibraryCollection; public JpsProjectImpl(JpsModel model, JpsEventDispatcher eventDispatcher) { @@ -32,6 +37,7 @@ public class JpsProjectImpl extends JpsRootElementBase implement myContainer.setChild(JpsModuleRole.MODULE_COLLECTION_ROLE); myContainer.setChild(EXTERNAL_REFERENCES_COLLECTION_ROLE); myContainer.setChild(JpsSdkReferencesTableImpl.ROLE); + myContainer.setChild(RUN_CONFIGURATIONS_ROLE); myLibraryCollection = new JpsLibraryCollectionImpl(myContainer.setChild(JpsLibraryRole.LIBRARIES_COLLECTION_ROLE)); } @@ -89,6 +95,24 @@ public class JpsProjectImpl extends JpsRootElementBase implement return myContainer.getChild(JpsSdkReferencesTableImpl.ROLE); } + @NotNull + @Override + public

Iterable> getRunConfigurations(JpsRunConfigurationType

type) { + return getRunConfigurationsCollection().getElementsOfType(type); + } + + @NotNull + @Override + public

JpsTypedRunConfiguration

addRunConfiguration(@NotNull String name, + @NotNull JpsRunConfigurationType

type, + @NotNull P properties) { + return getRunConfigurationsCollection().addChild(new JpsRunConfigurationImpl

(name, type, properties)); + } + + private JpsElementCollection getRunConfigurationsCollection() { + return myContainer.getChild(RUN_CONFIGURATIONS_ROLE); + } + @NotNull @Override public JpsElementReference createReference() { diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/runConfiguration/JpsRunConfigurationImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/runConfiguration/JpsRunConfigurationImpl.java new file mode 100644 index 000000000000..de7f031abeed --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/runConfiguration/JpsRunConfigurationImpl.java @@ -0,0 +1,43 @@ +package org.jetbrains.jps.model.impl.runConfiguration; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.ex.JpsNamedCompositeElementBase; +import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType; +import org.jetbrains.jps.model.runConfiguration.JpsTypedRunConfiguration; + +/** + * @author nik + */ +public class JpsRunConfigurationImpl

extends JpsNamedCompositeElementBase> implements + JpsTypedRunConfiguration

{ + private final JpsRunConfigurationType

myType; + + public JpsRunConfigurationImpl(@NotNull String name, JpsRunConfigurationType

type, P properties) { + super(name); + myType = type; + myContainer.setChild(myType.getPropertiesRole(), properties); + } + + private JpsRunConfigurationImpl(JpsRunConfigurationImpl

original) { + super(original); + myType = original.myType; + } + + @NotNull + @Override + public JpsRunConfigurationImpl

createCopy() { + return new JpsRunConfigurationImpl

(this); + } + + @NotNull + @Override + public P getProperties() { + return myContainer.getChild(myType.getPropertiesRole()); + } + + @Override + public JpsRunConfigurationType

getType() { + return myType; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java index 610739b05d3c..2809b79a5fbd 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java @@ -3,6 +3,9 @@ package org.jetbrains.jps.model.java.impl; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.java.impl.runConfiguration.JpsApplicationRunConfigurationPropertiesImpl; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationProperties; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationState; import org.jetbrains.jps.util.JpsPathUtil; import org.jetbrains.jps.model.JpsDummyElement; import org.jetbrains.jps.model.JpsGlobal; @@ -152,6 +155,12 @@ public class JpsJavaExtensionServiceImpl extends JpsJavaExtensionService { return new JpsWrappedJavaSdkReferenceImpl(sdkType, wrapperReference); } + @NotNull + @Override + public JpsApplicationRunConfigurationProperties createRunConfigurationProperties(JpsApplicationRunConfigurationState state) { + return new JpsApplicationRunConfigurationPropertiesImpl(state); + } + @Override @NotNull public JpsProductionModuleOutputPackagingElement createProductionModuleOutput(@NotNull JpsModuleReference moduleReference) { diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/runConfiguration/JpsApplicationRunConfigurationPropertiesImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/runConfiguration/JpsApplicationRunConfigurationPropertiesImpl.java new file mode 100644 index 000000000000..57b61c017aed --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/runConfiguration/JpsApplicationRunConfigurationPropertiesImpl.java @@ -0,0 +1,39 @@ +package org.jetbrains.jps.model.java.impl.runConfiguration; + +import com.intellij.util.xmlb.XmlSerializerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.ex.JpsElementBase; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationProperties; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationState; + +/** + * @author nik + */ +public class JpsApplicationRunConfigurationPropertiesImpl extends JpsElementBase implements JpsApplicationRunConfigurationProperties { + private JpsApplicationRunConfigurationState myState; + + public JpsApplicationRunConfigurationPropertiesImpl(JpsApplicationRunConfigurationState state) { + myState = state; + } + + @NotNull + @Override + public JpsApplicationRunConfigurationPropertiesImpl createCopy() { + return new JpsApplicationRunConfigurationPropertiesImpl(XmlSerializerUtil.createCopy(myState)); + } + + @Override + public void applyChanges(@NotNull JpsApplicationRunConfigurationPropertiesImpl modified) { + XmlSerializerUtil.copyBean(modified.myState, myState); + } + + @Override + public String getMainClass() { + return myState.MAIN_CLASS_NAME; + } + + @Override + public void setMainClass(String value) { + myState.MAIN_CLASS_NAME = value; + } +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java index 10e5e6fe7846..11f68f5fef87 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java @@ -15,6 +15,7 @@ import org.jetbrains.jps.model.serialization.library.JpsLibraryRootTypeSerialize import org.jetbrains.jps.model.serialization.library.JpsSdkPropertiesSerializer; import org.jetbrains.jps.model.serialization.module.JpsModuleClasspathSerializer; import org.jetbrains.jps.model.serialization.module.JpsModulePropertiesSerializer; +import org.jetbrains.jps.model.serialization.runConfigurations.JpsRunConfigurationPropertiesSerializer; import org.jetbrains.jps.service.JpsServiceManager; import java.util.Collections; @@ -106,4 +107,9 @@ public abstract class JpsModelSerializerExtension { public JpsModuleClasspathSerializer getClasspathSerializer() { return null; } + + @NotNull + public List> getRunConfigurationPropertiesSerializers() { + return Collections.emptyList(); + } } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java index 95e03d399cbe..b70f3917447c 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java @@ -21,6 +21,7 @@ import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer; import org.jetbrains.jps.model.serialization.module.JpsModuleClasspathSerializer; import org.jetbrains.jps.model.serialization.module.JpsModulePropertiesSerializer; import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; +import org.jetbrains.jps.model.serialization.runConfigurations.JpsRunConfigurationSerializer; import org.jetbrains.jps.service.SharedThreadPool; import java.io.File; @@ -88,6 +89,26 @@ public class JpsProjectLoader extends JpsLoaderBase { for (File artifactFile : listXmlFiles(new File(dir, "artifacts"))) { loadArtifacts(loadRootElement(artifactFile)); } + + if (hasRunConfigurationSerializers()) { + for (File configurationFile : listXmlFiles(new File(dir, "runConfigurations"))) { + JpsRunConfigurationSerializer.loadRunConfigurations(myProject, loadRootElement(configurationFile)); + } + File workspaceFile = new File(dir, "workspace.xml"); + if (workspaceFile.exists()) { + Element runManager = JDomSerializationUtil.findComponent(loadRootElement(workspaceFile), "RunManager"); + JpsRunConfigurationSerializer.loadRunConfigurations(myProject, runManager); + } + } + } + + private static boolean hasRunConfigurationSerializers() { + for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { + if (!extension.getRunConfigurationPropertiesSerializers().isEmpty()) { + return true; + } + } + return false; } @NotNull @@ -120,9 +141,13 @@ public class JpsProjectLoader extends JpsLoaderBase { loadModules(iprRoot, projectSdkType); loadProjectLibraries(JDomSerializationUtil.findComponent(iprRoot, "libraryTable")); loadArtifacts(JDomSerializationUtil.findComponent(iprRoot, "ArtifactManager")); + if (hasRunConfigurationSerializers()) { + JpsRunConfigurationSerializer.loadRunConfigurations(myProject, JDomSerializationUtil.findComponent(iprRoot, "ProjectRunConfigurationManager")); + JpsRunConfigurationSerializer.loadRunConfigurations(myProject, JDomSerializationUtil.findComponent(iwsRoot, "RunManager")); + } } - private void loadArtifacts(Element artifactManagerComponent) { + private void loadArtifacts(@Nullable Element artifactManagerComponent) { JpsArtifactSerializer.loadArtifacts(myProject, artifactManagerComponent); } @@ -141,7 +166,7 @@ public class JpsProjectLoader extends JpsLoaderBase { return sdkType; } - private void loadProjectLibraries(Element libraryTableElement) { + private void loadProjectLibraries(@Nullable Element libraryTableElement) { JpsLibraryTableSerializer.loadLibraries(libraryTableElement, myProject.getLibraryCollection()); } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsApplicationRunConfigurationSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsApplicationRunConfigurationSerializer.java new file mode 100644 index 000000000000..e2d135968def --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsApplicationRunConfigurationSerializer.java @@ -0,0 +1,32 @@ +package org.jetbrains.jps.model.serialization.java; + +import com.intellij.util.xmlb.XmlSerializer; +import org.jdom.Element; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.java.JpsJavaExtensionService; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationProperties; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationState; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationType; +import org.jetbrains.jps.model.serialization.runConfigurations.JpsRunConfigurationPropertiesSerializer; + +/** + * Currently java run configurations aren't used in external compiler so this serializer is registered for tests only for performance reasons + * + * @author nik + */ +public class JpsApplicationRunConfigurationSerializer extends JpsRunConfigurationPropertiesSerializer { + public JpsApplicationRunConfigurationSerializer() { + super(JpsApplicationRunConfigurationType.INSTANCE, "Application"); + } + + @Override + public JpsApplicationRunConfigurationProperties loadProperties(@Nullable Element runConfigurationTag) { + JpsApplicationRunConfigurationState properties = runConfigurationTag != null ? + XmlSerializer.deserialize(runConfigurationTag, JpsApplicationRunConfigurationState.class) : new JpsApplicationRunConfigurationState(); + return JpsJavaExtensionService.getInstance().createRunConfigurationProperties(properties != null ? properties : new JpsApplicationRunConfigurationState()); + } + + @Override + public void saveProperties(JpsApplicationRunConfigurationProperties properties, Element runConfigurationTag) { + } +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryTableSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryTableSerializer.java index 50f99e6864ff..a65c3fdd06cc 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryTableSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryTableSerializer.java @@ -45,7 +45,7 @@ public class JpsLibraryTableSerializer { private static final String PROJECT_LEVEL = "project"; private static final String APPLICATION_LEVEL = "application"; - public static void loadLibraries(Element libraryTableElement, JpsLibraryCollection result) { + public static void loadLibraries(@Nullable Element libraryTableElement, JpsLibraryCollection result) { for (Element libraryElement : JDOMUtil.getChildren(libraryTableElement, LIBRARY_TAG)) { result.addLibrary(loadLibrary(libraryElement)); } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationPropertiesSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationPropertiesSerializer.java new file mode 100644 index 000000000000..934f058dc980 --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationPropertiesSerializer.java @@ -0,0 +1,20 @@ +package org.jetbrains.jps.model.serialization.runConfigurations; + +import org.jdom.Element; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType; +import org.jetbrains.jps.model.serialization.JpsElementPropertiesSerializer; + +/** + * @author nik + */ +public abstract class JpsRunConfigurationPropertiesSerializer

extends JpsElementPropertiesSerializer> { + protected JpsRunConfigurationPropertiesSerializer(JpsRunConfigurationType

type, String typeId) { + super(type, typeId); + } + + public abstract P loadProperties(@Nullable Element runConfigurationTag); + + public abstract void saveProperties(P properties, Element runConfigurationTag); +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java new file mode 100644 index 000000000000..a01b22531623 --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java @@ -0,0 +1,46 @@ +package org.jetbrains.jps.model.serialization.runConfigurations; + +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.util.containers.hash.HashMap; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; + +import java.util.Map; + +/** + * @author nik + */ +public class JpsRunConfigurationSerializer { + public static void loadRunConfigurations(@NotNull JpsProject project, @Nullable Element runManagerTag) { + Map> serializers = new HashMap>(); + for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { + for (JpsRunConfigurationPropertiesSerializer serializer : extension.getRunConfigurationPropertiesSerializers()) { + serializers.put(serializer.getTypeId(), serializer); + } + } + + for (Element configurationTag : JDOMUtil.getChildren(runManagerTag, "configuration")) { + if (Boolean.parseBoolean(configurationTag.getAttributeValue("default"))) { + continue; + } + + String typeId = configurationTag.getAttributeValue("type"); + JpsRunConfigurationPropertiesSerializer serializer = serializers.get(typeId); + if (serializer != null) { + loadRunConfiguration(configurationTag, serializer, project); + } + } + } + + private static

void loadRunConfiguration(Element configurationTag, + JpsRunConfigurationPropertiesSerializer

serializer, + JpsProject project) { + P properties = serializer.loadProperties(configurationTag); + project.addRunConfiguration(configurationTag.getAttributeValue("name"), serializer.getType(), properties); + + } +} diff --git a/jps/model-serialization/testData/run-configurations-dir/.idea/misc.xml b/jps/model-serialization/testData/run-configurations-dir/.idea/misc.xml new file mode 100644 index 000000000000..94bc8fc64a28 --- /dev/null +++ b/jps/model-serialization/testData/run-configurations-dir/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/jps/model-serialization/testData/run-configurations-dir/.idea/modules.xml b/jps/model-serialization/testData/run-configurations-dir/.idea/modules.xml new file mode 100644 index 000000000000..29d91f22949a --- /dev/null +++ b/jps/model-serialization/testData/run-configurations-dir/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/shared.xml b/jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/shared.xml new file mode 100644 index 000000000000..10ef6ba27c3b --- /dev/null +++ b/jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/shared.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/test.xml b/jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/test.xml new file mode 100644 index 000000000000..189abcb66b1d --- /dev/null +++ b/jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/test.xml @@ -0,0 +1,23 @@ + + + + + + + + + + \ No newline at end of file diff --git a/jps/model-serialization/testData/run-configurations-dir/.idea/workspace.xml b/jps/model-serialization/testData/run-configurations-dir/.idea/workspace.xml new file mode 100644 index 000000000000..83beffbead44 --- /dev/null +++ b/jps/model-serialization/testData/run-configurations-dir/.idea/workspace.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + diff --git a/jps/model-serialization/testData/run-configurations-dir/run-configurations.iml b/jps/model-serialization/testData/run-configurations-dir/run-configurations.iml new file mode 100644 index 000000000000..d5c074327501 --- /dev/null +++ b/jps/model-serialization/testData/run-configurations-dir/run-configurations.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jps/model-serialization/testData/run-configurations/run-configurations.iml b/jps/model-serialization/testData/run-configurations/run-configurations.iml new file mode 100644 index 000000000000..d5c074327501 --- /dev/null +++ b/jps/model-serialization/testData/run-configurations/run-configurations.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jps/model-serialization/testData/run-configurations/run-configurations.ipr b/jps/model-serialization/testData/run-configurations/run-configurations.ipr new file mode 100644 index 000000000000..93c6bd97232b --- /dev/null +++ b/jps/model-serialization/testData/run-configurations/run-configurations.ipr @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jps/model-serialization/testData/run-configurations/run-configurations.iws b/jps/model-serialization/testData/run-configurations/run-configurations.iws new file mode 100644 index 000000000000..9a6aefa67f30 --- /dev/null +++ b/jps/model-serialization/testData/run-configurations/run-configurations.iws @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jps/model-serialization/testSrc/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension b/jps/model-serialization/testSrc/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension new file mode 100644 index 000000000000..5d950b5e2031 --- /dev/null +++ b/jps/model-serialization/testSrc/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension @@ -0,0 +1 @@ +org.jetbrains.jps.model.serialization.JpsTestSerializerExtension \ No newline at end of file diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsRunConfigurationsSerializationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsRunConfigurationsSerializationTest.java new file mode 100644 index 000000000000..894e5ee6f8d8 --- /dev/null +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsRunConfigurationsSerializationTest.java @@ -0,0 +1,36 @@ +package org.jetbrains.jps.model.serialization; + +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationProperties; +import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationType; +import org.jetbrains.jps.model.runConfiguration.JpsTypedRunConfiguration; + +import java.util.List; + +/** + * @author nik + */ +public class JpsRunConfigurationsSerializationTest extends JpsSerializationTestCase { + public void testLoadIpr() { + doTest("jps/model-serialization/testData/run-configurations/run-configurations.ipr"); + } + + public void testLoadDirectoryBased() { + doTest("jps/model-serialization/testData/run-configurations-dir"); + } + + private void doTest(final String relativePath) { + loadProject(relativePath); + List> + configurations = ContainerUtil.newArrayList(myProject.getRunConfigurations(JpsApplicationRunConfigurationType.INSTANCE)); + assertEquals(2, configurations.size()); + + JpsTypedRunConfiguration shared = configurations.get(0); + assertEquals("shared", shared.getName()); + assertEquals("xxx.Main2", shared.getProperties().getMainClass()); + + JpsTypedRunConfiguration main = configurations.get(1); + assertEquals("Main", main.getName()); + assertEquals("xxx.Main", main.getProperties().getMainClass()); + } +} diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsTestSerializerExtension.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsTestSerializerExtension.java new file mode 100644 index 000000000000..745a53ba9e39 --- /dev/null +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsTestSerializerExtension.java @@ -0,0 +1,19 @@ +package org.jetbrains.jps.model.serialization; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.serialization.java.JpsApplicationRunConfigurationSerializer; +import org.jetbrains.jps.model.serialization.runConfigurations.JpsRunConfigurationPropertiesSerializer; + +import java.util.Collections; +import java.util.List; + +/** + * @author nik + */ +public class JpsTestSerializerExtension extends JpsModelSerializerExtension { + @NotNull + @Override + public List> getRunConfigurationPropertiesSerializers() { + return Collections.singletonList(new JpsApplicationRunConfigurationSerializer()); + } +} From 33fc1f427cd99df7750798f381b85956a0b71c36 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 16 Oct 2012 16:26:44 +0400 Subject: [PATCH 07/57] IDEA-60774 target/generated-sources/annotations and target/generated-sources/test-annotations should be specially handled for maven 2 projects (Configure test-annotation output on reimport) --- .../maven/importing/MavenModuleImporter.java | 24 ++++++++++++++----- .../idea/maven/project/MavenProject.java | 2 +- .../AnnotationProcessorImportingTest.groovy | 1 + 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java index a44a1cd2dd45..64fb51cb8053 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java @@ -60,6 +60,8 @@ public class MavenModuleImporter { public static final String MAVEN_DEFAULT_ANNOTATION_PROFILE = "Maven default annotation processors profile"; public static final String SUREFIRE_PLUGIN_LIBRARY_NAME = "maven-surefire-plugin urls"; + public static final String DEFAULT_ANNOTATION_PATH_OUTPUT = "target/generated-sources/annotations"; + public static final String DEFAULT_TEST_ANNOTATION_OUTPUT = "target/generated-test-sources/test-annotations"; private final Module myModule; private final MavenProjectsTree myMavenTree; @@ -337,16 +339,24 @@ public class MavenModuleImporter { ProcessorConfigProfile defaultMavenProfile = compilerConfiguration.findModuleProcessorProfile(MAVEN_DEFAULT_ANNOTATION_PROFILE); if (shouldEnableAnnotationProcessors()) { - String annotationProcessorDirectory = getRelativeAnnotationProcessorDirectory(); + String annotationProcessorDirectory = getRelativeAnnotationProcessorDirectory(false); if (annotationProcessorDirectory == null) { - annotationProcessorDirectory = "target/generated-sources/annotations"; + annotationProcessorDirectory = DEFAULT_ANNOTATION_PATH_OUTPUT; + } + + String testAnnotationProcessorDirectory = getRelativeAnnotationProcessorDirectory(true); + if (testAnnotationProcessorDirectory == null) { + testAnnotationProcessorDirectory = DEFAULT_TEST_ANNOTATION_OUTPUT; } Map options = myMavenProject.getAnnotationProcessorOptions(); List processors = myMavenProject.getDeclaredAnnotationProcessors(); - if (processors == null && options.isEmpty() && "target/generated-sources/annotations".equals(annotationProcessorDirectory.replace('\\', '/'))) { + if (processors == null + && options.isEmpty() + && DEFAULT_ANNOTATION_PATH_OUTPUT.equals(annotationProcessorDirectory.replace('\\', '/')) + && DEFAULT_TEST_ANNOTATION_OUTPUT.equals(testAnnotationProcessorDirectory.replace('\\', '/'))) { if (moduleProfile != null) { compilerConfiguration.removeModuleProcessorProfile(moduleProfile); } @@ -355,7 +365,8 @@ public class MavenModuleImporter { defaultMavenProfile = new ProcessorConfigProfileImpl(MAVEN_DEFAULT_ANNOTATION_PROFILE); defaultMavenProfile.setEnabled(true); defaultMavenProfile.setObtainProcessorsFromClasspath(true); - defaultMavenProfile.setGeneratedSourcesDirectoryName("target/generated-sources/annotations", false); + defaultMavenProfile.setGeneratedSourcesDirectoryName(DEFAULT_ANNOTATION_PATH_OUTPUT, false); + defaultMavenProfile.setGeneratedSourcesDirectoryName(DEFAULT_TEST_ANNOTATION_OUTPUT, true); compilerConfiguration.addModuleProcessorProfile(defaultMavenProfile); } @@ -379,6 +390,7 @@ public class MavenModuleImporter { } moduleProfile.setGeneratedSourcesDirectoryName(annotationProcessorDirectory, false); + moduleProfile.setGeneratedSourcesDirectoryName(testAnnotationProcessorDirectory, true); moduleProfile.clearProcessorOptions(); for (Map.Entry entry : options.entrySet()) { @@ -410,8 +422,8 @@ public class MavenModuleImporter { } @Nullable - private String getRelativeAnnotationProcessorDirectory() { - String absoluteAnnotationProcessorDirectory = myMavenProject.getAnnotationProcessorDirectory(false); + private String getRelativeAnnotationProcessorDirectory(boolean isTest) { + String absoluteAnnotationProcessorDirectory = myMavenProject.getAnnotationProcessorDirectory(isTest); String absoluteProjectDirectory = myMavenProject.getDirectory(); return FileUtil.getRelativePath(new File(absoluteProjectDirectory), new File(absoluteAnnotationProcessorDirectory)); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java index 4a5445afea8e..5a5ad6ab3607 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java @@ -357,7 +357,7 @@ public class MavenProject { @NotNull public String getAnnotationProcessorDirectory(boolean testSources) { - String def = getGeneratedSourcesDirectory(false) + (testSources ? "/test-annotations" : "/annotations"); + String def = getGeneratedSourcesDirectory(testSources) + (testSources ? "/test-annotations" : "/annotations"); return MavenJDOMUtil.findChildValueByPath(getCompilerConfig(), testSources ? "generatedTestSourcesDirectory" : "generatedSourcesDirectory", def); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/AnnotationProcessorImportingTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/AnnotationProcessorImportingTest.groovy index b7d162dda648..1230c0c4446f 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/AnnotationProcessorImportingTest.groovy +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/AnnotationProcessorImportingTest.groovy @@ -120,6 +120,7 @@ class AnnotationProcessorImportingTest extends MavenImportingTestCase { maven-compiler-plugin out/generated + From 5f3a65167f464f063c442440e9056d0ff265df83 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 15 Oct 2012 17:13:19 +0200 Subject: [PATCH 08/57] Typo --- .../src/com/intellij/psi/JavaCodeFragment.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/java/java-psi-api/src/com/intellij/psi/JavaCodeFragment.java b/java/java-psi-api/src/com/intellij/psi/JavaCodeFragment.java index 25f4ad4c60c4..b7537c3df6f8 100644 --- a/java/java-psi-api/src/com/intellij/psi/JavaCodeFragment.java +++ b/java/java-psi-api/src/com/intellij/psi/JavaCodeFragment.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -20,8 +20,6 @@ package com.intellij.psi; * in a foreign language code or in a user interface element other than the main source code editor). */ public interface JavaCodeFragment extends PsiImportHolder, PsiCodeFragment { - - /** * Returns the type corresponding to the this keyword in the code fragment. * @@ -107,7 +105,7 @@ public interface JavaCodeFragment extends PsiImportHolder, PsiCodeFragment { * * @param declaration the referenced declaration. * @param place the location of the reference to the declaration. - * @return the visibility of the declaraion. + * @return the visibility of the declaration. */ Visibility isDeclarationVisible(PsiElement declaration, PsiElement place); @@ -162,5 +160,4 @@ public interface JavaCodeFragment extends PsiImportHolder, PsiCodeFragment { */ boolean isHandledException(PsiClassType exceptionType); } - } From c8383de82f92f19b1c443c7717d1df807232f963 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 16 Oct 2012 14:56:28 +0200 Subject: [PATCH 09/57] idea.log in CE run configuration --- .idea/runConfigurations/IDEA.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.idea/runConfigurations/IDEA.xml b/.idea/runConfigurations/IDEA.xml index 49551f37037d..f8e1c1f854d0 100644 --- a/.idea/runConfigurations/IDEA.xml +++ b/.idea/runConfigurations/IDEA.xml @@ -1,5 +1,6 @@ - + +

* * Q: How do I plug into those funny texts below the items in shown lookup?
- * A: Use {@link CompletionContributor#advertise(CompletionParameters)} or - * {@link CompletionService#setAdvertisementText(String)}. Don't forget to check whether you are in correct place - * (see {@link CompletionParameters}).

+ * A: Use {@link CompletionResultSet#addLookupAdvertisement(String)}

* * Q: How do I change the text that gets shown when there are no suitable variants at all?
* A: Use {@link CompletionContributor#handleEmptyLookup(CompletionParameters, Editor)}. @@ -179,7 +177,7 @@ public abstract class CompletionContributor { /** * @param parameters - * @deprecated use {@link com.intellij.codeInsight.completion.CompletionService#setAdvertisementText(String)} + * @deprecated use {@link com.intellij.codeInsight.completion.CompletionResultSet#addLookupAdvertisement(String)} * @return text to be shown at the bottom of lookup list */ @Nullable diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java index 9fc19839c3d2..5bcc12583567 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java @@ -66,6 +66,8 @@ public abstract class CompletionResultSet { @NotNull public abstract CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter); + public abstract void addLookupAdvertisement(@NotNull String text); + /** * @return A result set with the same prefix, but the lookup strings will be matched case-insensitively. Their lookup strings will * remain as they are though, so upon insertion the prefix case will be changed. diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionService.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionService.java index 590f5e2b7520..74f53b5b933d 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionService.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionService.java @@ -58,6 +58,7 @@ public abstract class CompletionService { /** * Set lookup advertisement text (at the bottom) at any time. Will do nothing if no completion process is in progress. * @param text + * @deprecated use {@link CompletionResultSet#addLookupAdvertisement(String)} */ public abstract void setAdvertisementText(@Nullable String text); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java index a9d7020a83d5..c491bec4d4a0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java @@ -71,7 +71,7 @@ public class FilePathCompletionContributor extends CompletionContributor { if (getReference(psiReference) != null && parameters.getInvocationCount() == 1) { final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION); if (shortcut != null) { - CompletionService.getCompletionService().setAdvertisementText(CodeInsightBundle.message("class.completion.file.path", shortcut)); + result.addLookupAdvertisement(CodeInsightBundle.message("class.completion.file.path", shortcut)); } } } @@ -155,8 +155,7 @@ public class FilePathCompletionContributor extends CompletionContributor { if (set.getSuitableFileTypes().length > 0 && parameters.getInvocationCount() == 1) { final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION); if (shortcut != null) { - CompletionService.getCompletionService() - .setAdvertisementText(CodeInsightBundle.message("class.completion.file.path.all.variants", shortcut)); + result.addLookupAdvertisement(CodeInsightBundle.message("class.completion.file.path.all.variants", shortcut)); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index 19362bb71cad..8ab05d80133f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -160,6 +160,11 @@ public class CompletionServiceImpl extends CompletionService{ return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this); } + @Override + public void addLookupAdvertisement(@NotNull String text) { + getCompletionService().setAdvertisementText(text); + } + @NotNull @Override public CompletionResultSet caseInsensitive() { diff --git a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java index 4f8a070af8fc..a9b7722f7403 100644 --- a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java @@ -59,18 +59,16 @@ public class TextFieldWithAutoCompletionContributor extends CompletionContrib final TextFieldWithAutoCompletionListProvider provider = file.getUserData(KEY); if (provider != null) { - if (CompletionService.getCompletionService().getAdvertisementText() == null) { - String adv = provider.getAdvertisement(); - if (adv == null) { - final String shortcut = getActionShortcut(IdeActions.ACTION_QUICK_JAVADOC); - if (shortcut != null) { - adv = provider.getQuickDocHotKeyAdvertisement(shortcut); - } - } - if (adv != null) { - CompletionService.getCompletionService().setAdvertisementText(adv); + String adv = provider.getAdvertisement(); + if (adv == null) { + final String shortcut = getActionShortcut(IdeActions.ACTION_QUICK_JAVADOC); + if (shortcut != null) { + adv = provider.getQuickDocHotKeyAdvertisement(shortcut); } } + if (adv != null) { + result.addLookupAdvertisement(adv); + } final String prefix = provider.getPrefix(parameters); if (prefix == null) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index c5cc1e79a756..de8dc8f2affb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -225,11 +225,11 @@ public class GroovyCompletionContributor extends CompletionContributor { final PsiElement resolved = referenceExpression.resolve(); if (!(resolved instanceof PsiClass)) return; - if (CompletionService.getCompletionService().getAdvertisementText() == null && parameters.getInvocationCount() > 0 && + if (parameters.getInvocationCount() > 0 && CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.GLOBAL_MEMBER_NAME)) { final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION); if (shortcut != null) { - CompletionService.getCompletionService().setAdvertisementText("Pressing " + shortcut + " twice without a class qualifier would show all accessible static methods"); + result.addLookupAdvertisement("Pressing " + shortcut + " twice without a class qualifier would show all accessible static methods"); } } @@ -317,7 +317,7 @@ public class GroovyCompletionContributor extends CompletionContributor { if (parameters.getInvocationCount() >= 2) { addAllClasses(parameters, result, inheritors); } else { - JavaCompletionContributor.advertiseSecondCompletion(position.getProject()); + JavaCompletionContributor.advertiseSecondCompletion(position.getProject(), result); } } } @@ -536,10 +536,8 @@ public class GroovyCompletionContributor extends CompletionContributor { } private static void showInfo() { - if (StringUtil.isEmpty(CompletionService.getCompletionService().getAdvertisementText())) { - CompletionService.getCompletionService() - .setAdvertisementText(GroovyBundle.message("invoke.completion.second.time.to.show.skipped.methods")); - } + CompletionService.getCompletionService() + .setAdvertisementText(GroovyBundle.message("invoke.completion.second.time.to.show.skipped.methods")); } private static boolean checkForIterator(PsiMethod method) { From e48668b498029a18f977a6b1ae2afac5ffe8157a Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 16 Oct 2012 14:55:17 +0200 Subject: [PATCH 21/57] annotation processors: allow configuration of generated sources production/test directory names either relative to module content root or module output directory --- .../options/ProcessorProfilePanel.java | 106 ++++++++++++------ .../openapi/compiler/CompilerPaths.java | 12 +- .../src/org/jetbrains/jps/ProjectPaths.java | 16 ++- .../jps/incremental/IncProjectBuilder.java | 4 +- .../jps/incremental/java/JavaBuilder.java | 3 +- .../AnnotationProcessingConfiguration.java | 5 +- .../java/compiler/ProcessorConfigProfile.java | 5 + .../compiler/ProcessorConfigProfileImpl.java | 26 ++++- .../AnnotationProcessorProfileSerializer.java | 13 ++- 9 files changed, 128 insertions(+), 62 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java b/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java index 88287542f066..1553b84f16a6 100644 --- a/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java +++ b/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java @@ -56,6 +56,8 @@ public class ProcessorProfilePanel extends JPanel { private TextFieldWithBrowseButton myProcessorPathField; private JTextField myGeneratedProductionDirField; private JTextField myGeneratedTestsDirField; + private JRadioButton myRbRelativeToOutputRoot; + private JRadioButton myRbRelativeToContentRoot; private ProcessorTableModel myProcessorsModel; private JCheckBox myCbEnableProcessing; private JBTable myProcessorTable; @@ -63,6 +65,12 @@ public class ProcessorProfilePanel extends JPanel { private JPanel myProcessorPanel; private JPanel myOptionsPanel; private OptionsTableModel myOptionsModel; + private JLabel myWarninglabel; + private JLabel myStoreGenSourcesLabel; + private JLabel myProductionLabel; + private JLabel myTestLabel; + private JPanel myProcessorTablePanel; + private JPanel myOptionsTablePanel; public ProcessorProfilePanel(Project project) { @@ -71,11 +79,21 @@ public class ProcessorProfilePanel extends JPanel { myCbEnableProcessing = new JCheckBox("Enable annotation processing"); - myRbClasspath = new JRadioButton("Obtain processors from project classpath"); - myRbProcessorsPath = new JRadioButton("Processor path:"); - ButtonGroup group = new ButtonGroup(); - group.add(myRbClasspath); - group.add(myRbProcessorsPath); + { + myRbClasspath = new JRadioButton("Obtain processors from project classpath"); + myRbProcessorsPath = new JRadioButton("Processor path:"); + ButtonGroup group = new ButtonGroup(); + group.add(myRbClasspath); + group.add(myRbProcessorsPath); + } + + { + myRbRelativeToContentRoot = new JRadioButton("Module content root"); + myRbRelativeToOutputRoot = new JRadioButton("Module output directory"); + final ButtonGroup group = new ButtonGroup(); + group.add(myRbRelativeToContentRoot); + group.add(myRbRelativeToOutputRoot); + } myProcessorPathField = new TextFieldWithBrowseButton(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -94,62 +112,66 @@ public class ProcessorProfilePanel extends JPanel { } }); - final JPanel processorTablePanel = new JPanel(new BorderLayout()); + myProcessorTablePanel = new JPanel(new BorderLayout()); myProcessorsModel = new ProcessorTableModel(); - processorTablePanel.setBorder(IdeBorderFactory.createTitledBorder("Annotation Processors", false)); + myProcessorTablePanel.setBorder(IdeBorderFactory.createTitledBorder("Annotation Processors", false)); myProcessorTable = new JBTable(myProcessorsModel); myProcessorTable.getEmptyText().setText("Compiler will run all automatically discovered processors"); myProcessorPanel = createTablePanel(myProcessorTable); - processorTablePanel.add(myProcessorPanel, BorderLayout.CENTER); + myProcessorTablePanel.add(myProcessorPanel, BorderLayout.CENTER); - final JPanel optionsTablePanel = new JPanel(new BorderLayout()); + myOptionsTablePanel = new JPanel(new BorderLayout()); myOptionsModel = new OptionsTableModel(); - optionsTablePanel.setBorder(IdeBorderFactory.createTitledBorder("Annotation Processor options", false)); + myOptionsTablePanel.setBorder(IdeBorderFactory.createTitledBorder("Annotation Processor options", false)); myOptionsTable = new JBTable(myOptionsModel); myOptionsTable.getEmptyText().setText("No processor-specific options configured"); myOptionsPanel = createTablePanel(myOptionsTable); - optionsTablePanel.add(myOptionsPanel, BorderLayout.CENTER); + myOptionsTablePanel.add(myOptionsPanel, BorderLayout.CENTER); myGeneratedProductionDirField = new JTextField(); myGeneratedTestsDirField = new JTextField(); - final JLabel warning = new JLabel("WARNING!
" + + myWarninglabel = new JLabel("WARNING!
" + /*"All source files located in the generated sources output directory WILL BE EXCLUDED from annotation processing. " +*/ "If option 'Clear output directory on rebuild' is enabled, " + "the entire contents of directories where generated sources are stored WILL BE CLEARED on rebuild."); - warning.setFont(warning.getFont().deriveFont(Font.BOLD)); + myWarninglabel.setFont(myWarninglabel.getFont().deriveFont(Font.BOLD)); add(myCbEnableProcessing, - new GridBagConstraints(0, 0, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); add(myRbClasspath, - new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 0, 0, 0), 0, 0)); + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 0, 0, 0), 0, 0)); add(myRbProcessorsPath, - new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0)); + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0)); add(myProcessorPathField, - new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 0, 0), 0, 0)); + new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 0, 0), 0, 0)); - final JLabel noteMessage = new JLabel("Source files generated by annotation processors will be stored under the project output directory. " + - "To override this behaviour for this profile you may specify the directory name in the field below. " + - "If specified, the directory will be created under corresponding module's content root."); - add(noteMessage, - new GridBagConstraints(0, 3, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); + myStoreGenSourcesLabel = new JLabel("Store generated sources relative to: "); + add(myStoreGenSourcesLabel, + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(15, 5, 0, 0), 0, 0)); + add(myRbRelativeToOutputRoot, + new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(15, 5, 0, 0), 0, 0)); + add(myRbRelativeToContentRoot, + new GridBagConstraints(2, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(15, 5, 0, 0), 0, 0)); - add(new JLabel("Production sources directory:"), - new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); + myProductionLabel = new JLabel("Production sources directory:"); + add(myProductionLabel, + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); add(myGeneratedProductionDirField, - new GridBagConstraints(1, 4, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); + new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); - add(new JLabel("Test sources directory:"), - new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); + myTestLabel = new JLabel("Test sources directory:"); + add(myTestLabel, + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); add(myGeneratedTestsDirField, - new GridBagConstraints(1, 5, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); + new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); - add(processorTablePanel, - new GridBagConstraints(0, 6, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 0, 0, 0), 0, 0)); - add(optionsTablePanel, - new GridBagConstraints(0, 7, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 0, 0, 0), 0, 0)); - add(warning, - new GridBagConstraints(0, 8, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); + add(myProcessorTablePanel, + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 0, 0, 0), 0, 0)); + add(myOptionsTablePanel, + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 0, 0, 0), 0, 0)); + add(myWarninglabel, + new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); myRbClasspath.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { @@ -185,6 +207,12 @@ public class ProcessorProfilePanel extends JPanel { myGeneratedProductionDirField.setText(productionDirName != null? productionDirName.trim() : ""); final String testsDirName = config.getGeneratedSourcesDirectoryName(true); myGeneratedTestsDirField.setText(testsDirName != null? testsDirName.trim() : ""); + if (config.isOutputRelativeToContentRoot()) { + myRbRelativeToContentRoot.setSelected(true); + } + else { + myRbRelativeToOutputRoot.setSelected(true); + } myProcessorsModel.setProcessors(config.getProcessors()); myOptionsModel.setOptions(config.getProcessorOptions()); @@ -201,6 +229,8 @@ public class ProcessorProfilePanel extends JPanel { final String testsDir = myGeneratedTestsDirField.getText().trim(); profile.setGeneratedSourcesDirectoryName(StringUtil.isEmpty(testsDir)? null : testsDir, true); + profile.setOutputRelativeToContentRoot(myRbRelativeToContentRoot.isSelected()); + profile.clearProcessors(); for (String processor : myProcessorsModel.getProcessors()) { profile.addProcessor(processor); @@ -240,6 +270,14 @@ public class ProcessorProfilePanel extends JPanel { updateTable(myOptionsPanel, myOptionsTable, enabled); myGeneratedProductionDirField.setEnabled(enabled); myGeneratedTestsDirField.setEnabled(enabled); + myRbRelativeToOutputRoot.setEnabled(enabled); + myRbRelativeToContentRoot.setEnabled(enabled); + myWarninglabel.setEnabled(enabled); + myStoreGenSourcesLabel.setEnabled(enabled); + myProductionLabel.setEnabled(enabled); + myTestLabel.setEnabled(enabled); + myProcessorTablePanel.setEnabled(enabled); + myOptionsTablePanel.setEnabled(enabled); } private static void updateTable(final JPanel tablePanel, final JBTable table, boolean enabled) { diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java index dcd4e27a2e2f..86d4e0299348 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java @@ -34,6 +34,7 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.util.PathUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration; import java.io.File; import java.util.Arrays; @@ -214,10 +215,9 @@ public class CompilerPaths { @Nullable public static String getAnnotationProcessorsGenerationPath(Module module) { - final CompilerConfiguration config = CompilerConfiguration.getInstance(module.getProject()); - - final String sourceDirName = config.getAnnotationProcessingConfiguration(module).getGeneratedSourcesDirectoryName(false); - if (!StringUtil.isEmpty(sourceDirName)) { + final AnnotationProcessingConfiguration config = CompilerConfiguration.getInstance(module.getProject()).getAnnotationProcessingConfiguration(module); + final String sourceDirName = config.getGeneratedSourcesDirectoryName(false); + if (config.isOutputRelativeToContentRoot()) { final String[] roots = ModuleRootManager.getInstance(module).getContentRootUrls(); if (roots.length == 0) { return null; @@ -225,7 +225,7 @@ public class CompilerPaths { if (roots.length > 1) { Arrays.sort(roots, URLS_COMPARATOR); } - return VirtualFileManager.extractPath(roots[0]) + "/" + sourceDirName; + return StringUtil.isEmpty(sourceDirName)? VirtualFileManager.extractPath(roots[0]): VirtualFileManager.extractPath(roots[0]) + "/" + sourceDirName; } final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(module.getProject()); @@ -236,7 +236,7 @@ public class CompilerPaths { if (url == null) { return null; } - return VirtualFileManager.extractPath(url) + "/" + DEFAULT_GENERATED_DIR_NAME + "/" + module.getName().toLowerCase(); + return StringUtil.isEmpty(sourceDirName)? VirtualFileManager.extractPath(url) : VirtualFileManager.extractPath(url) + "/" + sourceDirName; } @NonNls diff --git a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java index ba752157c796..08d4e54ea41d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java +++ b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java @@ -9,6 +9,7 @@ import org.jetbrains.jps.model.JpsDummyElement; import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.JpsSimpleElement; import org.jetbrains.jps.model.java.*; +import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile; import org.jetbrains.jps.model.library.JpsOrderRootType; import org.jetbrains.jps.model.library.sdk.JpsSdk; import org.jetbrains.jps.model.module.JpsDependencyElement; @@ -25,7 +26,6 @@ import java.util.*; * Date: 9/30/11 */ public class ProjectPaths { - private static final String DEFAULT_GENERATED_DIR_NAME = "generated"; @NotNull private final JpsProject myProject; //private final Map>> myCachedClasspath = new HashMap>>(); @@ -148,8 +148,9 @@ public class ProjectPaths { } @Nullable - public File getAnnotationProcessorGeneratedSourcesOutputDir(JpsModule module, final boolean forTests, String sourceDirName) { - if (!StringUtil.isEmpty(sourceDirName)) { + public File getAnnotationProcessorGeneratedSourcesOutputDir(JpsModule module, final boolean forTests, ProcessorConfigProfile profile) { + final String sourceDirName = profile.getGeneratedSourcesDirectoryName(forTests); + if (profile.isOutputRelativeToContentRoot()) { List roots = module.getContentRootsList().getUrls(); if (roots.isEmpty()) { return null; @@ -163,18 +164,15 @@ public class ProjectPaths { } }); } - return new File(JpsPathUtil.urlToFile(roots.get(0)), sourceDirName); + final File parent = JpsPathUtil.urlToFile(roots.get(0)); + return StringUtil.isEmpty(sourceDirName)? parent : new File(parent, sourceDirName); } final File outputDir = getModuleOutputDir(module, forTests); if (outputDir == null) { return null; } - final File parentFile = outputDir.getParentFile(); - if (parentFile == null) { - return null; - } - return new File(parentFile, DEFAULT_GENERATED_DIR_NAME); + return StringUtil.isEmpty(sourceDirName)? outputDir : new File(outputDir, sourceDirName); } private enum ClasspathPart {WHOLE, BEFORE_JDK, AFTER_JDK} diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index 26cee42e7982..cd5d40998a25 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -368,9 +368,7 @@ public class IncProjectBuilder { for (ModuleBuildTarget target : projectDescriptor.getBuildTargetIndex().getAllTargets(type)) { final ProcessorConfigProfile profile = context.getAnnotationProcessingProfile(target.getModule()); if (profile.isEnabled()) { - final File annotationOut = paths.getAnnotationProcessorGeneratedSourcesOutputDir( - target.getModule(), target.isTests(), profile.getGeneratedSourcesDirectoryName(target.isTests()) - ); + final File annotationOut = paths.getAnnotationProcessorGeneratedSourcesOutputDir(target.getModule(), target.isTests(), profile); if (annotationOut != null) { annotationOutputs.add(annotationOut); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 4b2ab483f882..3d4b4f2ee275 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -751,9 +751,8 @@ public class JavaBuilder extends ModuleLevelBuilder { options.add("-A" + optionEntry.getKey() + "=" + optionEntry.getValue()); } - final boolean forTests = chunk.containsTests(); final File srcOutput = context.getProjectPaths().getAnnotationProcessorGeneratedSourcesOutputDir( - chunk.getModules().iterator().next(), forTests, profile.getGeneratedSourcesDirectoryName(forTests) + chunk.getModules().iterator().next(), chunk.containsTests(), profile ); if (srcOutput != null) { srcOutput.mkdirs(); diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/compiler/AnnotationProcessingConfiguration.java b/jps/model-api/src/org/jetbrains/jps/model/java/compiler/AnnotationProcessingConfiguration.java index 4133955a01df..91009b952740 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/compiler/AnnotationProcessingConfiguration.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/compiler/AnnotationProcessingConfiguration.java @@ -16,7 +16,6 @@ package org.jetbrains.jps.model.java.compiler; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Map; import java.util.Set; @@ -31,9 +30,11 @@ public interface AnnotationProcessingConfiguration { @NotNull String getProcessorPath(); - @Nullable + @NotNull String getGeneratedSourcesDirectoryName(boolean forTests); + boolean isOutputRelativeToContentRoot(); + @NotNull Set getProcessors(); diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/compiler/ProcessorConfigProfile.java b/jps/model-api/src/org/jetbrains/jps/model/java/compiler/ProcessorConfigProfile.java index 2baf37316741..aab4f690279f 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/compiler/ProcessorConfigProfile.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/compiler/ProcessorConfigProfile.java @@ -10,6 +10,9 @@ import java.util.Set; * @author nik */ public interface ProcessorConfigProfile extends AnnotationProcessingConfiguration { + String DEFAULT_PRODUCTION_DIR_NAME = "generated"; + String DEFAULT_TESTS_DIR_NAME = "generated_tests"; + void initFrom(ProcessorConfigProfile other); String getName(); @@ -49,4 +52,6 @@ public interface ProcessorConfigProfile extends AnnotationProcessingConfiguratio String getOption(String key); void clearProcessorOptions(); + + void setOutputRelativeToContentRoot(boolean outputRelativeToContentRoot); } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/ProcessorConfigProfileImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/ProcessorConfigProfileImpl.java index b3cca63ad370..3ee4e8b9f045 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/ProcessorConfigProfileImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/ProcessorConfigProfileImpl.java @@ -26,15 +26,17 @@ import java.util.*; * Date: 5/25/12 */ public final class ProcessorConfigProfileImpl implements ProcessorConfigProfile { + private String myName = ""; private boolean myEnabled = false; private boolean myObtainProcessorsFromClasspath = true; private String myProcessorPath = ""; private final Set myProcessors = new HashSet(); // empty list means all discovered private final Map myProcessorOptions = new HashMap(); // key=value map of options - @Nullable - private String myGeneratedProductionDirectoryName = null; // null means 'auto' - private String myGeneratedTestsDirectoryName = null; // null means 'auto' + private String myGeneratedProductionDirectoryName = DEFAULT_PRODUCTION_DIR_NAME; + private String myGeneratedTestsDirectoryName = DEFAULT_TESTS_DIR_NAME; + private boolean myOutputRelativeToContentRoot = false; + private final Set myModuleNames = new HashSet(); public ProcessorConfigProfileImpl(String name) { @@ -57,6 +59,7 @@ public final class ProcessorConfigProfileImpl implements ProcessorConfigProfile myProcessorOptions.putAll(other.getProcessorOptions()); myGeneratedProductionDirectoryName = other.getGeneratedSourcesDirectoryName(false); myGeneratedTestsDirectoryName = other.getGeneratedSourcesDirectoryName(true); + myOutputRelativeToContentRoot = other.isOutputRelativeToContentRoot(); myModuleNames.clear(); myModuleNames.addAll(other.getModuleNames()); } @@ -103,13 +106,16 @@ public final class ProcessorConfigProfileImpl implements ProcessorConfigProfile } @Override - @Nullable + @NotNull public String getGeneratedSourcesDirectoryName(boolean forTests) { return forTests? myGeneratedTestsDirectoryName : myGeneratedProductionDirectoryName; } @Override public void setGeneratedSourcesDirectoryName(@Nullable String name, boolean forTests) { + if (name == null || name.trim().isEmpty()) { + name = ""; + } if (forTests) { myGeneratedTestsDirectoryName = name; } @@ -118,6 +124,16 @@ public final class ProcessorConfigProfileImpl implements ProcessorConfigProfile } } + @Override + public boolean isOutputRelativeToContentRoot() { + return myOutputRelativeToContentRoot; + } + + @Override + public void setOutputRelativeToContentRoot(boolean relativeToContent) { + myOutputRelativeToContentRoot = relativeToContent; + } + @Override @NotNull public Set getModuleNames() { @@ -211,6 +227,7 @@ public final class ProcessorConfigProfileImpl implements ProcessorConfigProfile : profile.myGeneratedTestsDirectoryName != null) { return false; } + if (myOutputRelativeToContentRoot != profile.myOutputRelativeToContentRoot)return false; if (!myModuleNames.equals(profile.myModuleNames)) return false; if (!myProcessorOptions.equals(profile.myProcessorOptions)) return false; if (myProcessorPath != null ? !myProcessorPath.equals(profile.myProcessorPath) : profile.myProcessorPath != null) return false; @@ -230,6 +247,7 @@ public final class ProcessorConfigProfileImpl implements ProcessorConfigProfile result = 31 * result + myProcessorOptions.hashCode(); result = 31 * result + (myGeneratedProductionDirectoryName != null ? myGeneratedProductionDirectoryName.hashCode() : 0); result = 31 * result + (myGeneratedTestsDirectoryName != null ? myGeneratedTestsDirectoryName.hashCode() : 0); + result = 31 * result + (myOutputRelativeToContentRoot ? 1 : 0); result = 31 * result + myModuleNames.hashCode(); return result; } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/AnnotationProcessorProfileSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/AnnotationProcessorProfileSerializer.java index 2d2311f93144..4760cfb0d247 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/AnnotationProcessorProfileSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/AnnotationProcessorProfileSerializer.java @@ -50,6 +50,11 @@ public class AnnotationProcessorProfileSerializer { final Element srcTestOutput = element.getChild("sourceTestOutputDir"); profile.setGeneratedSourcesDirectoryName(srcTestOutput != null ? srcTestOutput.getAttributeValue(NAME) : null, true); + final Element isRelativeToContentRoot = element.getChild("outputRelativeToContentRoot"); + if (isRelativeToContentRoot != null) { + profile.setOutputRelativeToContentRoot(Boolean.parseBoolean(isRelativeToContentRoot.getAttributeValue(VALUE))); + } + profile.clearProcessorOptions(); for (Object optionElement : element.getChildren(OPTION)) { final Element elem = (Element)optionElement; @@ -98,14 +103,18 @@ public class AnnotationProcessorProfileSerializer { element.setAttribute(ENABLED, Boolean.toString(profile.isEnabled())); final String srcDirName = profile.getGeneratedSourcesDirectoryName(false); - if (srcDirName != null) { + if (!StringUtil.equals(ProcessorConfigProfile.DEFAULT_PRODUCTION_DIR_NAME, srcDirName)) { addChild(element, "sourceOutputDir").setAttribute(NAME, srcDirName); } final String testSrcDirName = profile.getGeneratedSourcesDirectoryName(true); - if (testSrcDirName != null) { + if (!StringUtil.equals(ProcessorConfigProfile.DEFAULT_TESTS_DIR_NAME, testSrcDirName)) { addChild(element, "sourceTestOutputDir").setAttribute(NAME, testSrcDirName); } + if (profile.isOutputRelativeToContentRoot()) { + addChild(element, "outputRelativeToContentRoot").setAttribute(VALUE, "true"); + } + final Map options = profile.getProcessorOptions(); if (!options.isEmpty()) { final List keys = new ArrayList(options.keySet()); From 1028a95c837e2b6dbcb915c07b0e0eeee41ef092 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 16 Oct 2012 17:11:54 +0400 Subject: [PATCH 22/57] IDEA-91638 Make "Maven > Importing > Keep source and test folders on reimport" setting enabled by default --- .../jetbrains/idea/maven/project/MavenProjectsManager.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java index a119acc0921b..b5d449241feb 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java @@ -171,10 +171,6 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent synchronized (isInitialized) { if (isInitialized.getAndSet(true)) return; - if (isNew) { - getImportingSettings().setKeepSourceFolders(false); - } - initProjectsTree(!isNew); initWorkers(); From d86d163a7a63b7fb16bce043a4767c5125178ab7 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 16 Oct 2012 17:23:14 +0400 Subject: [PATCH 23/57] Fix Maven test --- .../jetbrains/idea/maven/importing/FoldersImportingTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java index 6af937ebb3e1..f5eb127d737e 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/FoldersImportingTest.java @@ -995,7 +995,7 @@ public class FoldersImportingTest extends MavenImportingTestCase { createStdProjectFolders(); createProjectSubDirs("target/generated-sources/foo", "target/generated-sources/annotations", - "target/generated-sources/test-annotations", + "target/generated-test-sources/test-annotations", "target/generated-test-sources/foo"); importProject("test" + @@ -1012,7 +1012,7 @@ public class FoldersImportingTest extends MavenImportingTestCase { "src/test/java", "src/test/resources", "target/generated-test-sources/foo", - "target/generated-sources/test-annotations"); + "target/generated-test-sources/test-annotations"); } public void testCustomAnnotationProcessorSources() throws Exception { From 8c47800630175398d2f3c5abcfbc72a22411cf94 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 16 Oct 2012 15:40:30 +0200 Subject: [PATCH 24/57] NPE (IDEA-93019) --- .../codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index fc3f446418a2..f0239340f572 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -983,7 +983,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } if (!myHolder.hasErrorResults()) { final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType(); - if (LambdaUtil.dependsOnTypeParams(functionalInterfaceType, functionalInterfaceType, expression, null)) { + if (functionalInterfaceType != null && LambdaUtil.dependsOnTypeParams(functionalInterfaceType, functionalInterfaceType, expression, null)) { myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, "Cyclic inference")); //todo[ann] append not inferred type params info } else { final PsiElement referenceNameElement = expression.getReferenceNameElement(); From 3ec3f15f9258bc4f0af2fdc560d215bb985b15d8 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 16 Oct 2012 17:28:50 +0400 Subject: [PATCH 25/57] IDEA-92949: xml mapping for dynamic child. nested children supported --- .../com/intellij/openapi/options/ConfigurableEP.java | 7 +++++++ .../openapi/options/ex/ConfigurableWrapper.java | 10 +++++----- plugins/copyright/src/META-INF/plugin.xml | 7 ++++++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java index 72880d015536..26d725a9f7bf 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java +++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java @@ -68,6 +68,13 @@ public class ConfigurableEP extends AbstractExten @Attribute("childrenEPName") public String childrenEPName; + /** + * Indicates that configurable has dynamically calculated children. + * {@link com.intellij.openapi.options.Configurable.Composite#getConfigurables()} will be called for such configurables. + */ + @Attribute("dynamic") + public boolean dynamic; + @Attribute("parentId") public String parentId; diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java index f309e7532bd5..cdd01d2ff80a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java @@ -46,7 +46,7 @@ public class ConfigurableWrapper implements SearchableConfigurable { @Nullable public static T wrapConfigurable(ConfigurableEP ep) { if (ep.displayName != null || ep.key != null) { - return (T)(ep.children != null || ep.childrenEPName != null ? new CompositeWrapper(ep) : new ConfigurableWrapper(ep)); + return (T)(ep.children != null || ep.childrenEPName != null || ep.dynamic ? new CompositeWrapper(ep) : new ConfigurableWrapper(ep)); } else { return ep.createConfigurable(); @@ -162,15 +162,15 @@ public class ConfigurableWrapper implements SearchableConfigurable { public CompositeWrapper(ConfigurableEP ep, Configurable... kids) { super(ep); - if (ep.children == null) { - kids = EMPTY_ARRAY; + if (ep.dynamic) { + kids = ((Composite)getConfigurable()).getConfigurables(); } - else { + else if (ep.children != null) { kids = ContainerUtil.mapNotNull(ep.getChildren(), new NullableFunction() { @Override public ConfigurableWrapper fun(ConfigurableEP ep) { - return ep.isAvailable() ? new ConfigurableWrapper(ep) : null; + return ep.isAvailable() ? (ConfigurableWrapper)wrapConfigurable(ep) : null; } }, EMPTY_ARRAY); } diff --git a/plugins/copyright/src/META-INF/plugin.xml b/plugins/copyright/src/META-INF/plugin.xml index 9bd98018d7f6..75e879b8636e 100644 --- a/plugins/copyright/src/META-INF/plugin.xml +++ b/plugins/copyright/src/META-INF/plugin.xml @@ -11,7 +11,12 @@ com.intellij.modules.java - + + + + Date: Tue, 16 Oct 2012 18:00:00 +0400 Subject: [PATCH 26/57] IDEA-92963 Groovy: Good code is red (Invalid value to assign to) --- .../plugins/groovy/lang/psi/util/PsiUtil.java | 9 +++++++-- .../lang/highlighting/GroovyHighlightingTest.groovy | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index f8dc893854d1..d981a05bb719 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -69,6 +69,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClaus import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrPropertySelection; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; @@ -653,8 +654,12 @@ public class PsiUtil { public static boolean mightBeLValue(@Nullable GrExpression expr) { if (expr instanceof GrParenthesizedExpression) return mightBeLValue(((GrParenthesizedExpression)expr).getOperand()); - if (expr instanceof GrTupleExpression) return true; - if (expr instanceof GrReferenceExpression || expr instanceof GrIndexProperty) return true; + if (expr instanceof GrTupleExpression || + expr instanceof GrReferenceExpression || + expr instanceof GrIndexProperty || + expr instanceof GrPropertySelection) { + return true; + } if ((expr instanceof GrThisReferenceExpression || expr instanceof GrSuperReferenceExpression) && GroovyConfigUtils.getInstance().isVersionAtLeast(expr, GroovyConfigUtils.GROOVY1_8)) { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy index de3eaf4d8586..ca662474daf2 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy @@ -884,6 +884,18 @@ class X { } } } +''') + } + + void testPropertySelectionMayBeLValue() { + testHighlighting('''\ +def methodMissing(String methodName, args) { + def closure = { + callSomeOtherMethodInstead() + } + this.metaClass."$methodName" = closure + closure() = 2 +} ''') } } \ No newline at end of file From 30cdd2b4bc88bc6989d845177a8e32337091cb2c Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 16 Oct 2012 15:57:35 +0200 Subject: [PATCH 27/57] java class reference: search subtypes only on smart completion, work as usual (and fast) on basic (IDEA-92934) --- ...vaClassReferenceCompletionContributor.java | 27 ++++++-- .../impl/providers/JavaClassReference.java | 52 ++++++-------- .../impl/providers/JavaClassReferenceSet.java | 5 ++ .../intellij/codeInsight/lookup/Lookup.java | 2 + .../codeInsight/lookup/impl/Advertiser.java | 3 + .../codeInsight/lookup/impl/LookupImpl.java | 14 +++- .../fixtures/CodeInsightTestFixture.java | 3 + .../impl/CodeInsightTestFixtureImpl.java | 2 +- ...howAnActionInheritorsOnSmartCompletion.xml | 5 ++ .../codeInsight/ShowPackagesInActionClass.xml | 5 ++ ...st.java => PluginXmlFunctionalTest.groovy} | 69 +++++++++++-------- 11 files changed, 116 insertions(+), 71 deletions(-) create mode 100644 plugins/devkit/testData/codeInsight/ShowAnActionInheritorsOnSmartCompletion.xml create mode 100644 plugins/devkit/testData/codeInsight/ShowPackagesInActionClass.xml rename plugins/devkit/testSources/codeInsight/{PluginXmlFunctionalTest.java => PluginXmlFunctionalTest.groovy} (74%) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java index fd8b67027027..e7ad8966c1f3 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java @@ -15,11 +15,15 @@ */ package com.intellij.codeInsight.completion; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; import com.intellij.psi.PsiReference; import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference; import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReference; +import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,24 +35,33 @@ public class JavaClassReferenceCompletionContributor extends CompletionContribut public void duringCompletion(@NotNull CompletionInitializationContext context) { JavaClassReference reference = findJavaClassReference(context.getFile(), context.getStartOffset()); if (reference != null && reference.getExtendClassNames() != null) { - final PsiReference[] references = reference.getJavaClassReferenceSet().getReferences(); - final PsiReference last = references[references.length - 1]; - context.setReplacementOffset(last.getRangeInElement().getEndOffset() + last.getElement().getTextRange().getStartOffset()); + JavaClassReferenceSet set = reference.getJavaClassReferenceSet(); + context.setReplacementOffset(set.getRangeInElement().getEndOffset() + set.getElement().getTextRange().getStartOffset()); } } @Override public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) { - if (parameters.getCompletionType() == CompletionType.SMART) { - return; - } - PsiElement position = parameters.getPosition(); JavaClassReference reference = findJavaClassReference(position.getContainingFile(), parameters.getOffset()); if (reference == null) { return; } + String[] extendClassNames = reference.getExtendClassNames(); + PsiElement context = reference.getCompletionContext(); + if (extendClassNames != null && context instanceof PsiPackage) { + if (parameters.getCompletionType() == CompletionType.SMART) { + JavaClassReferenceSet set = reference.getJavaClassReferenceSet(); + int setStart = set.getRangeInElement().getStartOffset() + set.getElement().getTextRange().getStartOffset(); + String fullPrefix = parameters.getPosition().getContainingFile().getText().substring(setStart, parameters.getOffset()); + reference.processSubclassVariants((PsiPackage)context, extendClassNames, result.withPrefixMatcher(fullPrefix)); + return; + } + result.addLookupAdvertisement("Press " + getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION) + " to see inheritors of " + + StringUtil.join(extendClassNames, ", ")); + } + if (parameters.getCompletionType() == CompletionType.CLASS_NAME) { JavaClassNameCompletionContributor.addAllClasses(parameters, result); } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java index e73e5c627192..b91cfc74191a 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl.source.resolve.reference.impl.providers; +import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.codeInsight.completion.JavaLookupElementBuilder; import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor; import com.intellij.codeInsight.daemon.QuickFixProvider; @@ -23,6 +24,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix; import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixActionRegistrarImpl; import com.intellij.codeInsight.daemon.quickFix.CreateClassOrPackageFix; +import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.LocalQuickFixProvider; import com.intellij.lang.java.JavaLanguage; @@ -55,7 +57,10 @@ import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; /** * @author peter @@ -225,15 +230,8 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer @Override @NotNull public Object[] getVariants() { - PsiElement context = getContext(); - if (context == null) { - context = JavaPsiFacade.getInstance(getElement().getProject()).findPackage(""); - } + PsiElement context = getCompletionContext(); if (context instanceof PsiPackage) { - final String[] extendClasses = getExtendClassNames(); - if (extendClasses != null) { - return getSubclassVariants((PsiPackage)context, extendClasses); - } return processPackage((PsiPackage)context); } if (context instanceof PsiClass) { @@ -257,6 +255,12 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer return ArrayUtil.EMPTY_OBJECT_ARRAY; } + @NotNull + public PsiElement getCompletionContext() { + PsiElement context = getContext(); + return context == null ? JavaPsiFacade.getInstance(getElement().getProject()).findPackage("") : context; + } + public String[] getExtendClassNames() { return JavaClassReferenceProvider.EXTEND_CLASS_NAMES.getValue(getOptions()); } @@ -508,8 +512,7 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer } @NotNull - private Object[] getSubclassVariants(@NotNull PsiPackage context, @NotNull String[] extendClasses) { - HashSet lookups = new HashSet(); + public void processSubclassVariants(@NotNull PsiPackage context, @NotNull String[] extendClasses, CompletionResultSet result) { GlobalSearchScope packageScope = PackageScope.packageScope(context, true); GlobalSearchScope scope = myJavaClassReferenceSet.getProvider().getScope(getElement().getProject()); if (scope != null) { @@ -529,35 +532,22 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer // add itself if (packageScope.contains(extendClass.getContainingFile().getVirtualFile())) { if (isClassAccepted(extendClass, classKind, instantiatable, concrete, notInterface, notEnum)) { - ContainerUtil.addIfNotNull(createSubclassLookupValue(context, extendClass), lookups); + result.addElement(createSubclassLookupValue(extendClass, extendClassName)); } } for (final PsiClass clazz : ClassInheritorsSearch.search(extendClass, packageScope, true)) { - if (isClassAccepted(clazz, classKind, instantiatable, concrete, notInterface, notEnum)) { - ContainerUtil.addIfNotNull(createSubclassLookupValue(context, clazz), lookups); + String qname = clazz.getQualifiedName(); + if (qname != null && isClassAccepted(clazz, classKind, instantiatable, concrete, notInterface, notEnum)) { + result.addElement(createSubclassLookupValue(clazz, qname)); } } } } - return lookups.toArray(); } - @Nullable - private static Object createSubclassLookupValue(@NotNull final PsiPackage context, @NotNull final PsiClass clazz) { - final String qname = clazz.getQualifiedName(); - if (qname == null) return null; - - String name = qname; - final String pack = context.getQualifiedName(); - if (pack.length() > 0) { - if (name.startsWith(pack)) { - name = name.substring(pack.length() + 1); - } - else { - return null; - } - } - return JavaLookupElementBuilder.forClass(clazz, name, true).withLookupString(qname).withLookupString(clazz.getName()); + @NotNull + private static LookupElementBuilder createSubclassLookupValue(@NotNull final PsiClass clazz, @NotNull String qname) { + return JavaLookupElementBuilder.forClass(clazz, qname, true).withPresentableText(StringUtil.getShortName(qname)); } @Override diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java index 0b212aa49494..c184775ad11b 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReferenceSet.java @@ -59,6 +59,11 @@ public class JavaClassReferenceSet { return myProvider; } + public TextRange getRangeInElement() { + PsiReference[] references = getReferences(); + return new TextRange(references[0].getRangeInElement().getStartOffset(), references[references.length - 1].getRangeInElement().getEndOffset()); + } + private void reparse(String str, PsiElement element, final boolean isStaticImport, JavaClassReferenceSet context) { myElement = element; myContext = context; diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/Lookup.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/Lookup.java index b41fb9330f53..10f124ab0b7f 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/lookup/Lookup.java +++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/Lookup.java @@ -69,4 +69,6 @@ public interface Lookup { PrefixMatcher itemMatcher(@NotNull LookupElement item); boolean isSelectionTouched(); + + List getAdvertisements(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java index 78222057f2fd..e35986dfafdd 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java @@ -138,4 +138,7 @@ public class Advertiser { return myComponent; } + public List getAdvertisements() { + return myTexts; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 72ef454026b1..35a119bbee76 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1158,6 +1158,11 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable return mySelectionTouched; } + @Override + public List getAdvertisements() { + return myAdComponent.getAdvertisements(); + } + @Override public void hide(){ hideLookup(true); @@ -1290,7 +1295,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable } public void addAdvertisement(@NotNull final String text) { - ApplicationManager.getApplication().invokeLater(new Runnable() { + Runnable runnable = new Runnable() { @Override public void run() { if (!myDisposed) { @@ -1301,7 +1306,12 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable } } } - }, myModalityState); + }; + if (ApplicationManager.getApplication().isDispatchThread()) { + runnable.run(); + } else { + ApplicationManager.getApplication().invokeLater(runnable, myModalityState); + } } public boolean isLookupDisposed() { diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java index 3c2c00c87705..506e478d2b24 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java @@ -19,6 +19,7 @@ package com.intellij.testFramework.fixtures; import com.intellij.codeInsight.completion.CompletionType; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.lookup.Lookup; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInspection.InspectionProfileEntry; import com.intellij.codeInspection.InspectionToolProvider; @@ -361,6 +362,8 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void finishLookup(); + Lookup getLookup(); + @NotNull PsiElement getElementAtCaret(); diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 933eb4e26ee9..50ea02ec1ad9 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1879,7 +1879,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig } } - private LookupImpl getLookup() { + public LookupImpl getLookup() { return (LookupImpl)LookupManager.getActiveLookup(myEditor); } diff --git a/plugins/devkit/testData/codeInsight/ShowAnActionInheritorsOnSmartCompletion.xml b/plugins/devkit/testData/codeInsight/ShowAnActionInheritorsOnSmartCompletion.xml new file mode 100644 index 000000000000..e201819aa60c --- /dev/null +++ b/plugins/devkit/testData/codeInsight/ShowAnActionInheritorsOnSmartCompletion.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/devkit/testData/codeInsight/ShowPackagesInActionClass.xml b/plugins/devkit/testData/codeInsight/ShowPackagesInActionClass.xml new file mode 100644 index 000000000000..e201819aa60c --- /dev/null +++ b/plugins/devkit/testData/codeInsight/ShowPackagesInActionClass.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy similarity index 74% rename from plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java rename to plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy index 050f604ce17e..9c331f1749cf 100644 --- a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java +++ b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy @@ -13,28 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.idea.devkit.codeInsight; - -import com.intellij.codeInsight.TargetElementUtilBase; -import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.openapi.application.PluginPathManager; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.psi.ElementDescriptionUtil; -import com.intellij.psi.PsiElement; -import com.intellij.testFramework.PsiTestUtil; -import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; -import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; -import com.intellij.testFramework.fixtures.TempDirTestFixture; -import com.intellij.usageView.UsageViewNodeTextLocation; -import com.intellij.usageView.UsageViewTypeLocation; -import com.intellij.util.xml.DeprecatedClassUsageInspection; -import org.jetbrains.idea.devkit.inspections.*; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; - +package org.jetbrains.idea.devkit.codeInsight +import com.intellij.codeInsight.TargetElementUtilBase +import com.intellij.codeInsight.completion.CompletionType +import com.intellij.codeInspection.LocalInspectionTool +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.PluginPathManager +import com.intellij.psi.ElementDescriptionUtil +import com.intellij.psi.PsiElement +import com.intellij.testFramework.PsiTestUtil +import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory +import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase +import com.intellij.testFramework.fixtures.TempDirTestFixture +import com.intellij.usageView.UsageViewNodeTextLocation +import com.intellij.usageView.UsageViewTypeLocation +import com.intellij.util.xml.DeprecatedClassUsageInspection +import org.jetbrains.idea.devkit.inspections.* /** * @author peter */ @@ -124,14 +118,8 @@ public class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase { } private void addPluginXml(final String root, final String text) throws IOException { - myTempDirFixture.createFile(root + - "/META-INF/plugin.xml", text); - new WriteCommandAction(getProject()) { - @Override - protected void run(Result result) throws Throwable { - PsiTestUtil.addSourceContentToRoots(myModule, myTempDirFixture.getFile(root)); - } - }.execute(); + myTempDirFixture.createFile(root + "/META-INF/plugin.xml", text); + ApplicationManager.application.runWriteAction { PsiTestUtil.addSourceContentToRoots(myModule, myTempDirFixture.getFile(root)) } } public void testNoWordCompletionInClassPlaces() throws Throwable { @@ -152,6 +140,27 @@ public class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase { myFixture.checkResultByFile(getTestName(false) + "_after.xml"); } + public void testShowPackagesInActionClass() { + myFixture.addClass("package com.intellij.openapi.actionSystem; public class AnAction { }"); + myFixture.addClass("package foo.bar; public class BarAction extends com.intellij.openapi.actionSystem.AnAction { }"); + myFixture.addClass("package foo.goo; public class GooAction extends com.intellij.openapi.actionSystem.AnAction { }"); + myFixture.configureByFile(getTestName(false) + ".xml"); + myFixture.completeBasic(); + assert myFixture.lookupElementStrings == ['bar', 'goo'] + assert myFixture.lookup.advertisements.find { it.contains('to see inheritors of com.intellij.openapi.actionSystem.AnAction') } + } + + public void testShowAnActionInheritorsOnSmartCompletion() { + myFixture.addClass("package com.intellij.openapi.actionSystem; public class AnAction { }"); + myFixture.addClass("package foo.bar; public class BarAction extends com.intellij.openapi.actionSystem.AnAction { }"); + myFixture.addClass("package foo.goo; public class GooAction extends com.intellij.openapi.actionSystem.AnAction { }"); + myFixture.addClass("package another.goo; public class AnotherAction extends com.intellij.openapi.actionSystem.AnAction { }"); + myFixture.configureByFile(getTestName(false) + ".xml"); + myFixture.complete(CompletionType.SMART); + assert myFixture.lookupElementStrings == ['foo.bar.BarAction', 'foo.goo.GooAction'] + assert !myFixture.lookup.advertisements.find { it.contains('to see inheritors of com.intellij.openapi.actionSystem.AnAction') } + } + public void testDeprecatedExtensionAttribute() { myFixture.enableInspections(DeprecatedClassUsageInspection.class); myFixture.testHighlighting("deprecatedExtensionAttribute.xml", "MyExtBean.java"); From 18b7ea11fdc3486af04b5e4fa4e708b5b0d0d523 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 16 Oct 2012 16:16:00 +0200 Subject: [PATCH 28/57] do not override default values if corresponding attributes is missing from the xml --- .../java/impl/compiler/ProcessorConfigProfileImpl.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/ProcessorConfigProfileImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/ProcessorConfigProfileImpl.java index 3ee4e8b9f045..c7a1403441fe 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/ProcessorConfigProfileImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/ProcessorConfigProfileImpl.java @@ -113,14 +113,11 @@ public final class ProcessorConfigProfileImpl implements ProcessorConfigProfile @Override public void setGeneratedSourcesDirectoryName(@Nullable String name, boolean forTests) { - if (name == null || name.trim().isEmpty()) { - name = ""; - } if (forTests) { - myGeneratedTestsDirectoryName = name; + myGeneratedTestsDirectoryName = name != null? name.trim() : DEFAULT_TESTS_DIR_NAME; } else { - myGeneratedProductionDirectoryName = name; + myGeneratedProductionDirectoryName = name != null? name.trim() : DEFAULT_PRODUCTION_DIR_NAME; } } From 57bcfa36a84291a83499606bfcab204329cc879c Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 16 Oct 2012 18:28:10 +0400 Subject: [PATCH 29/57] EA-39331 - CCE: MavenPathReferenceConverter$$.innerResolveInContext --- .../maven/dom/references/MavenPathReferenceConverter.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPathReferenceConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPathReferenceConverter.java index 7cdcc5204945..86a28d2adf56 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPathReferenceConverter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPathReferenceConverter.java @@ -24,6 +24,7 @@ import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet; import com.intellij.util.xml.ConvertContext; +import com.intellij.util.xml.DomElement; import com.intellij.util.xml.DomUtil; import com.intellij.util.xml.GenericDomValue; import com.intellij.util.xml.converters.PathReferenceConverter; @@ -78,10 +79,13 @@ public class MavenPathReferenceConverter extends PathReferenceConverter { Collection result, boolean caseSensitive) { if (model == null) { - model = (MavenDomProjectModel)DomUtil.getFileElement(genericDomValue).getRootElement(); + DomElement rootElement = DomUtil.getFileElement(genericDomValue).getRootElement(); + if (rootElement instanceof MavenDomProjectModel) { + model = (MavenDomProjectModel)rootElement; + } } - String resolvedText = MavenPropertyResolver.resolve(text, model); + String resolvedText = model == null ? text : MavenPropertyResolver.resolve(text, model); if (resolvedText.equals(text)) { super.innerResolveInContext(resolvedText, context, result, caseSensitive); From b7244a22b7ce36d3c6bf4a7f754ec2ecfe14ba61 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 16 Oct 2012 18:56:30 +0400 Subject: [PATCH 30/57] test for configurable mappings --- .../intellij/openapi/options/ex/ConfigurableWrapper.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java index cdd01d2ff80a..e981d43b83f5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.options.ex; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; @@ -42,6 +43,7 @@ public class ConfigurableWrapper implements SearchableConfigurable { return wrapConfigurable(ep); } }; + private static final Logger LOG = Logger.getInstance(ConfigurableWrapper.class); @Nullable public static T wrapConfigurable(ConfigurableEP ep) { @@ -80,11 +82,11 @@ public class ConfigurableWrapper implements SearchableConfigurable { private UnnamedConfigurable myConfigurable; - protected UnnamedConfigurable getConfigurable() { + public UnnamedConfigurable getConfigurable() { if (myConfigurable == null) { myConfigurable = myEp.createConfigurable(); if (myConfigurable == null) { - System.out.println("oops"); + LOG.error("Can't instantiate configurable for " + myEp); } } return myConfigurable; From f2298c83e89435c192418b50d94f362880ea0eeb Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 16 Oct 2012 14:29:04 +0400 Subject: [PATCH 31/57] notnull --- .../intellij/execution/ui/RunnerLayoutUi.java | 9 ++- .../ui/actions/AbstractFocusOnAction.java | 6 +- .../ui/layout/LayoutStateDefaults.java | 9 ++- .../ui/layout/LayoutViewOptions.java | 13 +++- .../actions/ToggleToolbarLayoutAction.java | 5 +- .../ui/layout/impl/RunnerContentUi.java | 60 ++++++++------- .../ui/layout/impl/RunnerLayout.java | 72 ++++++++++-------- .../ui/layout/impl/RunnerLayoutSettings.java | 5 +- .../impl/RunnerLayoutUiFactoryImpl.java | 2 + .../ui/layout/impl/RunnerLayoutUiImpl.java | 76 ++++++++++++++++--- .../execution/ui/layout/impl/TabImpl.java | 5 ++ .../intellij/ui/docking/DockableContent.java | 3 +- .../impl/EditorTabbedContainer.java | 1 + 13 files changed, 180 insertions(+), 86 deletions(-) diff --git a/platform/lang-api/src/com/intellij/execution/ui/RunnerLayoutUi.java b/platform/lang-api/src/com/intellij/execution/ui/RunnerLayoutUi.java index e5c6f004b1e1..68131d6429c8 100644 --- a/platform/lang-api/src/com/intellij/execution/ui/RunnerLayoutUi.java +++ b/platform/lang-api/src/com/intellij/execution/ui/RunnerLayoutUi.java @@ -47,7 +47,7 @@ public interface RunnerLayoutUi { Content addContent(@NotNull Content content); @NotNull - Content addContent(@NotNull Content content, int defaultTabId, PlaceInGrid defaultPlace, boolean defaultIsMinimized); + Content addContent(@NotNull Content content, int defaultTabId, @NotNull PlaceInGrid defaultPlace, boolean defaultIsMinimized); @NotNull Content createContent(@NotNull String contentId, @NotNull JComponent component, @NotNull String displayName, @Nullable Icon icon, @Nullable JComponent toFocus); @@ -60,15 +60,18 @@ public interface RunnerLayoutUi { @Nullable Content findContent(@NotNull String contentId); + @NotNull ActionCallback selectAndFocus(@Nullable Content content, boolean requestFocus, final boolean forced); + @NotNull ActionCallback selectAndFocus(@Nullable Content content, boolean requestFocus, final boolean forced, final boolean implicit); + @NotNull RunnerLayoutUi addListener(@NotNull ContentManagerListener listener, @NotNull Disposable parent); void removeListener(@NotNull final ContentManagerListener listener); void attractBy(@NotNull String condition); - void clearAttractionBy(final String condition); + void clearAttractionBy(@NotNull String condition); void setBouncing(@NotNull Content content, final boolean activate); @@ -79,6 +82,7 @@ public interface RunnerLayoutUi { void updateActionsNow(); + @NotNull Content[] getContents(); abstract class Factory { @@ -89,6 +93,7 @@ public interface RunnerLayoutUi { return ServiceManager.getService(project, Factory.class); } + @NotNull public abstract RunnerLayoutUi create(@NotNull String runnerId, @NotNull String runnerTitle, @NotNull String sessionName, @NotNull Disposable parent); } diff --git a/platform/lang-api/src/com/intellij/execution/ui/actions/AbstractFocusOnAction.java b/platform/lang-api/src/com/intellij/execution/ui/actions/AbstractFocusOnAction.java index 198fe1c6e4fb..02f6d4956b90 100644 --- a/platform/lang-api/src/com/intellij/execution/ui/actions/AbstractFocusOnAction.java +++ b/platform/lang-api/src/com/intellij/execution/ui/actions/AbstractFocusOnAction.java @@ -20,14 +20,17 @@ import com.intellij.execution.ui.layout.ViewContext; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Toggleable; import com.intellij.ui.content.Content; +import org.jetbrains.annotations.NotNull; public class AbstractFocusOnAction extends BaseViewAction implements Toggleable { + @NotNull private final String myCondition; - public AbstractFocusOnAction(String condition) { + public AbstractFocusOnAction(@NotNull String condition) { myCondition = condition; } + @Override protected void update(final AnActionEvent e, final ViewContext context, final Content[] content) { final boolean visible = content.length == 1; e.getPresentation().setVisible(visible); @@ -40,6 +43,7 @@ public class AbstractFocusOnAction extends BaseViewAction implements Toggleable return context.getRunnerLayoutUi().getOptions().isToFocus(content[0], myCondition); } + @Override protected void actionPerformed(final AnActionEvent e, final ViewContext context, final Content[] content) { final boolean toFocus = isToFocus(context, content); context.getRunnerLayoutUi().getOptions().setToFocus(toFocus ? null : content[0], myCondition); diff --git a/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutStateDefaults.java b/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutStateDefaults.java index b19d6a93b46a..17c69166f8a1 100644 --- a/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutStateDefaults.java +++ b/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutStateDefaults.java @@ -22,11 +22,12 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; public interface LayoutStateDefaults { - + @NotNull //this LayoutStateDefaults initTabDefaults(int tabId, @Nullable String defaultTabText, @Nullable Icon defaultTabIcon); - LayoutStateDefaults initFocusContent(@NotNull String id, final String condition); - - LayoutStateDefaults initFocusContent(@NotNull String id, final String condition, @NotNull final LayoutAttractionPolicy policy); + @NotNull // this + LayoutStateDefaults initFocusContent(@NotNull String id, @NotNull String condition); + @NotNull //this + LayoutStateDefaults initFocusContent(@NotNull String id, @NotNull String condition, @NotNull final LayoutAttractionPolicy policy); } \ No newline at end of file diff --git a/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java b/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java index d0faa6782ec0..bd24a4a8af92 100644 --- a/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java +++ b/platform/lang-api/src/com/intellij/execution/ui/layout/LayoutViewOptions.java @@ -29,6 +29,7 @@ public interface LayoutViewOptions { @NotNull LayoutViewOptions setTopToolbar(@NotNull ActionGroup actions, @NotNull String place); + @NotNull LayoutViewOptions setLeftToolbar(@NotNull ActionGroup leftToolbar, @NotNull String place); @NotNull @@ -39,17 +40,23 @@ public interface LayoutViewOptions { @NotNull LayoutViewOptions setAttractionPolicy(@NotNull String contentId, LayoutAttractionPolicy policy); + + @NotNull LayoutViewOptions setConditionAttractionPolicy(@NotNull String condition, LayoutAttractionPolicy policy); - boolean isToFocus(Content content, final String condition); + boolean isToFocus(@NotNull Content content, @NotNull String condition); - LayoutViewOptions setToFocus(@Nullable Content content, final String condition); + @NotNull + LayoutViewOptions setToFocus(@Nullable Content content, @NotNull String condition); AnAction getLayoutActions(); + @NotNull AnAction[] getLayoutActionsList(); - LayoutViewOptions setAdditionalFocusActions(ActionGroup group); + @NotNull + LayoutViewOptions setAdditionalFocusActions(@NotNull ActionGroup group); AnAction getSettingsActions(); + @NotNull AnAction[] getSettingsActionsList(); } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/ToggleToolbarLayoutAction.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/ToggleToolbarLayoutAction.java index e6106488c0ad..c9ccade706fb 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/ToggleToolbarLayoutAction.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/ToggleToolbarLayoutAction.java @@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable; public class ToggleToolbarLayoutAction extends ToggleAction { + @Override public void update(final AnActionEvent e) { if (getRunnerUi(e) == null) { e.getPresentation().setEnabled(false); @@ -31,11 +32,13 @@ public class ToggleToolbarLayoutAction extends ToggleAction { } } + @Override public boolean isSelected(final AnActionEvent e) { final RunnerContentUi ui = getRunnerUi(e); - return ui != null ? ui.isHorizontalToolbar() : false; + return ui != null && ui.isHorizontalToolbar(); } + @Override public void setSelected(final AnActionEvent e, final boolean state) { getRunnerUi(e).setHorizontalToolbar(state); } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java index f010e6c71741..0a20452ae039 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java @@ -69,18 +69,19 @@ import java.util.concurrent.CopyOnWriteArraySet; public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Facade, ViewContextEx, PropertyChangeListener, SwitchProvider, QuickActionProvider, DockContainer.Dialog { + public static final DataKey KEY = DataKey.create("DebuggerContentUI"); - @NonNls public static final String LAYOUT = "Runner.Layout"; - @NonNls public static final String SETTINGS = "XDebugger.Settings"; - @NonNls public static final String VIEW_POPUP = "Runner.View.Popup"; - @NonNls public static final String VIEW_TOOLBAR = "Runner.View.Toolbar"; + @NonNls private static final String LAYOUT = "Runner.Layout"; + @NonNls private static final String SETTINGS = "XDebugger.Settings"; + @NonNls private static final String VIEW_POPUP = "Runner.View.Popup"; + @NonNls static final String VIEW_TOOLBAR = "Runner.View.Toolbar"; - ContentManager myManager; - RunnerLayout myLayoutSettings; + private ContentManager myManager; + private final RunnerLayout myLayoutSettings; - ActionManager myActionManager; - String mySessionName; - MyComponent myComponent = new MyComponent(); + private final ActionManager myActionManager; + private final String mySessionName; + private final MyComponent myComponent = new MyComponent(); private final Wrapper myToolbar = new Wrapper(); final MyDragOutDelegate myDragOutDelegate = new MyDragOutDelegate(); @@ -96,20 +97,19 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac return index1 - index2; } }; - Project myProject; + private final Project myProject; - ActionGroup myTopActions = new DefaultActionGroup(); + private ActionGroup myTopActions = new DefaultActionGroup(); - DefaultActionGroup myMinimizedViewActions = new DefaultActionGroup(); + private final DefaultActionGroup myMinimizedViewActions = new DefaultActionGroup(); - Map myMinimizedButtonsPlaceholder = new HashMap(); - Map myCommonActionsPlaceholder = new HashMap(); - Map myContextActions = new HashMap(); + private final Map myMinimizedButtonsPlaceholder = new HashMap(); + private final Map myCommonActionsPlaceholder = new HashMap(); + private final Map myContextActions = new HashMap(); - boolean myUiLastStateWasRestored; + private boolean myUiLastStateWasRestored; private final Set myRestoreStateRequestors = new HashSet(); - public static final DataKey KEY = DataKey.create("DebuggerContentUI"); private String myActionsPlace = ActionPlaces.UNKNOWN; private final IdeFocusManager myFocusManager; @@ -132,8 +132,8 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac private Image myCurrentOverImg; private TabInfo myCurrentOverInfo; private RunnerContentUi myOriginal; - private CopyOnWriteArraySet myDockingListeners = new CopyOnWriteArraySet(); - private Set myChildren = new TreeSet(new Comparator() { + private final CopyOnWriteArraySet myDockingListeners = new CopyOnWriteArraySet(); + private final Set myChildren = new TreeSet(new Comparator() { @Override public int compare(RunnerContentUi o1, RunnerContentUi o2) { return o1.myWindow - o2.myWindow; @@ -142,12 +142,12 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac private int myWindow; private boolean myDisposing; - public RunnerContentUi(Project project, - RunnerLayoutUi ui, - ActionManager actionManager, - IdeFocusManager focusManager, - RunnerLayout settings, - String sessionName) { + public RunnerContentUi(@NotNull Project project, + @NotNull RunnerLayoutUi ui, + @NotNull ActionManager actionManager, + @NotNull IdeFocusManager focusManager, + @NotNull RunnerLayout settings, + @NotNull String sessionName) { myProject = project; myRunnerUi = ui; myLayoutSettings = settings; @@ -156,7 +156,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac myFocusManager = focusManager; } - public RunnerContentUi(RunnerContentUi ui, RunnerContentUi original, int window) { + public RunnerContentUi(@NotNull RunnerContentUi ui, @NotNull RunnerContentUi original, int window) { this(ui.myProject, ui.myRunnerUi, ui.myActionManager, ui.myFocusManager, ui.myLayoutSettings, ui.mySessionName); myOriginal = original; original.myChildren.add(this); @@ -1282,7 +1282,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac processAttraction(content.getUserData(ViewImpl.ID), myAttractions, new LayoutAttractionPolicy.Bounce(), afterInitialized, true); } - public void attractByCondition(String condition, boolean afterInitialized) { + public void attractByCondition(@NotNull String condition, boolean afterInitialized) { processAttraction(myLayoutSettings.getToFocus(condition), myConditionAttractions, myLayoutSettings.getAttractionPolicy(condition), afterInitialized, true); } @@ -1639,8 +1639,8 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac } class DockableGrid implements DockableContent> { - final Image myImg; - private Presentation myPresentation; + private final Image myImg; + private final Presentation myPresentation; private final Dimension myPreferredSize; private final List myContents; private final int myWindow; @@ -1653,6 +1653,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac myWindow = window; } + @NotNull @Override public List getKey() { return myContents; @@ -1686,6 +1687,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac return myOriginal != null ? myOriginal : RunnerContentUi.this; } + @NotNull public List getContents() { return myContents; } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayout.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayout.java index 2f6dbc88635c..bb95ef2dd9fe 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayout.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayout.java @@ -52,7 +52,7 @@ public class RunnerLayout { private final Map> myDefaultFocus = new HashMap>(); - public RunnerLayout(final String ID) { + public RunnerLayout(@NotNull String ID) { myID = ID; } @@ -72,17 +72,17 @@ public class RunnerLayout { return tab; } + @NotNull private TabImpl createNewTab(final int index) { - final TabImpl tab; - final TabImpl.Default defaultTab = getOrCreateDefaultTab(index); - tab = defaultTab.createTab(); + final TabImpl tab = defaultTab.createTab(); myTabs.add(tab); return tab; } + @NotNull private TabImpl.Default getOrCreateDefaultTab(final int index) { TabImpl.Default tab = myDefaultTabs.get(index); if (tab == null) { @@ -92,6 +92,7 @@ public class RunnerLayout { return tab; } + @NotNull public TabImpl createNewTab() { int index = 0; for (TabImpl each : myTabs) { @@ -108,7 +109,7 @@ public class RunnerLayout { return createNewTab(index); } - private boolean isUsed(TabImpl tab) { + private boolean isUsed(@NotNull TabImpl tab) { for (ViewImpl each : myViews.values()) { if (each.getTab() == tab) return true; } @@ -125,15 +126,17 @@ public class RunnerLayout { return null; } + @NotNull public Element getState() { return write(new Element("layout")); } - public void loadState(final Element state) { + public void loadState(@NotNull Element state) { read(state); } - public Element read(final Element parentNode) { + @NotNull + public Element read(@NotNull Element parentNode) { List tabs = parentNode.getChildren(StringUtil.getShortName(TabImpl.class.getName())); for (Object eachTabElement : tabs) { TabImpl eachTab = new TabImpl((Element)eachTabElement); @@ -151,7 +154,8 @@ public class RunnerLayout { return parentNode; } - public Element write(final Element parentNode) { + @NotNull + public Element write(@NotNull Element parentNode) { for (ViewImpl eachState : myViews.values()) { eachState.write(parentNode); } @@ -181,11 +185,12 @@ public class RunnerLayout { myGeneral.horizontalToolbar = horizontal; } - public ViewImpl getStateFor(Content content) { + @NotNull + public ViewImpl getStateFor(@NotNull Content content) { return getOrCreateView(getOrCreateContentId(content)); } - public void clearStateFor(Content content) { + public void clearStateFor(@NotNull Content content) { final ViewImpl view = myViews.remove(getOrCreateContentId(content)); if (view != null) { final Tab tab = view.getTab(); @@ -195,7 +200,8 @@ public class RunnerLayout { } } - private static String getOrCreateContentId(final Content content) { + @NotNull + private static String getOrCreateContentId(@NotNull Content content) { @NonNls String id = content.getUserData(ViewImpl.ID); if (id == null) { id = "UnknownView-" + content.getDisplayName(); @@ -204,71 +210,71 @@ public class RunnerLayout { return id; } - private ViewImpl getOrCreateView(String id) { + @NotNull + private ViewImpl getOrCreateView(@NotNull String id) { if (myViews.containsKey(id)) { return myViews.get(id); - } else { - final ViewImpl.Default defaultView = getOrCreateDefault(id); - final ViewImpl view = defaultView.createView(this); - myViews.put(id, view); - return view; } + final ViewImpl.Default defaultView = getOrCreateDefault(id); + final ViewImpl view = defaultView.createView(this); + myViews.put(id, view); + return view; } - private ViewImpl.Default getOrCreateDefault(String id) { + @NotNull + private ViewImpl.Default getOrCreateDefault(@NotNull String id) { if (myDefaultViews.containsKey(id)) { return myDefaultViews.get(id); - } else { - return setDefault(id, Integer.MAX_VALUE, PlaceInGrid.bottom, false); } + return setDefault(id, Integer.MAX_VALUE, PlaceInGrid.bottom, false); } + @NotNull public TabImpl.Default setDefault(int tabID, String displayName, Icon icon) { final TabImpl.Default tab = new TabImpl.Default(tabID, displayName, icon); myDefaultTabs.put(tabID, tab); return tab; } - public ViewImpl.Default setDefault(String id, int tabIndex, PlaceInGrid placeInGrid, boolean isMinimized) { + @NotNull + public ViewImpl.Default setDefault(@NotNull String id, int tabIndex, @NotNull PlaceInGrid placeInGrid, boolean isMinimized) { final ViewImpl.Default view = new ViewImpl.Default(id, tabIndex, placeInGrid, isMinimized); myDefaultViews.put(id, view); return view; } - public PlaceInGrid getDefaultGridPlace(final Content content) { + @NotNull + public PlaceInGrid getDefaultGridPlace(@NotNull Content content) { return getOrCreateDefault(getOrCreateContentId(content)).getPlaceInGrid(); } - public int getDefaultSelectedTabIndex() { - return 0; - } - - public boolean isToFocus(final String id, final String condition) { + public boolean isToFocus(final String id, @NotNull String condition) { return Comparing.equal(id, getToFocus(condition)); } - public void setToFocus(final String id, final String condition) { + public void setToFocus(final String id, @NotNull String condition) { myGeneral.focusOnCondition.put(condition, id); } - public void setDefaultToFocus(String id, final String condition, @NotNull final LayoutAttractionPolicy policy) { + public void setDefaultToFocus(@NotNull String id, @NotNull String condition, @NotNull final LayoutAttractionPolicy policy) { myDefaultFocus.put(condition, Pair.create(id, policy)); } @Nullable - public String getToFocus(final String condition) { - return myGeneral.focusOnCondition.containsKey(condition) ? myGeneral.focusOnCondition.get(condition) : (myDefaultFocus.containsKey(condition) ? myDefaultFocus.get(condition).getFirst() : null); + public String getToFocus(@NotNull String condition) { + return myGeneral.focusOnCondition.containsKey(condition) ? myGeneral.focusOnCondition.get(condition) : + myDefaultFocus.containsKey(condition) ? myDefaultFocus.get(condition).getFirst() : null; } - public LayoutAttractionPolicy getAttractionPolicy(final String condition) { + @NotNull + public LayoutAttractionPolicy getAttractionPolicy(@NotNull String condition) { final Pair pair = myDefaultFocus.get(condition); return pair == null ? new LayoutAttractionPolicy.FocusOnce() : pair.getSecond(); } public static class General { public volatile boolean horizontalToolbar = false; - public volatile int selectedTab = 0; public volatile Map focusOnCondition = new HashMap(); } } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutSettings.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutSettings.java index 060c5d5d3994..decdcba56bf6 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutSettings.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutSettings.java @@ -18,6 +18,7 @@ package com.intellij.execution.ui.layout.impl; import com.intellij.openapi.components.*; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import java.util.LinkedHashMap; import java.util.List; @@ -34,7 +35,7 @@ public class RunnerLayoutSettings implements PersistentStateComponent { private final Map myRunnerId2Settings = new LinkedHashMap(); - public RunnerLayout getLayout(String id) { + public RunnerLayout getLayout(@NotNull String id) { RunnerLayout layout = myRunnerId2Settings.get(id); if (layout == null) { layout = new RunnerLayout(id); @@ -44,6 +45,7 @@ public class RunnerLayoutSettings implements PersistentStateComponent { return layout; } + @Override public Element getState() { final Element runners = new Element("runners"); for (String eachID : myRunnerId2Settings.keySet()) { @@ -56,6 +58,7 @@ public class RunnerLayoutSettings implements PersistentStateComponent { return runners; } + @Override public void loadState(final Element state) { final List runners = state.getChildren("runner"); for (Object each : runners) { diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiFactoryImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiFactoryImpl.java index adc11e73663b..313f7237fa48 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiFactoryImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiFactoryImpl.java @@ -28,6 +28,8 @@ public class RunnerLayoutUiFactoryImpl extends RunnerLayoutUi.Factory { myProject = project; } + @NotNull + @Override public RunnerLayoutUi create(@NotNull final String runnerId, @NotNull final String runnerTitle, @NotNull final String sessionName, @NotNull final Disposable parent) { return new RunnerLayoutUiImpl(myProject, parent, runnerId, runnerTitle, sessionName); } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java index 7b5ec5a58e89..00e2ecb2b8a1 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java @@ -54,7 +54,11 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La private final ContentManager myViewsContentManager; public static final Key CONTENT_TYPE = Key.create("ContentType"); - public RunnerLayoutUiImpl(Project project, Disposable parent, String runnerId, String runnerTitle, String sessionName) { + public RunnerLayoutUiImpl(@NotNull Project project, + @NotNull Disposable parent, + @NotNull String runnerId, + @NotNull String runnerTitle, + @NotNull String sessionName) { myLayout = RunnerLayoutSettings.getInstance().getLayout(runnerId); Disposer.register(parent, this); @@ -69,6 +73,7 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La myContentPanel.add(myViewsContentManager.getComponent(), BorderLayout.CENTER); } + @Override @NotNull public LayoutViewOptions setTopToolbar(@NotNull ActionGroup actions, @NotNull String place) { myContentUI.setTopActions(actions, place); @@ -76,31 +81,39 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La } + @NotNull + @Override public LayoutStateDefaults initTabDefaults(int id, String text, Icon icon) { getLayout().setDefault(id, text, icon); return this; } + @NotNull + @Override public LayoutStateDefaults initFocusContent(@NotNull final String id, @NotNull final String condition) { return initFocusContent(id, condition, new LayoutAttractionPolicy.FocusOnce()); } + @NotNull + @Override public LayoutStateDefaults initFocusContent(@NotNull final String id, @NotNull final String condition, @NotNull final LayoutAttractionPolicy policy) { getLayout().setDefaultToFocus(id, condition, policy); return this; } + @Override @NotNull public Content addContent(@NotNull Content content) { return addContent(content, false, -1, PlaceInGrid.center, false); } + @Override @NotNull - public Content addContent(@NotNull Content content, int defaultTabId, PlaceInGrid defaultPlace, boolean defaultIsMinimized) { + public Content addContent(@NotNull Content content, int defaultTabId, @NotNull PlaceInGrid defaultPlace, boolean defaultIsMinimized) { return addContent(content, true, defaultTabId, defaultPlace, defaultIsMinimized); } - public Content addContent(Content content, boolean applyDefaults, int defaultTabId, PlaceInGrid defaultPlace, boolean defaultIsMinimized) { + public Content addContent(@NotNull Content content, boolean applyDefaults, int defaultTabId, @NotNull PlaceInGrid defaultPlace, boolean defaultIsMinimized) { final String id = content.getUserData(CONTENT_TYPE); assert id != null : "Content id is missing, use RunnerLayoutUi to create content instances"; @@ -113,11 +126,13 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La return content; } + @Override @NotNull public Content createContent(@NotNull String id, @NotNull JComponent component, @NotNull String displayName, @Nullable Icon icon, @Nullable JComponent focusable) { return createContent(id, new ComponentWithActions.Impl(component), displayName, icon, focusable); } + @Override @NotNull public Content createContent(@NotNull final String contentId, @NotNull final ComponentWithActions withActions, @NotNull final String displayName, @Nullable final Icon icon, @@ -138,6 +153,7 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La return content; } + @Override @NotNull public JComponent getComponent() { return myContentPanel; @@ -151,6 +167,7 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La return myLayout; } + @Override public void updateActionsNow() { myContentUI.updateActionsImmediately(); } @@ -160,18 +177,24 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La myContentUI.saveUiState(); } + @Override public void dispose() { } + @Override @NotNull public ContentManager getContentManager() { return myViewsContentManager; } + @NotNull + @Override public ActionCallback selectAndFocus(@Nullable final Content content, boolean requestFocus, final boolean forced) { return selectAndFocus(content, requestFocus, forced, false); } + @NotNull + @Override public ActionCallback selectAndFocus(@Nullable final Content content, boolean requestFocus, final boolean forced, boolean implicit) { if (content == null) return new ActionCallback.Rejected(); return getContentManager(content).setSelectedContent(content, requestFocus || shouldRequestFocus(), forced, implicit); @@ -186,59 +209,73 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La return focused != null && SwingUtilities.isDescendingFrom(focused, getContentManager().getComponent()); } - public boolean removeContent(final Content content, final boolean dispose) { - if (content == null) return false; - return getContentManager().removeContent(content, dispose); + @Override + public boolean removeContent(@Nullable Content content, final boolean dispose) { + return content != null && getContentManager().removeContent(content, dispose); } - public boolean isToFocus(final Content content, final String condition) { + @Override + public boolean isToFocus(@NotNull final Content content, @NotNull final String condition) { final String id = content.getUserData(ViewImpl.ID); return getLayout().isToFocus(id, condition); } - public LayoutViewOptions setToFocus(@Nullable final Content content, final String condition) { + @NotNull + @Override + public LayoutViewOptions setToFocus(@Nullable final Content content, @NotNull final String condition) { getLayout().setToFocus(content != null ? content.getUserData(ViewImpl.ID) : null, condition); return this; } + @Override public void attractBy(@NotNull final String condition) { myContentUI.attractByCondition(condition, true); } - public void clearAttractionBy(final String condition) { + @Override + public void clearAttractionBy(@NotNull final String condition) { myContentUI.clearAttractionByCondition(condition, true); } - public void removeContent(String id, final boolean dispose) { + public void removeContent(@NotNull String id, final boolean dispose) { final Content content = findContent(id); if (content != null) { getContentManager().removeContent(content, dispose); } } + @Override public AnAction getLayoutActions() { return myContentUI.getLayoutActions(); } + @NotNull + @Override public AnAction[] getLayoutActionsList() { final ActionGroup group = (ActionGroup)getLayoutActions(); return group.getChildren(null); } + @NotNull + @Override public LayoutViewOptions setLeftToolbar(@NotNull final ActionGroup leftToolbar, @NotNull final String place) { myContentUI.setLeftToolbar(leftToolbar, place); return this; } + @Override @Nullable public Content findContent(@NotNull final String key) { return myContentUI.findContent(key); } + @NotNull + @Override public RunnerLayoutUi addListener(@NotNull final ContentManagerListener listener, @NotNull final Disposable parent) { final ContentManager mgr = getContentManager(); mgr.addContentManagerListener(listener); Disposer.register(parent, new Disposable() { + @Override public void dispose() { mgr.removeContentManagerListener(listener); } @@ -246,19 +283,23 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La return this; } + @Override public void removeListener(@NotNull final ContentManagerListener listener) { getContentManager().removeContentManagerListener(listener); } + @Override public void setBouncing(@NotNull final Content content, final boolean activate) { myContentUI.processBounce(content, activate); } + @Override public boolean isDisposed() { return getContentManager().isDisposed(); } + @Override @NotNull public LayoutViewOptions setMinimizeActionEnabled(final boolean enabled) { myContentUI.setMinimizeActionEnabled(enabled); @@ -270,34 +311,42 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La return this; } + @Override @NotNull public LayoutViewOptions setMoveToGridActionEnabled(final boolean enabled) { myContentUI.setMovetoGridActionEnabled(enabled); return this; } + @Override @NotNull public LayoutViewOptions setAttractionPolicy(@NotNull final String contentId, final LayoutAttractionPolicy policy) { myContentUI.setPolicy(contentId, policy); return this; } + @NotNull + @Override public LayoutViewOptions setConditionAttractionPolicy(@NotNull final String condition, final LayoutAttractionPolicy policy) { myContentUI.setConditionPolicy(condition, policy); return this; } + @Override @NotNull public LayoutStateDefaults getDefaults() { return this; } + @Override @NotNull public LayoutViewOptions getOptions() { return this; } - public LayoutViewOptions setAdditionalFocusActions(final ActionGroup group) { + @NotNull + @Override + public LayoutViewOptions setAdditionalFocusActions(@NotNull final ActionGroup group) { myContentUI.setAdditionalFocusActions(group); return this; } @@ -307,11 +356,15 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La return myContentUI.getSettingsActions(); } + @NotNull + @Override public AnAction[] getSettingsActionsList() { final ActionGroup group = (ActionGroup)getSettingsActions(); return group.getChildren(null); } + @NotNull + @Override public Content[] getContents() { Content[] contents = new Content[getContentManager().getContentCount()]; for (int i = 0; i < contents.length; i++) { @@ -325,6 +378,7 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La super(new BorderLayout()); } + @Override public Object getData(@NonNls String dataId) { if (SwitchProvider.KEY.getName().equals(dataId)) { return myContentUI; diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/TabImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/TabImpl.java index 673c7bbe9898..bfa546d008db 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/TabImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/TabImpl.java @@ -36,10 +36,12 @@ public class TabImpl extends AbstractTab implements Tab { TabImpl() { } + @Override public int getIndex() { return myIndex; } + @Override public int getDefaultIndex() { return myDefaultIndex >= 0 ? myDefaultIndex : myIndex; } @@ -129,10 +131,12 @@ public class TabImpl extends AbstractTab implements Tab { myBottomDetached = bottomDetached; } + @Override public boolean isDefault() { return myIndex == 0; } + @Override public boolean isDetached(PlaceInGrid place) { switch (place) { case bottom: @@ -148,6 +152,7 @@ public class TabImpl extends AbstractTab implements Tab { return false; } + @Override public void setDetached(PlaceInGrid place, boolean detached) { switch (place) { case bottom: diff --git a/platform/platform-api/src/com/intellij/ui/docking/DockableContent.java b/platform/platform-api/src/com/intellij/ui/docking/DockableContent.java index e4981fb47eb4..2fcbc4e7e8f3 100644 --- a/platform/platform-api/src/com/intellij/ui/docking/DockableContent.java +++ b/platform/platform-api/src/com/intellij/ui/docking/DockableContent.java @@ -16,11 +16,12 @@ package com.intellij.ui.docking; import com.intellij.openapi.actionSystem.Presentation; +import org.jetbrains.annotations.NotNull; import java.awt.*; public interface DockableContent { - + @NotNull T getKey(); Image getPreviewImage(); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java index ac515bd374bb..df58b3c97f57 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java @@ -642,6 +642,7 @@ final class EditorTabbedContainer implements Disposable, CloseAction.CloseTarget myPinned = window.isFilePinned(file); } + @NotNull @Override public VirtualFile getKey() { return myFile; From cb8a385d0d5e4b0865e73bd3a6d502fe54b21846 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 16 Oct 2012 17:22:07 +0400 Subject: [PATCH 32/57] cleanup --- .../com/intellij/execution/ui/layout/impl/GridImpl.java | 1 + .../src/com/intellij/usages/impl/PreviewUsageAction.java | 4 ++-- .../src/com/intellij/usages/impl/RuleAction.java | 5 +++-- .../src/com/intellij/usages/impl/UsageTargetNode.java | 1 + .../src/com/intellij/openapi/ui/NullableComponent.java | 9 ++------- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridImpl.java index f023d86d3a9b..2ad716142c98 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridImpl.java @@ -291,6 +291,7 @@ public class GridImpl extends Wrapper implements Grid, Disposable, DataProvider break; case bottom: mySplitter.setProportion(tab.getBottomProportion()); + break; case center: break; } diff --git a/platform/usageView/src/com/intellij/usages/impl/PreviewUsageAction.java b/platform/usageView/src/com/intellij/usages/impl/PreviewUsageAction.java index fd8134466529..d9a58924ad46 100644 --- a/platform/usageView/src/com/intellij/usages/impl/PreviewUsageAction.java +++ b/platform/usageView/src/com/intellij/usages/impl/PreviewUsageAction.java @@ -18,13 +18,13 @@ package com.intellij.usages.impl; import com.intellij.icons.AllIcons; import com.intellij.usageView.UsageViewBundle; import com.intellij.usages.UsageViewSettings; +import org.jetbrains.annotations.NotNull; /** * @author cdr */ class PreviewUsageAction extends RuleAction { - - PreviewUsageAction(UsageViewImpl usageView) { + PreviewUsageAction(@NotNull UsageViewImpl usageView) { super(usageView, UsageViewBundle.message("preview.usages.action.text"), AllIcons.Actions.Preview); } diff --git a/platform/usageView/src/com/intellij/usages/impl/RuleAction.java b/platform/usageView/src/com/intellij/usages/impl/RuleAction.java index 0b7e90177b61..0d4d2be93e15 100644 --- a/platform/usageView/src/com/intellij/usages/impl/RuleAction.java +++ b/platform/usageView/src/com/intellij/usages/impl/RuleAction.java @@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.ToggleAction; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.usages.rules.UsageFilteringRuleProvider; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -28,11 +29,11 @@ import javax.swing.*; * @author Eugene Zhuravlev * Date: Jan 19, 2005 */ -public abstract class RuleAction extends ToggleAction implements DumbAware { +abstract class RuleAction extends ToggleAction implements DumbAware { private final UsageViewImpl myView; private boolean myState; - public RuleAction(UsageViewImpl view, final String text, final Icon icon) { + RuleAction(@NotNull UsageViewImpl view, @NotNull String text, @NotNull Icon icon) { super(text, null, icon); myView = view; myState = getOptionValue(); diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageTargetNode.java b/platform/usageView/src/com/intellij/usages/impl/UsageTargetNode.java index aa1ec1528ca0..d0ee47818f04 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageTargetNode.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageTargetNode.java @@ -58,6 +58,7 @@ public class UsageTargetNode extends Node { return myTarget.getPresentation().getPresentableText(); } + @NotNull public UsageTarget getTarget() { return myTarget; } diff --git a/platform/util/src/com/intellij/openapi/ui/NullableComponent.java b/platform/util/src/com/intellij/openapi/ui/NullableComponent.java index 5e3b7f08850d..aa00d69da338 100644 --- a/platform/util/src/com/intellij/openapi/ui/NullableComponent.java +++ b/platform/util/src/com/intellij/openapi/ui/NullableComponent.java @@ -23,24 +23,19 @@ public interface NullableComponent { boolean isNull(); class Check { - private Check() { } public static boolean isNull(Component c) { - if (c == null) return true; - if (c instanceof NullableComponent) return ((NullableComponent)c).isNull(); - return false; + return c == null || c instanceof NullableComponent && ((NullableComponent)c).isNull(); } public static boolean isNullOrHidden(Component c) { - if (c != null && !c.isShowing()) return true; - return isNull(c); + return c != null && !c.isShowing() || isNull(c); } public static boolean isNotNullAndVisible(Component c) { return !isNull(c) && c.isVisible(); } } - } From 9cd94acc54d58fcbda674d8af1170e948dc40ac9 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 16 Oct 2012 19:07:15 +0400 Subject: [PATCH 33/57] off by 1 --- .../ide/util/gotoByName/ChooseByNameBase.java | 2 +- .../ide/util/gotoByName/ModelDiff.java | 19 ++++++++++++------- .../util/src/com/intellij/util/diff/Diff.java | 7 +++++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 3550a712e443..9e81748a37ab 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -998,7 +998,7 @@ public abstract class ChooseByNameBase { List commands = ModelDiff.createDiffCmds(myListModel, oldElements, newElements); if (commands == null) { myListUpdater.doPostponedOkIfNeeded(); - return; + return; // Nothing changed } myTextField.setForeground(UIUtil.getTextFieldForeground()); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ModelDiff.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ModelDiff.java index 96f4601c1e30..1cef825ab9fc 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ModelDiff.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ModelDiff.java @@ -17,12 +17,15 @@ package com.intellij.ide.util.gotoByName; import com.intellij.util.diff.Diff; import com.intellij.util.diff.FilesTooBigForDiffException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; public class ModelDiff { - public static List createDiffCmds(Model listModel, Object[] oldElements, Object[] newElements) { + @Nullable + public static List createDiffCmds(@NotNull Model listModel, @NotNull Object[] oldElements, @NotNull Object[] newElements) { Diff.Change change = null; try { change = Diff.buildChanges(oldElements, newElements); @@ -41,12 +44,12 @@ public class ModelDiff { while (change != null) { if (change.deleted > 0) { final int start = change.line0 + inserted - deleted; - commands.add(new RemoveCmd(listModel, start, start + change.deleted - 1)); + commands.add(new RemoveCmd(listModel, start, start + change.deleted - 1)); } if (change.inserted > 0) { for (int i = 0; i < change.inserted; i++) { - commands.add(new InsertCmd(listModel, change.line0 + i + inserted - deleted, newElements[change.line1 + i])); + commands.add(new InsertCmd(listModel, change.line0 + i + inserted - deleted, newElements[change.line1 + i])); } } @@ -72,7 +75,7 @@ public class ModelDiff { private final int start; private final int end; - private RemoveCmd(Model model, final int start, final int end) { + private RemoveCmd(@NotNull Model model, final int start, final int end) { myListModel = model; this.start = start; this.end = end; @@ -80,7 +83,8 @@ public class ModelDiff { @Override public void apply() { - myListModel.removeRangeFromModel(start, end+1); + //System.out.println("removing: "+this); + myListModel.removeRangeFromModel(start, end); } @Override @@ -92,7 +96,7 @@ public class ModelDiff { @Override public String toString() { - return "-["+start+", "+end+")"; + return "-["+start+", "+end+"]"; } } @@ -101,7 +105,7 @@ public class ModelDiff { private final int idx; private final T element; - private InsertCmd(Model model, final int idx, T element) { + private InsertCmd(@NotNull Model model, final int idx, @NotNull T element) { myListModel = model; this.idx = idx; this.element = element; @@ -109,6 +113,7 @@ public class ModelDiff { @Override public void apply() { + //System.out.println("Adding: "+this+"-> "+element); myListModel.addToModel(idx, element); } diff --git a/platform/util/src/com/intellij/util/diff/Diff.java b/platform/util/src/com/intellij/util/diff/Diff.java index 2424b60c811e..ee68fade417a 100644 --- a/platform/util/src/com/intellij/util/diff/Diff.java +++ b/platform/util/src/com/intellij/util/diff/Diff.java @@ -37,8 +37,9 @@ public class Diff { final String[] strings2 = LineTokenizer.tokenize(after, false); return buildChanges(strings1, strings2); } - - public static Change buildChanges(T[] objects1, T[] objects2) throws FilesTooBigForDiffException { + + @Nullable + public static Change buildChanges(@NotNull T[] objects1, @NotNull T[] objects2) throws FilesTooBigForDiffException { // Old variant of enumerator worked incorrectly with null values. // This check is to ensure that the corrected version does not introduce bugs. @@ -180,6 +181,7 @@ public class Diff { skip(startShift, startShift); } + @Override public void addChange(int first, int second) { Change change = new Change(myIndex1, myIndex2, first, second, null); if (myLastChange != null) myLastChange.link = change; @@ -193,6 +195,7 @@ public class Diff { myIndex2 += second; } + @Override public void addEqual(int length) { skip(length, length); } From a9c31750f1c9bc19844cb95ac7833eb41f7e0ce0 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 16 Oct 2012 17:18:05 +0200 Subject: [PATCH 34/57] fix teamcity compilation --- .../testSources/codeInsight/PluginXmlFunctionalTest.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy index 9c331f1749cf..25c19d643ee4 100644 --- a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy +++ b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy @@ -197,7 +197,7 @@ public class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase { } static Collection> getInspectionClasses() { - return Arrays.>asList( + return Arrays.asList( //RegistrationProblemsInspection.class, PluginXmlDomInspection.class, ComponentNotRegisteredInspection.class, From e2ef716ad6c2b1505ceee7ba8cb64681cb2a4204 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 16 Oct 2012 17:32:36 +0200 Subject: [PATCH 35/57] IDEA-88148 (Create new inspection for String concatenation as argument to log statement.) --- .../InspectionGadgets/src/META-INF/plugin.xml | 4 + .../siyeh/InspectionGadgetsBundle.properties | 2 +- ...catenationArgumentToLogCallInspection.java | 282 ++++++++++++++++++ .../StringConcatenationArgumentToLogCall.html | 10 + 4 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java create mode 100644 plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationArgumentToLogCall.html diff --git a/plugins/InspectionGadgets/src/META-INF/plugin.xml b/plugins/InspectionGadgets/src/META-INF/plugin.xml index 067031b9c329..1df5b70f00e4 100644 --- a/plugins/InspectionGadgets/src/META-INF/plugin.xml +++ b/plugins/InspectionGadgets/src/META-INF/plugin.xml @@ -1445,6 +1445,10 @@ key="public.method.without.logging.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.logging.issues" enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.logging.PublicMethodWithoutLoggingInspection"/> + #ref() logging call #loc \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java new file mode 100644 index 000000000000..4be50aedfd82 --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java @@ -0,0 +1,282 @@ +/* + * Copyright 2000-2012 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.siyeh.ig.logging; + +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.IncorrectOperationException; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.InspectionGadgetsFix; +import com.siyeh.ig.psiutils.ExpressionUtils; +import com.siyeh.ig.psiutils.ParenthesesUtils; +import com.siyeh.ig.psiutils.TypeUtils; +import gnu.trove.THashSet; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * @author Bas Leijdekkers + */ +public class StringConcatenationArgumentToLogCallInspection extends BaseInspection { + + private static final Set logNames = new THashSet(); + static { + logNames.add("trace"); + logNames.add("debug"); + logNames.add("info"); + logNames.add("warn"); + logNames.add("error"); + } + + @Nls + @NotNull + @Override + public String getDisplayName() { + return InspectionGadgetsBundle.message("string.concatenation.argument.to.log.call.display.name"); + } + + @NotNull + @Override + protected String buildErrorString(Object... infos) { + return InspectionGadgetsBundle.message("string.concatenation.argument.to.log.call.problem.descriptor"); + } + + @Nullable + @Override + protected InspectionGadgetsFix buildFix(Object... infos) { + final int count = StringConcatenationArgumentToLogCallFix.isAvailable((PsiExpression)infos[0]); + if (count == 0) { + return null; + } + return new StringConcatenationArgumentToLogCallFix(count > 1); + } + + private static class StringConcatenationArgumentToLogCallFix extends InspectionGadgetsFix { + + private final boolean myPlural; + + public StringConcatenationArgumentToLogCallFix(boolean plural) { + myPlural = plural; + } + + @NotNull + @Override + public String getName() { + if (myPlural) { + return InspectionGadgetsBundle.message("string.concatenation.in.format.call.plural.quickfix"); + } + else { + return InspectionGadgetsBundle.message("string.concatenation.in.format.call.quickfix"); + } + } + + @Override + protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { + final PsiElement element = descriptor.getPsiElement(); + final PsiElement grandParent = element.getParent().getParent(); + if (!(grandParent instanceof PsiMethodCallExpression)) { + return; + } + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent; + final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); + final PsiExpression[] arguments = argumentList.getExpressions(); + if (arguments.length == 0) { + return; + } + final StringBuilder newMethodCall = new StringBuilder(methodCallExpression.getMethodExpression().getText()); + newMethodCall.append("("); + PsiExpression argument = arguments[0]; + int usedArguments; + if (!(argument instanceof PsiPolyadicExpression)) { + if (!TypeUtils.expressionHasTypeOrSubtype(argument, "org.slf4j.Marker") || arguments.length < 2) { + return; + } + newMethodCall.append(argument.getText()).append(",\""); + argument = arguments[1]; + usedArguments = 2; + if (!(argument instanceof PsiPolyadicExpression)) { + return; + } + } + else { + newMethodCall.append('\"'); + usedArguments = 1; + } + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)argument; + final PsiMethod method = methodCallExpression.resolveMethod(); + if (method == null) { + return; + } + final String methodName = method.getName(); + final PsiClass containingClass = method.getContainingClass(); + if (containingClass == null) { + return; + } + final PsiMethod[] methods = containingClass.findMethodsByName(methodName, false); + boolean varArgs = false; + for (PsiMethod otherMethod : methods) { + if (otherMethod.isVarArgs()) { + varArgs = true; + break; + } + } + final List newArguments = new ArrayList(); + final PsiExpression[] operands = polyadicExpression.getOperands(); + for (PsiExpression operand : operands) { + if (operand instanceof PsiLiteralExpression) { + final String text = operand.getText(); + final int count = StringUtil.getOccurrenceCount(text, "{}"); + for (int i = 0; i < count && usedArguments + i < arguments.length; i++) { + newArguments.add((PsiExpression)arguments[i + usedArguments].copy()); + } + usedArguments += count; + newMethodCall.append(text.substring(1, text.length() - 1)); + } + else { + newArguments.add((PsiExpression)operand.copy()); + newMethodCall.append("{}"); + } + } + while (usedArguments < arguments.length) { + newArguments.add(arguments[usedArguments++]); + } + newMethodCall.append('"'); + if (!varArgs && newArguments.size() > 2) { + newMethodCall.append(", new Object[]{"); + boolean comma = false; + for (PsiExpression newArgument : newArguments) { + if (comma) { + newMethodCall.append(','); + } + else { + comma =true; + } + newMethodCall.append(newArgument.getText()); + } + newMethodCall.append('}'); + } + else { + for (PsiExpression newArgument : newArguments) { + newMethodCall.append(',').append(newArgument.getText()); + } + } + newMethodCall.append(')'); + replaceExpression(methodCallExpression, newMethodCall.toString()); + } + + public static int isAvailable(PsiExpression expression) { + int count = 0; + if (!(expression instanceof PsiPolyadicExpression)) { + return count; + } + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression; + final PsiExpression[] operands = polyadicExpression.getOperands(); + for (PsiExpression operand : operands) { + if (operand instanceof PsiLiteralExpression) { + if (!ExpressionUtils.hasStringType(operand)) { + return count; + } + continue; + } + if (!(operand instanceof PsiReferenceExpression)) { + return count; + } + count++; + } + return count; + } + } + + @Override + public BaseInspectionVisitor buildVisitor() { + return new StringConcatenationArgumentToLogCallVisitor(); + } + + private static class StringConcatenationArgumentToLogCallVisitor extends BaseInspectionVisitor { + + @Override + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); + final PsiReferenceExpression methodExpression = expression.getMethodExpression(); + final String referenceName = methodExpression.getReferenceName(); + if (!logNames.contains(referenceName)) { + return; + } + final PsiMethod method = expression.resolveMethod(); + if (method == null) { + return; + } + final PsiClass containingClass = method.getContainingClass(); + if (containingClass == null || !"org.slf4j.Logger".equals(containingClass.getQualifiedName())) { + return; + } + final PsiExpressionList argumentList = expression.getArgumentList(); + final PsiExpression[] arguments = argumentList.getExpressions(); + if (arguments.length == 0) { + return; + } + PsiExpression argument = arguments[0]; + if (!ExpressionUtils.hasStringType(argument)) { + if (arguments.length < 2) { + return; + } + argument = arguments[1]; + if (!ExpressionUtils.hasStringType(argument)) { + return; + } + } + argument = ParenthesesUtils.stripParentheses(argument); + if (argument == null || !containsConcatenation(argument)) { + return; + } + registerMethodCallError(expression, argument); + } + + private static boolean containsConcatenation(@Nullable PsiExpression expression) { + if (expression instanceof PsiParenthesizedExpression) { + final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression; + containsConcatenation(parenthesizedExpression.getExpression()); + } + else if (expression instanceof PsiPolyadicExpression) { + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression; + if (!ExpressionUtils.hasStringType(polyadicExpression)) { + return false; + } + final IElementType tokenType = polyadicExpression.getOperationTokenType(); + if (!JavaTokenType.PLUS.equals(tokenType)) { + return false; + } + final PsiExpression[] operands = polyadicExpression.getOperands(); + for (PsiExpression operand : operands) { + if (operand instanceof PsiReferenceExpression) { + return true; + } + } + } + return false; + } + } +} diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationArgumentToLogCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationArgumentToLogCall.html new file mode 100644 index 000000000000..1d12ca412f2d --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationArgumentToLogCall.html @@ -0,0 +1,10 @@ + + +This inspection reports non-constant string concatenations used as an argument to a SLF4J log method. +Concatenation will be evaluated even when the logging message will not be logged; this can negatively impact performance. +It is recommended to use parameterization instead which will only be evaluated when the string is actually logged and not when logging is disabled. + +

+New in 12, Powered by InspectionGadgets + + \ No newline at end of file From 0facdd6517c9bc936beed56229ffc4961c73f20b Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 16 Oct 2012 16:07:12 +0200 Subject: [PATCH 36/57] EA-36125 - IOE: PsiJavaParserFacadeImpl.createTypeElementFromText --- .../src/com/intellij/psi/impl/source/PsiTypeElementImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java index 76f3b7ddcbf2..1d2ed507b7f2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java @@ -158,7 +158,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl PsiModifierList list = ((PsiModifierListOwner)member).getModifierList(); PsiAnnotation[] gluedAnnotations = list == null ? PsiAnnotation.EMPTY_ARRAY : list.getAnnotations(); for (PsiAnnotation anno : gluedAnnotations) { - if (PsiAnnotationImpl.isAnnotationApplicableTo(anno, false, "TYPE_USE")) { + if (PsiAnnotationImpl.isAnnotationApplicableTo(anno, true, "TYPE_USE")) { typeAnnotations.add(anno); } } From 3e198a4c4cf993ea96531bd13b72f0b402200513 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 16 Oct 2012 17:44:28 +0200 Subject: [PATCH 37/57] replace method reference with lambda: default constructor processing (IDEA-93025) --- .../ipp/types/ReplaceMethodRefWithLambdaIntention.java | 2 ++ .../types/methodRefs2lambda/NewDefaultConstructor.java | 10 ++++++++++ .../methodRefs2lambda/NewDefaultConstructor_after.java | 10 ++++++++++ .../ReplaceMethodReferenceWithLambdaIntentionTest.java | 4 ++++ 4 files changed, 26 insertions(+) create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewDefaultConstructor.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewDefaultConstructor_after.java diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java index d54828570e2c..923146ee532d 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java @@ -87,6 +87,8 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention { final PsiClass containingClass = ((PsiMember)resolveElement).getContainingClass(); LOG.assertTrue(containingClass != null); isReceiver = LambdaUtil.isReceiverType(functionalInterfaceType, containingClass, (PsiMethod)resolveElement); + } else if (resolveElement instanceof PsiClass) { + isReceiver = LambdaUtil.isReceiverType(functionalInterfaceType, (PsiClass)resolveElement, (PsiMethod)null); } final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement(); diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewDefaultConstructor.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewDefaultConstructor.java new file mode 100644 index 000000000000..3dc2facab3c4 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewDefaultConstructor.java @@ -0,0 +1,10 @@ +class Test1 { + class Inner {} + void test() { + BlahBlah6 blahBlah62 = Inner::new; + } +} + +interface BlahBlah6 { + Test1.Inner foo6(Test1 p); +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewDefaultConstructor_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewDefaultConstructor_after.java new file mode 100644 index 000000000000..f346d7d7a18c --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewDefaultConstructor_after.java @@ -0,0 +1,10 @@ +class Test1 { + class Inner {} + void test() { + BlahBlah6 blahBlah62 = (p) -> p.new Inner(); + } +} + +interface BlahBlah6 { + Test1.Inner foo6(Test1 p); +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceMethodReferenceWithLambdaIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceMethodReferenceWithLambdaIntentionTest.java index bbc28d89732d..0a4dc30371f2 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceMethodReferenceWithLambdaIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceMethodReferenceWithLambdaIntentionTest.java @@ -85,4 +85,8 @@ public class ReplaceMethodReferenceWithLambdaIntentionTest extends IPPTestCase { public void testTypeElementOnTheLeft() throws Exception { doTest(); } + + public void testNewDefaultConstructor() throws Exception { + doTest(); + } } From 36e47d77b6a2f160c143bebfd82dea0c6a9615dc Mon Sep 17 00:00:00 2001 From: Vassiliy Kudryashov Date: Tue, 16 Oct 2012 20:35:29 +0400 Subject: [PATCH 38/57] IDEA-82372 Select Font dialog can't render some OTF fonts --- .../options/colors/FontOptions.java | 45 +++++++++++-------- .../application/options/SelectFontDialog.java | 30 ++++++------- .../src/messages/ApplicationBundle.properties | 2 +- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/FontOptions.java b/platform/lang-impl/src/com/intellij/application/options/colors/FontOptions.java index 2d8cfd90f960..96daec48e80d 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/FontOptions.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/FontOptions.java @@ -28,7 +28,7 @@ import com.intellij.openapi.ui.Messages; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.IdeBorderFactory; import com.intellij.util.EventDispatcher; -import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; @@ -37,7 +37,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; public class FontOptions extends JPanel implements OptionsPanel{ @@ -48,8 +47,8 @@ public class FontOptions extends JPanel implements OptionsPanel{ private JTextField myLineSpacingField; private JTextField myFontNameField; - private static ArrayList myFontNamesVector; - private static HashMap myFontNameToIsMonospaced; + private static ArrayList myFontNames; + private static ArrayList myMonospacedFontNames; private final EventDispatcher myDispatcher = EventDispatcher.create(ColorAndFontSettingsListener.class); private boolean myIsInSchemeChange = false; private String myTitle; @@ -114,13 +113,13 @@ public class FontOptions extends JPanel implements OptionsPanel{ } @Override + @Nullable public Runnable showOption(final String option) { return null; } @Override public void applyChangesToScheme() { - } @Override @@ -241,16 +240,16 @@ public class FontOptions extends JPanel implements OptionsPanel{ private void selectFont() { initFontTables(); - List fontNamesVector = (List)myFontNamesVector.clone(); - HashMap fontNameToIsMonospaced = (HashMap)myFontNameToIsMonospaced.clone(); + ArrayList fontNames = new ArrayList(myFontNames); + ArrayList monospacedFontNames = new ArrayList(myMonospacedFontNames); String initialFontName = myFontNameField.getText(); - if (!fontNamesVector.contains(EditorSettingsExternalizable.DEFAULT_FONT_NAME)) { - fontNamesVector.add(0, EditorSettingsExternalizable.DEFAULT_FONT_NAME); + if (!fontNames.contains(EditorSettingsExternalizable.DEFAULT_FONT_NAME)) { + fontNames.add(0, EditorSettingsExternalizable.DEFAULT_FONT_NAME); } - if (!fontNamesVector.contains(initialFontName)) { - fontNamesVector.add(0, initialFontName); + if (!fontNames.contains(initialFontName)) { + fontNames.add(0, initialFontName); } - SelectFontDialog selectFontDialog = new SelectFontDialog(this, fontNamesVector, initialFontName, fontNameToIsMonospaced); + SelectFontDialog selectFontDialog = new SelectFontDialog(this, fontNames, initialFontName, monospacedFontNames); selectFontDialog.show(); if (!selectFontDialog.isOK()) { return; @@ -265,9 +264,9 @@ public class FontOptions extends JPanel implements OptionsPanel{ @SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"}) private void initFontTables() { - if (myFontNamesVector == null) { - myFontNamesVector = new ArrayList(); - myFontNameToIsMonospaced = new HashMap(); + if (myFontNames == null) { + myFontNames = new ArrayList(); + myMonospacedFontNames = new ArrayList(); ProgressManager.getInstance().runProcessWithProgressSynchronously(new InitFontsRunnable(), ApplicationBundle.message("progress.analyzing.fonts"), false, null); } @@ -326,15 +325,25 @@ public class FontOptions extends JPanel implements OptionsPanel{ } FontMetrics plainMetrics = getFontMetrics(plainFont); FontMetrics boldMetrics = getFontMetrics(boldFont); - myFontNamesVector.add(fontName); + if (plainMetrics.getDescent() < 0 || + boldMetrics.getDescent() < 0 || + plainMetrics.getAscent() < 0 || + boldMetrics.getAscent() < 0) { + continue; + } int plainL = plainMetrics.charWidth('l'); int boldL = boldMetrics.charWidth('l'); int plainW = plainMetrics.charWidth('W'); int boldW = boldMetrics.charWidth('W'); int plainSpace = plainMetrics.charWidth(' '); int boldSpace = boldMetrics.charWidth(' '); - boolean isMonospaced = plainL == plainW && plainL == boldL && plainW == boldW && plainSpace == boldSpace; - myFontNameToIsMonospaced.put(fontName, isMonospaced); + if (plainL <= 0 || boldL <= 0 || plainW <= 0 || boldW <= 0 || plainSpace <= 0 || boldSpace <= 0) { + continue; + } + myFontNames.add(fontName); + if (plainL == plainW && plainL == boldL && plainW == boldW && plainSpace == boldSpace) { + myMonospacedFontNames.add(fontName); + } } } catch (Throwable e) { diff --git a/platform/platform-impl/src/com/intellij/application/options/SelectFontDialog.java b/platform/platform-impl/src/com/intellij/application/options/SelectFontDialog.java index ec6e723dde3c..1d8055a981b8 100644 --- a/platform/platform-impl/src/com/intellij/application/options/SelectFontDialog.java +++ b/platform/platform-impl/src/com/intellij/application/options/SelectFontDialog.java @@ -23,9 +23,10 @@ import com.intellij.ui.ListScrollingUtil; import com.intellij.ui.ListSpeedSearch; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.components.JBList; -import com.intellij.util.containers.HashMap; import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -37,11 +38,11 @@ public class SelectFontDialog extends DialogWrapper { private JCheckBox myShowMonospacedCheckbox; private final List myFontNames; private final String myInitialFontName; - private final HashMap myNameToIsMonospaced; + private final List myMonospacedFontNames; - public SelectFontDialog(Component parent, List fontNames, String initialFontName, HashMap nameToIsMonospaced) { + public SelectFontDialog(Component parent, List fontNames, String initialFontName, List monospacedFontNames) { super(parent, true); - myNameToIsMonospaced = nameToIsMonospaced; + myMonospacedFontNames = monospacedFontNames; setTitle(ApplicationBundle.message("title.select.font")); myFontNames = fontNames; myInitialFontName = initialFontName; @@ -51,7 +52,6 @@ public class SelectFontDialog extends DialogWrapper { protected JComponent createCenterPanel() { myShowMonospacedCheckbox = new JCheckBox(ApplicationBundle.message("checkbox.show.only.monospaced.fonts")); final boolean useOnlyMonospacedFonts = EditorColorsManager.getInstance().isUseOnlyMonospacedFonts(); - myShowMonospacedCheckbox.setSelected(useOnlyMonospacedFonts); myFontList = new JBList(); new ListSpeedSearch(myFontList); myFontList.setModel(new DefaultListModel()); @@ -84,10 +84,11 @@ public class SelectFontDialog extends DialogWrapper { panel.add(myShowMonospacedCheckbox, BorderLayout.NORTH); panel.add(ScrollPaneFactory.createScrollPane(myFontList), BorderLayout.CENTER); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - myShowMonospacedCheckbox.setSelected(useOnlyMonospacedFonts); + myShowMonospacedCheckbox.setSelected(useOnlyMonospacedFonts); + myFontList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + setOKActionEnabled(myFontList.getSelectedValue() != null); } }); @@ -97,20 +98,15 @@ public class SelectFontDialog extends DialogWrapper { private void fillList(boolean onlyMonospaced) { DefaultListModel model = (DefaultListModel) myFontList.getModel(); model.removeAllElements(); - for (int i = 0; i < myFontNames.size(); i++) { - String fontName = myFontNames.get(i); - if (!onlyMonospaced || Boolean.TRUE.equals(myNameToIsMonospaced.get(fontName))) { + for (String fontName : myFontNames) { + if (!onlyMonospaced || myMonospacedFontNames.contains(fontName)) { model.addElement(fontName); } } } public void show() { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - ListScrollingUtil.selectItem(myFontList, myInitialFontName); - } - }); + ListScrollingUtil.selectItem(myFontList, myInitialFontName); super.show(); } diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 044966a4cbfe..94317160eb17 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -501,7 +501,7 @@ combobox.scheme.name=Scheme name: progress.analyzing.fonts=Analyzing Fonts error.readonly.scheme.cannot.be.modified=Read-only scheme cannot be modified. Please do "Save As..." first. error.shared.scheme.cannot.be.modified=Shared scheme cannot be modified. Please do "Save As..." first. -title.cannot.modify.readonly.scheme=Cannot Modify read-only Scheme +title.cannot.modify.readonly.scheme=Cannot Modify Read-Only Scheme title.save.color.scheme.as=Save Color Scheme As title.path.variables=Path Variables editbox.path.macro.value=Value: From cd9443b34f72f531f9305da3765493bd32a6ceed Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 16 Oct 2012 19:02:46 +0200 Subject: [PATCH 39/57] fix maven test --- .../resolve/reference/impl/providers/JavaClassReference.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java index b91cfc74191a..e5f78ae5a64c 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java @@ -255,7 +255,7 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer return ArrayUtil.EMPTY_OBJECT_ARRAY; } - @NotNull + @Nullable public PsiElement getCompletionContext() { PsiElement context = getContext(); return context == null ? JavaPsiFacade.getInstance(getElement().getProject()).findPackage("") : context; From 9c7006241d86b6dd2a978c420fad3b450c8b55de Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 16 Oct 2012 19:07:02 +0200 Subject: [PATCH 40/57] serializer bindings thread safety --- .../util/xmlb/AbstractCollectionBinding.java | 31 ++++++------------- .../com/intellij/util/xmlb/BeanBinding.java | 2 +- .../com/intellij/util/xmlb/TextBinding.java | 2 +- 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java b/platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java index f1f2ee2751db..cf6db68d2dab 100644 --- a/platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java @@ -29,18 +29,14 @@ abstract class AbstractCollectionBinding implements Binding { private final Class myElementType; private final String myTagName; - @Nullable protected Accessor myAccessor; - private AbstractCollection myAnnotation = null; - private boolean myUsingOptionBinding = false; + @Nullable protected final Accessor myAccessor; + private final AbstractCollection myAnnotation; public AbstractCollectionBinding(Class elementType, String tagName, @Nullable Accessor accessor) { myElementType = elementType; myTagName = tagName; myAccessor = accessor; - - if (accessor != null) { - myAnnotation = XmlSerializerImpl.findAnnotation(accessor.getAnnotations(), AbstractCollection.class); - } + myAnnotation = accessor == null ? null : XmlSerializerImpl.findAnnotation(accessor.getAnnotations(), AbstractCollection.class); } public void init() { @@ -51,10 +47,10 @@ abstract class AbstractCollectionBinding implements Binding { } if (myAnnotation.elementTag().equals(Constants.OPTION)) { - getElementBindings(); - - if (myUsingOptionBinding) { - throw new XmlSerializationException("If surround with tag is turned off, element tag must be specified for: " + myAccessor); + for (Binding binding : getElementBindings().values()) { + if (binding instanceof TagBindingWrapper) { + throw new XmlSerializationException("If surround with tag is turned off, element tag must be specified for: " + myAccessor); + } } } } @@ -66,7 +62,7 @@ abstract class AbstractCollectionBinding implements Binding { return binding == null ? XmlSerializerImpl.getBinding(elementClass) : binding; } - private Map getElementBindings() { + private synchronized Map getElementBindings() { if (myElementBindings == null) { myElementBindings = new HashMap(); @@ -91,15 +87,8 @@ abstract class AbstractCollectionBinding implements Binding { } private Binding getBinding(final Class type) { - Binding binding; - binding = XmlSerializerImpl.getBinding(type); - - if (!binding.getBoundNodeType().isAssignableFrom(Element.class)) { - binding = createElementTagWrapper(binding); - myUsingOptionBinding = true; - } - - return binding; + Binding binding = XmlSerializerImpl.getBinding(type); + return binding.getBoundNodeType().isAssignableFrom(Element.class) ? binding : createElementTagWrapper(binding); } private Binding createElementTagWrapper(final Binding elementBinding) { diff --git a/platform/util/src/com/intellij/util/xmlb/BeanBinding.java b/platform/util/src/com/intellij/util/xmlb/BeanBinding.java index 562380c8a2fc..a40a40ed6e3e 100644 --- a/platform/util/src/com/intellij/util/xmlb/BeanBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/BeanBinding.java @@ -64,7 +64,7 @@ class BeanBinding implements Binding { initPropertyBindings(myBeanClass); } - private void initPropertyBindings(Class beanClass) { + private synchronized void initPropertyBindings(Class beanClass) { for (Accessor accessor : getAccessors(beanClass)) { final Binding binding = createBindingByAccessor(accessor); myPropertyBindingsList.add(binding); diff --git a/platform/util/src/com/intellij/util/xmlb/TextBinding.java b/platform/util/src/com/intellij/util/xmlb/TextBinding.java index 781b023ac7b2..ff6bed258705 100644 --- a/platform/util/src/com/intellij/util/xmlb/TextBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/TextBinding.java @@ -22,7 +22,7 @@ import org.jetbrains.annotations.Nullable; public class TextBinding implements Binding { private final Accessor myAccessor; - private Binding myBinding; + private volatile Binding myBinding; public TextBinding(final Accessor accessor) { myAccessor = accessor; From a19e50a24f1fd60e49afcb1e851619b442f373f4 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 16 Oct 2012 20:31:26 +0200 Subject: [PATCH 41/57] fix maven tests --- .../com/intellij/openapi/compiler/CompilerPaths.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java index 86d4e0299348..f02820fa0f93 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java @@ -24,7 +24,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.CompilerModuleExtension; -import com.intellij.openapi.roots.CompilerProjectExtension; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; @@ -228,15 +227,12 @@ public class CompilerPaths { return StringUtil.isEmpty(sourceDirName)? VirtualFileManager.extractPath(roots[0]): VirtualFileManager.extractPath(roots[0]) + "/" + sourceDirName; } - final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(module.getProject()); - if (extension == null) { + + final String path = getModuleOutputPath(module, false); + if (path == null) { return null; } - final String url = extension.getCompilerOutputUrl(); - if (url == null) { - return null; - } - return StringUtil.isEmpty(sourceDirName)? VirtualFileManager.extractPath(url) : VirtualFileManager.extractPath(url) + "/" + sourceDirName; + return StringUtil.isEmpty(sourceDirName)? path : path + "/" + sourceDirName; } @NonNls From 60715a71b7c66f1da0e9e9537b667c5db771a66b Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 16 Oct 2012 22:48:35 +0400 Subject: [PATCH 42/57] IDEA-92487 Added edit record button for Database records. --- platform/platform-resources/src/idea/Keymap_Default.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml index 0df3265f28b1..362305aac499 100644 --- a/platform/platform-resources/src/idea/Keymap_Default.xml +++ b/platform/platform-resources/src/idea/Keymap_Default.xml @@ -922,6 +922,7 @@ + From 06d2066d507729b4ae63de224e8063f264a6c697 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 16 Oct 2012 20:57:48 +0200 Subject: [PATCH 43/57] cache valid p4 changelist numbers during command execution (IDEA-93033) --- .../src/com/intellij/openapi/vcs/changes/Change.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/Change.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/Change.java index c62db4ccd872..8e300bd2a291 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/Change.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/Change.java @@ -60,11 +60,11 @@ public class Change { // if null, vcs's is used. intended: for property conflict case private Getter myMergeProvider; - public Change(final ContentRevision beforeRevision, final ContentRevision afterRevision) { + public Change(@Nullable final ContentRevision beforeRevision, @Nullable final ContentRevision afterRevision) { this(beforeRevision, afterRevision, convertStatus(beforeRevision, afterRevision)); } - public Change(final ContentRevision beforeRevision, final ContentRevision afterRevision, FileStatus fileStatus) { + public Change(@Nullable final ContentRevision beforeRevision, @Nullable final ContentRevision afterRevision, @Nullable FileStatus fileStatus) { assert beforeRevision != null || afterRevision != null; myBeforeRevision = beforeRevision; myAfterRevision = afterRevision; @@ -73,7 +73,7 @@ public class Change { myOtherLayers = new HashMap(0); } - private static FileStatus convertStatus(ContentRevision beforeRevision, ContentRevision afterRevision) { + private static FileStatus convertStatus(@Nullable ContentRevision beforeRevision, @Nullable ContentRevision afterRevision) { if (beforeRevision == null) return FileStatus.ADDED; if (afterRevision == null) return FileStatus.DELETED; return FileStatus.MODIFIED; From a14b58075c08203e26ddb5ee9c609caddf474f5d Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 16 Oct 2012 21:12:20 +0200 Subject: [PATCH 44/57] creating FilePathImpl from VirtualFile --- .../vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java index efb49b2029ee..22aa60ac6d21 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java @@ -292,6 +292,10 @@ public class FilePathImpl implements FilePath { return myVirtualFile != null ? myVirtualFile.getFileType() : FileTypeManager.getInstance().getFileTypeByFileName(myFile.getName()); } + public static FilePathImpl create(VirtualFile file) { + return create(VfsUtilCore.virtualToIoFile(file), file.isDirectory()); + } + public static FilePathImpl create(File selectedFile) { return create(selectedFile, false); } From 38f536cc87387b0062eeb5cf47ed6be366a8ab29 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 16 Oct 2012 12:22:00 +0200 Subject: [PATCH 45/57] plugin descriptions --- plugins/android-designer/src/META-INF/plugin.xml | 3 +++ plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/plugins/android-designer/src/META-INF/plugin.xml b/plugins/android-designer/src/META-INF/plugin.xml index e4e7726d743e..612d8c99c969 100644 --- a/plugins/android-designer/src/META-INF/plugin.xml +++ b/plugins/android-designer/src/META-INF/plugin.xml @@ -1,6 +1,9 @@ Android Designer com.intellij.android-designer + + Provides visual editing support for Android layout files. + JetBrains messages.AndroidDesignerBundle diff --git a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml index ca2b538f5ef2..da8173ba69be 100644 --- a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml +++ b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml @@ -1,6 +1,9 @@ UI Designer (Core) com.intellij.ui-designer-new + + Provides shared functionality for visual editing plugins. + JetBrains messages.DesignerBundle From 082399e06ecb2da670871de48e19bc0cd612b885 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 16 Oct 2012 12:28:09 +0200 Subject: [PATCH 46/57] cosmetics (IDEA-93001) --- .../platform-resources-en/src/messages/IdeBundle.properties | 2 +- .../projectModel-impl/src/messages/ProjectBundle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index b516a727efc1..4c2dc5defe14 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -931,7 +931,7 @@ add.scope.popup.title=Add scope add.scope.name.label=Name add.scope.dialog.title=Add New Scope scope.banner.text=Scope ''{0}'' -prompt.please.select.module.jdk=Please select {0} to be set for this module +prompt.please.select.module.jdk=Please select the {0} to be set for this module scopes.save.dialog.title.shared=Save as shared scope scopes.save.dialog.title.local=Save as local scope plugin.version.label=Version diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties index a009a97741db..d04d18e7b436 100644 --- a/platform/projectModel-impl/src/messages/ProjectBundle.properties +++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties @@ -53,7 +53,7 @@ message.text.stop.searching.for.frameworks={0} is currently searching for framew label.text.the.following.frameworks.are.detected=Several frameworks are detected in the project. Please review the following items and exclude mistakenly detected. label.text.no.frameworks.detected=No frameworks detected. -sdk.java.name=JSDK +sdk.java.name=JDK sdk.java.unknown.name=Unknown sdk.java.corrupt.error=Probably SDK installed in ''{0}'' is corrupt sdk.java.corrupt.title=Cannot Detect SDK Version From a6f3240055c0763cb4de96217da57afa480a39fa Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 16 Oct 2012 18:23:40 +0200 Subject: [PATCH 47/57] cosmetics --- .../designer/designSurface/AndroidDesignerEditorPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java index f7fd4655835d..605c39c71a91 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java @@ -113,7 +113,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { } }); - showProgress("Load configuration"); + showProgress("Loading configuration..."); myProfileAction = new ProfileAction(this, new Runnable() { @Override public void run() { @@ -253,7 +253,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { @Override public void run() { if (mySession == null) { - showProgress("Create RenderLib"); + showProgress("Creating RenderLib..."); } } }, 500); From e6e4f240f6976628a54d60469809f7ea655a5bd6 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 17 Oct 2012 09:02:50 +0400 Subject: [PATCH 48/57] EA-39371 - NPE: GenericInlineHandler.initializeInliners --- .../intellij/lang/refactoring/InlineHandler.java | 13 ++++++------- .../refactoring/inline/GenericInlineHandler.java | 11 +++++++++-- .../groovy/refactoring/GroovyRefactoringUtil.java | 2 +- .../refactoring/inline/GrVariableInliner.java | 5 +++-- .../refactoring/inline/GroovyInlineHandler.java | 3 ++- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/platform/lang-api/src/com/intellij/lang/refactoring/InlineHandler.java b/platform/lang-api/src/com/intellij/lang/refactoring/InlineHandler.java index 4b8e7a65b927..773e9e9d2235 100644 --- a/platform/lang-api/src/com/intellij/lang/refactoring/InlineHandler.java +++ b/platform/lang-api/src/com/intellij/lang/refactoring/InlineHandler.java @@ -22,10 +22,9 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.usageView.UsageInfo; import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Map; - /** * Interface that should be implemented by the language in order to provide inline functionality and possibly * participate in inline of elements in other languages this language may reference. @@ -60,19 +59,19 @@ public interface InlineHandler { * @return Settings object in case refactoring should be performed or null otherwise */ - @Nullable Settings prepareInlineElement(PsiElement element, Editor editor, boolean invokedOnReference); + @Nullable Settings prepareInlineElement(@NotNull PsiElement element, @Nullable Editor editor, boolean invokedOnReference); /** * @param element inlined element */ - void removeDefinition(PsiElement element, Settings settings); + void removeDefinition(@NotNull PsiElement element, @NotNull Settings settings); /** * @param element inlined element * @param settings * @return Inliner instance to be used for inlining references in this language */ - @Nullable Inliner createInliner(PsiElement element, Settings settings); + @Nullable Inliner createInliner(@NotNull PsiElement element, @NotNull Settings settings); interface Inliner { /** @@ -82,13 +81,13 @@ public interface InlineHandler { * or null if no conflicts detected. */ @Nullable - MultiMap getConflicts(PsiReference reference, PsiElement referenced); + MultiMap getConflicts(@NotNull PsiReference reference, @NotNull PsiElement referenced); /** * Perform actual inline of element to the point where it is referenced * @param usage usage of inlined element * @param referenced inlined element */ - void inlineUsage(UsageInfo usage, PsiElement referenced); + void inlineUsage(@NotNull UsageInfo usage, @NotNull PsiElement referenced); } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java b/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java index dcf1c7db77cd..79c2b3f1c479 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/inline/GenericInlineHandler.java @@ -22,10 +22,12 @@ import com.intellij.lang.refactoring.InlineHandler; import com.intellij.lang.refactoring.InlineHandlers; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.PsiReference; @@ -48,6 +50,8 @@ import java.util.*; @SuppressWarnings({"UtilityClassWithoutPrivateConstructor"}) public class GenericInlineHandler { + private static final Logger LOG = Logger.getInstance(GenericInlineHandler.class); + public static boolean invoke(final PsiElement element, @Nullable Editor editor, final InlineHandler languageSpecific) { final PsiReference invocationReference = editor != null ? TargetElementUtilBase.findReference(editor) : null; final InlineHandler.Settings settings = languageSpecific.prepareInlineElement(element, editor, invocationReference != null); @@ -128,7 +132,7 @@ public class GenericInlineHandler { languageSpecific.removeDefinition(element, settings); } } - }, RefactoringBundle.message("inline.command", subj), null); + }, RefactoringBundle.message("inline.command", StringUtil.notNullize(subj, "")), null); } }); return true; @@ -139,7 +143,10 @@ public class GenericInlineHandler { Collection allReferences) { final Map inliners = new HashMap(); for (PsiReference ref : allReferences) { - final Language language = ref.getElement().getLanguage(); + PsiElement refElement = ref.getElement(); + LOG.assertTrue(refElement != null, ref.getClass().getName()); + + final Language language = refElement.getLanguage(); if (inliners.containsKey(language)) continue; final List handlers = InlineHandlers.getInlineHandlers(language); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java index 7af121dece2c..b83555bf9b3f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java @@ -201,7 +201,7 @@ public abstract class GroovyRefactoringUtil { } - public static void highlightOccurrences(Project project, Editor editor, PsiElement[] elements) { + public static void highlightOccurrences(Project project, @Nullable Editor editor, PsiElement[] elements) { if (editor == null) return; ArrayList highlighters = new ArrayList(); HighlightManager highlightManager = HighlightManager.getInstance(project); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GrVariableInliner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GrVariableInliner.java index 9cab0479bdd8..91d423edc5d5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GrVariableInliner.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GrVariableInliner.java @@ -28,6 +28,7 @@ import com.intellij.psi.util.PsiFormatUtilBase; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.usageView.UsageInfo; import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; @@ -62,7 +63,7 @@ public class GrVariableInliner implements InlineHandler.Inliner { } @Nullable - public MultiMap getConflicts(PsiReference reference, PsiElement referenced) { + public MultiMap getConflicts(@NotNull PsiReference reference, @NotNull PsiElement referenced) { MultiMap conflicts = new MultiMap(); GrExpression expr = (GrExpression)reference.getElement(); if (expr.getParent() instanceof GrAssignmentExpression) { @@ -86,7 +87,7 @@ public class GrVariableInliner implements InlineHandler.Inliner { return conflicts; } - public void inlineUsage(final UsageInfo usage, final PsiElement referenced) { + public void inlineUsage(@NotNull final UsageInfo usage, @NotNull final PsiElement referenced) { inlineReference(usage, referenced, myTempExpr); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyInlineHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyInlineHandler.java index 66d5df0d2d40..a1282a069328 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyInlineHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyInlineHandler.java @@ -23,6 +23,7 @@ import com.intellij.psi.PsiMember; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.usageView.UsageViewUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GrClassSubstitution; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; @@ -38,7 +39,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; public class GroovyInlineHandler implements InlineHandler { @Nullable - public Settings prepareInlineElement(final PsiElement element, Editor editor, boolean invokedOnReference) { + public Settings prepareInlineElement(@NotNull final PsiElement element, @Nullable Editor editor, boolean invokedOnReference) { if (element instanceof GrField) { return GrInlineFieldUtil.inlineFieldSettings((GrField)element, editor, invokedOnReference); } From e7116a7f7187daee6f9c0cca2b41f9c374ba8c92 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 17 Oct 2012 09:15:11 +0400 Subject: [PATCH 49/57] EA-39157 Groovy allows empty method names --- .../src/com/intellij/psi/impl/search/MethodUsagesSearcher.java | 3 +-- .../groovy/findUsages/MethodLateBoundReferencesSearcher.java | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java index 64e25dda9870..49bd3f3c2ca3 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java @@ -59,8 +59,7 @@ public class MethodUsagesSearcher extends QueryExecutorBase consumer) { From d16590a0e74b239a1d860bbdc87ef139e66840de Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 17 Oct 2012 13:15:46 +0400 Subject: [PATCH 50/57] IDEA-92814 Groovy: don't complete 'def' after 'new' --- .../lang/completion/GroovyCompletionData.java | 100 ++++++++---------- .../lang/completion/GroovyCompletionUtil.java | 22 ++++ .../completion/GroovyCompletionTest.groovy | 28 ++--- .../GroovyCompletionTestBase.groovy | 20 +++- 4 files changed, 100 insertions(+), 70 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java index 4de511021a00..6dacfc710bab 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java @@ -66,6 +66,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import static com.intellij.patterns.PsiJavaPatterns.psiElement; import static com.intellij.patterns.StandardPatterns.or; +import static org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionUtil.*; /** * @author ilyas @@ -148,11 +149,10 @@ public class GroovyCompletionData { addModifiers(position, result); } if (psiElement().afterLeaf(MODIFIERS).accepts(position) || - GroovyCompletionUtil.isInTypeDefinitionBody(position) && GroovyCompletionUtil.isNewStatement(position, true)) { + isInTypeDefinitionBody(position) && isNewStatement(position, true)) { addKeywords(result, true, PsiKeyword.SYNCHRONIZED); } - if (suggestFinalDef(position) || psiElement().afterLeaf( - psiElement().withText("(").withParent(GrForStatement.class)).accepts(position)) { + if (suggestFinalDef(position) || psiElement().afterLeaf(psiElement().withText("(").withParent(GrForStatement.class)).accepts(position)) { addKeywords(result, true, PsiKeyword.FINAL, "def"); } } @@ -160,7 +160,7 @@ public class GroovyCompletionData { } private static void addExtendsForTypeParams(PsiElement position, CompletionResultSet result) { - if (GroovyCompletionUtil.isWildcardCompletion(position)) { + if (isWildcardCompletion(position)) { addKeywords(result, true, PsiKeyword.EXTENDS, PsiKeyword.SUPER); } } @@ -314,13 +314,13 @@ public class GroovyCompletionData { return true; } - final PsiElement leaf = GroovyCompletionUtil.getLeafByOffset(context.getTextRange().getStartOffset() - 1, context); + final PsiElement leaf = getLeafByOffset(context.getTextRange().getStartOffset() - 1, context); if (leaf != null) { PsiElement parent = leaf.getParent(); if (parent instanceof GroovyFile) { GroovyFile groovyFile = (GroovyFile) parent; if (groovyFile.getPackageDefinition() == null) { - return GroovyCompletionUtil.isNewStatement(context, false); + return isNewStatement(context, false); } } } @@ -331,15 +331,15 @@ public class GroovyCompletionData { private static boolean suggestImport(PsiElement context) { if (context.getParent() != null && !(context.getParent() instanceof PsiErrorElement) && - GroovyCompletionUtil.isNewStatement(context, false) && + isNewStatement(context, false) && context.getParent().getParent() instanceof GroovyFile) { return true; } - final PsiElement leaf = GroovyCompletionUtil.getLeafByOffset(context.getTextRange().getStartOffset() - 1, context); + final PsiElement leaf = getLeafByOffset(context.getTextRange().getStartOffset() - 1, context); if (leaf != null) { PsiElement parent = leaf.getParent(); if (parent instanceof GroovyFile) { - return GroovyCompletionUtil.isNewStatement(context, false); + return isNewStatement(context, false); } } return context.getTextRange().getStartOffset() == 0 && !(context instanceof OuterLanguageElement); @@ -367,7 +367,7 @@ public class GroovyCompletionData { return true; } } - final PsiElement leaf = GroovyCompletionUtil.getLeafByOffset(context.getTextRange().getStartOffset() - 1, context); + final PsiElement leaf = getLeafByOffset(context.getTextRange().getStartOffset() - 1, context); if (leaf != null) { PsiElement prev = leaf; prev = PsiImplUtil.realPrevious(prev); @@ -378,7 +378,7 @@ public class GroovyCompletionData { } if (leaf.getParent() instanceof GroovyFile) { - return GroovyCompletionUtil.isNewStatement(context, false); + return isNewStatement(context, false); } } @@ -403,8 +403,8 @@ public class GroovyCompletionData { ASTNode node = prevSibling.getNode(); return !TokenSets.DOTS.contains(node.getElementType()); } - if (GroovyCompletionUtil.isNewStatement(context, true)) { - final PsiElement leaf = GroovyCompletionUtil.getLeafByOffset(offset - 1, context); + if (isNewStatement(context, true)) { + final PsiElement leaf = getLeafByOffset(offset - 1, context); if (leaf != null && (leaf.getParent() instanceof GrStatementOwner || leaf.getParent() instanceof GrLabeledStatement)) { return true; } @@ -458,17 +458,17 @@ public class GroovyCompletionData { private static boolean afterTry(PsiElement context) { if (context != null && - GroovyCompletionUtil.nearestLeftSibling(context) instanceof GrTryCatchStatement) { - GrTryCatchStatement tryStatement = (GrTryCatchStatement) GroovyCompletionUtil.nearestLeftSibling(context); + nearestLeftSibling(context) instanceof GrTryCatchStatement) { + GrTryCatchStatement tryStatement = (GrTryCatchStatement) nearestLeftSibling(context); if (tryStatement == null) return false; if (tryStatement.getFinallyClause() == null) { return true; } } if (context != null && - GroovyCompletionUtil.nearestLeftSibling(context) instanceof PsiErrorElement && - GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling() instanceof GrTryCatchStatement) { - GrTryCatchStatement tryStatement = (GrTryCatchStatement) GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling(); + nearestLeftSibling(context) instanceof PsiErrorElement && + nearestLeftSibling(context).getPrevSibling() instanceof GrTryCatchStatement) { + GrTryCatchStatement tryStatement = (GrTryCatchStatement) nearestLeftSibling(context).getPrevSibling(); if (tryStatement == null) return false; if (tryStatement.getFinallyClause() == null) { return true; @@ -476,8 +476,8 @@ public class GroovyCompletionData { } if (context != null && (context.getParent() instanceof GrReferenceExpression || context.getParent() instanceof PsiErrorElement) && - GroovyCompletionUtil.nearestLeftSibling(context.getParent()) instanceof GrTryCatchStatement) { - GrTryCatchStatement tryStatement = (GrTryCatchStatement) GroovyCompletionUtil.nearestLeftSibling(context.getParent()); + nearestLeftSibling(context.getParent()) instanceof GrTryCatchStatement) { + GrTryCatchStatement tryStatement = (GrTryCatchStatement) nearestLeftSibling(context.getParent()); if (tryStatement == null) return false; if (tryStatement.getFinallyClause() == null) { return true; @@ -488,13 +488,13 @@ public class GroovyCompletionData { private static boolean afterIfOrElse(PsiElement context) { if (context.getParent() != null && - GroovyCompletionUtil.nearestLeftSibling(context.getParent()) instanceof GrIfStatement) { + nearestLeftSibling(context.getParent()) instanceof GrIfStatement) { return true; } if (context.getParent() != null && - GroovyCompletionUtil.nearestLeftSibling(context) != null && - GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling() instanceof GrIfStatement) { - GrIfStatement statement = (GrIfStatement) GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling(); + nearestLeftSibling(context) != null && + nearestLeftSibling(context).getPrevSibling() instanceof GrIfStatement) { + GrIfStatement statement = (GrIfStatement) nearestLeftSibling(context).getPrevSibling(); if (statement.getElseBranch() == null) { return true; } @@ -512,7 +512,7 @@ public class GroovyCompletionData { private static boolean afterAbstractMethod(PsiElement context) { PsiElement candidate = null; - if (GroovyCompletionUtil.isInTypeDefinitionBody(context)) { + if (isInTypeDefinitionBody(context)) { PsiElement run = context; while(!(run.getParent() instanceof GrTypeDefinitionBody)) { run = run.getParent(); @@ -551,9 +551,9 @@ public class GroovyCompletionData { if (previous != null && GroovyTokenTypes.mAT.equals(previous.getNode().getElementType())) { return false; } - if (GroovyCompletionUtil.asSimpleVariable(context) || - GroovyCompletionUtil.asTypedMethod(context) || - GroovyCompletionUtil.asVariableInBlock(context)) { + if (asSimpleVariable(context) || + asTypedMethod(context) || + asVariableInBlock(context)) { return true; } if ((parent instanceof GrParameter && @@ -578,7 +578,7 @@ public class GroovyCompletionData { } return parent instanceof GrExpression && parent.getParent() instanceof GroovyFile && - GroovyCompletionUtil.isNewStatement(context, false); + isNewStatement(context, false); } private static boolean isInfixOperatorPosition(PsiElement context) { @@ -588,17 +588,17 @@ public class GroovyCompletionData { context.getParent().getParent() instanceof GrCommandArgumentList) { return true; } - if (GroovyCompletionUtil.nearestLeftSibling(context) instanceof PsiErrorElement && - GroovyCompletionUtil.endsWithExpression(GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling())) { + if (nearestLeftSibling(context) instanceof PsiErrorElement && + endsWithExpression(nearestLeftSibling(context).getPrevSibling())) { return true; } if (context.getParent() instanceof GrReferenceExpression && - GroovyCompletionUtil.nearestLeftLeaf(context) instanceof PsiErrorElement && - GroovyCompletionUtil.endsWithExpression(GroovyCompletionUtil.nearestLeftLeaf(context).getPrevSibling())) { + nearestLeftLeaf(context) instanceof PsiErrorElement && + endsWithExpression(nearestLeftLeaf(context).getPrevSibling())) { return true; } if (context.getParent() instanceof PsiErrorElement && - GroovyCompletionUtil.endsWithExpression(GroovyCompletionUtil.nearestLeftSibling(context.getParent()))) { + endsWithExpression(nearestLeftSibling(context.getParent()))) { return true; } @@ -606,12 +606,12 @@ public class GroovyCompletionData { } private static boolean suggestModifiers(PsiElement context) { - if (GroovyCompletionUtil.asSimpleVariable(context) || - GroovyCompletionUtil.asTypedMethod(context) || - GroovyCompletionUtil.isNewStatementInScript(context)) { + if (asSimpleVariable(context) || + asTypedMethod(context) || + isNewStatementInScript(context)) { return true; } - if (GroovyCompletionUtil.isFirstElementAfterPossibleModifiersInVariableDeclaration(context, false) && + if (isFirstElementAfterPossibleModifiersInVariableDeclaration(context, false) && !psiElement().afterLeaf("def").accepts(context)) { return true; } @@ -636,7 +636,7 @@ public class GroovyCompletionData { } if (contextParent instanceof GrExpression && contextParent.getParent() instanceof GroovyFile && - GroovyCompletionUtil.isNewStatement(context, false)) { + isNewStatement(context, false)) { return true; } if (context.getTextRange().getStartOffset() == 0 && !(context instanceof OuterLanguageElement)) { @@ -645,22 +645,16 @@ public class GroovyCompletionData { return contextParent instanceof GrExpression && contextParent.getParent() instanceof GrApplicationStatement && contextParent.getParent().getParent() instanceof GroovyFile && - GroovyCompletionUtil.isNewStatement(context, false); + isNewStatement(context, false); } public static boolean suggestFinalDef(PsiElement context) { - if (GroovyCompletionUtil.asSimpleVariable(context) || - GroovyCompletionUtil.asTypedMethod(context) || - GroovyCompletionUtil.asVariableInBlock(context) || - GroovyCompletionUtil.isNewStatementInScript(context)) { - return true; - } - if ((context.getParent() instanceof GrParameter && - ((GrParameter) context.getParent()).getTypeElementGroovy() == null) || - context.getParent() instanceof GrReferenceElement && - !(context.getParent() instanceof GrReferenceExpression) && - !(context.getParent().getParent() instanceof GrImportStatement) && - !(context.getParent().getParent() instanceof GrPackageDefinition)) { + if (asSimpleVariable(context) || + asTypedMethod(context) || + asVariableInBlock(context) || + isNewStatementInScript(context) && !isReferenceElementInNewExpr(context) || + isTypelessParameter(context) || + isCodeReferenceElementApplicableToModifierCompletion(context)) { return true; } if (PsiImplUtil.realPrevious(context.getParent().getPrevSibling()) instanceof GrModifierList) { @@ -671,6 +665,6 @@ public class GroovyCompletionData { } return context.getParent() instanceof GrExpression && context.getParent().getParent() instanceof GroovyFile && - GroovyCompletionUtil.isNewStatement(context, false); + isNewStatement(context, false); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java index e71f78596c48..315c00aa3f18 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java @@ -62,12 +62,14 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClassTypeElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; @@ -577,4 +579,24 @@ public class GroovyCompletionUtil { } return false; } + + public static boolean isReferenceElementInNewExpr(PsiElement context) { + if (context.getParent() instanceof GrCodeReferenceElement) { + PsiElement pparent = context.getParent().getParent(); + if (pparent instanceof GrNewExpression) return true; + } + + return false; + } + + static boolean isCodeReferenceElementApplicableToModifierCompletion(PsiElement context) { + return context.getParent() instanceof GrCodeReferenceElement && + !(context.getParent().getParent() instanceof GrImportStatement) && + !(context.getParent().getParent() instanceof GrPackageDefinition) && + !(context.getParent().getParent() instanceof GrNewExpression); + } + + static boolean isTypelessParameter(PsiElement context) { + return (context.getParent() instanceof GrParameter && ((GrParameter)context.getParent()).getTypeElementGroovy() == null); + } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 8b6a02a96ac3..3bb489d4fa9b 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -35,7 +35,7 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase { @Override protected void setUp() { super.setUp() - CamelHumpMatcher.forceStartMatching(getTestRootDisposable()); + CamelHumpMatcher.forceStartMatching(testRootDisposable); } @Override @@ -135,27 +135,27 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase { public void testFieldSuggestedOnce1() { myFixture.testCompletion(getTestName(false) + ".groovy", getTestName(false) + ".groovy"); - assertNull(myFixture.getLookupElements()); + assertNull(myFixture.lookupElements); } public void testFieldSuggestedOnce2() { myFixture.testCompletion(getTestName(false) + ".groovy", getTestName(false) + ".groovy"); - assertNull(myFixture.getLookupElements()); + assertNull(myFixture.lookupElements); } public void testFieldSuggestedOnce3() { myFixture.testCompletion(getTestName(false) + ".groovy", getTestName(false) + ".groovy"); - assertNull(myFixture.getLookupElements()); + assertNull(myFixture.lookupElements); } public void testFieldSuggestedOnce4() { myFixture.testCompletion(getTestName(false) + ".groovy", getTestName(false) + ".groovy"); - assertNull(myFixture.getLookupElements()); + assertNull(myFixture.lookupElements); } public void testFieldSuggestedOnce5() { myFixture.testCompletion(getTestName(false) + ".groovy", getTestName(false) + ".groovy"); - assertNull(myFixture.getLookupElements()); + assertNull(myFixture.lookupElements); } public void testFieldSuggestedInMethodCall() { @@ -300,7 +300,7 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase { } public void testCompletionNamedArgumentWithoutSpace() { - def settings = CodeStyleSettingsManager.getSettings(getProject()).getCustomSettings(GroovyCodeStyleSettings.class) + def settings = CodeStyleSettingsManager.getSettings(project).getCustomSettings(GroovyCodeStyleSettings.class) settings.SPACE_IN_NAMED_ARGUMENT = false try { @@ -937,12 +937,12 @@ class Fopppp { public void testExcludeStringBuffer() { assert doContainsTest('StringBuffer', 'StringBufff') - CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = [StringBuffer.name] as String[] + CodeInsightSettings.instance.EXCLUDED_PACKAGES = [StringBuffer.name] as String[] try { assert !doContainsTest('StringBuffer', 'StringBufff') } finally { - CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = new String[0] + CodeInsightSettings.instance.EXCLUDED_PACKAGES = new String[0] } } @@ -1022,10 +1022,6 @@ while(true) { assertEquals 'stryng', myFixture.lookupElementStrings[0] } - private def caseSensitiveNone() { - CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE - } - public void testFieldVsPackage() { myFixture.addFileToProject 'aaa/bbb/Foo.groovy', 'package aaa.bbb; class Foo{}' def file = myFixture.addFileToProject('aaa/bar.groovy', ''' @@ -1340,7 +1336,7 @@ def map = [1:2] print map.metc '''); myFixture.complete(CompletionType.BASIC); - assertEmpty myFixture.getLookupElements() + assertEmpty myFixture.lookupElements } void testAnnotationCompletion0() { @@ -1572,4 +1568,8 @@ setBarrr() void testParenthesesAfterDot() { myFixture.testCompletionTyping(getTestName(false) + '.groovy', '\t', getTestName(false) + '_after.groovy') } + + void testNewExprDoesntCompleteDef() { + doNoVariantsTest('def a = \new ', 'def', 'final') + } } \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.groovy index 3da5c3713b40..8dfd44884b66 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.groovy @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.completion; - +package org.jetbrains.plugins.groovy.completion +import com.intellij.codeInsight.CodeInsightSettings import com.intellij.codeInsight.completion.CompletionType import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase - +import com.intellij.util.containers.ContainerUtil +import org.jetbrains.plugins.groovy.GroovyFileType /** * @author Maxim.Medvedev */ @@ -96,4 +97,17 @@ abstract public class GroovyCompletionTestBase extends LightCodeInsightFixtureTe myFixture.checkResult(after); } + public void doNoVariantsTest(String before, String... excludedVariants) { + myFixture.configureByText(GroovyFileType.GROOVY_FILE_TYPE, before) + myFixture.completeBasic() + final excluded = ContainerUtil.newHashSet(excludedVariants) + for (String lookup : myFixture.lookupElementStrings) { + assertFalse(lookup, excluded.contains(lookup)) + } + } + + protected static def caseSensitiveNone() { + CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE + } + } From 8b5dcc6b5e4c1b11cec5a0013a9974632d38ade4 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 17 Oct 2012 10:49:25 +0200 Subject: [PATCH 51/57] fix ftl tests --- .../completion/JavaClassReferenceCompletionContributor.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java index e7ad8966c1f3..be4867cc9c05 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java @@ -62,6 +62,10 @@ public class JavaClassReferenceCompletionContributor extends CompletionContribut StringUtil.join(extendClassNames, ", ")); } + if (parameters.getCompletionType() == CompletionType.SMART) { + return; + } + if (parameters.getCompletionType() == CompletionType.CLASS_NAME) { JavaClassNameCompletionContributor.addAllClasses(parameters, result); } From 8edf4011f831512cd35949d65fb5611041903713 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 17 Oct 2012 11:30:25 +0200 Subject: [PATCH 52/57] CompletionResultSet implements Consumer --- .../completion/JavaClassNameCompletionContributor.java | 7 +------ .../completion/JavaCompletionContributor.java | 7 +------ .../codeInsight/completion/JavaCompletionData.java | 7 +------ .../codeInsight/completion/JavaNoVariantsDelegator.java | 7 +------ .../reference/impl/providers/JavaClassReference.java | 9 +++++---- .../codeInsight/completion/CompletionResultSet.java | 7 ++++++- 6 files changed, 15 insertions(+), 29 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java index edd11ed4728b..99d3cfea274f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java @@ -60,12 +60,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { static void addAllClasses(CompletionParameters parameters, final CompletionResultSet _result) { CompletionResultSet result = _result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters)); - addAllClasses(parameters, parameters.getInvocationCount() <= 1, result.getPrefixMatcher(), new Consumer() { - @Override - public void consume(LookupElement element) { - _result.addElement(element); - } - }); + addAllClasses(parameters, parameters.getInvocationCount() <= 1, result.getPrefixMatcher(), _result); } private static boolean mayContainClassName(CompletionParameters parameters) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 2bb455223430..cf4a331e058e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -237,12 +237,7 @@ public class JavaCompletionContributor extends CompletionContributor { !((PsiReferenceExpression)parent).isQualified() && parameters.isExtendedCompletion() && StringUtil.isNotEmpty(matcher.getPrefix())) { - new JavaStaticMemberProcessor(parameters).processStaticMethodsGlobally(matcher, new Consumer() { - @Override - public void consume(LookupElement element) { - result.addElement(element); - } - }); + new JavaStaticMemberProcessor(parameters).processStaticMethodsGlobally(matcher, result); } result.stopHere(); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java index ce09e552c4c0..e143706d6eed 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java @@ -554,12 +554,7 @@ public class JavaCompletionData extends JavaAwareCompletionData { static void addExpectedTypeMembers(CompletionParameters parameters, final CompletionResultSet result, PsiElement position) { for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) { - new JavaMembersGetter(info.getDefaultType(), parameters).addMembers(parameters.getInvocationCount() > 1, new Consumer() { - @Override - public void consume(LookupElement element) { - result.addElement(element); - } - }); + new JavaMembersGetter(info.getDefaultType(), parameters).addMembers(parameters.getInvocationCount() > 1, result); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java index af6dc31c8482..8e604a247d33 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java @@ -90,12 +90,7 @@ public class JavaNoVariantsDelegator extends CompletionContributor { private static void suggestCollectionUtilities(CompletionParameters parameters, final CompletionResultSet result, PsiElement position) { if (StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix())) { for (ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) { - new CollectionsUtilityMethodsProvider(position, info.getType(), info.getDefaultType(), new Consumer() { - @Override - public void consume(LookupElement element) { - result.addElement(element); - } - }).addCompletions(true); + new CollectionsUtilityMethodsProvider(position, info.getType(), info.getDefaultType(), result).addCompletions(true); } } } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java index e5f78ae5a64c..04dd71c7970d 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java @@ -15,7 +15,6 @@ */ package com.intellij.psi.impl.source.resolve.reference.impl.providers; -import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.codeInsight.completion.JavaLookupElementBuilder; import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor; import com.intellij.codeInsight.daemon.QuickFixProvider; @@ -24,6 +23,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix; import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixActionRegistrarImpl; import com.intellij.codeInsight.daemon.quickFix.CreateClassOrPackageFix; +import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.LocalQuickFixProvider; @@ -51,6 +51,7 @@ import com.intellij.psi.util.ClassKind; import com.intellij.psi.util.ClassUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; +import com.intellij.util.Consumer; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.CharArrayUtil; @@ -512,7 +513,7 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer } @NotNull - public void processSubclassVariants(@NotNull PsiPackage context, @NotNull String[] extendClasses, CompletionResultSet result) { + public void processSubclassVariants(@NotNull PsiPackage context, @NotNull String[] extendClasses, Consumer result) { GlobalSearchScope packageScope = PackageScope.packageScope(context, true); GlobalSearchScope scope = myJavaClassReferenceSet.getProvider().getScope(getElement().getProject()); if (scope != null) { @@ -532,13 +533,13 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer // add itself if (packageScope.contains(extendClass.getContainingFile().getVirtualFile())) { if (isClassAccepted(extendClass, classKind, instantiatable, concrete, notInterface, notEnum)) { - result.addElement(createSubclassLookupValue(extendClass, extendClassName)); + result.consume(createSubclassLookupValue(extendClass, extendClassName)); } } for (final PsiClass clazz : ClassInheritorsSearch.search(extendClass, packageScope, true)) { String qname = clazz.getQualifiedName(); if (qname != null && isClassAccepted(clazz, classKind, instantiatable, concrete, notInterface, notEnum)) { - result.addElement(createSubclassLookupValue(clazz, qname)); + result.consume(createSubclassLookupValue(clazz, qname)); } } } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java index 5bcc12583567..5d616e277359 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java @@ -22,7 +22,7 @@ import java.util.LinkedHashSet; * * @author peter */ -public abstract class CompletionResultSet { +public abstract class CompletionResultSet implements Consumer { private final PrefixMatcher myPrefixMatcher; private final Consumer myConsumer; protected final CompletionService myCompletionService = CompletionService.getCompletionService(); @@ -39,6 +39,11 @@ public abstract class CompletionResultSet { return myConsumer; } + @Override + public void consume(LookupElement element) { + addElement(element); + } + /** * If a given element matches the prefix, give it for further processing (which may eventually result in its appearing in the completion list) * @param element From e62e2e76524fcdd2f90e3f464f5cc1cf7acbf971 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 17 Oct 2012 15:07:07 +0400 Subject: [PATCH 53/57] settings duplication problem fixed --- .../newProjectWizard/SelectTemplateSettings.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateSettings.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateSettings.java index 4bc065fc4f81..f0677f6f6e4b 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateSettings.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateSettings.java @@ -22,7 +22,7 @@ import com.intellij.openapi.util.WriteExternalException; import com.intellij.util.xmlb.annotations.Tag; import com.intellij.util.xmlb.annotations.Transient; import org.jdom.Element; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; /** * @author Dmitry Avdeev @@ -31,7 +31,9 @@ import org.jetbrains.annotations.Nullable; @State(name = "SelectProjectTemplateSettings", storages = {@Storage( file = StoragePathMacros.APP_CONFIG + "/other.xml")}) public class SelectTemplateSettings implements PersistentStateComponent { - static SelectTemplateSettings getInstance() { + private static final String STATE_ELEMENT_NAME = "treeState"; + + public static SelectTemplateSettings getInstance() { return ServiceManager.getService(SelectTemplateSettings.class); } @@ -45,11 +47,11 @@ public class SelectTemplateSettings implements PersistentStateComponent Date: Wed, 17 Oct 2012 15:11:48 +0400 Subject: [PATCH 54/57] simplify --- plugins/git4idea/src/git4idea/ui/branch/GitBranchUiUtil.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchUiUtil.java b/plugins/git4idea/src/git4idea/ui/branch/GitBranchUiUtil.java index 9f5341545ec4..d84a1af832a5 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitBranchUiUtil.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitBranchUiUtil.java @@ -165,9 +165,6 @@ public class GitBranchUiUtil { return null; } GitRepositoryManager manager = GitUtil.getRepositoryManager(project); - if (manager == null) { - return null; - } VirtualFile file = getSelectedFile(project); if (file != null) { return manager.getRepositoryForRoot(getVcsRootFor(project, file)); From 1f3a88d4d6a088d727869f846642305c74480c12 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 17 Oct 2012 13:32:47 +0400 Subject: [PATCH 55/57] IDEA-92820 Groovy: parse extends list in enums --- .../plugins/groovy/GroovyBundle.properties | 3 +- .../groovy/annotator/GroovyAnnotator.java | 3 + .../typeDefinitions/TypeDefinition.java | 55 ++++++++++--------- .../members/InterfaceMember.java | 3 +- .../GroovyHighlightingTest.groovy | 7 +++ 5 files changed, 43 insertions(+), 28 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index 52a2e53b9862..7aee00157951 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -333,4 +333,5 @@ top.level.class.maynot.have.private.modifier=Top level class may not have 'priva top.level.class.maynot.have.protected.modifier=Top level class may not have 'protected' modifier property.missing=propertyMissing attribute.name.expected=Attribute name expected -java.style.for.each.statement.requires.a.type.declaration=Java-style for-each statement requires a type declaration \ No newline at end of file +java.style.for.each.statement.requires.a.type.declaration=Java-style for-each statement requires a type declaration +enums.may.not.have.extends.clause=Enums may not have 'extends' clause \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index c168691e949a..a0c9e87c6bbf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -1341,6 +1341,9 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { if (typeDefinition.isInterface()) { checkReferenceList(myHolder, extendsClause, true, GroovyBundle.message("no.class.expected.here"), null); } + else if (typeDefinition.isEnum()) { + myHolder.createErrorAnnotation(extendsClause, GroovyBundle.message("enums.may.not.have.extends.clause")); + } else { checkReferenceList(myHolder, extendsClause, false, GroovyBundle.message("no.interface.expected.here"), new ChangeExtendsImplementsQuickFix(typeDefinition)); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/TypeDefinition.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/TypeDefinition.java index 25d76ec43ce2..a0278029fa22 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/TypeDefinition.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/TypeDefinition.java @@ -23,8 +23,8 @@ import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.Separators; -import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.declaration.Declaration; import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.modifiers.Modifiers; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.declaration.Declaration; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.members.ClassMember; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.members.EnumConstant; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.members.InterfaceMember; @@ -83,15 +83,14 @@ public class TypeDefinition implements GroovyElementTypes { return false; } - String name; - if (!mIDENT.equals(builder.getTokenType())) { + if (builder.getTokenType() != mIDENT) { builder.error(GroovyBundle.message("identifier.expected")); return false; - } else { - name = builder.getTokenText(); - builder.advanceLexer(); } + String name = builder.getTokenText(); + builder.advanceLexer(); + ParserUtils.getToken(builder, mNLS); TypeParameters.parse(builder); @@ -114,39 +113,38 @@ public class TypeDefinition implements GroovyElementTypes { return false; } - String name; - if (!mIDENT.equals(builder.getTokenType())) { + if (builder.getTokenType() != mIDENT) { builder.error(GroovyBundle.message("identifier.expected")); return false; - } else { - name = builder.getTokenText(); - builder.advanceLexer(); } + String name = builder.getTokenText(); + builder.advanceLexer(); + ParserUtils.getToken(builder, mNLS); TypeParameters.parse(builder); ParserUtils.getToken(builder, mNLS); - if (kEXTENDS.equals(builder.getTokenType())) { + if (builder.getTokenType() == kEXTENDS) { ReferenceElement.parseReferenceList(builder, kEXTENDS, EXTENDS_CLAUSE); ParserUtils.getToken(builder, mNLS); } - if (kIMPLEMENTS.equals(builder.getTokenType())) { + if (builder.getTokenType() == kIMPLEMENTS) { ReferenceElement.parseReferenceList(builder, kIMPLEMENTS, IMPLEMENTS_CLAUSE); } ParserUtils.getToken(builder, mNLS); - if (mLCURLY.equals(builder.getTokenType())) { - parseClassBody(builder, name, parser); - } else { + if (builder.getTokenType() != mLCURLY) { builder.error(GroovyBundle.message("lcurly.expected")); return true; } + parseClassBody(builder, name, parser); + return true; } @@ -155,17 +153,21 @@ public class TypeDefinition implements GroovyElementTypes { return false; } - String name; - if (!mIDENT.equals(builder.getTokenType())) { + if (builder.getTokenType() != mIDENT) { builder.error(GroovyBundle.message("identifier.expected")); return false; - } else { - name = builder.getTokenText(); - builder.advanceLexer(); } - if (WRONGWAY.equals(ReferenceElement.parseReferenceList(builder, kIMPLEMENTS, IMPLEMENTS_CLAUSE))) { - return true; + String name = builder.getTokenText(); + builder.advanceLexer(); + + if (builder.getTokenType() == kEXTENDS) { + ReferenceElement.parseReferenceList(builder, kEXTENDS, EXTENDS_CLAUSE); + ParserUtils.getToken(builder, mNLS); + } + + if (builder.getTokenType() == kIMPLEMENTS) { + ReferenceElement.parseReferenceList(builder, kIMPLEMENTS, IMPLEMENTS_CLAUSE); } Separators.parse(builder); @@ -265,7 +267,7 @@ public class TypeDefinition implements GroovyElementTypes { return true; } - private static boolean parseEnumBlock(PsiBuilder builder, String enumName, GroovyParser parser) { + private static boolean parseEnumBlock(PsiBuilder builder, @Nullable String enumName, GroovyParser parser) { //see also InterfaceBlock, EnumBlock, AnnotationBlock PsiBuilder.Marker ebMarker = builder.mark(); @@ -278,7 +280,8 @@ public class TypeDefinition implements GroovyElementTypes { if (parseEnumConstantStart(builder, parser)) { EnumConstant.parseConstantList(builder, parser); - } else { + } + else { ClassMember.parse(builder, enumName, parser); } @@ -305,7 +308,7 @@ public class TypeDefinition implements GroovyElementTypes { return result; } - private static boolean parseInterfaceBlock(PsiBuilder builder, String interfaceName, GroovyParser parser) { + private static boolean parseInterfaceBlock(PsiBuilder builder, @Nullable String interfaceName, GroovyParser parser) { //see also InterfaceBlock, EnumBlock, AnnotationBlock PsiBuilder.Marker ibMarker = builder.mark(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/members/InterfaceMember.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/members/InterfaceMember.java index 05c73bb8cc91..303a93782d3f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/members/InterfaceMember.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/members/InterfaceMember.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.members; import com.intellij.lang.PsiBuilder; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; @@ -31,7 +32,7 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; * @date: 20.03.2007 */ public class InterfaceMember implements GroovyElementTypes { - public static boolean parse(PsiBuilder builder, String interfaceName, GroovyParser parser) { + public static boolean parse(PsiBuilder builder, @Nullable String interfaceName, GroovyParser parser) { //constructor if (ConstructorDefinition.parse(builder, interfaceName, parser)) return true; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy index ca662474daf2..90cecfa9decf 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy @@ -896,6 +896,13 @@ def methodMissing(String methodName, args) { this.metaClass."$methodName" = closure closure() = 2 } +''') + } + + void testEnumExtendsList() { + testHighlighting('''\ +enum Ee extends Enum { +} ''') } } \ No newline at end of file From dca6846a6aaabfb779151c2ac305ce6b7ceacd03 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 17 Oct 2012 14:57:54 +0400 Subject: [PATCH 56/57] cleanup --- .../lang/resolve/TypeInferenceTest.groovy | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy index 6b46d50c2a0a..3e337f53a3dc 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy @@ -37,111 +37,111 @@ public class TypeInferenceTest extends GroovyResolveTestCase { final String basePath = TestUtils.testDataPath + "resolve/inference/" public void testTryFinallyFlow() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("tryFinallyFlow/A.groovy").getElement(); - final PsiType type = ref.getType(); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("tryFinallyFlow/A.groovy").element; + final PsiType type = ref.type; assertTrue(type instanceof PsiIntersectionType); - final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts(); + final PsiType[] conjuncts = ((PsiIntersectionType)type).conjuncts; assertEquals(conjuncts.length, 2); } public void testTryFinallyFlow1() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("tryFinallyFlow1/A.groovy").getElement(); - final PsiType type = ref.getType(); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("tryFinallyFlow1/A.groovy").element; + final PsiType type = ref.type; assertNotNull(type); assertTrue(type.equalsToText("java.lang.Integer")); } public void testTryFinallyFlow2() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("tryFinallyFlow2/A.groovy").getElement(); - final PsiType type = ref.getType(); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("tryFinallyFlow2/A.groovy").element; + final PsiType type = ref.type; assertNotNull(type); assertTrue(type.equalsToText("java.lang.Integer")); } public void testThrowVariable() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("throwVariable/A.groovy").getElement(); - final PsiType type = ref.getType(); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("throwVariable/A.groovy").element; + final PsiType type = ref.type; assertNotNull(type); - assertEquals("java.lang.Exception", type.getCanonicalText()); + assertEquals("java.lang.Exception", type.canonicalText); } public void testGrvy852() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("grvy852/A.groovy").getElement(); - final PsiType type = ref.getType(); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("grvy852/A.groovy").element; + final PsiType type = ref.type; assertNotNull(type); - assertEquals("java.lang.Object", type.getCanonicalText()); + assertEquals("java.lang.Object", type.canonicalText); } public void testGenericMethod() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("genericMethod/A.groovy").getElement(); - final PsiType type = ref.getType(); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("genericMethod/A.groovy").element; + final PsiType type = ref.type; assertNotNull(type); - assertEquals("java.util.List", type.getCanonicalText()); + assertEquals("java.util.List", type.canonicalText); } public void testCircular() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("circular/A.groovy").getElement(); - assertNull(ref.getType()); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("circular/A.groovy").element; + assertNull(ref.type); } public void testCircular1() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("circular1/A.groovy").getElement(); - assertNull(ref.getType()); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("circular1/A.groovy").element; + assertNull(ref.type); } public void testClosure() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("closure/A.groovy").getElement(); - assertNotNull(ref.getType()); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("closure/A.groovy").element; + assertNotNull(ref.type); } public void testClosure1() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("closure1/A.groovy").getElement(); - assertTrue(ref.getType().equalsToText("java.lang.Integer")); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("closure1/A.groovy").element; + assertTrue(ref.type.equalsToText("java.lang.Integer")); } public void testClosure2() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("closure2/A.groovy").getElement(); - assertTrue(ref.getType().equalsToText("java.lang.Integer")); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("closure2/A.groovy").element; + assertTrue(ref.type.equalsToText("java.lang.Integer")); } public void testGrvy1209() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("grvy1209/A.groovy").getElement(); - assertTrue(ref.getType().equalsToText("java.lang.String")); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("grvy1209/A.groovy").element; + assertTrue(ref.type.equalsToText("java.lang.String")); } public void testLeastUpperBoundClosureType() { - GrReferenceExpression ref = (GrReferenceExpression)configureByFile("leastUpperBoundClosureType/A.groovy").getElement(); - assertInstanceOf(ref.getType(), GrClosureType.class); + GrReferenceExpression ref = (GrReferenceExpression)configureByFile("leastUpperBoundClosureType/A.groovy").element; + assertInstanceOf(ref.type, GrClosureType.class); } public void testJavaLangClassType() { - final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("javaLangClassType/A.groovy").getElement(); - assertEquals("java.lang.String", ref.getType().getCanonicalText()); + final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("javaLangClassType/A.groovy").element; + assertEquals("java.lang.String", ref.type.canonicalText); } public void testGenericWildcard() { - final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("genericWildcard/A.groovy").getElement(); - assertEquals("A", ref.getType().getCanonicalText()); + final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("genericWildcard/A.groovy").element; + assertEquals("A", ref.type.canonicalText); } public void testArrayLikeAccessWithIntSequence() { - final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("arrayLikeAccessWithIntSequence/A.groovy").getElement(); - assertEquals("java.util.List", ref.getType().getCanonicalText()); + final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("arrayLikeAccessWithIntSequence/A.groovy").element; + assertEquals("java.util.List", ref.type.canonicalText); } public void testArrayAccess() { final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("arrayAccess/A.groovy"); - assertEquals(JAVA_LANG_STRING, ref.getType().getCanonicalText()); + assertEquals(JAVA_LANG_STRING, ref.type.canonicalText); } public void testReturnTypeByTailExpression() { final GrReferenceExpression ref = (GrReferenceExpression)configureByFile("returnTypeByTailExpression/A.groovy"); - assertEquals(JAVA_LANG_STRING, ref.getType().getCanonicalText()); + assertEquals(JAVA_LANG_STRING, ref.type.canonicalText); } public void testParameterWithBuiltinType() { GrReferenceExpression refExpr = (GrReferenceExpression)configureByFile("parameterWithBuiltinType/A.groovy"); - assertEquals("java.lang.Integer", refExpr.getType().getCanonicalText()); + assertEquals("java.lang.Integer", refExpr.type.canonicalText); } public void testRawTypeInReturnExpression() { @@ -150,15 +150,15 @@ public class TypeInferenceTest extends GroovyResolveTestCase { public void testMethodCallInvokedOnArrayAccess() { final GrReferenceExpression reference = (GrReferenceExpression)configureByFile("A.groovy"); - assertEquals("java.lang.Integer", reference.getType().getCanonicalText()); + assertEquals("java.lang.Integer", reference.type.canonicalText); } private void assertTypeEquals(String expected, String fileName) { final PsiReference ref = configureByFile(getTestName(true) + "/" + fileName); assertInstanceOf(ref, GrReferenceExpression.class); - final PsiType type = ((GrReferenceExpression)ref).getType(); + final PsiType type = ((GrReferenceExpression)ref).type; assertNotNull(type); - assertEquals(expected, type.getCanonicalText()); + assertEquals(expected, type.canonicalText); } public void testTypeOfGroupBy() { @@ -170,7 +170,7 @@ public class TypeInferenceTest extends GroovyResolveTestCase { } public void testImplicitCallMethod() { - assertEquals("java.lang.String", ((GrExpression)configureByFile("A.groovy")).getType().getCanonicalText()); + assertEquals("java.lang.String", ((GrExpression)configureByFile("A.groovy")).type.canonicalText); } public void testTupleWithNullInIt() { @@ -220,7 +220,7 @@ public class TypeInferenceTest extends GroovyResolveTestCase { public void testNoSOF() { final PsiReference ref = configureByFile(getTestName(true) + "/A.groovy"); assertInstanceOf(ref, GrReferenceExpression.class); - final PsiType type = ((GrReferenceExpression)ref).getType(); + final PsiType type = ((GrReferenceExpression)ref).type; assertNull(type); } From 53283e232241d7ab99f5dbd03253fdda58cf475d Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 17 Oct 2012 15:26:19 +0400 Subject: [PATCH 57/57] IDEA-92833 Type inference doesn't update type after assert instanceof --- .../com/intellij/psi/CommonClassNames.java | 1 + .../ipp/asserttoif/IfStatementPredicate.java | 2 +- .../controlFlow/impl/ControlFlowBuilder.java | 25 ++++++-- .../lang/controlFlow/ControlFlowTest.groovy | 64 ++++++++++--------- .../lang/resolve/TypeInferenceTest.groovy | 9 +++ .../testdata/groovy/controlFlow/assert0.test | 14 ++++ .../testdata/groovy/controlFlow/assert1.test | 25 ++++++++ 7 files changed, 101 insertions(+), 39 deletions(-) create mode 100644 plugins/groovy/testdata/groovy/controlFlow/assert0.test create mode 100644 plugins/groovy/testdata/groovy/controlFlow/assert1.test diff --git a/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java b/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java index 16b51cc9fa61..50d680fe8e5d 100644 --- a/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java +++ b/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java @@ -89,4 +89,5 @@ public interface CommonClassNames { String TARGET_ANNOTATION_FQ_NAME = "java.lang.annotation.Target"; @NonNls String JAVA_LANG_RUNNABLE = "java.lang.Runnable"; @NonNls String JAVA_IO_FILE = "java.io.File"; + String JAVA_LANG_ASSERTION_ERROR = "java.lang.AssertionError"; } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/asserttoif/IfStatementPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/asserttoif/IfStatementPredicate.java index aa86dace15fb..2a904a5b2a66 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/asserttoif/IfStatementPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/asserttoif/IfStatementPredicate.java @@ -61,7 +61,7 @@ class IfStatementPredicate implements PsiElementPredicate { } final PsiClass aClass = (PsiClass)target; final String qualifiedName = aClass.getQualifiedName(); - return "java.lang.AssertionError".equals(qualifiedName); + return CommonClassNames.JAVA_LANG_ASSERTION_ERROR.equals(qualifiedName); } else if (element instanceof PsiBlockStatement) { final PsiBlockStatement blockStatement = diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java index c368b4094d36..b281c2a82088 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java @@ -378,25 +378,34 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor { } public void visitAssertStatement(GrAssertStatement assertStatement) { + final InstructionImpl assertInstruction = startNode(assertStatement); + final GrExpression assertion = assertStatement.getAssertion(); if (assertion != null) { - myConditions.push(addNodeAndCheckPending(new ConditionInstruction(assertion))); assertion.accept(this); - final InstructionImpl assertInstruction = startNode(assertStatement); + + InstructionImpl positiveHead = myHead; + interruptFlow(); + + List negations = collectAndRemoveAllPendingNegations(assertStatement); + reduceAllNegationsIntoInstruction(assertStatement, negations); + GrExpression errorMessage = assertStatement.getErrorMessage(); if (errorMessage != null) { errorMessage.accept(this); } - final PsiType type = TypesUtil.createTypeByFQClassName("java.lang.AssertionError", assertStatement); + final PsiType type = TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_LANG_ASSERTION_ERROR, assertStatement); ExceptionInfo info = findCatch(type); if (info != null) { - info.myThrowers.add(assertInstruction); + info.myThrowers.add(myHead); } else { - addPendingEdge(null, assertInstruction); + addPendingEdge(null, myHead); } - finishNode(assertInstruction); + + myHead = positiveHead; } + finishNode(assertInstruction); } public void visitThrowStatement(GrThrowStatement throwStatement) { @@ -525,7 +534,9 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor { return instruction; } else if (negations.size() == 1) { - return negations.get(0); + GotoInstruction instruction = negations.get(0); + myHead = instruction; + return instruction; } return null; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/controlFlow/ControlFlowTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/controlFlow/ControlFlowTest.groovy index 6a01df4ac5ce..634def671721 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/controlFlow/ControlFlowTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/controlFlow/ControlFlowTest.groovy @@ -17,37 +17,37 @@ import org.jetbrains.plugins.groovy.util.TestUtils public class ControlFlowTest extends LightCodeInsightFixtureTestCase { final String basePath = TestUtils.testDataPath + "groovy/controlFlow/" - public void testAssignment() throws Throwable { doTest(); } - public void testClosure1() throws Throwable { doTest(); } - public void testComplexAssign() throws Throwable { doTest(); } - public void testFor1() throws Throwable { doTest(); } - public void testForeach1() throws Throwable { doTest(); } - public void testGrvy1497() throws Throwable { doTest(); } - public void testIf1() throws Throwable { doTest(); } - public void testMultipleAssignment() throws Throwable { doTest(); } - public void testNested() throws Throwable { doTest(); } - public void testReturn() throws Throwable { doTest(); } - public void testSwitch1() throws Throwable { doTest(); } - public void testSwitch2() throws Throwable { doTest(); } - public void testSwitch3() throws Throwable { doTest(); } - public void testSwitch4() throws Throwable { doTest(); } - public void testSwitch5() throws Throwable { doTest(); } - public void testThrow1() throws Throwable { doTest(); } - public void testThrowInCatch() throws Throwable { doTest(); } - public void testTry1() throws Throwable { doTest(); } - public void testTry2() throws Throwable { doTest(); } - public void testTry3() throws Throwable { doTest(); } - public void testTry4() throws Throwable { doTest(); } - public void testTry5() throws Throwable { doTest(); } - public void testTry6() throws Throwable { doTest(); } - public void testTry7() throws Throwable { doTest(); } - public void testTry8() throws Throwable { doTest(); } - public void testTry9() throws Throwable { doTest(); } - public void testTry10() throws Throwable { doTest(); } - public void testWhile1() throws Throwable { doTest(); } - public void testWhile2() throws Throwable { doTest(); } - public void testWhileNonConstant() throws Throwable { doTest(); } - public void testIfInstanceofElse() throws Throwable { doTest(); } + public void testAssignment() { doTest(); } + public void testClosure1() { doTest(); } + public void testComplexAssign() { doTest(); } + public void testFor1() { doTest(); } + public void testForeach1() { doTest(); } + public void testGrvy1497() { doTest(); } + public void testIf1() { doTest(); } + public void testMultipleAssignment() { doTest(); } + public void testNested() { doTest(); } + public void testReturn() { doTest(); } + public void testSwitch1() { doTest(); } + public void testSwitch2() { doTest(); } + public void testSwitch3() { doTest(); } + public void testSwitch4() { doTest(); } + public void testSwitch5() { doTest(); } + public void testThrow1() { doTest(); } + public void testThrowInCatch() { doTest(); } + public void testTry1() { doTest(); } + public void testTry2() { doTest(); } + public void testTry3() { doTest(); } + public void testTry4() { doTest(); } + public void testTry5() { doTest(); } + public void testTry6() { doTest(); } + public void testTry7() { doTest(); } + public void testTry8() { doTest(); } + public void testTry9() { doTest(); } + public void testTry10() { doTest(); } + public void testWhile1() { doTest(); } + public void testWhile2() { doTest(); } + public void testWhileNonConstant() { doTest(); } + public void testIfInstanceofElse() { doTest(); } public void testReturnMapFromClosure() {doTest();} public void testSwitchInTryWithThrows() {doTest();} public void testClosure() {doTest();} @@ -56,6 +56,8 @@ public class ControlFlowTest extends LightCodeInsightFixtureTestCase { public void testOrInReturn() {doTest();} public void testVarInString() {doTest();} public void testMayBeStaticWithCondition() {doTest()} + public void testAssert0() { doTest() } + public void testAssert1() { doTest() } public void doTest() { final List input = TestUtils.readInput(testDataPath + getTestName(true) + ".test"); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy index 3e337f53a3dc..73dd4fdd2dfa 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy @@ -568,6 +568,15 @@ def method(List t) { ''', 'Tx') } + void testAssert() { + doTest('''\ +def foo(def var) { + assert var instanceof String + var.isEmpty() +} +''', 'java.lang.String') + } + private void doTest(String text, String type) { def file = myFixture.configureByText('_.groovy', text) def ref = file.findReferenceAt(myFixture.editor.caretModel.offset) as GrReferenceExpression diff --git a/plugins/groovy/testdata/groovy/controlFlow/assert0.test b/plugins/groovy/testdata/groovy/controlFlow/assert0.test new file mode 100644 index 000000000000..84acf05162cd --- /dev/null +++ b/plugins/groovy/testdata/groovy/controlFlow/assert0.test @@ -0,0 +1,14 @@ +assert x instanceof String : bar() +return x.isEmpty() +----- +0(1) element: null +1(2) element: ASSERT statement +2(3) READ x +3(4,6) Condition Instanceof expression +4(5) instanceof: x instanceof String +5(7) Negating goto instruction, condition=3Instanceof expression +6(8) instanceof: x instanceof String +7(10) READ bar +8(9) READ x +9(10) element: RETURN statement +10() element: null \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/controlFlow/assert1.test b/plugins/groovy/testdata/groovy/controlFlow/assert1.test new file mode 100644 index 000000000000..56a9b23234e7 --- /dev/null +++ b/plugins/groovy/testdata/groovy/controlFlow/assert1.test @@ -0,0 +1,25 @@ +try { + assert x instanceof String : bar() +} +catch (java.lang.AssertionError e) { + return true +} + +return x.isEmpty() +----- +0(1) element: null +1(2) element: Open block +2(3) element: ASSERT statement +3(4) READ x +4(5,7) Condition Instanceof expression +5(6) instanceof: x instanceof String +6(8) Negating goto instruction, condition=4Instanceof expression +7(13) instanceof: x instanceof String +8(9) READ bar +9(10) THROW. element: Method call +10(11) element: Catch clause +11(12) WRITE e +12(15) element: RETURN statement +13(14) READ x +14(15) element: RETURN statement +15() element: null