summaryrefslogtreecommitdiff
path: root/platform/lang-api/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'platform/lang-api/src/com')
-rw-r--r--platform/lang-api/src/com/intellij/diagnostic/logging/AdditionalTabComponent.java4
-rw-r--r--platform/lang-api/src/com/intellij/execution/DefaultExecutionResult.java11
-rw-r--r--platform/lang-api/src/com/intellij/execution/ExecutionResult.java1
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/AdditionalTabComponentManager.java9
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/LogFileOptions.java65
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/ModuleRunProfile.java2
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java3
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java3
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvider.java4
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvidingRunProfile.java34
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/SimpleJavaParameters.java10
-rw-r--r--platform/lang-api/src/com/intellij/execution/filters/ConsoleDependentFilterProvider.java32
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java13
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java4
-rw-r--r--platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java21
-rw-r--r--platform/lang-api/src/com/intellij/find/FindModel.java4
-rw-r--r--platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java67
-rw-r--r--platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java1
-rw-r--r--platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java12
-rw-r--r--platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java8
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java1
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java65
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetector.java106
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageInfo.java39
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatistics.java30
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatisticsImpl.java149
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfo.java56
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfoBuilder.java80
-rw-r--r--platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java5
29 files changed, 696 insertions, 143 deletions
diff --git a/platform/lang-api/src/com/intellij/diagnostic/logging/AdditionalTabComponent.java b/platform/lang-api/src/com/intellij/diagnostic/logging/AdditionalTabComponent.java
index b45abc181736..4991071477fb 100644
--- a/platform/lang-api/src/com/intellij/diagnostic/logging/AdditionalTabComponent.java
+++ b/platform/lang-api/src/com/intellij/diagnostic/logging/AdditionalTabComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.intellij.diagnostic.logging;
import com.intellij.openapi.ui.ComponentContainer;
@@ -36,6 +35,7 @@ public abstract class AdditionalTabComponent extends JPanel implements Component
protected AdditionalTabComponent() {
}
+ @NotNull
public abstract String getTabTitle();
@Nullable
diff --git a/platform/lang-api/src/com/intellij/execution/DefaultExecutionResult.java b/platform/lang-api/src/com/intellij/execution/DefaultExecutionResult.java
index 8a951da7d74f..75f117122e96 100644
--- a/platform/lang-api/src/com/intellij/execution/DefaultExecutionResult.java
+++ b/platform/lang-api/src/com/intellij/execution/DefaultExecutionResult.java
@@ -34,7 +34,8 @@ public class DefaultExecutionResult implements ExecutionResult {
private final ExecutionConsole myConsole;
private final ProcessHandler myProcessHandler;
private AnAction[] myActions;
- private AnAction[] myRestartActions;
+ @NotNull
+ private AnAction[] myRestartActions = AnAction.EMPTY_ARRAY;
private final List<AnAction> myStopActions = new ArrayList<AnAction>();
public DefaultExecutionResult() {
@@ -67,12 +68,14 @@ public class DefaultExecutionResult implements ExecutionResult {
myActions = actions;
}
+ @NotNull
public AnAction[] getRestartActions() {
return myRestartActions;
}
- public void setRestartActions(AnAction... restartActions) {
- myRestartActions = restartActions;
+ // TODO: Find all usages, make sure there is no null and make this method NotNull
+ public void setRestartActions(@Nullable AnAction... restartActions) {
+ myRestartActions = (restartActions != null ? restartActions : AnAction.EMPTY_ARRAY);
}
public void addStopAction(AnAction action) {
@@ -104,7 +107,7 @@ public class DefaultExecutionResult implements ExecutionResult {
@Override
public void actionPerformed(final AnActionEvent e) {
- if(myProcessHandler.detachIsDefault()) {
+ if (myProcessHandler.detachIsDefault()) {
myProcessHandler.detachProcess();
}
else {
diff --git a/platform/lang-api/src/com/intellij/execution/ExecutionResult.java b/platform/lang-api/src/com/intellij/execution/ExecutionResult.java
index 116ce555e94d..91f888aa8dc6 100644
--- a/platform/lang-api/src/com/intellij/execution/ExecutionResult.java
+++ b/platform/lang-api/src/com/intellij/execution/ExecutionResult.java
@@ -40,6 +40,7 @@ public interface ExecutionResult {
*/
AnAction[] getActions();
+
/**
* Returns the ProcessHandler attached to the running process.
*
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/AdditionalTabComponentManager.java b/platform/lang-api/src/com/intellij/execution/configurations/AdditionalTabComponentManager.java
index 26f1273b2698..701f1b294003 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/AdditionalTabComponentManager.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/AdditionalTabComponentManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
/*
* Created by IntelliJ IDEA.
* User: Anna.Kozlova
@@ -23,8 +22,10 @@
package com.intellij.execution.configurations;
import com.intellij.diagnostic.logging.AdditionalTabComponent;
+import org.jetbrains.annotations.NotNull;
public interface AdditionalTabComponentManager {
- void addAdditionalTabComponent(AdditionalTabComponent component, final String id);
- void removeAdditionalTabComponent(AdditionalTabComponent component);
+ void addAdditionalTabComponent(@NotNull AdditionalTabComponent component, @NotNull String id);
+
+ void removeAdditionalTabComponent(@NotNull AdditionalTabComponent component);
} \ No newline at end of file
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/LogFileOptions.java b/platform/lang-api/src/com/intellij/execution/configurations/LogFileOptions.java
index 6f23831c9e3a..0a4132d83a52 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/LogFileOptions.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/LogFileOptions.java
@@ -20,6 +20,8 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.SmartHashSet;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -27,8 +29,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
@@ -80,46 +81,50 @@ public class LogFileOptions implements JDOMExternalizable {
return myPathPattern;
}
+ @NotNull
public Set<String> getPaths(){
- Set<String> result = new HashSet<String>();
- final File logFile = new File(myPathPattern);
+ File logFile = new File(myPathPattern);
if (logFile.exists()){
- result.add(myPathPattern);
+ return Collections.singleton(myPathPattern);
+ }
+
+ int dirIndex = myPathPattern.lastIndexOf(File.separator);
+ if (dirIndex == -1) {
+ return Collections.emptySet();
+ }
+
+ List<File> files = new SmartList<File>();
+ collectMatchedFiles(new File(myPathPattern.substring(0, dirIndex)), Pattern.compile(FileUtil.convertAntToRegexp(myPathPattern.substring(dirIndex + File.separator.length()))), files);
+ if (files.isEmpty()) {
+ return Collections.emptySet();
+ }
+
+ if (myShowAll) {
+ SmartHashSet<String> result = new SmartHashSet<String>();
+ result.ensureCapacity(files.size());
+ for (File file : files) {
+ result.add(file.getPath());
+ }
return result;
}
- final int dirIndex = myPathPattern.lastIndexOf(File.separator);
- if (dirIndex != -1) {
- final ArrayList<File> files = new ArrayList<File>();
- final String basePath = myPathPattern.substring(0, dirIndex);
- final String pattern = myPathPattern.substring(dirIndex + File.separator.length());
- collectMatchedFiles(new File(basePath), Pattern.compile(FileUtil.convertAntToRegexp(pattern)), files);
- if (!files.isEmpty()) {
- if (myShowAll) {
- for (File file : files) {
- result.add(file.getPath());
+ else {
+ File lastFile = null;
+ for (File file : files) {
+ if (lastFile != null) {
+ if (file.lastModified() > lastFile.lastModified()) {
+ lastFile = file;
}
}
else {
- File lastFile = null;
- for (File file : files) {
- if (lastFile != null) {
- if (file.lastModified() > lastFile.lastModified()) {
- lastFile = file;
- }
- }
- else {
- lastFile = file;
- }
- }
- assert lastFile != null;
- result.add(lastFile.getPath());
+ lastFile = file;
}
}
+ assert lastFile != null;
+ return Collections.singleton(lastFile.getPath());
}
- return result;
}
- public static void collectMatchedFiles(final File root, final Pattern pattern, final List<File> files) {
+ public static void collectMatchedFiles(@NotNull File root, @NotNull Pattern pattern, @NotNull List<File> files) {
final File[] dirs = root.listFiles();
if (dirs == null) return;
for (File dir : dirs) {
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/ModuleRunProfile.java b/platform/lang-api/src/com/intellij/execution/configurations/ModuleRunProfile.java
index 9a1dfad2955a..45519c91baeb 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/ModuleRunProfile.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/ModuleRunProfile.java
@@ -19,5 +19,5 @@ package com.intellij.execution.configurations;
/**
* @author spleaner
*/
-public interface ModuleRunProfile extends RunProfileWithCompileBeforeLaunchOption {
+public interface ModuleRunProfile extends RunProfileWithCompileBeforeLaunchOption, SearchScopeProvidingRunProfile {
}
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java
index 0e852c6c577a..d0a180114587 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java
@@ -154,8 +154,9 @@ public abstract class RunConfigurationBase extends UserDataHolderBase
return myPredefinedLogFiles;
}
+ @NotNull
public ArrayList<LogFileOptions> getAllLogFiles() {
- final ArrayList<LogFileOptions> list = new ArrayList<LogFileOptions>(myLogFiles);
+ ArrayList<LogFileOptions> list = new ArrayList<LogFileOptions>(myLogFiles);
for (PredefinedLogFile predefinedLogFile : myPredefinedLogFiles) {
final LogFileOptions options = getOptionsForPredefinedLogFile(predefinedLogFile);
if (options != null) {
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java
index 259fd4e7484c..732976cf73a7 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java
@@ -17,12 +17,11 @@ package com.intellij.execution.configurations;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.UnnamedConfigurable;
-import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
public interface RunConfigurationsSettings {
ExtensionPointName<RunConfigurationsSettings> EXTENSION_POINT = ExtensionPointName.create("com.intellij.runConfigurationsSettings");
@NotNull
- UnnamedConfigurable createConfigurable(@NotNull Project project);
+ UnnamedConfigurable createConfigurable();
} \ No newline at end of file
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvider.java b/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvider.java
index ea6b158e0bc2..e3f0c22a2132 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvider.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvider.java
@@ -28,8 +28,8 @@ public class SearchScopeProvider {
@NotNull
public static GlobalSearchScope createSearchScope(@NotNull Project project, @Nullable RunProfile runProfile) {
Module[] modules = null;
- if (runProfile instanceof ModuleRunProfile) {
- modules = ((ModuleRunProfile)runProfile).getModules();
+ if (runProfile instanceof SearchScopeProvidingRunProfile) {
+ modules = ((SearchScopeProvidingRunProfile)runProfile).getModules();
}
if (modules == null || modules.length == 0) {
return GlobalSearchScope.allScope(project);
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvidingRunProfile.java b/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvidingRunProfile.java
new file mode 100644
index 000000000000..afdd273384e8
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/execution/configurations/SearchScopeProvidingRunProfile.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.execution.configurations;
+
+import com.intellij.openapi.module.Module;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Base interface for run configurations that can specify which part of the project should be used to search sources. This information
+ * will be used to provide more accurate navigation to sources from stack traces, debugger, etc
+ *
+ * @author nik
+ */
+public interface SearchScopeProvidingRunProfile extends RunProfile {
+ /**
+ * @return modules where to search sources for this configuration
+ */
+ @NotNull
+ Module[] getModules();
+} \ No newline at end of file
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/SimpleJavaParameters.java b/platform/lang-api/src/com/intellij/execution/configurations/SimpleJavaParameters.java
index 7b3c45d5c7de..59fe6c2f1be2 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/SimpleJavaParameters.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/SimpleJavaParameters.java
@@ -40,11 +40,16 @@ public class SimpleJavaParameters extends SimpleProgramParameters {
private Charset myCharset = CharsetToolkit.getDefaultSystemCharset();
private boolean myUseDynamicClasspath;
private boolean myUseDynamicVMOptions;
-
+ private String myJarPath;
+
public String getMainClass() {
return myMainClass;
}
+ public String getJarPath() {
+ return myJarPath;
+ }
+
/**
* @return jdk used to launch the application.
* If the instance of the JavaParameters is used to configure app server startup script,
@@ -62,6 +67,9 @@ public class SimpleJavaParameters extends SimpleProgramParameters {
public void setMainClass(@NonNls final String mainClass) {
myMainClass = mainClass;
}
+ public void setJarPath(@NonNls final String jarPath) {
+ myJarPath = jarPath;
+ }
public PathsList getClassPath() {
return myClassPath;
diff --git a/platform/lang-api/src/com/intellij/execution/filters/ConsoleDependentFilterProvider.java b/platform/lang-api/src/com/intellij/execution/filters/ConsoleDependentFilterProvider.java
new file mode 100644
index 000000000000..1b5f625b9b0e
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/execution/filters/ConsoleDependentFilterProvider.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.execution.filters;
+
+import com.intellij.execution.ui.ConsoleView;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.GlobalSearchScope;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class ConsoleDependentFilterProvider implements ConsoleFilterProvider {
+ @NotNull
+ public abstract Filter[] getDefaultFilters(@NotNull ConsoleView consoleView, @NotNull Project project, @NotNull GlobalSearchScope scope);
+
+ @NotNull
+ @Override
+ public Filter[] getDefaultFilters(@NotNull Project project) {
+ return Filter.EMPTY_ARRAY;
+ }
+} \ No newline at end of file
diff --git a/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java
index ce7145adeaf9..6b63ec402320 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java
@@ -21,6 +21,7 @@ import com.intellij.execution.RunProfileStarter;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
@@ -61,7 +62,17 @@ public abstract class AsyncGenericProgramRunner<Settings extends RunnerSettings>
* @return RunProfileStarter async result
*/
@NotNull
- protected abstract AsyncResult<RunProfileStarter> prepare(@NotNull ExecutionEnvironment environment, @NotNull RunProfileState state) throws ExecutionException;
+ protected AsyncResult<RunProfileStarter> prepare(@NotNull ExecutionEnvironment environment, @NotNull RunProfileState state) throws ExecutionException {
+ return prepare(environment.getProject(), environment, state);
+ }
+
+ /**
+ * @deprecated override {@link #prepare(ExecutionEnvironment, com.intellij.execution.configurations.RunProfileState)} instead
+ */
+ @Deprecated
+ protected AsyncResult<RunProfileStarter> prepare(@NotNull Project project, @NotNull ExecutionEnvironment environment, @NotNull RunProfileState state) throws ExecutionException {
+ throw new UnsupportedOperationException();
+ }
private static void startRunProfile(@NotNull ExecutionEnvironment environment,
@NotNull RunProfileState state,
diff --git a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java
index b6c300c3f7e2..5a395ab5dd79 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java
@@ -112,6 +112,10 @@ public class ExecutionUtil {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
+ if (project.isDisposed()) {
+ return;
+ }
+
ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project);
if (toolWindowManager.canShowNotification(toolWindowId)) {
//noinspection SSBasedInspection
diff --git a/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java b/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java
index 60e7f03d54db..5a23ed45b1a9 100644
--- a/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java
+++ b/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java
@@ -15,11 +15,13 @@
*/
package com.intellij.execution.ui;
+import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.ide.HelpIdProvider;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.content.Content;
@@ -44,6 +46,8 @@ public class RunContentDescriptor implements Disposable {
private Content myContent;
private Runnable myRestarter;
+ @NotNull
+ private AnAction[] myRestartActions = AnAction.EMPTY_ARRAY;
public RunContentDescriptor(@Nullable ExecutionConsole executionConsole,
@Nullable ProcessHandler processHandler,
@@ -66,7 +70,19 @@ public class RunContentDescriptor implements Disposable {
}
public RunContentDescriptor(@NotNull RunProfile profile, @NotNull ExecutionResult executionResult, @NotNull RunnerLayoutUi ui) {
- this(executionResult.getExecutionConsole(), executionResult.getProcessHandler(), ui.getComponent(), profile.getName(), profile.getIcon());
+ this(executionResult.getExecutionConsole(), executionResult.getProcessHandler(), ui.getComponent(), profile.getName(),
+ profile.getIcon());
+ if (executionResult instanceof DefaultExecutionResult) {
+ myRestartActions = ((DefaultExecutionResult)executionResult).getRestartActions();
+ }
+ }
+
+ /**
+ * @return actions to restart or rerun
+ */
+ @NotNull
+ public AnAction[] getRestartActions() {
+ return myRestartActions.clone();
}
public ExecutionConsole getExecutionConsole() {
@@ -81,6 +97,8 @@ public class RunContentDescriptor implements Disposable {
}
myComponent = null;
myRestarter = null;
+ myProcessHandler = null;
+ myContent = null;
}
/**
@@ -127,6 +145,7 @@ public class RunContentDescriptor implements Disposable {
myContent = content;
}
+ @SuppressWarnings("UnusedDeclaration")
@Nullable
@Deprecated
/**
diff --git a/platform/lang-api/src/com/intellij/find/FindModel.java b/platform/lang-api/src/com/intellij/find/FindModel.java
index 5dafc2db8acf..d07187796872 100644
--- a/platform/lang-api/src/com/intellij/find/FindModel.java
+++ b/platform/lang-api/src/com/intellij/find/FindModel.java
@@ -107,9 +107,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
if (!multiline) {
initStringToFindNoMultiline(this, getStringToFind());
}
- else {
- setRegularExpressions(false);
- }
+
isMultiline = multiline;
notifyObservers();
}
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
index fddb2b2f50b7..861123ab7839 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
@@ -25,6 +25,8 @@ import com.intellij.openapi.module.*;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectType;
+import com.intellij.openapi.project.ProjectTypeService;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
@@ -56,12 +58,12 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
public static final ExtensionPointName<ModuleBuilderFactory> EP_NAME = ExtensionPointName.create("com.intellij.moduleBuilder");
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.projectWizard.ModuleBuilder");
+ private final Set<ModuleConfigurationUpdater> myUpdaters = new HashSet<ModuleConfigurationUpdater>();
+ private final EventDispatcher<ModuleBuilderListener> myDispatcher = EventDispatcher.create(ModuleBuilderListener.class);
protected Sdk myJdk;
private String myName;
@NonNls private String myModuleFilePath;
private String myContentEntryPath;
- private final Set<ModuleConfigurationUpdater> myUpdaters = new HashSet<ModuleConfigurationUpdater>();
- private final EventDispatcher<ModuleBuilderListener> myDispatcher = EventDispatcher.create(ModuleBuilderListener.class);
@NotNull
public static List<ModuleBuilder> getAllBuilders() {
@@ -81,6 +83,17 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
});
}
+ public static void deleteModuleFile(String moduleFilePath) {
+ final File moduleFile = new File(moduleFilePath);
+ if (moduleFile.exists()) {
+ FileUtil.delete(moduleFile);
+ }
+ final VirtualFile file = LocalFileSystem.getInstance().findFileByIoFile(moduleFile);
+ if (file != null) {
+ file.refresh(false, false);
+ }
+ }
+
protected boolean isAvailable() {
return true;
}
@@ -95,6 +108,11 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
}
@Override
+ public void setName(String name) {
+ myName = acceptParameter(name);
+ }
+
+ @Override
@Nullable
public String getBuilderId() {
ModuleType moduleType = getModuleType();
@@ -167,24 +185,19 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
return Collections.emptyList();
}
- @Override
- public void setName(String name) {
- myName = acceptParameter(name);
- }
-
public String getModuleFilePath() {
return myModuleFilePath;
}
- public void addModuleConfigurationUpdater(ModuleConfigurationUpdater updater) {
- myUpdaters.add(updater);
- }
-
@Override
public void setModuleFilePath(@NonNls String path) {
myModuleFilePath = acceptParameter(path);
}
+ public void addModuleConfigurationUpdater(ModuleConfigurationUpdater updater) {
+ myUpdaters.add(updater);
+ }
+
@Nullable
public String getContentEntryPath() {
if (myContentEntryPath == null) {
@@ -259,6 +272,7 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
updater.update(module, modifiableModel);
}
modifiableModel.commit();
+ setProjectType(module);
}
private void onModuleInitialized(final Module module) {
@@ -269,6 +283,17 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
public abstract ModuleType getModuleType();
+ protected ProjectType getProjectType() {
+ return null;
+ }
+
+ protected void setProjectType(Module module) {
+ ProjectType projectType = getProjectType();
+ if (projectType != null && ProjectTypeService.getProjectType(module.getProject()) == null) {
+ ProjectTypeService.setProjectType(module.getProject(), projectType);
+ }
+ }
+
@NotNull
public Module createAndCommitIfNeeded(@NotNull Project project, @Nullable ModifiableModuleModel model, boolean runFromProjectWizard)
throws InvalidDataException, ConfigurationException, IOException, JDOMException, ModuleWithNameAlreadyExists {
@@ -295,7 +320,6 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
return module;
}
-
public void addListener(ModuleBuilderListener listener) {
myDispatcher.addListener(listener);
}
@@ -340,17 +364,6 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
return null;
}
- public static void deleteModuleFile(String moduleFilePath) {
- final File moduleFile = new File(moduleFilePath);
- if (moduleFile.exists()) {
- FileUtil.delete(moduleFile);
- }
- final VirtualFile file = LocalFileSystem.getInstance().findFileByIoFile(moduleFile);
- if (file != null) {
- file.refresh(false, false);
- }
- }
-
public Icon getBigIcon() {
return getModuleType().getBigIcon();
}
@@ -396,14 +409,14 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
myModuleFilePath = from.getModuleFilePath();
}
- public void setModuleJdk(Sdk jdk) {
- myJdk = jdk;
- }
-
public Sdk getModuleJdk() {
return myJdk;
}
+ public void setModuleJdk(Sdk jdk) {
+ myJdk = jdk;
+ }
+
@NotNull
public FrameworkRole getDefaultAcceptableRole() {
return getModuleType().getDefaultAcceptableRole();
diff --git a/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java b/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java
index 8b9143a0d995..9d7a10d6ba5e 100644
--- a/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java
+++ b/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java
@@ -29,6 +29,7 @@ import java.util.List;
* @author peter
*/
public class DocumentationProviderEx implements DocumentationProvider {
+ @Nullable
@Override
public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
return null;
diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java
index 4291e9b401bf..337909b318e5 100644
--- a/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java
+++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java
@@ -247,7 +247,15 @@ public class JdkUtil {
}
final String mainClass = javaParameters.getMainClass();
- commandLine.addParameter(mainClass);
+ String jarPath = javaParameters.getJarPath();
+ if (mainClass != null) {
+ commandLine.addParameter(mainClass);
+ }
+ else if (jarPath != null) {
+ commandLine.addParameter("-jar");
+ commandLine.addParameter(jarPath);
+ }
+
commandLine.addParameters(javaParameters.getProgramParametersList().getList());
commandLine.setWorkDirectory(javaParameters.getWorkingDirectory());
@@ -260,7 +268,7 @@ public class JdkUtil {
ParametersList parametersList) {
commandLine.addParameters(parametersList.getList());
appendEncoding(javaParameters, commandLine, parametersList);
- if (!parametersList.hasParameter("-classpath") && !parametersList.hasParameter("-cp")){
+ if (!parametersList.hasParameter("-classpath") && !parametersList.hasParameter("-cp") && !javaParameters.getClassPath().getPathList().isEmpty()){
commandLine.addParameter("-classpath");
commandLine.addParameter(javaParameters.getClassPath().getPathsString());
}
diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java
index ecebb9db73f3..ae9f0142f246 100644
--- a/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java
+++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java
@@ -23,7 +23,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.FileChooserDialog;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
@@ -67,7 +66,6 @@ public class PathEditor {
public PathEditor(final FileChooserDescriptor descriptor) {
myDescriptor = descriptor;
- myDescriptor.putUserData(FileChooserDialog.PREFER_LAST_OVER_TO_SELECT, Boolean.TRUE);
myModel = createListModel();
}
@@ -176,12 +174,8 @@ public class PathEditor {
}
protected VirtualFile[] doAdd() {
- VirtualFile baseDir = myAddBaseDir;
Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myPanel));
- if (baseDir == null && project != null) {
- baseDir = project.getBaseDir();
- }
- VirtualFile[] files = FileChooser.chooseFiles(myDescriptor, myPanel, project, baseDir);
+ VirtualFile[] files = FileChooser.chooseFiles(myDescriptor, myPanel, project, myAddBaseDir);
files = adjustAddedFileSet(myPanel, files);
List<VirtualFile> added = new ArrayList<VirtualFile>(files.length);
for (VirtualFile vFile : files) {
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java
index 290078e39aa9..2ef2c998b3b4 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java
@@ -214,6 +214,7 @@ public interface CodeStyleSettingsCustomizable {
String WRAPPING_KEEP = ApplicationBundle.message("wrapping.keep.when.reformatting");
String WRAPPING_BRACES = ApplicationBundle.message("wrapping.brace.placement");
+ String WRAPPING_COMMENTS = ApplicationBundle.message("wrapping.comments");
String WRAPPING_METHOD_PARAMETERS = ApplicationBundle.message("wrapping.method.parameters");
String WRAPPING_METHOD_PARENTHESES = ApplicationBundle.message("wrapping.method.parentheses");
String WRAPPING_METHOD_ARGUMENTS_WRAPPING = ApplicationBundle.message("wrapping.method.arguments");
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java
index 299d17215fdf..fa284c8fd33c 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,7 +21,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.*;
import com.intellij.psi.codeStyle.arrangement.ArrangementSettings;
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
-import com.intellij.util.containers.HashSet;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializer;
import org.intellij.lang.annotations.MagicConstant;
@@ -31,8 +31,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
import java.util.Set;
/**
@@ -155,63 +153,20 @@ public class CommonCodeStyleSettings {
protected static void copyPublicFields(Object from, Object to) {
assert from != to;
- copyFields(to.getClass().getFields(), from, to);
+ ReflectionUtil.copyFields(to.getClass().getFields(), from, to);
}
void copyNonDefaultValuesFrom(CommonCodeStyleSettings from) {
CommonCodeStyleSettings defaultSettings = new CommonCodeStyleSettings(null);
PARENT_SETTINGS_INSTALLED =
- copyFields(getClass().getFields(), from, this, new SupportedFieldsDiffFilter(from, getSupportedFields(), defaultSettings) {
- @Override
- public boolean isAccept(@NotNull Field field) {
- if ("RIGHT_MARGIN".equals(field.getName())) return false; // Never copy RIGHT_MARGIN, it is inherited automatically if -1
- return super.isAccept(field);
- }
- });
- }
-
- private static void copyFields(Field[] fields, Object from, Object to) {
- copyFields(fields, from, to, null);
- }
-
- private static boolean copyFields(Field[] fields, Object from, Object to, @Nullable DifferenceFilter diffFilter) {
- Set<Field> sourceFields = new HashSet<Field>(Arrays.asList(from.getClass().getFields()));
- boolean valuesChanged = false;
- for (Field field : fields) {
- if (sourceFields.contains(field)) {
- if (isPublic(field) && !isFinal(field)) {
- try {
- if (diffFilter == null || diffFilter.isAccept(field)) {
- copyFieldValue(from, to, field);
- valuesChanged = true;
- }
- }
- catch (Exception e) {
- throw new RuntimeException(e);
+ ReflectionUtil
+ .copyFields(getClass().getFields(), from, this, new SupportedFieldsDiffFilter(from, getSupportedFields(), defaultSettings) {
+ @Override
+ public boolean isAccept(@NotNull Field field) {
+ if ("RIGHT_MARGIN".equals(field.getName())) return false; // Never copy RIGHT_MARGIN, it is inherited automatically if -1
+ return super.isAccept(field);
}
- }
- }
- }
- return valuesChanged;
- }
-
- private static void copyFieldValue(final Object from, Object to, final Field field)
- throws IllegalAccessException {
- Class<?> fieldType = field.getType();
- if (fieldType.isPrimitive() || fieldType.equals(String.class)) {
- field.set(to, field.get(from));
- }
- else {
- throw new RuntimeException("Field not copied " + field.getName());
- }
- }
-
- private static boolean isPublic(final Field field) {
- return (field.getModifiers() & Modifier.PUBLIC) != 0;
- }
-
- private static boolean isFinal(final Field field) {
- return (field.getModifiers() & Modifier.FINAL) != 0;
+ });
}
@Nullable
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetector.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetector.java
new file mode 100644
index 000000000000..527ee9e79a49
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetector.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.autodetect;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+import static com.intellij.psi.codeStyle.CommonCodeStyleSettings.*;
+
+public class IndentOptionsDetector {
+ private static Logger LOG = Logger.getInstance("#com.intellij.psi.codeStyle.CommonCodeStyleSettings.IndentOptionsDetector");
+
+ private static final double RATE_THRESHOLD = 0.8;
+ private static final int MIN_LINES_THRESHOLD = 50;
+ private static final int MAX_INDENT_TO_DETECT = 8;
+
+ private final PsiFile myFile;
+ private final Project myProject;
+ private final Document myDocument;
+
+ public IndentOptionsDetector(@NotNull PsiFile file) {
+ myFile = file;
+ myProject = file.getProject();
+ myDocument = PsiDocumentManager.getInstance(myProject).getDocument(myFile);
+ }
+
+ @NotNull
+ public IndentOptions getIndentOptions() {
+ IndentOptions indentOptions = (IndentOptions)CodeStyleSettingsManager.getSettings(myProject).getIndentOptions(myFile.getFileType()).clone();
+
+ if (myDocument != null) {
+ List<LineIndentInfo> linesInfo = new LineIndentInfoBuilder(myDocument.getCharsSequence()).build();
+ IndentUsageStatistics stats = new IndentUsageStatisticsImpl(linesInfo);
+ adjustIndentOptions(indentOptions, stats);
+ }
+
+ return indentOptions;
+ }
+
+ private void adjustIndentOptions(@NotNull IndentOptions indentOptions, @NotNull IndentUsageStatistics stats) {
+ int linesWithTabs = stats.getTotalLinesWithLeadingTabs();
+ int linesWithWhiteSpaceIndent = stats.getTotalLinesWithLeadingSpaces();
+
+ int totalLines = linesWithTabs + linesWithWhiteSpaceIndent;
+ double lineWithTabsRate = (double)linesWithTabs / totalLines;
+
+ if (linesWithTabs > MIN_LINES_THRESHOLD && lineWithTabsRate > RATE_THRESHOLD) {
+ if (!indentOptions.USE_TAB_CHARACTER) {
+ indentOptions.USE_TAB_CHARACTER = true;
+ LOG.info("Detected tab usage in" + myFile);
+ }
+ }
+ else if (linesWithWhiteSpaceIndent > MIN_LINES_THRESHOLD && (1 - lineWithTabsRate) > RATE_THRESHOLD) {
+ int newIndentSize = getPositiveIndentSize(stats);
+ if (newIndentSize > 0 && indentOptions.INDENT_SIZE != newIndentSize) {
+ indentOptions.INDENT_SIZE = newIndentSize;
+ LOG.info("Detected indent size: " + newIndentSize + " for file " + myFile);
+ }
+ }
+ }
+
+ private static int getPositiveIndentSize(@NotNull IndentUsageStatistics stats) {
+ int totalIndentSizesDetected = stats.getTotalIndentSizesDetected();
+ if (totalIndentSizesDetected == 0) return -1;
+
+ IndentUsageInfo maxUsedIndentInfo = stats.getKMostUsedIndentInfo(0);
+ int maxUsedIndentSize = maxUsedIndentInfo.getIndentSize();
+
+ if (maxUsedIndentSize == 0) {
+ if (totalIndentSizesDetected < 1) return -1;
+
+ maxUsedIndentInfo = stats.getKMostUsedIndentInfo(1);
+ maxUsedIndentSize = maxUsedIndentInfo.getIndentSize();
+ }
+
+ if (maxUsedIndentSize <= MAX_INDENT_TO_DETECT) {
+ int totalUsagesWithoutZeroIndent = stats.getTotalLinesWithLeadingSpaces() - stats.getTimesIndentUsed(0);
+ double usageRate = (double)maxUsedIndentInfo.getTimesUsed() / totalUsagesWithoutZeroIndent;
+ if (usageRate > RATE_THRESHOLD) {
+ return maxUsedIndentSize;
+ }
+ }
+
+ return -1;
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageInfo.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageInfo.java
new file mode 100644
index 000000000000..a600483a07a6
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageInfo.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.autodetect;
+
+public class IndentUsageInfo {
+ private final int indentSize;
+ private final int timesUsed;
+
+ public IndentUsageInfo(int indentSize, int timesUsed) {
+ this.indentSize = indentSize;
+ this.timesUsed = timesUsed;
+ }
+
+ public int getIndentSize() {
+ return indentSize;
+ }
+
+ public int getTimesUsed() {
+ return timesUsed;
+ }
+
+ @Override
+ public String toString() {
+ return "indent: " + indentSize + ", used " + timesUsed;
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatistics.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatistics.java
new file mode 100644
index 000000000000..7e3bee7221da
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatistics.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.autodetect;
+
+public interface IndentUsageStatistics {
+
+ int getTotalLinesWithLeadingTabs();
+
+ int getTotalLinesWithLeadingSpaces();
+
+ IndentUsageInfo getKMostUsedIndentInfo(int k);
+
+ int getTotalIndentSizesDetected();
+
+ int getTimesIndentUsed(int indent);
+
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatisticsImpl.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatisticsImpl.java
new file mode 100644
index 000000000000..99de432f101d
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/IndentUsageStatisticsImpl.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.autodetect;
+
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.Stack;
+import gnu.trove.TIntIntHashMap;
+import gnu.trove.TIntIntIterator;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Comparator;
+import java.util.List;
+
+public class IndentUsageStatisticsImpl implements IndentUsageStatistics {
+ private static final Comparator<IndentUsageInfo> DECREASING_ORDER = new Comparator<IndentUsageInfo>() {
+ @Override
+ public int compare(@NotNull IndentUsageInfo o1, @NotNull IndentUsageInfo o2) {
+ return o1.getTimesUsed() < o2.getTimesUsed() ? 1 : o1.getTimesUsed() == o2.getTimesUsed() ? 0 : -1;
+ }
+ };
+
+ private List<LineIndentInfo> myLineInfos;
+
+ private int myPreviousLineIndent;
+ private int myPreviousRelativeIndent;
+
+ private int myTotalLinesWithTabs = 0;
+ private int myTotalLinesWithWhiteSpaces = 0;
+
+ private TIntIntHashMap myIndentToUsagesMap = new TIntIntHashMap();
+ private List<IndentUsageInfo> myIndentUsages = ContainerUtil.newArrayList();
+ private Stack<IndentData> myParentIndents = ContainerUtil.newStack(new IndentData(0, 0));
+
+ public IndentUsageStatisticsImpl(@NotNull List<LineIndentInfo> lineInfos) {
+ myLineInfos = lineInfos;
+ buildIndentToUsagesMap();
+ myIndentUsages = toIndentUsageList(myIndentToUsagesMap);
+ ContainerUtil.sort(myIndentUsages, DECREASING_ORDER);
+ }
+
+ @NotNull
+ private static List<IndentUsageInfo> toIndentUsageList(@NotNull TIntIntHashMap indentToUsages) {
+ List<IndentUsageInfo> indentUsageInfos = ContainerUtil.newArrayList();
+ TIntIntIterator it = indentToUsages.iterator();
+ while (it.hasNext()) {
+ it.advance();
+ indentUsageInfos.add(new IndentUsageInfo(it.key(), it.value()));
+ }
+ return indentUsageInfos;
+ }
+
+ public void buildIndentToUsagesMap() {
+ myPreviousLineIndent = 0;
+ myPreviousRelativeIndent = 0;
+
+ for (LineIndentInfo lineInfo : myLineInfos) {
+ if (lineInfo.isLineWithTabs()) {
+ myTotalLinesWithTabs++;
+ }
+ else if (lineInfo.isLineWithWhiteSpaceIndent()) {
+ handleWhiteSpaceIndent(lineInfo.getIndentSize());
+ }
+ }
+ }
+
+ @NotNull
+ private IndentData findParentIndent(int indent) {
+ while (myParentIndents.size() != 1 && myParentIndents.peek().indent > indent) {
+ myParentIndents.pop();
+ }
+ return myParentIndents.peek();
+ }
+
+ private void handleWhiteSpaceIndent(int currentIndent) {
+ int relativeIndent = currentIndent - myPreviousLineIndent;
+ if (relativeIndent < 0) {
+ IndentData indentData = findParentIndent(currentIndent);
+ myPreviousLineIndent = indentData.indent;
+ myPreviousRelativeIndent = indentData.relativeIndent;
+ relativeIndent = currentIndent - myPreviousLineIndent;
+ }
+
+ if (relativeIndent == 0) {
+ relativeIndent = myPreviousRelativeIndent;
+ }
+ else {
+ myParentIndents.push(new IndentData(currentIndent, relativeIndent));
+ }
+
+ increaseIndentUsage(relativeIndent);
+
+ myPreviousRelativeIndent = relativeIndent;
+ myPreviousLineIndent = currentIndent;
+ myTotalLinesWithWhiteSpaces++;
+ }
+
+ private void increaseIndentUsage(int relativeIndent) {
+ int timesUsed = myIndentToUsagesMap.get(relativeIndent);
+ myIndentToUsagesMap.put(relativeIndent, ++timesUsed);
+ }
+
+ @Override
+ public int getTotalLinesWithLeadingTabs() {
+ return myTotalLinesWithTabs;
+ }
+
+ @Override
+ public int getTotalLinesWithLeadingSpaces() {
+ return myTotalLinesWithWhiteSpaces;
+ }
+
+ @Override
+ public IndentUsageInfo getKMostUsedIndentInfo(int k) {
+ return myIndentUsages.get(k);
+ }
+
+ @Override
+ public int getTimesIndentUsed(int indent) {
+ return myIndentToUsagesMap.get(indent);
+ }
+
+ @Override
+ public int getTotalIndentSizesDetected() {
+ return myIndentToUsagesMap.size();
+ }
+
+ private static class IndentData {
+ public final int indent;
+ public final int relativeIndent;
+
+ public IndentData(int indent, int relativeIndent) {
+ this.indent = indent;
+ this.relativeIndent = relativeIndent;
+ }
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfo.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfo.java
new file mode 100644
index 000000000000..d85a4cbcaa0e
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfo.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.autodetect;
+
+import org.jetbrains.annotations.NotNull;
+
+public class LineIndentInfo {
+ public static final LineIndentInfo EMPTY_LINE = new LineIndentInfo(LineType.EMPTY_LINE, -1);
+ public static final LineIndentInfo LINE_WITH_COMMENT = new LineIndentInfo(LineType.LINE_WITH_COMMENT, -1);
+ public static final LineIndentInfo LINE_WITH_TABS = new LineIndentInfo(LineType.LINE_WITH_TABS, -1);
+
+ private final int myIndentSize;
+ private final LineType myType;
+
+ private LineIndentInfo(@NotNull LineType type, int indentSize) {
+ myType = type;
+ myIndentSize = indentSize;
+ }
+
+ @NotNull
+ public static LineIndentInfo newWhiteSpaceIndent(int indentSize) {
+ return new LineIndentInfo(LineType.LINE_WITH_WHITESPACE_INDENT, indentSize);
+ }
+
+ public int getIndentSize() {
+ return myIndentSize;
+ }
+
+ public boolean isLineWithWhiteSpaceIndent() {
+ return myType == LineType.LINE_WITH_WHITESPACE_INDENT;
+ }
+
+ public boolean isLineWithTabs() {
+ return myType == LineType.LINE_WITH_TABS;
+ }
+
+ private enum LineType {
+ EMPTY_LINE,
+ LINE_WITH_COMMENT,
+ LINE_WITH_TABS,
+ LINE_WITH_WHITESPACE_INDENT
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfoBuilder.java b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfoBuilder.java
new file mode 100644
index 000000000000..8efbbc495750
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/autodetect/LineIndentInfoBuilder.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.autodetect;
+
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+public class LineIndentInfoBuilder {
+ private static final int MAX_LINES_TO_PROCESS = 500;
+
+ private final CharSequence myText;
+ private final int myLength;
+
+ public LineIndentInfoBuilder(@NotNull CharSequence text) {
+ myText = text;
+ myLength = text.length();
+ }
+
+ @NotNull
+ public List<LineIndentInfo> build() {
+ List<LineIndentInfo> lineIndentInfos = ContainerUtil.newArrayList();
+
+ int lineStartOffset = 0;
+ int currentLine = 0;
+
+ while (lineStartOffset < myText.length() && currentLine < MAX_LINES_TO_PROCESS) {
+ int lineEndOffset = getLineEndOffset(lineStartOffset);
+ int textStartOffset = CharArrayUtil.shiftForward(myText, lineStartOffset, lineEndOffset, " \t");
+
+ if (textStartOffset != lineEndOffset) {
+ lineIndentInfos.add(createInfoFromWhiteSpaceRange(lineStartOffset, textStartOffset));
+ } else {
+ lineIndentInfos.add(LineIndentInfo.EMPTY_LINE);
+ }
+
+ lineStartOffset = lineEndOffset + 1;
+ currentLine++;
+ }
+
+ return lineIndentInfos;
+ }
+
+ @NotNull
+ private LineIndentInfo createInfoFromWhiteSpaceRange(int lineStartOffset, int textStartOffset) {
+ if (myText.charAt(textStartOffset) == '*') {
+ return LineIndentInfo.LINE_WITH_COMMENT;
+ }
+ else if (CharArrayUtil.indexOf(myText, "\t", lineStartOffset, textStartOffset) > 0) {
+ return LineIndentInfo.LINE_WITH_TABS;
+ }
+ else {
+ int indentSize = textStartOffset - lineStartOffset;
+ return LineIndentInfo.newWhiteSpaceIndent(indentSize);
+ }
+ }
+
+ private int getLineEndOffset(int lineStartOffset) {
+ int lineEndOffset = CharArrayUtil.indexOf(myText, "\n", lineStartOffset, myLength);
+ if (lineEndOffset < 0) {
+ lineEndOffset = myText.length();
+ }
+ return lineEndOffset;
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
index 4565832c310b..b63ee1d6ab2d 100644
--- a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
+++ b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
@@ -40,7 +40,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.awt.*;
import java.util.*;
+import java.util.List;
public class PsiUtilBase extends PsiUtilCore implements PsiEditorUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.util.PsiUtilBase");
@@ -235,6 +237,9 @@ public class PsiUtilBase extends PsiUtilCore implements PsiEditorUtil {
*/
@Nullable
public static Editor findEditor(@NotNull PsiElement element) {
+ if (!EventQueue.isDispatchThread()) {
+ LOG.warn("Invoke findEditor() from EDT only. Otherwise, it causes deadlocks.");
+ }
PsiFile psiFile = element.getContainingFile();
VirtualFile virtualFile = PsiUtilCore.getVirtualFile(element);
if (virtualFile == null) {