Merge "Merge remote-tracking branch 'aosp/snapshot-master' into merge"
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 7294669..babd7be 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -24,7 +24,6 @@
<module fileurl="file://$PROJECT_DIR$/jps/antLayout/antlayout.iml" filepath="$PROJECT_DIR$/jps/antLayout/antlayout.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/plugins/google-app-engine/runtime/appEngine-runtime.iml" filepath="$PROJECT_DIR$/plugins/google-app-engine/runtime/appEngine-runtime.iml" group="plugins/GAE" />
<module fileurl="file://$PROJECT_DIR$/../base/asset-studio/assetstudio.iml" filepath="$PROJECT_DIR$/../base/asset-studio/assetstudio.iml" group="plugins/Android/android-sdk" />
- <module fileurl="file://$PROJECT_DIR$/plugins/svn4idea/bindSvn/bindSvn.iml" filepath="$PROJECT_DIR$/plugins/svn4idea/bindSvn/bindSvn.iml" group="plugins/VCS" />
<module fileurl="file://$PROJECT_DIR$/platform/boot/boot.iml" filepath="$PROJECT_DIR$/platform/boot/boot.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" filepath="$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/build/build.iml" filepath="$PROJECT_DIR$/build/build.iml" />
diff --git a/bin/win/jumplistbridge.dll b/bin/win/jumplistbridge.dll
index 611dd62..4a0cf8a 100644
--- a/bin/win/jumplistbridge.dll
+++ b/bin/win/jumplistbridge.dll
Binary files differ
diff --git a/bin/win/jumplistbridge64.dll b/bin/win/jumplistbridge64.dll
index fad8c52..2d830ce 100644
--- a/bin/win/jumplistbridge64.dll
+++ b/bin/win/jumplistbridge64.dll
Binary files differ
diff --git a/build.txt b/build.txt
index bc0cfb9..7a425c0 100644
--- a/build.txt
+++ b/build.txt
@@ -1 +1 @@
-130.SNAPSHOT
+132.SNAPSHOT
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
index db74272..655b0b5 100644
--- a/build/scripts/layouts.gant
+++ b/build/scripts/layouts.gant
@@ -323,9 +323,6 @@
}
layoutPlugin("svn4idea") {
- jar("bindSvn.jar") {
- module("bindSvn")
- }
fileset(dir: "$home/plugins/svn4idea/lib", excludes: "**/svnkitsrc.zip")
}
diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant
index b4fd69a..f952acd 100644
--- a/build/scripts/libLicenses.gant
+++ b/build/scripts/libLicenses.gant
@@ -248,7 +248,7 @@
libraryLicense(name: "XStream", version: "1.4.3", license: "BSD", url: "http://xstream.codehaus.org/", licenseUrl: "http://xstream.codehaus.org/license.html")
libraryLicense(name: "YourKit Java Profiler", libraryName: "yjp-controller-api-redist.jar", version: "8.0.x", license: "link (commercial license)", url: "http://yourkit.com/", licenseUrl: "http://www.yourkit.com/purchase/license.html")
libraryLicense(name: "protobuf", version: "2.5.0", license: "New BSD", url: "http://code.google.com/p/protobuf/", licenseUrl: "http://code.google.com/p/protobuf/source/browse/trunk/COPYING.txt?r=367")
-libraryLicense(name: "Netty", libraryName: "Netty", version: "4.0.8-SNAPSHOT", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Netty", libraryName: "Netty", version: "4.1.0.Alpha1", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Kryo", libraryName: "Kryo", version: "1.04", license: "New BSD License", url: "http://code.google.com/p/kryo/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php")
libraryLicense(name: "Snappy-Java", libraryName: "Snappy-Java", version: "1.0.5", license: "Apache 2.0", url: "http://code.google.com/p/snappy-java/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Cucumber-Java", libraryName: "cucumber-java", version: "1.0.14", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
diff --git a/community-resources/src/idea/IdeaApplicationInfo.xml b/community-resources/src/idea/IdeaApplicationInfo.xml
index e76db38..8e36755 100644
--- a/community-resources/src/idea/IdeaApplicationInfo.xml
+++ b/community-resources/src/idea/IdeaApplicationInfo.xml
@@ -2,7 +2,7 @@
<version codename="Community Edition" major="13" minor="0" eap="true"/>
<company name="JetBrains s.r.o." url="http://www.jetbrains.com/?fromIDE"/>
<build number="__BUILD_NUMBER__" date="__BUILD_DATE__"/>
- <install-over minbuild="129.1" maxbuild="130.9999" version="12.1"/>
+ <install-over minbuild="129.1" maxbuild="132.9999" version="12.1"/>
<logo url="/idea_community_logo.png" textcolor="ffffff" progressColor="ffaa16" progressY="230" progressTailIcon="/community_progress_tail.png"/>
<about url="/idea_community_about.png" foreground="f5f5f5" linkColor="9dc0ff" logoX="300" logoY="265" logoW="75" logoH="30"/>
<icon size32="/icon_CE.png" size16="/icon_CEsmall.png" size32opaque="/icon_CEwhite.png" size12="/toolwindows/toolWindowProject.png" size128="/icon_CE_128.png" ico="idea_CE.ico"/>
@@ -10,7 +10,7 @@
<names product="IDEA" fullname="IntelliJ IDEA" script="idea"/>
<welcome-screen logo-url="/Logo_welcomeScreen.png"
- caption-url="/welcomeCaption_community.png"
+ caption-url="/welcomeCaption_community.png"
slogan-url="/developSlogan_community.png"/>
<third-party url="http://www.jetbrains.org/"/>
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsManager.java b/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsFilter.java
similarity index 90%
rename from java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsManager.java
rename to java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsFilter.java
index ed2973a..49ad310 100644
--- a/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsFilter.java
@@ -29,9 +29,9 @@
* @author Denis Zhdanov
* @since 7/18/13 12:40 PM
*/
-public interface CompilerOptionsManager {
+public interface CompilerOptionsFilter {
- ExtensionPointName<CompilerOptionsManager> EP_NAME = ExtensionPointName.create("com.intellij.compiler.optionsManager");
+ ExtensionPointName<CompilerOptionsFilter> EP_NAME = ExtensionPointName.create("com.intellij.compiler.optionsManager");
enum Setting {
RESOURCE_PATTERNS, CLEAR_OUTPUT_DIR_ON_REBUILD, ADD_NOT_NULL_ASSERTIONS, AUTO_SHOW_FIRST_ERROR_IN_EDITOR,
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
index 57eb699..38769dc 100644
--- a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
@@ -40,7 +40,7 @@
import java.awt.event.ItemListener;
import java.util.*;
-import static com.intellij.compiler.options.CompilerOptionsManager.*;
+import static com.intellij.compiler.options.CompilerOptionsFilter.*;
public class CompilerUIConfigurable implements SearchableConfigurable, Configurable.NoScroll {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.options.CompilerUIConfigurable");
@@ -110,9 +110,9 @@
}
private void tweakControls(@NotNull Project project) {
- CompilerOptionsManager[] managers = CompilerOptionsManager.EP_NAME.getExtensions();
+ CompilerOptionsFilter[] managers = CompilerOptionsFilter.EP_NAME.getExtensions();
boolean showExternalBuildSetting = true;
- for (CompilerOptionsManager manager : managers) {
+ for (CompilerOptionsFilter manager : managers) {
showExternalBuildSetting = manager.isAvailable(Setting.EXTERNAL_BUILD, project);
if (!showExternalBuildSetting) {
myDisabledSettings.add(Setting.EXTERNAL_BUILD);
@@ -126,7 +126,7 @@
myDisabledSettings.add(setting);
}
else {
- for (CompilerOptionsManager manager : managers) {
+ for (CompilerOptionsFilter manager : managers) {
if (!manager.isAvailable(setting, project)) {
myDisabledSettings.add(setting);
break;
diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java
index a15f2de..f981000 100644
--- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java
+++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -111,7 +111,7 @@
if (MAIN_CLASS_NAME == null) {
return null;
}
- return JavaExecutionUtil.getPresentableClassName(MAIN_CLASS_NAME, getConfigurationModule());
+ return JavaExecutionUtil.getPresentableClassName(MAIN_CLASS_NAME);
}
@Override
diff --git a/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java b/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java
index 95a2c2d..0e06157 100644
--- a/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java
+++ b/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -141,12 +141,17 @@
}
@Nullable
+ public static String getPresentableClassName(final String rtClassName) {
+ return getPresentableClassName(rtClassName, null);
+ }
+
+ /**
+ * {@link JavaExecutionUtil#getPresentableClassName(java.lang.String)}
+ */
+ @Deprecated
+ @Nullable
public static String getPresentableClassName(final String rtClassName, final JavaRunConfigurationModule configurationModule) {
if (StringUtil.isEmpty(rtClassName)) return null;
- final PsiClass psiClass = configurationModule.findClass(rtClassName);
- if (psiClass != null) {
- return psiClass.getName();
- }
final int lastDot = rtClassName.lastIndexOf('.');
if (lastDot == -1 || lastDot == rtClassName.length() - 1) {
return rtClassName;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java
index 2ed1ac7..2c6d8d8 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java
@@ -30,6 +30,7 @@
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.concurrency.SwingWorker;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
import javax.swing.*;
import java.awt.*;
@@ -41,12 +42,12 @@
public class JavaContentEntriesEditor extends CommonContentEntriesEditor {
public JavaContentEntriesEditor(String moduleName, ModuleConfigurationState state) {
- super(moduleName, state, true, true);
+ super(moduleName, state, JavaSourceRootType.SOURCE, JavaSourceRootType.TEST_SOURCE);
}
@Override
protected ContentEntryEditor createContentEntryEditor(final String contentEntryUrl) {
- return new JavaContentEntryEditor(contentEntryUrl) {
+ return new JavaContentEntryEditor(contentEntryUrl, getEditHandlers()) {
@Override
protected ModifiableRootModel getModel() {
return JavaContentEntriesEditor.this.getModel();
@@ -55,11 +56,6 @@
}
@Override
- protected ContentEntryTreeEditor createContentEntryTreeEditor(Project project) {
- return new ContentEntryTreeEditor(project, true, true);
- }
-
- @Override
protected List<ContentEntry> addContentEntries(VirtualFile[] files) {
List<ContentEntry> contentEntries = super.addContentEntries(files);
if (!contentEntries.isEmpty()) {
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntryEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntryEditor.java
index 41b8c8d..7d3c535 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntryEditor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntryEditor.java
@@ -18,28 +18,38 @@
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ExcludeFolder;
+import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
+import java.util.List;
+
public abstract class JavaContentEntryEditor extends ContentEntryEditor {
private final CompilerModuleExtension myCompilerExtension;
- public JavaContentEntryEditor(final String contentEntryUrl) {
- super(contentEntryUrl, true, true);
+ public JavaContentEntryEditor(final String contentEntryUrl, List<ModuleSourceRootEditHandler<?>> moduleSourceRootEditHandlers) {
+ super(contentEntryUrl, moduleSourceRootEditHandlers);
myCompilerExtension = getModel().getModuleExtension(CompilerModuleExtension.class);
}
@Override
protected ContentRootPanel createContentRootPane() {
- return new JavaContentRootPanel(this) {
+ return new ContentRootPanel(this, getEditHandlers()) {
@Nullable
@Override
protected ContentEntry getContentEntry() {
return JavaContentEntryEditor.this.getContentEntry();
}
+
+ @Nullable
+ @Override
+ protected JComponent createRootPropertiesEditor(ModuleSourceRootEditHandler<?> editor, SourceFolder folder) {
+ return editor.createPropertiesEditor(folder, this, myCallback);
+ }
};
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentRootPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentRootPanel.java
deleted file mode 100644
index d0af3a1..0000000
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentRootPanel.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.roots.ui.configuration;
-
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.project.ProjectBundle;
-import com.intellij.openapi.roots.ContentFolder;
-import com.intellij.openapi.roots.SourceFolder;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.ui.roots.IconActionComponent;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.awt.*;
-
-public abstract class JavaContentRootPanel extends ContentRootPanel {
-
- public JavaContentRootPanel(ActionCallback callback) {
- super(callback, true, true);
- }
-
- @Override
- @Nullable
- protected JComponent createAdditionalComponent(ContentFolder folder) {
- if (folder instanceof SourceFolder) {
- return createAddPrefixComponent((SourceFolder)folder);
- }
- return null;
- }
-
- private JComponent createAddPrefixComponent(final SourceFolder folder) {
- final IconActionComponent iconComponent = new IconActionComponent(AllIcons.Modules.SetPackagePrefix,
- AllIcons.Modules.SetPackagePrefixRollover,
- ProjectBundle.message("module.paths.package.prefix.tooltip"), new Runnable() {
- @Override
- public void run() {
- final String message = ProjectBundle.message("module.paths.package.prefix.prompt",
- toRelativeDisplayPath(folder.getUrl(), getContentEntry().getUrl() + ":"));
- final String prefix = Messages.showInputDialog(JavaContentRootPanel.this, message,
- ProjectBundle.message("module.paths.package.prefix.title"), Messages.getQuestionIcon(), folder.getPackagePrefix(), null);
- if (prefix != null) {
- myCallback.setPackagePrefix(folder, prefix);
- }
- }
- });
- final JPanel panel = new JPanel(new BorderLayout());
- panel.setOpaque(false);
- panel.add(iconComponent, BorderLayout.CENTER);
- panel.add(Box.createHorizontalStrut(3), BorderLayout.EAST);
- return panel;
- }
-}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
index 9c6343a..af34e40 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
@@ -223,8 +223,8 @@
addArtifactsConfig();
}
- ProjectStructureConfigurableAdder[] adders = ProjectStructureConfigurableAdder.EP_NAME.getExtensions();
- for (ProjectStructureConfigurableAdder adder : adders) {
+ ProjectStructureConfigurableContributor[] adders = ProjectStructureConfigurableContributor.EP_NAME.getExtensions();
+ for (ProjectStructureConfigurableContributor adder : adders) {
for (Configurable configurable : adder.getExtraProjectConfigurables(myProject, myContext)) {
addConfigurable(configurable, true);
}
@@ -234,7 +234,7 @@
addJdkListConfig();
addGlobalLibrariesConfig();
- for (ProjectStructureConfigurableAdder adder : adders) {
+ for (ProjectStructureConfigurableContributor adder : adders) {
for (Configurable configurable : adder.getExtraPlatformConfigurables(myProject, myContext)) {
addConfigurable(configurable, true);
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableAdder.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableContributor.java
similarity index 89%
rename from java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableAdder.java
rename to java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableContributor.java
index 4a79ada..ad68806 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableAdder.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableContributor.java
@@ -24,8 +24,8 @@
import java.util.Collections;
import java.util.List;
-public abstract class ProjectStructureConfigurableAdder {
- public static final ExtensionPointName<ProjectStructureConfigurableAdder> EP_NAME = ExtensionPointName.create("com.intellij.projectStructureConfigurableAdder");
+public abstract class ProjectStructureConfigurableContributor {
+ public static final ExtensionPointName<ProjectStructureConfigurableContributor> EP_NAME = ExtensionPointName.create("com.intellij.projectStructureConfigurableAdder");
@NotNull
public List<? extends Configurable> getExtraProjectConfigurables(@NotNull Project project, @NotNull StructureConfigurableContext context) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
index daf675a..02a5c57 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -18,6 +18,7 @@
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocTag;
+import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -103,7 +104,12 @@
final PsiAnnotationMemberValue psiAnnotationMemberValue = pair.getValue();
if (psiAnnotationMemberValue != null) {
final String value = psiAnnotationMemberValue.getText();
- return value.substring(1, value.length() - 1).trim();
+ final String trim = value.substring(1, value.length() - 1).trim();
+ if (trim.equals("itself")) {
+ final PsiMember member = PsiTreeUtil.getParentOfType(annotation, PsiMember.class);
+ if (member != null) return member.getName();
+ }
+ return trim;
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java
index 9c8cc96..df96d14 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -263,7 +263,7 @@
}
}
- private static boolean isExternalizableNoParameterConstructor(PsiMethod method, RefClass refClass) {
+ private static boolean isExternalizableNoParameterConstructor(@NotNull PsiMethod method, RefClass refClass) {
if (!method.isConstructor()) return false;
if (!method.hasModifierProperty(PsiModifier.PUBLIC)) return false;
final PsiParameterList parameterList = method.getParameterList();
@@ -272,7 +272,7 @@
return aClass == null || isExternalizable(aClass, refClass);
}
- private static boolean isSerializationImplicitlyUsedField(PsiField field) {
+ private static boolean isSerializationImplicitlyUsedField(@NotNull PsiField field) {
@NonNls final String name = field.getName();
if (!HighlightUtilBase.SERIAL_VERSION_UID_FIELD_NAME.equals(name) && !"serialPersistentFields".equals(name)) return false;
if (!field.hasModifierProperty(PsiModifier.STATIC)) return false;
@@ -280,7 +280,7 @@
return aClass == null || isSerializable(aClass, null);
}
- private static boolean isWriteObjectMethod(PsiMethod method, RefClass refClass) {
+ private static boolean isWriteObjectMethod(@NotNull PsiMethod method, RefClass refClass) {
@NonNls final String name = method.getName();
if (!"writeObject".equals(name)) return false;
PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -291,7 +291,7 @@
return !(aClass != null && !isSerializable(aClass, refClass));
}
- private static boolean isReadObjectMethod(PsiMethod method, RefClass refClass) {
+ private static boolean isReadObjectMethod(@NotNull PsiMethod method, RefClass refClass) {
@NonNls final String name = method.getName();
if (!"readObject".equals(name)) return false;
PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -302,7 +302,7 @@
return !(aClass != null && !isSerializable(aClass, refClass));
}
- private static boolean isWriteReplaceMethod(PsiMethod method, RefClass refClass) {
+ private static boolean isWriteReplaceMethod(@NotNull PsiMethod method, RefClass refClass) {
@NonNls final String name = method.getName();
if (!"writeReplace".equals(name)) return false;
PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -313,7 +313,7 @@
return !(aClass != null && !isSerializable(aClass, refClass));
}
- private static boolean isReadResolveMethod(PsiMethod method, RefClass refClass) {
+ private static boolean isReadResolveMethod(@NotNull PsiMethod method, RefClass refClass) {
@NonNls final String name = method.getName();
if (!"readResolve".equals(name)) return false;
PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -329,7 +329,7 @@
return serializableClass != null && isSerializable(aClass, refClass, serializableClass);
}
- private static boolean isExternalizable(PsiClass aClass, RefClass refClass) {
+ private static boolean isExternalizable(@NotNull PsiClass aClass, RefClass refClass) {
final GlobalSearchScope scope = aClass.getResolveScope();
final PsiClass externalizableClass = JavaPsiFacade.getInstance(aClass.getProject()).findClass("java.io.Externalizable", scope);
return externalizableClass != null && isSerializable(aClass, refClass, externalizableClass);
@@ -537,7 +537,7 @@
public void visitField(@NotNull final RefField refField) {
myProcessedSuspicious.add(refField);
PsiField psiField = refField.getElement();
- if (isSerializationImplicitlyUsedField(psiField)) {
+ if (psiField != null && isSerializationImplicitlyUsedField(psiField)) {
getEntryPointsManager().addEntryPoint(refField, false);
}
else {
@@ -560,7 +560,7 @@
}
else {
PsiMethod psiMethod = (PsiMethod)refMethod.getElement();
- if (isSerializablePatternMethod(psiMethod, refMethod.getOwnerClass())) {
+ if (psiMethod != null && isSerializablePatternMethod(psiMethod, refMethod.getOwnerClass())) {
getEntryPointsManager().addEntryPoint(refMethod, false);
}
else if (!refMethod.isExternalOverride() && !PsiModifier.PRIVATE.equals(refMethod.getAccessModifier())) {
@@ -614,7 +614,7 @@
return true;
}
- private static boolean isSerializablePatternMethod(PsiMethod psiMethod, RefClass refClass) {
+ private static boolean isSerializablePatternMethod(@NotNull PsiMethod psiMethod, RefClass refClass) {
return isReadObjectMethod(psiMethod, refClass) || isWriteObjectMethod(psiMethod, refClass) || isReadResolveMethod(psiMethod, refClass) ||
isWriteReplaceMethod(psiMethod, refClass) || isExternalizableNoParameterConstructor(psiMethod, refClass);
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java
index 112aee0..e508a77 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -77,7 +77,7 @@
}
@Nullable
- private List<ProblemDescriptor> checkCodeBlock(final PsiCodeBlock body, InspectionManager manager, boolean onTheFly) {
+ private List<ProblemDescriptor> checkCodeBlock(final PsiCodeBlock body, final InspectionManager manager, final boolean onTheFly) {
if (body == null) return null;
final ControlFlow flow;
try {
@@ -120,9 +120,17 @@
final List<PsiVariable> writtenVariables = new ArrayList<PsiVariable>(ControlFlowUtil.getWrittenVariables(flow, start, end, false));
+ final List<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
final HashSet<PsiVariable> ssaVarsSet = new HashSet<PsiVariable>();
body.accept(new JavaRecursiveElementWalkingVisitor() {
@Override public void visitCodeBlock(PsiCodeBlock block) {
+ if (block.getParent() instanceof PsiLambdaExpression && block != body) {
+ final List<ProblemDescriptor> descriptors = checkCodeBlock(block, manager, onTheFly);
+ if (descriptors != null) {
+ problems.addAll(descriptors);
+ }
+ return;
+ }
super.visitCodeBlock(block);
PsiElement anchor = block;
if (block.getParent() instanceof PsiSwitchStatement) {
@@ -177,7 +185,7 @@
}
});
- ArrayList<PsiVariable> result = new ArrayList<PsiVariable>(ssaVarsSet);
+ final ArrayList<PsiVariable> result = new ArrayList<PsiVariable>(ssaVarsSet);
if (body.getParent() instanceof PsiMethod) {
PsiMethod method = (PsiMethod)body.getParent();
@@ -215,7 +223,7 @@
iterator.remove();
}
}
- List<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>(result.size());
+
for (PsiVariable variable : result) {
final PsiIdentifier nameIdenitier = variable.getNameIdentifier();
PsiElement problemElement = nameIdenitier != null ? nameIdenitier : variable;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java
index 8efcc45..3d45887 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java
@@ -21,7 +21,7 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
-import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -40,7 +40,7 @@
// does not work in tests since CodeInsightTestCase copies file into temporary location
if (ApplicationManager.getApplication().isUnitTestMode()) return null;
if (file instanceof PsiJavaFile) {
- if (isInJsp(file)) return null;
+ if (FileTypeUtils.isInServerPageFile(file)) return null;
PsiJavaFile javaFile = (PsiJavaFile)file;
PsiDirectory directory = javaFile.getContainingDirectory();
@@ -86,10 +86,6 @@
return null;
}
- private static boolean isInJsp(PsiFile file) {
- return PsiUtilCore.getTemplateLanguageFile(file) instanceof ServerPageFile;
- }
-
protected void addMoveToPackageFix(PsiFile file, String packName, List<LocalQuickFix> availableFixes) {
}
diff --git a/java/java-impl/src/com/intellij/analysis/JavaAnalysisScope.java b/java/java-impl/src/com/intellij/analysis/JavaAnalysisScope.java
index 6899c7a..1c49c3b 100644
--- a/java/java-impl/src/com/intellij/analysis/JavaAnalysisScope.java
+++ b/java/java-impl/src/com/intellij/analysis/JavaAnalysisScope.java
@@ -31,7 +31,7 @@
import com.intellij.psi.search.PackageScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.util.containers.ContainerUtil;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
diff --git a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
index fe002f6..9f2b486 100644
--- a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
@@ -43,7 +43,7 @@
import com.intellij.util.FilteredQuery;
import com.intellij.util.Processor;
import com.intellij.util.Query;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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 3ce6050..26b9fdb 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -589,6 +589,11 @@
return LangBundle.message("completion.no.suggestions") + suffix;
}
+ @Override
+ public boolean invokeAutoPopup(@NotNull PsiElement position, char typeChar) {
+ return typeChar == ':' && JavaTokenType.COLON == position.getNode().getElementType();
+ }
+
private static boolean shouldSuggestSmartCompletion(final PsiElement element) {
if (shouldSuggestClassNameCompletion(element)) return false;
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
index 9710f75..ac752ed 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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,6 +20,7 @@
import com.intellij.codeInsight.lookup.*;
import com.intellij.openapi.util.Key;
import com.intellij.patterns.ElementPattern;
+import com.intellij.patterns.ElementPatternCondition;
import com.intellij.patterns.PsiElementPattern;
import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.psi.*;
@@ -28,6 +29,7 @@
import com.intellij.psi.filters.GeneratorFilter;
import com.intellij.psi.filters.OrFilter;
import com.intellij.psi.filters.getters.*;
+import com.intellij.psi.filters.position.FilterPattern;
import com.intellij.psi.filters.types.AssignableFromFilter;
import com.intellij.psi.filters.types.AssignableGroupFilter;
import com.intellij.psi.filters.types.AssignableToFilter;
@@ -92,6 +94,21 @@
psiElement().withText(")").withParent(PsiTypeCastExpression.class)));
static final PsiElementPattern.Capture<PsiElement> IN_TYPE_ARGS =
psiElement().inside(psiElement(PsiReferenceParameterList.class));
+ static final PsiElementPattern.Capture<PsiElement> LAMBDA = psiElement().and(new FilterPattern(new ElementFilter() {
+ @Override
+ public boolean isAcceptable(Object element, @Nullable PsiElement context) {
+ if (context == null) return false;
+ final PsiElement originalElement = context.getOriginalElement();
+ if (originalElement == null) return false;
+ final PsiElement rulezzRef = originalElement.getParent();
+ return LambdaUtil.isValidLambdaContext(rulezzRef.getParent());
+ }
+
+ @Override
+ public boolean isClassAcceptable(Class hintClass) {
+ return true;
+ }
+ }));
@Nullable
private static ElementFilter getReferenceFilter(PsiElement element) {
@@ -313,6 +330,8 @@
}
}
});
+
+ extend(CompletionType.SMART, LAMBDA, new LambdaCompletionProvider());
}
private static void addExpectedTypeMembers(CompletionParameters params,
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/LambdaCompletionProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/LambdaCompletionProvider.java
new file mode 100644
index 0000000..eca5453
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/LambdaCompletionProvider.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2013 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.codeInsight.completion;
+
+import com.intellij.codeInsight.ExpectedTypeInfo;
+import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorModificationUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.Function;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: anna
+ */
+public class LambdaCompletionProvider extends CompletionProvider<CompletionParameters> {
+ @Override
+ protected void addCompletions(@NotNull CompletionParameters parameters,
+ ProcessingContext context,
+ @NotNull CompletionResultSet result) {
+ if (!PsiUtil.isLanguageLevel8OrHigher(parameters.getOriginalFile())) return;
+ final ExpectedTypeInfo[] expectedTypes = JavaSmartCompletionContributor.getExpectedTypes(parameters);
+ for (ExpectedTypeInfo expectedType : expectedTypes) {
+ final PsiType defaultType = expectedType.getDefaultType();
+ if (LambdaHighlightingUtil.checkInterfaceFunctional(defaultType) == null) {
+ final PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(defaultType);
+ if (method != null) {
+ final PsiParameter[] params = method.getParameterList().getParameters();
+ final String paramsString = "(" + StringUtil.join(params, new Function<PsiParameter, String>() {
+ @Override
+ public String fun(PsiParameter parameter) {
+ return parameter.getName();
+ }
+ }, ",") + ")";
+ final LookupElementBuilder builder =
+ LookupElementBuilder.create(paramsString).withPresentableText(paramsString + " -> {}").withInsertHandler(new InsertHandler<LookupElement>() {
+ @Override
+ public void handleInsert(InsertionContext context, LookupElement item) {
+ final Editor editor = context.getEditor();
+ EditorModificationUtil.insertStringAtCaret(editor, " -> ");
+ PsiDocumentManager.getInstance(context.getProject()).commitDocument(editor.getDocument());
+ }
+ });
+ result.addElement(builder.withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE));
+ }
+ }
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
index c32a30c..7cc7879 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
@@ -32,7 +32,7 @@
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Processor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
index 612d4704..3266e96 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
@@ -915,7 +915,7 @@
if (!hasNoBody) {
QuickFixAction.registerQuickFixAction(info, new DeleteMethodBodyFix(method));
}
- if (method.hasModifierProperty(PsiModifier.ABSTRACT) && isInterface) {
+ if (method.hasModifierProperty(PsiModifier.ABSTRACT) && !isInterface) {
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.ABSTRACT, false, false));
}
for (IntentionAction intentionAction : additionalFixes) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
index 5657a40..a3fb892 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
@@ -61,7 +61,7 @@
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import gnu.trove.THashMap;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NonNls;
@@ -808,7 +808,8 @@
}
else if (PsiModifier.STATIC.equals(modifier) || PsiModifier.PRIVATE.equals(modifier) || PsiModifier.PROTECTED.equals(modifier) ||
PsiModifier.PACKAGE_LOCAL.equals(modifier)) {
- isAllowed = modifierOwnerParent instanceof PsiClass && ((PsiClass)modifierOwnerParent).getQualifiedName() != null;
+ isAllowed = modifierOwnerParent instanceof PsiClass &&
+ ((PsiClass)modifierOwnerParent).getQualifiedName() != null || FileTypeUtils.isInServerPageFile(modifierOwnerParent);
}
if (aClass.isEnum()) {
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 5c9e198..40e2eaa 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
@@ -29,7 +29,7 @@
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
-import com.intellij.openapi.projectRoots.JavaSdkVersionUtil;
+import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
@@ -147,7 +147,7 @@
boolean success = true;
try {
myLanguageLevel = PsiUtil.getLanguageLevel(file);
- myJavaSdkVersion = ObjectUtils.notNull(JavaSdkVersionUtil.getJavaSdkVersion(file), JavaSdkVersion.fromLanguageLevel(myLanguageLevel));
+ myJavaSdkVersion = ObjectUtils.notNull(JavaVersionService.getInstance().getJavaSdkVersion(file), JavaSdkVersion.fromLanguageLevel(myLanguageLevel));
if (updateWholeFile) {
Project project = file.getProject();
DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(project);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java
index 13921e9..d564d3a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddNewArrayExpressionFix.java
@@ -32,7 +32,7 @@
public class AddNewArrayExpressionFix implements IntentionAction {
private final PsiArrayInitializerExpression myInitializer;
- public AddNewArrayExpressionFix(PsiArrayInitializerExpression initializer) {
+ public AddNewArrayExpressionFix(@NotNull PsiArrayInitializerExpression initializer) {
myInitializer = initializer;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java
index 67952e1..b9c5d21 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java
@@ -40,7 +40,7 @@
public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement {
private final PsiType myType;
- public AddTypeCastFix(PsiType type, PsiExpression expression) {
+ public AddTypeCastFix(@NotNull PsiType type, @NotNull PsiExpression expression) {
super(expression);
myType = type;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java
index 0683af7..513cb78 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java
@@ -36,7 +36,7 @@
private final PsiType myLhsType;
private final PsiAssignmentExpression myAssignmentExpression;
- public ChangeToAppendFix(IElementType eqOpSign, PsiType lType, PsiAssignmentExpression assignmentExpression) {
+ public ChangeToAppendFix(@NotNull IElementType eqOpSign, @NotNull PsiType lType, @NotNull PsiAssignmentExpression assignmentExpression) {
myTokenType = eqOpSign;
myLhsType = lType;
myAssignmentExpression = assignmentExpression;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
index a996525..dab9a3b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
@@ -40,7 +40,7 @@
public class ConvertSwitchToIfIntention implements IntentionAction {
private final PsiSwitchStatement mySwitchExpression;
- public ConvertSwitchToIfIntention(PsiSwitchStatement switchStatement) {
+ public ConvertSwitchToIfIntention(@NotNull PsiSwitchStatement switchStatement) {
mySwitchExpression = switchStatement;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java
index 139a605..939b8b6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java
@@ -32,8 +32,7 @@
* @author Mike
*/
public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
-
- public CreateFieldFromUsageFix(PsiReferenceExpression referenceElement) {
+ public CreateFieldFromUsageFix(@NotNull PsiReferenceExpression referenceElement) {
super(referenceElement);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java
index 35d25d8..ec6e0c3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java
@@ -27,7 +27,7 @@
public class DeleteCatchFix implements IntentionAction {
private final PsiParameter myCatchParameter;
- public DeleteCatchFix(PsiParameter myCatchParameter) {
+ public DeleteCatchFix(@NotNull PsiParameter myCatchParameter) {
this.myCatchParameter = myCatchParameter;
}
@@ -45,9 +45,7 @@
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- return myCatchParameter != null
- && myCatchParameter.isValid()
- && PsiManager.getInstance(project).isInProject(myCatchParameter.getContainingFile());
+ return myCatchParameter.isValid() && PsiManager.getInstance(project).isInProject(myCatchParameter.getContainingFile());
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java
index 41e08d6..c85e613 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java
@@ -32,7 +32,7 @@
public class DeleteMultiCatchFix implements IntentionAction {
private final PsiTypeElement myTypeElement;
- public DeleteMultiCatchFix(final PsiTypeElement typeElement) {
+ public DeleteMultiCatchFix(@NotNull PsiTypeElement typeElement) {
myTypeElement = typeElement;
}
@@ -50,9 +50,7 @@
@Override
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
- return myTypeElement != null &&
- myTypeElement.isValid() &&
- PsiManager.getInstance(project).isInProject(myTypeElement.getContainingFile());
+ return myTypeElement.isValid() && PsiManager.getInstance(project).isInProject(myTypeElement.getContainingFile());
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java
index b0c9790..64ad438 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java
@@ -32,7 +32,7 @@
private PsiTryStatement myTryStatement;
private PsiParameter myCatchParameter;
- public GeneralizeCatchFix(PsiElement element, PsiClassType unhandledException) {
+ public GeneralizeCatchFix(@NotNull PsiElement element, @NotNull PsiClassType unhandledException) {
myElement = element;
myUnhandledException = unhandledException;
}
@@ -53,9 +53,7 @@
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- if (!(myElement != null
- && myElement.isValid()
- && myUnhandledException != null
+ if (!(myElement.isValid()
&& myUnhandledException.isValid()
&& myElement.getManager().isInProject(myElement))) return false;
// find enclosing try
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
index 1a2683e..abc31adf 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
@@ -41,12 +41,12 @@
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.psi.util.FileTypeUtils;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
-import com.siyeh.ig.psiutils.FileTypeUtils;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java
index 48fae89..4110c91 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java
@@ -35,10 +35,10 @@
private final PsiCatchSection myCatchSection;
private final PsiCatchSection myMoveBeforeSection;
- public MoveCatchUpFix(PsiCatchSection catchSection, PsiCatchSection moveBeforeSection) {
+ public MoveCatchUpFix(@NotNull PsiCatchSection catchSection, @NotNull PsiCatchSection moveBeforeSection) {
this.myCatchSection = catchSection;
- myMoveBeforeSection = moveBeforeSection;
- }
+ myMoveBeforeSection = moveBeforeSection;
+ }
@Override
@NotNull
@@ -56,10 +56,8 @@
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- return myCatchSection != null
- && myCatchSection.isValid()
+ return myCatchSection.isValid()
&& myCatchSection.getManager().isInProject(myCatchSection)
- && myMoveBeforeSection != null
&& myMoveBeforeSection.isValid()
&& myCatchSection.getCatchType() != null
&& PsiUtil.resolveClassInType(myCatchSection.getCatchType()) != null
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/NegationBroadScopeFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/NegationBroadScopeFix.java
index dcbdd44..b628b9f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/NegationBroadScopeFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/NegationBroadScopeFix.java
@@ -33,7 +33,7 @@
public class NegationBroadScopeFix implements IntentionAction {
private final PsiPrefixExpression myPrefixExpression;
- public NegationBroadScopeFix(PsiPrefixExpression prefixExpression) {
+ public NegationBroadScopeFix(@NotNull PsiPrefixExpression prefixExpression) {
myPrefixExpression = prefixExpression;
}
@@ -70,7 +70,7 @@
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- if (myPrefixExpression == null || !myPrefixExpression.isValid()) return false;
+ if (!myPrefixExpression.isValid()) return false;
PsiElement parent = myPrefixExpression.getParent();
if (parent instanceof PsiInstanceOfExpression && ((PsiInstanceOfExpression)parent).getOperand() == myPrefixExpression) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveParameterListFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveParameterListFix.java
index 3fdf639..19f5359 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveParameterListFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveParameterListFix.java
@@ -29,7 +29,7 @@
private final PsiMethod myMethod;
- public RemoveParameterListFix(PsiMethod method) {
+ public RemoveParameterListFix(@NotNull PsiMethod method) {
myMethod = method;
}
@@ -47,7 +47,7 @@
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- return myMethod != null && myMethod.isValid();
+ return myMethod.isValid();
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveQualifierFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveQualifierFix.java
index 063f1b7..35a053e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveQualifierFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveQualifierFix.java
@@ -35,7 +35,7 @@
private final PsiReferenceExpression myExpression;
private final PsiClass myResolved;
- public RemoveQualifierFix(final PsiExpression qualifier, final PsiReferenceExpression expression, final PsiClass resolved) {
+ public RemoveQualifierFix(@NotNull PsiExpression qualifier, @NotNull PsiReferenceExpression expression, @NotNull PsiClass resolved) {
myQualifier = qualifier;
myExpression = expression;
myResolved = resolved;
@@ -56,14 +56,10 @@
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return
- myQualifier != null
- && myQualifier.isValid()
+ myQualifier.isValid()
&& myQualifier.getManager().isInProject(myQualifier)
- && myExpression != null
&& myExpression.isValid()
- && myResolved != null
- && myResolved.isValid()
- ;
+ && myResolved.isValid();
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefFix.java
index 42d42a4..6dc619d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefFix.java
@@ -49,11 +49,11 @@
@NonNls private static final String OTHER_VARIABLE_NAME = "OTHERVAR";
private final boolean myUnresolvedOnly;
- public RenameWrongRefFix(PsiReferenceExpression refExpr) {
+ public RenameWrongRefFix(@NotNull PsiReferenceExpression refExpr) {
this(refExpr, false);
}
- public RenameWrongRefFix(PsiReferenceExpression refExpr, final boolean unresolvedOnly) {
+ public RenameWrongRefFix(@NotNull PsiReferenceExpression refExpr, final boolean unresolvedOnly) {
myRefExpr = refExpr;
myUnresolvedOnly = unresolvedOnly;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ReplaceWithListAccessFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ReplaceWithListAccessFix.java
index 59d6f70..7e8161e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ReplaceWithListAccessFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ReplaceWithListAccessFix.java
@@ -33,7 +33,7 @@
public class ReplaceWithListAccessFix implements IntentionAction {
private final PsiArrayAccessExpression myArrayAccessExpression;
- public ReplaceWithListAccessFix(PsiArrayAccessExpression arrayAccessExpression) {
+ public ReplaceWithListAccessFix(@NotNull PsiArrayAccessExpression arrayAccessExpression) {
myArrayAccessExpression = arrayAccessExpression;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ReuseVariableDeclarationFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ReuseVariableDeclarationFix.java
index 78c0275..bc1aafd 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ReuseVariableDeclarationFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ReuseVariableDeclarationFix.java
@@ -36,7 +36,7 @@
public class ReuseVariableDeclarationFix implements IntentionAction {
private final PsiLocalVariable myVariable;
- public ReuseVariableDeclarationFix(final PsiLocalVariable variable) {
+ public ReuseVariableDeclarationFix(@NotNull PsiLocalVariable variable) {
this.myVariable = variable;
}
@@ -54,7 +54,7 @@
@Override
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
- if (myVariable == null || !myVariable.isValid()) {
+ if (!myVariable.isValid()) {
return false;
}
final PsiVariable previousVariable = findPreviousVariable();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ShowModulePropertiesFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ShowModulePropertiesFix.java
index 1912230..203612e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ShowModulePropertiesFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ShowModulePropertiesFix.java
@@ -21,7 +21,6 @@
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
@@ -33,13 +32,9 @@
public class ShowModulePropertiesFix implements IntentionAction {
private final String myModuleName;
- public ShowModulePropertiesFix(String moduleName) {
- myModuleName = moduleName;
- }
-
- public ShowModulePropertiesFix(PsiElement context) {
+ public ShowModulePropertiesFix(@NotNull PsiElement context) {
Module module = ModuleUtilCore.findModuleForPsiElement(context);
- myModuleName = module != null ? module.getName() : null;
+ myModuleName = module == null ? null : module.getName();
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java
index 1e91f9d..d617c8d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java
@@ -40,7 +40,7 @@
private PsiStatement myStatement = null;
- public SurroundWithTryCatchFix(PsiElement element) {
+ public SurroundWithTryCatchFix(@NotNull PsiElement element) {
final PsiMethodReferenceExpression methodReferenceExpression = PsiTreeUtil.getParentOfType(element, PsiMethodReferenceExpression.class, false);
if (methodReferenceExpression == null) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableParameterizedTypeFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableParameterizedTypeFix.java
index a8b3b28..60ba678 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableParameterizedTypeFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableParameterizedTypeFix.java
@@ -20,7 +20,7 @@
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
-import com.intellij.openapi.projectRoots.JavaSdkVersionUtil;
+import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
@@ -40,7 +40,7 @@
PsiShortNamesCache shortNamesCache = PsiShortNamesCache.getInstance(parameterList.getProject());
PsiClass[] classes = shortNamesCache.getClassesByName(shortName, GlobalSearchScope.allScope(manager.getProject()));
PsiElementFactory factory = facade.getElementFactory();
- JavaSdkVersion version = JavaSdkVersionUtil.getJavaSdkVersion(parameterList);
+ JavaSdkVersion version = JavaVersionService.getInstance().getJavaSdkVersion(parameterList);
for (PsiClass aClass : classes) {
if (GenericsHighlightUtil.checkReferenceTypeArgumentList(aClass, parameterList, PsiSubstitutor.EMPTY, false, version) == null) {
PsiType[] actualTypeParameters = parameterList.getTypeArguments();
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java
index 38fd5a9..bcfd4d0 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java
@@ -24,7 +24,7 @@
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.util.IncorrectOperationException;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
class JavaWithIfExpressionSurrounder extends JavaExpressionSurrounder{
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java
index c6a1221..a5e3f48 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java
@@ -24,7 +24,7 @@
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
class JavaWithNullCheckSurrounder extends JavaExpressionSurrounder{
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/ui/AbstractGenerateEqualsWizard.java b/java/java-impl/src/com/intellij/codeInsight/generation/ui/AbstractGenerateEqualsWizard.java
new file mode 100644
index 0000000..12e6903
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/ui/AbstractGenerateEqualsWizard.java
@@ -0,0 +1,200 @@
+package com.intellij.codeInsight.generation.ui;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.ide.wizard.AbstractWizard;
+import com.intellij.ide.wizard.Step;
+import com.intellij.ide.wizard.StepAdapter;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+import com.intellij.refactoring.ui.AbstractMemberSelectionPanel;
+import com.intellij.util.containers.HashMap;
+
+import javax.swing.*;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import java.awt.*;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Nikolay.Tropin
+ * 8/20/13
+ */
+public abstract class AbstractGenerateEqualsWizard <C extends PsiElement, M extends PsiElement, I extends MemberInfoBase<M>>
+ extends AbstractWizard<Step> {
+
+ protected final C myClass;
+
+ protected final AbstractMemberSelectionPanel<M, I> myEqualsPanel;
+ protected final AbstractMemberSelectionPanel<M, I> myHashCodePanel;
+ protected final AbstractMemberSelectionPanel<M, I> myNonNullPanel;
+ protected final HashMap<M, I> myFieldsToHashCode;
+ protected final HashMap<M, I> myFieldsToNonNull;
+
+ private int myNonNullStepCode;
+ private int myEqualsStepCode;
+ private int myHashCodeStepCode;
+
+ protected int getHashCodeStepCode() {
+ return myHashCodeStepCode;
+ }
+
+ protected int getEqualsStepCode() {
+ return myEqualsStepCode;
+ }
+
+ protected int getNonNullStepCode() {
+ return myNonNullStepCode;
+ }
+
+ protected final List<I> myClassFields;
+
+ protected final Builder<C, M, I> myBuilder;
+
+ public static abstract class Builder<C extends PsiElement, M extends PsiElement, I extends MemberInfoBase<M>> {
+ protected abstract C getPsiClass();
+ protected abstract List<I> getClassFields();
+ protected abstract HashMap<M, I> getFieldsToHashCode();
+ protected abstract HashMap<M, I> getFieldsToNonNull();
+ protected abstract AbstractMemberSelectionPanel<M, I> getEqualsPanel();
+ protected abstract AbstractMemberSelectionPanel<M, I> getHashCodePanel();
+ protected abstract AbstractMemberSelectionPanel<M, I> getNonNullPanel();
+ protected abstract void updateHashCodeMemberInfos(Collection<I> equalsMemberInfos);
+ protected abstract void updateNonNullMemberInfos(Collection<I> equalsMemberInfos);
+ }
+
+ public AbstractGenerateEqualsWizard(Project project, Builder<C, M, I> builder) {
+ super(CodeInsightBundle.message("generate.equals.hashcode.wizard.title"), project);
+ myBuilder = builder;
+ myClass = builder.getPsiClass();
+ myClassFields = builder.getClassFields();
+ myFieldsToHashCode = builder.getFieldsToHashCode();
+ myFieldsToNonNull = builder.getFieldsToNonNull();
+ myEqualsPanel = builder.getEqualsPanel();
+ myHashCodePanel = builder.getHashCodePanel();
+ myNonNullPanel = builder.getNonNullPanel();
+
+ addTableListeners();
+ addSteps();
+ init();
+ updateButtons();
+ }
+
+ protected void addSteps() {
+ myEqualsStepCode = addStepForPanel(myEqualsPanel);
+ myHashCodeStepCode = addStepForPanel(myHashCodePanel);
+ myNonNullStepCode = addStepForPanel(myNonNullPanel);
+ }
+
+ protected int addStepForPanel(AbstractMemberSelectionPanel<M, I> panel) {
+ if (panel != null) {
+ addStep(new MyStep(panel));
+ return getStepCount() - 1;
+ } else {
+ return -1;
+ }
+ }
+
+ protected void addTableListeners() {
+ final MyTableModelListener listener = new MyTableModelListener();
+ if (myEqualsPanel != null) myEqualsPanel.getTable().getModel().addTableModelListener(listener);
+ if (myHashCodePanel != null) myHashCodePanel.getTable().getModel().addTableModelListener(listener);
+ }
+
+ @Override
+ protected void doNextAction() {
+ if (getCurrentStep() == getEqualsStepCode() && myEqualsPanel != null) {
+ equalsFieldsSelected();
+ }
+ else if (getCurrentStep() == getHashCodeStepCode() && myHashCodePanel != null) {
+ Collection<I> selectedMemberInfos = myEqualsPanel != null ? myEqualsPanel.getTable().getSelectedMemberInfos()
+ : myHashCodePanel.getTable().getSelectedMemberInfos();
+ updateNonNullMemberInfos(selectedMemberInfos);
+ }
+
+ super.doNextAction();
+ updateButtons();
+ }
+
+ @Override
+ protected String getHelpID() {
+ return "editing.altInsert.equals";
+ }
+
+ private void equalsFieldsSelected() {
+ Collection<I> selectedMemberInfos = myEqualsPanel.getTable().getSelectedMemberInfos();
+ updateHashCodeMemberInfos(selectedMemberInfos);
+ updateNonNullMemberInfos(selectedMemberInfos);
+ }
+
+ @Override
+ protected void doOKAction() {
+ if (myEqualsPanel != null) {
+ equalsFieldsSelected();
+ }
+ super.doOKAction();
+ }
+
+ protected void updateHashCodeMemberInfos(Collection<I> equalsMemberInfos) {
+ myBuilder.updateHashCodeMemberInfos(equalsMemberInfos);
+ }
+
+ protected void updateNonNullMemberInfos(Collection<I> equalsMemberInfos) {
+ myBuilder.updateNonNullMemberInfos(equalsMemberInfos);
+ }
+
+ @Override
+ protected boolean canGoNext() {
+ if (getCurrentStep() == myEqualsStepCode) {
+ for (I classField : myClassFields) {
+ if (classField.isChecked()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ final Component stepComponent = getCurrentStepComponent();
+ if (stepComponent instanceof AbstractMemberSelectionPanel) {
+ return ((AbstractMemberSelectionPanel)stepComponent).getTable();
+ }
+ else {
+ return null;
+ }
+ }
+
+ private class MyTableModelListener implements TableModelListener {
+ public void tableChanged(TableModelEvent modelEvent) {
+ updateButtons();
+ }
+ }
+
+ private static class MyStep extends StepAdapter {
+ final AbstractMemberSelectionPanel myPanel;
+
+ public MyStep(AbstractMemberSelectionPanel panel) {
+ myPanel = panel;
+ }
+
+ @Override
+ public Icon getIcon() {
+ return null;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return myPanel;
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myPanel.getTable();
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java b/java/java-impl/src/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java
index bd7203f..d76caed 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java
@@ -18,16 +18,15 @@
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.generation.GenerateEqualsHelper;
-import com.intellij.ide.wizard.AbstractWizard;
import com.intellij.ide.wizard.StepAdapter;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.psi.*;
+import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
import com.intellij.refactoring.classMembers.MemberInfoBase;
-import com.intellij.refactoring.classMembers.MemberInfoChange;
-import com.intellij.refactoring.classMembers.MemberInfoModel;
import com.intellij.refactoring.classMembers.MemberInfoTooltipManager;
+import com.intellij.refactoring.ui.AbstractMemberSelectionPanel;
import com.intellij.refactoring.ui.MemberSelectionPanel;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.ui.NonFocusableCheckBox;
@@ -36,108 +35,144 @@
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.event.TableModelEvent;
-import javax.swing.event.TableModelListener;
-import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
-import java.util.List;
/**
* @author dsl
*/
-public class GenerateEqualsWizard extends AbstractWizard {
+public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass, PsiMember, MemberInfo> {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.ui.GenerateEqualsWizard");
- private final PsiClass myClass;
- private final MemberSelectionPanel myEqualsPanel;
- private final MemberSelectionPanel myHashCodePanel;
- private final HashMap myFieldsToHashCode;
- private final MemberSelectionPanel myNonNullPanel;
- private final HashMap<PsiElement, MemberInfo> myFieldsToNonNull;
-
- private final int myTestBoxedStep;
- private final int myEqualsStepCode;
- private final int myHashcodeStepCode;
-
- private final List<MemberInfo> myClassFields;
private static final MyMemberInfoFilter MEMBER_INFO_FILTER = new MyMemberInfoFilter();
+ public static class JavaGenerateEqualsWizardBuilder extends AbstractGenerateEqualsWizard.Builder<PsiClass, PsiMember, MemberInfo> {
+ private final PsiClass myClass;
- public GenerateEqualsWizard(Project project, PsiClass aClass, boolean needEquals, boolean needHashCode) {
- super(CodeInsightBundle.message("generate.equals.hashcode.wizard.title"), project);
- LOG.assertTrue(needEquals || needHashCode);
- myClass = aClass;
+ private final MemberSelectionPanel myEqualsPanel;
+ private final MemberSelectionPanel myHashCodePanel;
+ private final MemberSelectionPanel myNonNullPanel;
+ private final HashMap<PsiMember, MemberInfo> myFieldsToHashCode;
+ private final HashMap<PsiMember, MemberInfo> myFieldsToNonNull;
+ private final List<MemberInfo> myClassFields;
- myClassFields = MemberInfo.extractClassMembers(myClass, MEMBER_INFO_FILTER, false);
- for (MemberInfo myClassField : myClassFields) {
- myClassField.setChecked(true);
- }
- int testBoxedStep = 0;
- if (needEquals) {
- myEqualsPanel =
- new MemberSelectionPanel(CodeInsightBundle.message("generate.equals.hashcode.equals.fields.chooser.title"), myClassFields, null);
- myEqualsPanel.getTable().setMemberInfoModel(new EqualsMemberInfoModel());
- testBoxedStep+=2;
- }
- else {
- myEqualsPanel = null;
- }
- if (needHashCode) {
- final List<MemberInfo> hashCodeMemberInfos;
+ private JavaGenerateEqualsWizardBuilder(PsiClass aClass, boolean needEquals, boolean needHashCode) {
+ LOG.assertTrue(needEquals || needHashCode);
+ myClass = aClass;
+ myClassFields = MemberInfo.extractClassMembers(myClass, MEMBER_INFO_FILTER, false);
+ for (MemberInfo myClassField : myClassFields) {
+ myClassField.setChecked(true);
+ }
if (needEquals) {
- myFieldsToHashCode = createFieldToMemberInfoMap(true);
- hashCodeMemberInfos = Collections.emptyList();
+ myEqualsPanel = new MemberSelectionPanel(CodeInsightBundle.message("generate.equals.hashcode.equals.fields.chooser.title"),
+ myClassFields, null);
+ myEqualsPanel.getTable().setMemberInfoModel(new EqualsMemberInfoModel());
}
else {
- hashCodeMemberInfos = myClassFields;
+ myEqualsPanel = null;
+ }
+ if (needHashCode) {
+ final List<MemberInfo> hashCodeMemberInfos;
+ if (needEquals) {
+ myFieldsToHashCode = createFieldToMemberInfoMap(true);
+ hashCodeMemberInfos = Collections.emptyList();
+ }
+ else {
+ hashCodeMemberInfos = myClassFields;
+ myFieldsToHashCode = null;
+ }
+ myHashCodePanel = new MemberSelectionPanel(CodeInsightBundle.message("generate.equals.hashcode.hashcode.fields.chooser.title"), hashCodeMemberInfos, null);
+ myHashCodePanel.getTable().setMemberInfoModel(new HashCodeMemberInfoModel());
+ if (needEquals) {
+ updateHashCodeMemberInfos(myClassFields);
+ }
+ }
+ else {
+ myHashCodePanel = null;
myFieldsToHashCode = null;
}
- myHashCodePanel = new MemberSelectionPanel(CodeInsightBundle.message("generate.equals.hashcode.hashcode.fields.chooser.title"),
- hashCodeMemberInfos, null);
- myHashCodePanel.getTable().setMemberInfoModel(new HashCodeMemberInfoModel());
- if (needEquals) {
- updateHashCodeMemberInfos(myClassFields);
+ myNonNullPanel = new MemberSelectionPanel(CodeInsightBundle.message("generate.equals.hashcode.non.null.fields.chooser.title"), Collections.<MemberInfo>emptyList(), null);
+ myFieldsToNonNull = createFieldToMemberInfoMap(false);
+ for (final Map.Entry<PsiMember, MemberInfo> entry : myFieldsToNonNull.entrySet()) {
+ entry.getValue().setChecked(entry.getKey().getModifierList().findAnnotation(NotNull.class.getName()) != null);
}
- testBoxedStep++;
- }
- else {
- myHashCodePanel = null;
- myFieldsToHashCode = null;
- }
- myTestBoxedStep=testBoxedStep;
- myNonNullPanel = new MemberSelectionPanel(CodeInsightBundle.message("generate.equals.hashcode.non.null.fields.chooser.title"),
- Collections.<MemberInfo>emptyList(), null);
- myFieldsToNonNull = createFieldToMemberInfoMap(false);
- for (final Map.Entry<PsiElement, MemberInfo> entry : myFieldsToNonNull.entrySet()) {
- entry.getValue().setChecked(((PsiField)entry.getKey()).getModifierList().findAnnotation(NotNull.class.getName()) != null);
}
- final MyTableModelListener listener = new MyTableModelListener();
- if (myEqualsPanel != null) {
- myEqualsPanel.getTable().getModel().addTableModelListener(listener);
- addStep(new InstanceofOptionStep());
- addStep(new MyStep(myEqualsPanel));
- myEqualsStepCode = 1;
- }
- else {
- myEqualsStepCode = -1;
+ @Override
+ protected List<MemberInfo> getClassFields() {
+ return myClassFields;
}
- if (myHashCodePanel != null) {
- myHashCodePanel.getTable().getModel().addTableModelListener(listener);
- addStep(new MyStep(myHashCodePanel));
- myHashcodeStepCode = myEqualsStepCode > 0 ? myEqualsStepCode + 1 : 0;
- }
- else {
- myHashcodeStepCode = -1;
+ @Override
+ protected HashMap<PsiMember, MemberInfo> getFieldsToHashCode() {
+ return myFieldsToHashCode;
}
- addStep(new MyStep(myNonNullPanel));
+ @Override
+ protected HashMap<PsiMember, MemberInfo> getFieldsToNonNull() {
+ return myFieldsToNonNull;
+ }
- init();
- updateButtons();
+ @Override
+ protected AbstractMemberSelectionPanel<PsiMember, MemberInfo> getEqualsPanel() {
+ return myEqualsPanel;
+ }
+
+ @Override
+ protected AbstractMemberSelectionPanel<PsiMember, MemberInfo> getHashCodePanel() {
+ return myHashCodePanel;
+ }
+
+ @Override
+ protected AbstractMemberSelectionPanel<PsiMember, MemberInfo> getNonNullPanel() {
+ return myNonNullPanel;
+ }
+
+ @Override
+ protected PsiClass getPsiClass() {
+ return myClass;
+ }
+
+ @Override
+ protected void updateHashCodeMemberInfos(Collection<MemberInfo> equalsMemberInfos) {
+ if (myHashCodePanel == null) return;
+ List<MemberInfo> hashCodeFields = new ArrayList<MemberInfo>();
+
+ for (MemberInfo equalsMemberInfo : equalsMemberInfos) {
+ hashCodeFields.add(myFieldsToHashCode.get(equalsMemberInfo.getMember()));
+ }
+
+ myHashCodePanel.getTable().setMemberInfos(hashCodeFields);
+ }
+
+ @Override
+ protected void updateNonNullMemberInfos(Collection<MemberInfo> equalsMemberInfos) {
+ final ArrayList<MemberInfo> list = new ArrayList<MemberInfo>();
+
+ for (MemberInfo equalsMemberInfo : equalsMemberInfos) {
+ PsiField field = (PsiField)equalsMemberInfo.getMember();
+ if (!(field.getType() instanceof PsiPrimitiveType)) {
+ list.add(myFieldsToNonNull.get(equalsMemberInfo.getMember()));
+ }
+ }
+ myNonNullPanel.getTable().setMemberInfos(list);
+ }
+
+ private HashMap<PsiMember, MemberInfo> createFieldToMemberInfoMap(boolean checkedByDefault) {
+ Collection<MemberInfo> memberInfos = MemberInfo.extractClassMembers(myClass, MEMBER_INFO_FILTER, false);
+ final HashMap<PsiMember, MemberInfo> result = new HashMap<PsiMember, MemberInfo>();
+ for (MemberInfo memberInfo : memberInfos) {
+ memberInfo.setChecked(checkedByDefault);
+ result.put(memberInfo.getMember(), memberInfo);
+ }
+ return result;
+ }
+
+ }
+
+ public GenerateEqualsWizard(Project project, PsiClass aClass, boolean needEquals, boolean needHashCode) {
+ super(project, new JavaGenerateEqualsWizardBuilder(aClass, needEquals, needHashCode));
}
public PsiField[] getEqualsFields() {
@@ -171,21 +206,6 @@
}
@Override
- protected void doNextAction() {
- if (getCurrentStep() == myEqualsStepCode && myEqualsPanel != null) {
- equalsFieldsSelected();
- }
- else if (getCurrentStep() == myHashcodeStepCode && myHashCodePanel != null) {
- Collection<MemberInfo> selectedMemberInfos = myEqualsPanel != null ? myEqualsPanel.getTable().getSelectedMemberInfos()
- : myHashCodePanel.getTable().getSelectedMemberInfos();
- updateNonNullMemberInfos(selectedMemberInfos);
- }
-
- super.doNextAction();
- updateButtons();
- }
-
- @Override
protected String getHelpID() {
return "editing.altInsert.equals";
}
@@ -204,47 +224,14 @@
super.doOKAction();
}
- private HashMap<PsiElement, MemberInfo> createFieldToMemberInfoMap(boolean checkedByDefault) {
- Collection<MemberInfo> memberInfos = MemberInfo.extractClassMembers(myClass, MEMBER_INFO_FILTER, false);
- final HashMap<PsiElement, MemberInfo> result = new HashMap<PsiElement, MemberInfo>();
- for (MemberInfo memberInfo : memberInfos) {
- memberInfo.setChecked(checkedByDefault);
- result.put(memberInfo.getMember(), memberInfo);
- }
- return result;
- }
-
- private void updateHashCodeMemberInfos(Collection<MemberInfo> equalsMemberInfos) {
- if (myHashCodePanel == null) return;
- List<MemberInfo> hashCodeFields = new ArrayList<MemberInfo>();
-
- for (MemberInfo equalsMemberInfo : equalsMemberInfos) {
- hashCodeFields.add((MemberInfo)myFieldsToHashCode.get(equalsMemberInfo.getMember()));
- }
-
- myHashCodePanel.getTable().setMemberInfos(hashCodeFields);
- }
-
- private void updateNonNullMemberInfos(Collection<MemberInfo> equalsMemberInfos) {
- final ArrayList<MemberInfo> list = new ArrayList<MemberInfo>();
-
- for (MemberInfoBase<PsiMember> equalsMemberInfo : equalsMemberInfos) {
- PsiField field = (PsiField)equalsMemberInfo.getMember();
- if (!(field.getType() instanceof PsiPrimitiveType)) {
- list.add(myFieldsToNonNull.get(equalsMemberInfo.getMember()));
- }
- }
- myNonNullPanel.getTable().setMemberInfos(list);
- }
-
@Override
protected int getNextStep(int step) {
- if (step + 1 == myTestBoxedStep) {
+ if (step + 1 == getNonNullStepCode()) {
for (MemberInfo classField : myClassFields) {
if (classField.isChecked()) {
PsiField field = (PsiField)classField.getMember();
if (!(field.getType() instanceof PsiPrimitiveType)) {
- return myTestBoxedStep;
+ return getNonNullStepCode();
}
}
}
@@ -255,88 +242,11 @@
}
@Override
- protected boolean canGoNext() {
- if (getCurrentStep() == myEqualsStepCode) {
- for (MemberInfo classField : myClassFields) {
- if (classField.isChecked()) {
- return true;
- }
- }
- return false;
+ protected void addSteps() {
+ if (myEqualsPanel != null) {
+ addStep(new InstanceofOptionStep());
}
-
- return true;
- }
-
- @Override
- public JComponent getPreferredFocusedComponent() {
- final Component stepComponent = getCurrentStepComponent();
- if (stepComponent instanceof MemberSelectionPanel) {
- return ((MemberSelectionPanel)stepComponent).getTable();
- }
- else {
- return null;
- }
- }
-
- private class MyTableModelListener implements TableModelListener {
- @Override
- public void tableChanged(TableModelEvent e) {
- updateButtons();
- }
- }
-
- private static class InstanceofOptionStep extends StepAdapter {
- private final JComponent myPanel;
-
- private InstanceofOptionStep() {
- final JCheckBox checkbox = new NonFocusableCheckBox(CodeInsightBundle.message("generate.equals.hashcode.accept.sublcasses"));
- checkbox.setSelected(CodeInsightSettings.getInstance().USE_INSTANCEOF_ON_EQUALS_PARAMETER);
- checkbox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent e) {
- CodeInsightSettings.getInstance().USE_INSTANCEOF_ON_EQUALS_PARAMETER = checkbox.isSelected();
- }
- });
-
- myPanel = new JPanel(new VerticalFlowLayout());
- myPanel.add(checkbox);
- myPanel.add(new JLabel(CodeInsightBundle.message("generate.equals.hashcode.accept.sublcasses.explanation")));
- }
-
- @Override
- public JComponent getComponent() {
- return myPanel;
- }
-
- @Override
- @Nullable
- public Icon getIcon() {
- return null;
- }
- }
-
- private static class MyStep extends StepAdapter {
- final MemberSelectionPanel myPanel;
-
- public MyStep(MemberSelectionPanel panel) {
- myPanel = panel;
- }
-
- @Override
- public Icon getIcon() {
- return null;
- }
-
- @Override
- public JComponent getComponent() {
- return myPanel;
- }
-
- @Override
- public JComponent getPreferredFocusedComponent() {
- return myPanel.getTable();
- }
+ super.addSteps();
}
private static class MyMemberInfoFilter implements MemberInfoBase.Filter<PsiMember> {
@@ -346,9 +256,9 @@
}
}
-
- private static class EqualsMemberInfoModel implements MemberInfoModel<PsiMember, MemberInfo> {
- MemberInfoTooltipManager<PsiMember, MemberInfo> myTooltipManager = new MemberInfoTooltipManager<PsiMember, MemberInfo>(new MemberInfoTooltipManager.TooltipProvider<PsiMember, MemberInfo>() {
+ private static class EqualsMemberInfoModel extends AbstractMemberInfoModel<PsiMember, MemberInfo> {
+ MemberInfoTooltipManager<PsiMember, MemberInfo> myTooltipManager =
+ new MemberInfoTooltipManager<PsiMember, MemberInfo>(new MemberInfoTooltipManager.TooltipProvider<PsiMember, MemberInfo>() {
@Override
public String getTooltip(MemberInfo memberInfo) {
if (checkForProblems(memberInfo) == OK) return null;
@@ -372,26 +282,6 @@
}
@Override
- public boolean isCheckedWhenDisabled(MemberInfo member) {
- return false;
- }
-
- @Override
- public boolean isAbstractEnabled(MemberInfo member) {
- return false;
- }
-
- @Override
- public boolean isAbstractWhenDisabled(MemberInfo member) {
- return false;
- }
-
- @Override
- public Boolean isFixedAbstract(MemberInfo member) {
- return null;
- }
-
- @Override
public int checkForProblems(@NotNull MemberInfo member) {
if (!(member.getMember() instanceof PsiField)) return ERROR;
final PsiType type = ((PsiField)member.getMember()).getType();
@@ -401,16 +291,12 @@
}
@Override
- public void memberInfoChanged(MemberInfoChange<PsiMember, MemberInfo> event) {
- }
-
- @Override
public String getTooltipText(MemberInfo member) {
return myTooltipManager.getTooltip(member);
}
}
- private static class HashCodeMemberInfoModel implements MemberInfoModel<PsiMember, MemberInfo> {
+ private static class HashCodeMemberInfoModel extends AbstractMemberInfoModel<PsiMember, MemberInfo> {
private final MemberInfoTooltipManager<PsiMember, MemberInfo> myTooltipManager = new MemberInfoTooltipManager<PsiMember, MemberInfo>(new MemberInfoTooltipManager.TooltipProvider<PsiMember, MemberInfo>() {
@Override
public String getTooltip(MemberInfo memberInfo) {
@@ -429,37 +315,37 @@
}
@Override
- public boolean isCheckedWhenDisabled(MemberInfo member) {
- return false;
- }
-
- @Override
- public boolean isAbstractEnabled(MemberInfo member) {
- return false;
- }
-
- @Override
- public boolean isAbstractWhenDisabled(MemberInfo member) {
- return false;
- }
-
- @Override
- public Boolean isFixedAbstract(MemberInfo member) {
- return null;
- }
-
- @Override
- public int checkForProblems(@NotNull MemberInfo member) {
- return OK;
- }
-
- @Override
- public void memberInfoChanged(MemberInfoChange<PsiMember, MemberInfo> event) {
- }
-
- @Override
public String getTooltipText(MemberInfo member) {
return myTooltipManager.getTooltip(member);
}
}
+
+ private static class InstanceofOptionStep extends StepAdapter {
+ private final JComponent myPanel;
+
+ private InstanceofOptionStep() {
+ final JCheckBox checkbox = new NonFocusableCheckBox(CodeInsightBundle.message("generate.equals.hashcode.accept.sublcasses"));
+ checkbox.setSelected(CodeInsightSettings.getInstance().USE_INSTANCEOF_ON_EQUALS_PARAMETER);
+ checkbox.addActionListener(new ActionListener() {
+ public void actionPerformed(@NotNull final ActionEvent M) {
+ CodeInsightSettings.getInstance().USE_INSTANCEOF_ON_EQUALS_PARAMETER = checkbox.isSelected();
+ }
+ });
+
+ myPanel = new JPanel(new VerticalFlowLayout());
+ myPanel.add(checkbox);
+ myPanel.add(new JLabel(CodeInsightBundle.message("generate.equals.hashcode.accept.sublcasses.explanation")));
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return myPanel;
+ }
+
+ @Override
+ @Nullable
+ public Icon getIcon() {
+ return null;
+ }
+ }
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/SuppressManagerImpl.java b/java/java-impl/src/com/intellij/codeInspection/SuppressManagerImpl.java
index 18ba50a..c67f925 100644
--- a/java/java-impl/src/com/intellij/codeInspection/SuppressManagerImpl.java
+++ b/java/java-impl/src/com/intellij/codeInspection/SuppressManagerImpl.java
@@ -21,7 +21,6 @@
package com.intellij.codeInspection;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
-import com.intellij.codeInspection.ex.InspectionManagerEx;
import com.intellij.psi.PsiDocCommentOwner;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifierListOwner;
@@ -45,7 +44,7 @@
return ContainerUtil.map2Array(actions, SuppressIntentionAction.class, new Function<SuppressQuickFix, SuppressIntentionAction>() {
@Override
public SuppressIntentionAction fun(SuppressQuickFix fix) {
- return InspectionManagerEx.convertBatchToSuppressIntentionAction(fix);
+ return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction(fix);
}
});
}
diff --git a/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java b/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java
index e01c21c..4dacb84 100644
--- a/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java
+++ b/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java
@@ -39,7 +39,7 @@
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.LayeredIcon;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
diff --git a/java/java-impl/src/com/intellij/openapi/projectRoots/JavaVersionServiceImpl.java b/java/java-impl/src/com/intellij/openapi/projectRoots/JavaVersionServiceImpl.java
index 76e9875..1a3ce4e 100644
--- a/java/java-impl/src/com/intellij/openapi/projectRoots/JavaVersionServiceImpl.java
+++ b/java/java-impl/src/com/intellij/openapi/projectRoots/JavaVersionServiceImpl.java
@@ -27,4 +27,9 @@
public boolean isAtLeast(@NotNull PsiElement element, @NotNull JavaSdkVersion version) {
return JavaSdkVersionUtil.isAtLeast(element, version);
}
+
+ @Override
+ public JavaSdkVersion getJavaSdkVersion(@NotNull PsiElement element) {
+ return JavaSdkVersionUtil.getJavaSdkVersion(element);
+ }
}
diff --git a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java
index ad59dda..eb3ea75 100644
--- a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java
+++ b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java
@@ -109,25 +109,25 @@
}
@Override
- public void saveAdditionalData(SdkAdditionalData additionalData, Element additional) {
+ public void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional) {
}
@Override
@SuppressWarnings({"HardCodedStringLiteral"})
- public String getBinPath(Sdk sdk) {
+ public String getBinPath(@NotNull Sdk sdk) {
return getConvertedHomePath(sdk) + "bin";
}
@Override
@NonNls
- public String getToolsPath(Sdk sdk) {
+ public String getToolsPath(@NotNull Sdk sdk) {
final String versionString = sdk.getVersionString();
final boolean isJdk1_x = versionString != null && (versionString.contains("1.0") || versionString.contains("1.1"));
return getConvertedHomePath(sdk) + "lib" + File.separator + (isJdk1_x? "classes.zip" : "tools.jar");
}
@Override
- public String getVMExecutablePath(Sdk sdk) {
+ public String getVMExecutablePath(@NotNull Sdk sdk) {
/*
if ("64".equals(System.getProperty("sun.arch.data.model"))) {
return getBinPath(sdk) + File.separator + System.getProperty("os.arch") + File.separator + VM_EXE_NAME;
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java
index 39a8cdc..852c729 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.source.codeStyle;
+import com.intellij.codeInsight.ImportFilter;
import com.intellij.lang.ASTNode;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
@@ -368,6 +369,10 @@
String className = refClass.getQualifiedName();
if (className == null) return true;
+
+ if (!ImportFilter.shouldImport(className)) {
+ return false;
+ }
String packageName = getPackageOrClassName(className);
String shortName = PsiNameHelper.getShortClassName(className);
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java
index 2822fcf..fbf7ec3 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java
@@ -38,7 +38,7 @@
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -752,7 +752,7 @@
int pLength = prefix.length();
if (pLength > 0 && name.startsWith(prefix) && name.length() > pLength &&
// check it's not just a long camel word that happens to begin with the specified prefix
- (!Character.isJavaIdentifierPart(prefix.charAt(pLength - 1)) || Character.isUpperCase(name.charAt(pLength)))) {
+ (!Character.isLetter(prefix.charAt(pLength - 1)) || Character.isUpperCase(name.charAt(pLength)))) {
name = name.substring(pLength);
doDecapitalize = true;
}
diff --git a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java
index 346ed4c..390ac0e 100644
--- a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java
@@ -37,7 +37,7 @@
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.classMembers.ElementNeedsThis;
import com.intellij.util.IncorrectOperationException;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java
index bfbe8b2..df0afa8 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java
@@ -30,6 +30,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ValidationInfo;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
@@ -660,12 +661,12 @@
final String oldModifier = VisibilityUtil.getVisibilityModifier(modifierList);
final String newModifier = getVisibility();
String newModifierStr = VisibilityUtil.getVisibilityString(newModifier);
- if (!newModifier.equals(oldModifier)) {
+ if (!Comparing.equal(newModifier, oldModifier)) {
int index = modifiers.indexOf(oldModifier);
if (index >= 0) {
final StringBuilder buf = new StringBuilder(modifiers);
buf.replace(index,
- index + oldModifier.length() + ("".equals(newModifierStr) ? 1 : 0),
+ index + oldModifier.length() + (StringUtil.isEmpty(newModifierStr) ? 1 : 0),
newModifierStr);
modifiers = buf.toString();
} else {
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureHandler.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureHandler.java
index 5657803..a57b996 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -89,7 +89,7 @@
final PsiClass containingClass = method.getContainingClass();
final PsiReferenceExpression refExpr = editor != null ? TargetElementUtil.findReferenceExpression(editor) : null;
final boolean allowDelegation = containingClass != null && !containingClass.isInterface();
- final DialogWrapper dialog = new JavaChangeSignatureDialog(project, method, allowDelegation, refExpr);
+ final DialogWrapper dialog = new JavaChangeSignatureDialog(project, method, allowDelegation, refExpr == null ? method : refExpr);
dialog.show();
}
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
index 1aac71d..be633c4 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
@@ -67,7 +67,7 @@
import com.intellij.refactoring.util.occurrences.OccurrenceManager;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java
index 08a6bf6..cb027ac 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java
@@ -38,7 +38,7 @@
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
diff --git a/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanProcessor.java b/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanProcessor.java
index b859be9..0b84dfe 100644
--- a/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanProcessor.java
@@ -33,6 +33,7 @@
import com.intellij.util.Query;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
+import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -69,6 +70,18 @@
@Override
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
+ final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
+ for (UsageInfo info : myToInvert.keySet()) {
+ final PsiElement element = info.getElement();
+ if (element instanceof PsiMethodReferenceExpression) {
+ conflicts.putValue(element, "Method is used in method reference expression");
+ }
+ }
+
+ if (!conflicts.isEmpty()) {
+ return showConflicts(conflicts, null);
+ }
+
if (myRenameProcessor.preprocessUsages(refUsages)) {
prepareSuccessful();
return true;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java
index 930eafc..41e0a2b 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java
@@ -10,7 +10,7 @@
import com.intellij.usageView.UsageInfo;
import com.intellij.util.Function;
import com.intellij.util.containers.MultiMap;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import java.util.*;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java
index 5f3471f..c2cd0af 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java
@@ -38,7 +38,7 @@
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.Nullable;
import java.io.File;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java
index 3134f39..258c263 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java
@@ -29,7 +29,7 @@
import com.intellij.refactoring.util.MoveRenameUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/JavaVetoRenameCondition.java b/java/java-impl/src/com/intellij/refactoring/rename/JavaVetoRenameCondition.java
index 72231dc..0f290cf 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/JavaVetoRenameCondition.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/JavaVetoRenameCondition.java
@@ -20,7 +20,7 @@
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
public class JavaVetoRenameCondition implements Condition<PsiElement> {
@Override
diff --git a/java/java-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java b/java/java-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
new file mode 100644
index 0000000..0e9397a
--- /dev/null
+++ b/java/java-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionPanel.java
@@ -0,0 +1,14 @@
+package com.intellij.refactoring.ui;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.classMembers.MemberInfoBase;
+
+import javax.swing.*;
+
+/**
+ * Nikolay.Tropin
+ * 8/20/13
+ */
+public abstract class AbstractMemberSelectionPanel<T extends PsiElement, M extends MemberInfoBase<T>> extends JPanel {
+ public abstract AbstractMemberSelectionTable<T, M> getTable();
+}
diff --git a/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java b/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java
index 05dd6f8..c503a86 100644
--- a/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java
+++ b/java/java-impl/src/com/intellij/refactoring/ui/MemberSelectionPanel.java
@@ -24,18 +24,16 @@
*/
package com.intellij.refactoring.ui;
+import com.intellij.psi.PsiMember;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SeparatorFactory;
-import com.intellij.ui.TableUtil;
import javax.swing.*;
import java.awt.*;
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
import java.util.List;
-public class MemberSelectionPanel extends JPanel {
+public class MemberSelectionPanel extends AbstractMemberSelectionPanel<PsiMember, MemberInfo> {
private final MemberSelectionTable myTable;
/**
diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java
index add3fe2..e8af76b 100644
--- a/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java
+++ b/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java
@@ -32,7 +32,7 @@
import com.intellij.usages.UsageView;
import com.intellij.usages.rules.PsiElementUsage;
import com.intellij.usages.rules.UsageGroupingRule;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java
index 233bb42..be4c4f8 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java
@@ -83,6 +83,17 @@
});
}
+ public interface InheritanceChecker {
+ boolean checkInheritance(@NotNull PsiClass subClass, @NotNull PsiClass parentClass);
+
+ InheritanceChecker DEFAULT = new InheritanceChecker() {
+ @Override
+ public boolean checkInheritance(@NotNull PsiClass subClass, @NotNull PsiClass parentClass) {
+ return subClass.isInheritor(parentClass, false);
+ }
+ };
+ }
+
public static class SearchParameters {
private final PsiClass myClass;
private final SearchScope myScope;
@@ -90,6 +101,7 @@
private final boolean myCheckInheritance;
private final boolean myIncludeAnonymous;
private final Condition<String> myNameCondition;
+ private final InheritanceChecker myInheritanceChecker;
public SearchParameters(@NotNull final PsiClass aClass, @NotNull SearchScope scope, final boolean checkDeep, final boolean checkInheritance, boolean includeAnonymous) {
this(aClass, scope, checkDeep, checkInheritance, includeAnonymous, Condition.TRUE);
@@ -97,12 +109,18 @@
public SearchParameters(@NotNull final PsiClass aClass, @NotNull SearchScope scope, final boolean checkDeep, final boolean checkInheritance,
boolean includeAnonymous, @NotNull final Condition<String> nameCondition) {
+ this(aClass, scope, checkDeep, checkInheritance, includeAnonymous, nameCondition, InheritanceChecker.DEFAULT);
+ }
+
+ public SearchParameters(@NotNull final PsiClass aClass, @NotNull SearchScope scope, final boolean checkDeep, final boolean checkInheritance,
+ boolean includeAnonymous, @NotNull final Condition<String> nameCondition, @NotNull InheritanceChecker inheritanceChecker) {
myClass = aClass;
myScope = scope;
myCheckDeep = checkDeep;
myCheckInheritance = checkInheritance;
myIncludeAnonymous = includeAnonymous;
myNameCondition = nameCondition;
+ myInheritanceChecker = inheritanceChecker;
}
@NotNull
@@ -204,7 +222,7 @@
public void run() {
fqn[0] = candidate.getQualifiedName();
if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) {
- if (!candidate.isInheritor(currentBase.get(), false)) {
+ if (!parameters.myInheritanceChecker.checkInheritance(candidate, currentBase.get())) {
result.set(true);
return;
}
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/ImportFilter.java b/java/java-psi-api/src/com/intellij/codeInsight/ImportFilter.java
new file mode 100644
index 0000000..4863b82
--- /dev/null
+++ b/java/java-psi-api/src/com/intellij/codeInsight/ImportFilter.java
@@ -0,0 +1,22 @@
+package com.intellij.codeInsight;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public abstract class ImportFilter {
+ public static final ExtensionPointName<ImportFilter> EP_NAME = new ExtensionPointName<ImportFilter>("com.intellij.importFilter");
+
+ public abstract boolean shouldUseFullyQualifiedName(@NotNull String classQualifiedName);
+
+ public static boolean shouldImport(@NotNull String classQualifiedName) {
+ for (ImportFilter filter : EP_NAME.getExtensions()) {
+ if (filter.shouldUseFullyQualifiedName(classQualifiedName)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/TestFrameworks.java b/java/java-psi-api/src/com/intellij/codeInsight/TestFrameworks.java
index 9f7e024..248aad7 100644
--- a/java/java-psi-api/src/com/intellij/codeInsight/TestFrameworks.java
+++ b/java/java-psi-api/src/com/intellij/codeInsight/TestFrameworks.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -35,4 +35,13 @@
@Nullable
public abstract PsiMethod findSetUpMethod(PsiClass psiClass);
+
+ @Nullable
+ public abstract PsiMethod findTearDownMethod(PsiClass psiClass);
+
+ protected abstract boolean hasConfigMethods(PsiClass psiClass);
+
+ public boolean isTestOrConfig(PsiClass psiClass) {
+ return isTestClass(psiClass) || hasConfigMethods(psiClass);
+ }
}
diff --git a/java/java-psi-api/src/com/intellij/openapi/projectRoots/JavaVersionService.java b/java/java-psi-api/src/com/intellij/openapi/projectRoots/JavaVersionService.java
index 9e8338e..5108c59 100644
--- a/java/java-psi-api/src/com/intellij/openapi/projectRoots/JavaVersionService.java
+++ b/java/java-psi-api/src/com/intellij/openapi/projectRoots/JavaVersionService.java
@@ -32,4 +32,8 @@
public boolean isAtLeast(@NotNull PsiElement element, @NotNull JavaSdkVersion version) {
return PsiUtil.getLanguageLevel(element).isAtLeast(version.getMaxLanguageLevel());
}
+
+ public JavaSdkVersion getJavaSdkVersion(@NotNull PsiElement element) {
+ return JavaSdkVersion.fromLanguageLevel(PsiUtil.getLanguageLevel(element));
+ }
}
\ No newline at end of file
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
index 2bfe470..b0a0149 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -93,7 +93,7 @@
return initialSubst;
}
- public static boolean isValidLambdaContext(PsiElement context) {
+ public static boolean isValidLambdaContext(@Nullable PsiElement context) {
return context instanceof PsiTypeCastExpression ||
context instanceof PsiAssignmentExpression ||
context instanceof PsiVariable ||
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
index 17117c4..a2a75bc 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -107,6 +107,15 @@
}
return new QualifierResolveResult(containingClass, substitutor, false);
}
+
+ public static boolean isStaticallyReferenced(@NotNull PsiMethodReferenceExpression methodReferenceExpression) {
+ final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression();
+ if (qualifierExpression != null) {
+ return qualifierExpression instanceof PsiReferenceExpression &&
+ ((PsiReferenceExpression)qualifierExpression).resolve() instanceof PsiClass;
+ }
+ return true;
+ }
public static boolean isAcceptable(@Nullable final PsiMethodReferenceExpression methodReferenceExpression, PsiType left) {
if (methodReferenceExpression == null) return false;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java b/java/java-psi-api/src/com/intellij/psi/util/FileTypeUtils.java
similarity index 91%
rename from plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java
rename to java/java-psi-api/src/com/intellij/psi/util/FileTypeUtils.java
index 7888121..0080248 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/FileTypeUtils.java
@@ -13,11 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.siyeh.ig.psiutils;
+package com.intellij.psi.util;
import com.intellij.psi.PsiElement;
import com.intellij.psi.ServerPageFile;
-import com.intellij.psi.util.PsiUtilCore;
public class FileTypeUtils {
public static boolean isInServerPageFile(PsiElement file) {
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
index 3504ef8..e3e2511 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
@@ -19,7 +19,6 @@
import com.intellij.lang.java.parser.JavaParser;
import com.intellij.lang.java.parser.JavaParserUtil;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.Pair;
@@ -251,9 +250,9 @@
MostlySingularMultiMap<String, AnnotationData> fileData = getDataFromFile(file);
- addAnnotations(result, externalName, file, fileData);
+ ContainerUtil.addAll(result, fileData.get(externalName));
if (oldExternalName != null && !externalName.equals(oldExternalName)) {
- addAnnotations(result, oldExternalName, file, fileData);
+ ContainerUtil.addAll(result, fileData.get(oldExternalName));
}
}
if (result.isEmpty()) {
@@ -263,24 +262,6 @@
return result;
}
- private void addAnnotations(@NotNull List<AnnotationData> result,
- @NotNull String externalName,
- @NotNull PsiFile file,
- @NotNull MostlySingularMultiMap<String, AnnotationData> fileData) {
- Iterable<AnnotationData> data = fileData.get(externalName);
- for (AnnotationData ad : data) {
- if (result.contains(ad)) {
- // there can be compatible annotations in different files
- if (Comparing.equal(ad.virtualFile, file.getVirtualFile())) {
- duplicateError(file, externalName, "Duplicate signature");
- }
- }
- else {
- result.add(ad);
- }
- }
- }
-
@Override
@Nullable
public List<PsiFile> findExternalAnnotationsFiles(@NotNull PsiModifierListOwner listOwner) {
@@ -414,13 +395,11 @@
private static class AnnotationData {
@NotNull private final String annotationClassFqName;
@NotNull private final String annotationParameters;
- private final VirtualFile virtualFile;
private volatile PsiAnnotation annotation;
- private AnnotationData(@NotNull String annotationClassFqName, @NotNull String annotationParameters, VirtualFile virtualFile) {
+ private AnnotationData(@NotNull String annotationClassFqName, @NotNull String annotationParameters) {
this.annotationClassFqName = annotationClassFqName;
this.annotationParameters = annotationParameters;
- this.virtualFile = virtualFile;
}
@NotNull
@@ -514,7 +493,7 @@
duplicateError(file, externalName, "Duplicate annotation '" + annotationFQN + "' ");
}
}
- AnnotationData annData = internAnnotationData(new AnnotationData(annotationFQN, argumentsString, file.getVirtualFile()));
+ AnnotationData annData = internAnnotationData(new AnnotationData(annotationFQN, argumentsString));
data.add(externalName, annData);
annotationFQN = null;
arguments = null;
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java b/java/java-psi-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java
index 08c7cd2..7671eae 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -76,4 +76,28 @@
}
return null;
}
+
+ @Override
+ @Nullable
+ public PsiMethod findTearDownMethod(final PsiClass psiClass) {
+ final TestFramework[] testFrameworks = Extensions.getExtensions(TestFramework.EXTENSION_NAME);
+ for (TestFramework framework : testFrameworks) {
+ if (framework.isTestClass(psiClass)) {
+ final PsiMethod setUpMethod = (PsiMethod)framework.findTearDownMethod(psiClass);
+ if (setUpMethod != null) {
+ return setUpMethod;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected boolean hasConfigMethods(PsiClass psiClass) {
+ final TestFramework[] testFrameworks = Extensions.getExtensions(TestFramework.EXTENSION_NAME);
+ for (TestFramework framework : testFrameworks) {
+ if (framework.findSetUpMethod(psiClass) != null || framework.findTearDownMethod(psiClass) != null) return true;
+ }
+ return false;
+ }
}
\ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java b/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java
index 1df6096..dd39040 100644
--- a/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java
+++ b/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java
@@ -26,10 +26,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
/**
* @author yole
@@ -138,36 +135,48 @@
if (classes.length == 1) {
PsiClass curClass = classes[0];
- if (bucks > 0) {
- int newComponentStart = 0;
- int lookupStart = 0;
+ if (bucks > 0) {
+ Stack<ClassAndOffsets> currentPath = new Stack<ClassAndOffsets>();
+ currentPath.add(new ClassAndOffsets(curClass, 0, 0));
+ currentPath.add(currentPath.peek());
- while (lookupStart <= className.length()) {
- int b = className.indexOf("$", lookupStart);
- b = b < 0 ? className.length(): b;
+ while (currentPath.size() > 1) {
+ ClassAndOffsets classAndOffset = currentPath.pop();
+ int newComponentStart = classAndOffset.componentStart;
+ int lookupStart = classAndOffset.lookupStart;
+ curClass = currentPath.peek().clazz; //owner class
- String component = className.substring(newComponentStart, b);
- PsiClass inner = curClass.findInnerClassByName(component, false);
+ while (lookupStart <= className.length()) {
+ int bucksIndex = className.indexOf("$", lookupStart);
+ bucksIndex = bucksIndex < 0 ? className.length(): bucksIndex;
- lookupStart = b + 1;
- if (inner == null) {
- continue;
+ String component = className.substring(newComponentStart, bucksIndex);
+ PsiClass inner = curClass.findInnerClassByName(component, false);
+
+ lookupStart = bucksIndex + 1;
+ if (inner == null) {
+ continue;
+ }
+
+ currentPath.add(new ClassAndOffsets(inner, newComponentStart, lookupStart));
+
+ newComponentStart = lookupStart;
+ curClass = inner;
+ }
+
+ if (lookupStart == newComponentStart) {
+ return curClass;
+ }
}
- newComponentStart = lookupStart;
- curClass = inner;
- }
-
- if (lookupStart != newComponentStart) {
return null;
+
+ } else {
+ return curClass;
}
}
-
-
- return curClass;
}
}
- }
return null;
}
@@ -196,4 +205,17 @@
public void addToClasspath(VirtualFile root) {
myClasspath.add(root);
}
+
+ private static class ClassAndOffsets {
+
+ final PsiClass clazz;
+ final int componentStart;
+ final int lookupStart;
+
+ ClassAndOffsets(PsiClass clazz, int componentStart, int lookupStart) {
+ this.clazz = clazz;
+ this.componentStart = componentStart;
+ this.lookupStart = lookupStart;
+ }
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java
index 333ed4c..b5c0f8e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java
+++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java
@@ -47,7 +47,7 @@
}
if (codeFragment == null) return null;
if (myCodeFragment.getContainingFile() == codeFragment.getContainingFile() && // in order for jsp includes to work
- !myCodeFragment.equals(codeFragment)) {
+ !myCodeFragment.equals(codeFragment) && !(myCodeFragment.getParent() instanceof PsiLambdaExpression)) {
return null;
}
return (PsiVariable)refElement;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationParameterListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationParameterListImpl.java
index 0100ccc..03a14f4 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationParameterListImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationParameterListImpl.java
@@ -31,14 +31,20 @@
public ClsAnnotationParameterListImpl(@NotNull PsiAnnotation parent, @NotNull PsiNameValuePair[] psiAttributes) {
myParent = parent;
myAttributes = new ClsNameValuePairImpl[psiAttributes.length];
- for (int i = 0; i < myAttributes.length; i++) {
+ for (int i = 0; i < psiAttributes.length; i++) {
String name = psiAttributes[i].getName();
+
PsiAnnotationMemberValue value = psiAttributes[i].getValue();
if (value == null) {
String anno = parent instanceof ClsAnnotationImpl ? ((ClsAnnotationImpl)parent).getStub().getText() : parent.getText();
- Logger.getInstance(getClass()).error("name=" + name + " anno=[" + anno + "]");
+ Logger.getInstance(getClass()).error("name=" + name + " anno=[" + anno + "] file=" + parent.getContainingFile());
value = new ClsLiteralExpressionImpl(this, "null", PsiType.NULL, null);
}
+
+ if (psiAttributes.length == 1 && "value".equals(name)) {
+ name = null; // cosmetics - omit default attribute name
+ }
+
myAttributes[i] = new ClsNameValuePairImpl(this, name, value);
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java
index 8e79478..7324f7b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java
@@ -17,9 +17,7 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
-import com.intellij.psi.CommonClassNames;
-import com.intellij.psi.PsiNameHelper;
-import com.intellij.psi.PsiReferenceList;
+import com.intellij.psi.*;
import com.intellij.psi.impl.cache.ModifierFlags;
import com.intellij.psi.impl.cache.TypeInfo;
import com.intellij.psi.impl.java.stubs.*;
@@ -340,7 +338,7 @@
byte flags = PsiFieldStubImpl.packFlags((access & Opcodes.ACC_ENUM) != 0, (access & Opcodes.ACC_DEPRECATED) != 0, false);
TypeInfo type = fieldType(desc, signature);
- String initializer = constToString(value, "boolean".equals(type.text.getString()), false);
+ String initializer = constToString(value, type.text.getString(), false);
PsiFieldStub stub = new PsiFieldStubImpl(myResult, name, type, initializer, flags);
PsiModifierListStub modList = new PsiModifierListStubImpl(stub, packFieldFlags(access));
return new AnnotationCollectingVisitor(modList);
@@ -537,7 +535,7 @@
@Override
public void visit(final String name, final Object value) {
valuePairPrefix(name);
- myBuilder.append(constToString(value, false, true));
+ myBuilder.append(constToString(value, null, true));
}
@Override
@@ -556,7 +554,7 @@
myBuilder.append(',');
}
- if (name != null && !"value".equals(name)) {
+ if (name != null) {
myBuilder.append(name).append('=');
}
}
@@ -697,18 +695,34 @@
}
@Nullable
- private static String constToString(@Nullable Object value, boolean isBoolean, boolean anno) {
+ private static String constToString(@Nullable Object value, @Nullable String type, boolean anno) {
if (value == null) return null;
- if (value instanceof String) return "\"" + StringUtil.escapeStringCharacters((String)value) + "\"";
- if (value instanceof Boolean) return value.toString();
- if (value instanceof Long) return value.toString() + "L";
+ if (value instanceof String) {
+ return "\"" + StringUtil.escapeStringCharacters((String)value) + "\"";
+ }
+
+ if (value instanceof Boolean || value instanceof Short || value instanceof Byte) {
+ return value.toString();
+ }
+
+ if (value instanceof Character) {
+ return "'" + StringUtil.escapeCharCharacters(value.toString()) + "'";
+ }
+
+ if (value instanceof Long) {
+ return value.toString() + "L";
+ }
if (value instanceof Integer) {
- if (isBoolean) {
+ if ("boolean".equals(type)) {
if (value.equals(0)) return "false";
if (value.equals(1)) return "true";
}
+ if ("char".equals(type)) {
+ char ch = (char)((Integer)value).intValue();
+ return "'" + StringUtil.escapeCharCharacters(String.valueOf(ch)) + "'";
+ }
return value.toString();
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index 4c799c6..25ff273 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -427,7 +427,9 @@
boolean hasReceiver = false;
final PsiType[] parameterTypes = mySignature.getParameterTypes();
- if (parameterTypes.length > 0 && PsiMethodReferenceUtil.isReceiverType(parameterTypes[0], myContainingClass, mySubstitutor)) {
+ if (parameterTypes.length > 0 &&
+ PsiMethodReferenceUtil.isReceiverType(parameterTypes[0], myContainingClass, mySubstitutor) &&
+ PsiMethodReferenceUtil.isStaticallyReferenced(PsiMethodReferenceExpressionImpl.this)) {
hasReceiver = true;
}
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InLambdaPosition-out.java b/java/java-tests/testData/codeInsight/completion/smartType/InLambdaPosition-out.java
new file mode 100644
index 0000000..8b6864c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/smartType/InLambdaPosition-out.java
@@ -0,0 +1,3 @@
+class Test {
+ Runnable r = () -> <caret>
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/InLambdaPosition.java b/java/java-tests/testData/codeInsight/completion/smartType/InLambdaPosition.java
new file mode 100644
index 0000000..8bda0af
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/smartType/InLambdaPosition.java
@@ -0,0 +1,3 @@
+class Test {
+ Runnable r = <caret>
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ExprReceiver.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ExprReceiver.java
new file mode 100644
index 0000000..f3bc8d4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ExprReceiver.java
@@ -0,0 +1,15 @@
+class ThreadExample {
+ interface Function<T, R> {
+
+ R apply(T t);
+ }
+ {
+ A a = new A();
+ <error descr="Incompatible types. Found: '<method reference>', required: 'ThreadExample.Function<? super ThreadExample.A,? extends java.lang.String>'">Function<? super A,? extends String> foo = a::foo;</error>
+ }
+
+ static class A {
+ public String foo() { return "a"; }
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/modifier/after37.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/modifier/after37.java
new file mode 100644
index 0000000..97dcfd5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/modifier/after37.java
@@ -0,0 +1,8 @@
+// "Make 'a' not abstract" "true"
+import java.io.*;
+
+abstract class A {
+ void a<caret>() {
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/modifier/before37.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/modifier/before37.java
new file mode 100644
index 0000000..6be3122
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/modifier/before37.java
@@ -0,0 +1,8 @@
+// "Make 'a' not abstract" "true"
+import java.io.*;
+
+abstract class A {
+ abstract void a<caret>() {
+ }
+}
+
diff --git a/java/java-tests/testData/codeInsight/generateConstructor/afterFieldPrefixCoincidence1.java b/java/java-tests/testData/codeInsight/generateConstructor/afterFieldPrefixCoincidence1.java
new file mode 100644
index 0000000..29be0de
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generateConstructor/afterFieldPrefixCoincidence1.java
@@ -0,0 +1,7 @@
+class Test {
+ private int _foo;
+
+ Test(int foo) {
+ _foo = foo;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/generateConstructor/beforeFieldPrefixCoincidence1.java b/java/java-tests/testData/codeInsight/generateConstructor/beforeFieldPrefixCoincidence1.java
new file mode 100644
index 0000000..8acd4dc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generateConstructor/beforeFieldPrefixCoincidence1.java
@@ -0,0 +1,4 @@
+class Test {
+ private int _foo;
+ <caret>
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/guarded/itself.java b/java/java-tests/testData/inspection/guarded/itself.java
new file mode 100644
index 0000000..35b7845
--- /dev/null
+++ b/java/java-tests/testData/inspection/guarded/itself.java
@@ -0,0 +1,19 @@
+import net.jcip.annotations.GuardedBy;
+
+import java.lang.String;
+
+class A {
+
+ @GuardedBy("itself")
+ private String _foo;
+
+ public String getFoo() {
+ synchronized (_foo) {
+ return _foo;
+ }
+ }
+
+ public void setFoo(String foo) {
+ <warning descr="Access to field '_foo' outside of declared guards">_foo</warning> = foo;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/localCanBeFinal/LambdaBody/expected.xml b/java/java-tests/testData/inspection/localCanBeFinal/LambdaBody/expected.xml
new file mode 100644
index 0000000..1da1935
--- /dev/null
+++ b/java/java-tests/testData/inspection/localCanBeFinal/LambdaBody/expected.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Junk.java</file>
+ <line>4</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Local variable or parameter can be final</problem_class>
+ <description>Variable <code>i</code> can have <code>final</code> modifier</description>
+ </problem>
+ <problem>
+ <file>Junk.java</file>
+ <line>3</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Local variable or parameter can be final</problem_class>
+ <description>Variable <code>r</code> can have <code>final</code> modifier</description>
+ </problem>
+</problems>
+
diff --git a/java/java-tests/testData/inspection/localCanBeFinal/LambdaBody/src/Junk.java b/java/java-tests/testData/inspection/localCanBeFinal/LambdaBody/src/Junk.java
new file mode 100644
index 0000000..f89a1e2
--- /dev/null
+++ b/java/java-tests/testData/inspection/localCanBeFinal/LambdaBody/src/Junk.java
@@ -0,0 +1,10 @@
+public final class Junk {
+ public void sillyMethod() {
+ Runnable r = () -> {
+ int i = 0;
+ System.out.println(i);
+ };
+ }
+}
+
+
diff --git a/java/java-tests/testData/psi/cls/mirror/Annotations.txt b/java/java-tests/testData/psi/cls/mirror/Annotations.txt
index 9bbe384..58f2792 100644
--- a/java/java-tests/testData/psi/cls/mirror/Annotations.txt
+++ b/java/java-tests/testData/psi/cls/mirror/Annotations.txt
@@ -25,6 +25,9 @@
@pkg.Annotations.A4(ids = {42, 84})
abstract void m4b();
+ @pkg.Annotations.A5(b = true, value = java.lang.Integer.class)
+ abstract void m5();
+
static @interface IndeterminateAnno {
float f1() default -1.0f / 0.0;
@@ -39,6 +42,12 @@
double d3() default 1.0 / 0.0;
}
+ static @interface A5 {
+ boolean b() default false;
+
+ java.lang.Class<? extends java.lang.Number> value() default java.lang.Integer.class;
+ }
+
static @interface A4 {
int[] ids() default {};
}
diff --git a/java/java-tests/testData/psi/cls/mirror/Booleans.txt b/java/java-tests/testData/psi/cls/mirror/Booleans.txt
deleted file mode 100644
index 8def7d9..0000000
--- a/java/java-tests/testData/psi/cls/mirror/Booleans.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
- // IntelliJ API Decompiler stub source generated from a class file
- // Implementation of methods is not available
-
-package pkg;
-
-class Booleans {
- public static final boolean TRUE = true;
- public static final boolean FALSE = false;
-
- Booleans() { /* compiled code */ }
-
- @pkg.BooleanAnno(true)
- public static boolean TRUE() { /* compiled code */ }
-
- @pkg.BooleanAnno(false)
- public static boolean FALSE() { /* compiled code */ }
-}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/mirror/Primitives.txt b/java/java-tests/testData/psi/cls/mirror/Primitives.txt
new file mode 100644
index 0000000..4eb6750d
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/Primitives.txt
@@ -0,0 +1,30 @@
+
+ // IntelliJ API Decompiler stub source generated from a class file
+ // Implementation of methods is not available
+
+package pkg;
+
+class Primitives {
+ public static final boolean TRUE = true;
+ public static final boolean FALSE = false;
+ public static final byte BYTE = 1;
+ public static final char CHAR = '\'';
+ public static final short SHORT = 42;
+ public static final int INT = 42;
+ public static final long LONG = 42L;
+
+ Primitives() { /* compiled code */ }
+
+ @pkg.BooleanAnno(true)
+ public static boolean TRUE() { /* compiled code */ }
+
+ @pkg.BooleanAnno(false)
+ public static boolean FALSE() { /* compiled code */ }
+
+ @pkg.ByteAnno(1)
+ @pkg.CharAnno('\\')
+ @pkg.ShortAnno(42)
+ @pkg.IntAnno(42)
+ @pkg.LongAnno(42L)
+ public static void m() { /* compiled code */ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A1.class b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A1.class
index 6120960..00c4747 100644
--- a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A1.class
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A1.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A2.class b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A2.class
index 8d94afe..96bda0c 100644
--- a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A2.class
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A2.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A3.class b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A3.class
index 630cfd9..c23cb7c 100644
--- a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A3.class
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A3.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A4.class b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A4.class
index 040a84c..e00c95b 100644
--- a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A4.class
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A4.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A5.class b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A5.class
new file mode 100644
index 0000000..b85d9d0
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$A5.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$IndeterminateAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$IndeterminateAnno.class
index d77b499..101bbd2 100644
--- a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$IndeterminateAnno.class
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations$IndeterminateAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations.class b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations.class
index 03f1f52..a5293f0 100644
--- a/java/java-tests/testData/psi/cls/mirror/pkg/Annotations.class
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/Annotations.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/BooleanAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/BooleanAnno.class
index 64ba86f..118a4c4 100644
--- a/java/java-tests/testData/psi/cls/mirror/pkg/BooleanAnno.class
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/BooleanAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Booleans.class b/java/java-tests/testData/psi/cls/mirror/pkg/Booleans.class
deleted file mode 100644
index 1a71ca0..0000000
--- a/java/java-tests/testData/psi/cls/mirror/pkg/Booleans.class
+++ /dev/null
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/ByteAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/ByteAnno.class
new file mode 100644
index 0000000..6250428
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/ByteAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/CharAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/CharAnno.class
new file mode 100644
index 0000000..17e8b67
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/CharAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/IntAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/IntAnno.class
new file mode 100644
index 0000000..e3e7eed
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/IntAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/LongAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/LongAnno.class
new file mode 100644
index 0000000..6314705
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/LongAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Primitives.class b/java/java-tests/testData/psi/cls/mirror/pkg/Primitives.class
new file mode 100644
index 0000000..1e2d9f0
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/Primitives.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/ShortAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/ShortAnno.class
new file mode 100644
index 0000000..e5583b1
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/ShortAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/Annotations.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/Annotations.java
index 5aeda68..dafd4dc 100644
--- a/java/java-tests/testData/psi/cls/mirror/src/pkg/Annotations.java
+++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/Annotations.java
@@ -16,6 +16,11 @@
int[] ids() default { };
}
+ @interface A5 {
+ boolean b() default false;
+ Class<? extends Number> value() default Integer.class;
+ }
+
@A1 abstract void m1();
@A2() abstract void m2a();
@@ -26,6 +31,8 @@
@A4 abstract void m4a();
@A4(ids = {42, 84}) abstract void m4b();
+ @A5(b = true, value = Integer.class) abstract void m5();
+
@interface IndeterminateAnno {
float f1() default Float.NEGATIVE_INFINITY;
float f2() default Float.NaN;
diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/Booleans.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/Booleans.java
deleted file mode 100644
index 495e1ac..0000000
--- a/java/java-tests/testData/psi/cls/mirror/src/pkg/Booleans.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package pkg;
-
-class Booleans {
- public static final boolean TRUE = true;
- public static final boolean FALSE = false;
-
- @BooleanAnno(true) public static boolean TRUE() { return TRUE; }
- @BooleanAnno(false) public static boolean FALSE() { return FALSE; }
-}
-
-@interface BooleanAnno {
- boolean value();
-}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/Primitives.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/Primitives.java
new file mode 100644
index 0000000..4ffcf4a
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/Primitives.java
@@ -0,0 +1,42 @@
+package pkg;
+
+class Primitives {
+ public static final boolean TRUE = true;
+ public static final boolean FALSE = false;
+
+ @BooleanAnno(true) public static boolean TRUE() { return TRUE; }
+ @BooleanAnno(false) public static boolean FALSE() { return FALSE; }
+
+ public static final byte BYTE = 1;
+ public static final char CHAR = '\'';
+ public static final short SHORT = 42;
+ public static final int INT = 42;
+ public static final long LONG = 42L;
+
+ @ByteAnno(1) @CharAnno('\\') @ShortAnno(42) @IntAnno(42) @LongAnno(42L)
+ public static void m() { }
+}
+
+@interface BooleanAnno {
+ boolean value();
+}
+
+@interface ByteAnno {
+ byte value();
+}
+
+@interface CharAnno {
+ char value();
+}
+
+@interface ShortAnno {
+ short value();
+}
+
+@interface IntAnno {
+ int value();
+}
+
+@interface LongAnno {
+ long value();
+}
diff --git a/java/java-tests/testData/psi/cls/stubBuilder/Nullable.txt b/java/java-tests/testData/psi/cls/stubBuilder/Nullable.txt
index 277fe14..5f492a7 100644
--- a/java/java-tests/testData/psi/cls/stubBuilder/Nullable.txt
+++ b/java/java-tests/testData/psi/cls/stubBuilder/Nullable.txt
@@ -2,8 +2,8 @@
PsiClassStub[interface annotation name=Nullable fqn=org.jetbrains.annotations.Nullable]
PsiModifierListStub[mask=1025]
PsiAnnotationStub[@java.lang.annotation.Documented]
- PsiAnnotationStub[@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)]
- PsiAnnotationStub[@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.FIELD,java.lang.annotation.ElementType.PARAMETER,java.lang.annotation.ElementType.LOCAL_VARIABLE})]
+ PsiAnnotationStub[@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.CLASS)]
+ PsiAnnotationStub[@java.lang.annotation.Target(value={java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.FIELD,java.lang.annotation.ElementType.PARAMETER,java.lang.annotation.ElementType.LOCAL_VARIABLE})]
PsiTypeParameterListStub
PsiRefListStub[EXTENDS_LIST:]
PsiRefListStub[IMPLEMENTS_LIST:]
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java b/java/java-tests/testData/refactoring/extractMethod/FromLambdaBody1.java
similarity index 76%
copy from plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java
copy to java/java-tests/testData/refactoring/extractMethod/FromLambdaBody1.java
index 6830246..fcb14a8 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java
+++ b/java/java-tests/testData/refactoring/extractMethod/FromLambdaBody1.java
@@ -13,13 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn.properties;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/12/12
- * Time: 8:40 PM
- */
-public class SvnPropDetailsProvider {
+class Test {
+ public void foo(int ii) {
+ Runnable r = () -> {
+ <selection>System.out.println(ii);</selection>
+ };
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java b/java/java-tests/testData/refactoring/extractMethod/FromLambdaBody1_after.java
similarity index 76%
rename from plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java
rename to java/java-tests/testData/refactoring/extractMethod/FromLambdaBody1_after.java
index 6830246..6debfde 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java
+++ b/java/java-tests/testData/refactoring/extractMethod/FromLambdaBody1_after.java
@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn.properties;
+class Test {
+ public void foo(int ii) {
+ Runnable r = () -> {
+ newMethod(ii);
+ };
+ }
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/12/12
- * Time: 8:40 PM
- */
-public class SvnPropDetailsProvider {
+ private void newMethod(int ii) {
+ System.out.println(ii);
+ }
}
diff --git a/java/java-tests/testData/refactoring/invertBoolean/methodRefs.java b/java/java-tests/testData/refactoring/invertBoolean/methodRefs.java
new file mode 100644
index 0000000..b7477fc
--- /dev/null
+++ b/java/java-tests/testData/refactoring/invertBoolean/methodRefs.java
@@ -0,0 +1,14 @@
+abstract class A{
+ static boolean isB<caret>ool() {
+ return false;
+ }
+
+
+ interface I {
+ boolean b();
+ }
+
+ {
+ I i = A::isBool;
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java
index 3fb5b7c..5ef9e70 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -55,6 +55,11 @@
doTest();
}
+ public void testFieldPrefixCoincidence1() throws Exception {
+ CodeStyleSettingsManager.getInstance(getProject()).getCurrentSettings().FIELD_NAME_PREFIX = "_";
+ doTest();
+ }
+
private void doTest() throws Exception {
doTest(false);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
index 6690708..d626cba 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -83,6 +83,20 @@
assert lookup.focused
}
+ public void testAfterDblColon() {
+ myFixture.configureByText("a.java", """
+ class Foo {
+ void foo() {
+ Runnable::<caret>
+ }
+ }
+ """)
+ type('r')
+ def les = myFixture.lookupElementStrings
+ assert 'run' in les
+ assert lookup.focused
+ }
+
def assertContains(String... items) {
myFixture.assertPreferredCompletionItems(0, items)
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java
index f8ea1ba..c386bd3 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -66,6 +66,10 @@
doTest();
}
+ public void testInLambdaPosition() throws Exception {
+ doTest();
+ }
+
private void doTest() {
configureByFile("/" + getTestName(false) + ".java");
assertNotNull(myItems);
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
index 064b2c3..a1016d7 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
@@ -78,6 +78,7 @@
public void testAbstractMethod() { doTest(); }
public void testMethodRefAcceptance() { doTest(); }
public void testVarargsMethodRef() { doTest(); }
+ public void testExprReceiver() { doTest(); }
public void testTypeParameterWithExtendsList() throws Exception {
doTest();
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/FieldAccessedNotGuardedInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/FieldAccessedNotGuardedInspectionTest.java
new file mode 100644
index 0000000..88fd4ce
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/FieldAccessedNotGuardedInspectionTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2013 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.codeInspection;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.codeInspection.concurrencyAnnotations.FieldAccessNotGuardedInspection;
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import org.jetbrains.annotations.NotNull;
+
+public class FieldAccessedNotGuardedInspectionTest extends LightCodeInsightFixtureTestCase {
+ public void testItself() throws Exception {
+ myFixture.addClass("package net.jcip.annotations;\n" +
+ "@java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD})\n" +
+ "@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)\n" +
+ "public @interface GuardedBy {\n" +
+ " java.lang.String value();\n" +
+ "}");
+ myFixture.testHighlighting(true, false, false, getTestName(true) + ".java");
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myFixture.enableInspections(new FieldAccessNotGuardedInspection());
+ }
+
+ @NotNull
+ @Override
+ protected String getTestDataPath() {
+ return JavaTestUtil.getJavaTestDataPath() + "/inspection/guarded";
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java
index c8e5ecf..7dfa608 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2013 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.codeInspection;
import com.intellij.JavaTestUtil;
@@ -102,4 +117,10 @@
myTool.REPORT_VARIABLES = true;
doTest();
}
+
+ public void testLambdaBody() throws Exception {
+ myTool.REPORT_PARAMETERS = true;
+ myTool.REPORT_VARIABLES = true;
+ doTest();
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
index 65092f2..e579fbb 100644
--- a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
+++ b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
@@ -32,6 +32,7 @@
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.testFramework.IdeaTestUtil;
+import com.intellij.testFramework.LightVirtualFile;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.fixtures.TempDirTestFixture;
@@ -434,5 +435,116 @@
}
}
+ public void testFindInCommentsAndLiterals() throws Exception{
+ FindManager findManager = FindManager.getInstance(myProject);
+ FindModel findModel = new FindModel();
+ findModel.setStringToFind("done");
+ findModel.setWholeWordsOnly(false);
+ findModel.setFromCursor(false);
+ findModel.setGlobal(true);
+ findModel.setMultipleFiles(false);
+ findModel.setProjectScope(true);
+
+ String text = "\"done done done\" /* done done done */";
+
+ runFindInCommentsAndLiterals(findManager, findModel, text);
+
+ findModel.setRegularExpressions(true);
+ runFindInCommentsAndLiterals(findManager, findModel, text);
+ }
+
+ private static void runFindInCommentsAndLiterals(FindManager findManager, FindModel findModel, String text) {
+ runFindInCommentsAndLiterals(findManager, findModel, text, "java");
+ }
+
+ private static void runFindInCommentsAndLiterals(FindManager findManager,
+ FindModel findModel,
+ String text,
+ String ext) {
+ findModel.setInStringLiteralsOnly(true);
+ findModel.setInCommentsOnly(false);
+ runFindForwardAndBackward(findManager, findModel, text, ext);
+
+ findModel.setInStringLiteralsOnly(false);
+ findModel.setInCommentsOnly(true);
+ runFindForwardAndBackward(findManager, findModel, text, ext);
+ }
+
+ private static void runFindForwardAndBackward(FindManager findManager, FindModel findModel, String text) {
+ runFindForwardAndBackward(findManager, findModel, text, "java");
+ }
+
+ private static void runFindForwardAndBackward(FindManager findManager, FindModel findModel, String text, String ext) {
+ findModel.setForward(true);
+ LightVirtualFile file = new LightVirtualFile("A."+ext, text);
+ int prevousOffset;
+
+ FindResult findResult = findManager.findString(text, 0, findModel, file);
+ assertTrue(findResult.isStringFound());
+ prevousOffset = findResult.getStartOffset();
+
+ findResult = findManager.findString(text, findResult.getEndOffset(), findModel, file);
+ assertTrue(findResult.isStringFound());
+ assertTrue(findResult.getStartOffset() > prevousOffset);
+ prevousOffset = findResult.getStartOffset();
+
+ findResult = findManager.findString(text, findResult.getEndOffset(), findModel, file);
+ assertTrue(findResult.isStringFound());
+ assertTrue(findResult.getStartOffset() > prevousOffset);
+
+ findModel.setForward(false);
+
+ findResult = findManager.findString(text, text.length(), findModel, file);
+ assertTrue(findResult.isStringFound());
+ prevousOffset = findResult.getStartOffset();
+
+ findResult = findManager.findString(text, prevousOffset, findModel, file);
+ assertTrue(findResult.isStringFound());
+ assertTrue(prevousOffset > findResult.getStartOffset() );
+
+ prevousOffset = findResult.getStartOffset();
+
+ findResult = findManager.findString(text, prevousOffset, findModel, file);
+ assertTrue(findResult.isStringFound());
+ assertTrue(prevousOffset > findResult.getStartOffset() );
+ }
+
+ public void testFindInJavaDocs() throws Exception{
+ FindManager findManager = FindManager.getInstance(myProject);
+
+ FindModel findModel = new FindModel();
+ findModel.setStringToFind("done");
+ findModel.setWholeWordsOnly(false);
+ findModel.setFromCursor(false);
+ findModel.setGlobal(true);
+ findModel.setMultipleFiles(false);
+ findModel.setProjectScope(true);
+
+ String text = "/** done done done */";
+
+ findModel.setInCommentsOnly(true);
+ runFindForwardAndBackward(findManager, findModel, text);
+
+ findModel.setRegularExpressions(true);
+ runFindForwardAndBackward(findManager, findModel, text);
+ }
+
+ public void testFindInUserFileType() throws Exception{
+ FindManager findManager = FindManager.getInstance(myProject);
+
+ FindModel findModel = new FindModel();
+ findModel.setStringToFind("done");
+ findModel.setWholeWordsOnly(false);
+ findModel.setFromCursor(false);
+ findModel.setGlobal(true);
+ findModel.setMultipleFiles(false);
+ findModel.setProjectScope(true);
+
+ String text = "\"done done\"; 'done'; // done\n" +
+ "/* done\n" +
+ "done */";
+
+ runFindInCommentsAndLiterals(findManager, findModel, text, "cs");
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
index 0217607..a7deee8 100644
--- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
@@ -40,7 +40,7 @@
public void testMethodReceiver() { doTest(); }
public void testPackageInfo() { doTest("package-info"); }
public void testEA40568() { doTest(); }
- public void testBooleans() { doTest(); }
+ public void testPrimitives() { doTest(); }
public void testClassRefs() { doTest(); }
public void testEA46236() { doTest("ValuedEnum"); }
diff --git a/java/java-tests/testSrc/com/intellij/psi/CoreJavaFileManagerTest.java b/java/java-tests/testSrc/com/intellij/psi/CoreJavaFileManagerTest.java
index 1cd630c..5c12aff 100644
--- a/java/java-tests/testSrc/com/intellij/psi/CoreJavaFileManagerTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/CoreJavaFileManagerTest.java
@@ -22,26 +22,35 @@
import com.intellij.testFramework.PsiTestCase;
import com.intellij.testFramework.PsiTestUtil;
+import java.util.LinkedList;
+import java.util.Queue;
+
public class CoreJavaFileManagerTest extends PsiTestCase {
- public void testNotNullInnerClass() throws Exception {
+ private VirtualFile prepareClasses(String clazzName, String clazzData) throws Exception {
VirtualFile root = PsiTestUtil.createTestProjectStructure(myProject, myModule, myFilesToDelete);
VirtualFile pkg = root.createChildDirectory(this, "foo");
PsiDirectory dir = myPsiManager.findDirectory(pkg);
assertNotNull(dir);
+ dir.add(PsiFileFactory.getInstance(getProject()).createFileFromText(clazzName + ".java", JavaFileType.INSTANCE, clazzData));
+ return root;
+ }
+
+ public void testNotNullInnerClass() throws Exception {
String text = "package foo;\n\n" +
"public class Nested {\n" +
"public class InnerGeneral {}\n" +
- "public class Inner$ {}\n" +
+ "public class Inner$ {" +
+ "}\n" +
"\n" +
"public Inner$ inner() {\n" +
" return new Inner$();\n" +
"}\n" +
"\n" +
"}";
- PsiElement created = dir.add(PsiFileFactory.getInstance(getProject()).createFileFromText("Nested.java", JavaFileType.INSTANCE, text));
+ VirtualFile root = prepareClasses("Nested", text);
GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
CoreJavaFileManager manager = new CoreJavaFileManager(myPsiManager);
manager.addToClasspath(root);
@@ -65,4 +74,90 @@
assertNull(clazzInner$Wrong3);
}
+
+ public void testNotNullInnerClass2() throws Exception {
+ String text = "package foo;\n\n" +
+ "public class Nested {\n" +
+
+ "public class Inner {" +
+ " public class XInner{}" +
+ " public class XInner${}" +
+ "}\n" +
+ "public class Inner$ {" +
+ " public class XInner{}" +
+ " public class XInner${}" +
+ "}\n" +
+ "\n" +
+ "}";
+
+ VirtualFile root = prepareClasses("Nested", text);
+ GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
+ CoreJavaFileManager manager = new CoreJavaFileManager(myPsiManager);
+ manager.addToClasspath(root);
+
+ PsiClass clazzInner = manager.findClass("foo.Nested.Inner", scope);
+ assertNotNull(clazzInner);
+
+ PsiClass clazzXInner = manager.findClass("foo.Nested.Inner.XInner", scope);
+ assertNotNull(clazzXInner);
+
+ PsiClass clazzXInner$ = manager.findClass("foo.Nested.Inner.XInner$", scope);
+ assertNotNull(clazzXInner$);
+
+ PsiClass clazz$XInner = manager.findClass("foo.Nested.Inner$.XInner", scope);
+ assertNotNull(clazz$XInner);
+
+ PsiClass clazz$XInner$ = manager.findClass("foo.Nested.Inner$.XInner$", scope);
+ assertNotNull(clazz$XInner$);
+ }
+
+
+ public void testNotNullInnerClass3() throws Exception {
+ String text = "package foo;\n\n" +
+ "public class NestedX {\n" +
+
+ "public class XX {" +
+ " public class XXX{" +
+ " public class XXXX{ }" +
+ " public class XXXX${ }" +
+ " }" +
+ " public class XXX${" +
+ " public class XXXX{ }" +
+ " public class XXXX${ }" +
+ " }" +
+ "}\n" +
+ "public class XX$ {" +
+ " public class XXX{" +
+ " public class XXXX{ }" +
+ " public class XXXX${ }" +
+ " }" +
+ " public class XXX${" +
+ " public class XXXX{ }" +
+ " public class XXXX${ }" +
+ " }" +
+ "}\n" +
+ "\n" +
+ "}";
+
+ VirtualFile root = prepareClasses("NestedX", text);
+ GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
+ CoreJavaFileManager manager = new CoreJavaFileManager(myPsiManager);
+ manager.addToClasspath(root);
+
+ Queue<String> queue = new LinkedList<String>();
+ queue.add("foo.NestedX");
+
+ while(!queue.isEmpty()) {
+ String head = queue.remove();
+ PsiClass clazzInner = manager.findClass(head, scope);
+ assertNotNull(head, clazzInner);
+ String lastSegment = head.substring(head.lastIndexOf('.'));
+ String xs = lastSegment.substring(lastSegment.indexOf("X")).replace("$", "");
+ if (xs.length() < 4) {
+ queue.add(head + "." + xs + "X");
+ queue.add(head + "." + xs + "X$");
+ }
+ }
+ }
+
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
index b566465..0700225 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
@@ -547,6 +547,10 @@
doTest();
}
+ public void testFromLambdaBody1() throws Exception {
+ doTest();
+ }
+
public void testOneLineLambda() throws Exception {
doTest();
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InvertBooleanTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InvertBooleanTest.java
index 236ac1a..1755770 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/InvertBooleanTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/InvertBooleanTest.java
@@ -30,6 +30,15 @@
public void testInnerClasses() throws Exception {doTest();}
public void testAnonymousClasses() throws Exception {doTest();}
+ public void testMethodRefs() throws Exception {
+ try {
+ doTest();
+ fail("Conflict expected.");
+ }
+ catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
+ assertEquals("Method is used in method reference expression", e.getMessage());
+ }
+ }
private void doTest() throws Exception {
configureByFile(TEST_ROOT + getTestName(true) + ".java");
diff --git a/java/java-tests/testSrc/com/intellij/roots/ManagingContentRootsTest.java b/java/java-tests/testSrc/com/intellij/roots/ManagingContentRootsTest.java
index b0ed71e..d6468e3 100644
--- a/java/java-tests/testSrc/com/intellij/roots/ManagingContentRootsTest.java
+++ b/java/java-tests/testSrc/com/intellij/roots/ManagingContentRootsTest.java
@@ -83,7 +83,7 @@
assertEquals(root, findContentEntry(url).getFile());
}
- public void testGettingMofifiableModelCorrectlySetsRootModelForContentEntries() throws Exception {
+ public void testGettingModifiableModelCorrectlySetsRootModelForContentEntries() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
diff --git a/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
index 5dca4c34..b422156 100644
--- a/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
+++ b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
@@ -31,38 +31,53 @@
return ServiceManager.getService(QuickFixFactory.class);
}
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createModifierListFix(@NotNull PsiModifierList modifierList,
@PsiModifier.ModifierConstant @NotNull String modifier,
boolean shouldHave,
final boolean showContainingClass);
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createModifierListFix(@NotNull PsiModifierListOwner owner,
@PsiModifier.ModifierConstant @NotNull String modifier,
boolean shouldHave,
final boolean showContainingClass);
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createMethodReturnFix(@NotNull PsiMethod method, @NotNull PsiType toReturn, boolean fixWholeHierarchy);
-
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddMethodFix(@NotNull PsiMethod method, @NotNull PsiClass toClass);
- public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddMethodFix(@NotNull String methodText, @NotNull PsiClass toClass, String... exceptions);
+ @NotNull
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddMethodFix(@NotNull String methodText, @NotNull PsiClass toClass, @NotNull String... exceptions);
/**
* @param psiElement psiClass or enum constant without class initializer
*/
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createImplementMethodsFix(@NotNull PsiElement psiElement);
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createImplementMethodsFix(@NotNull PsiClass psiElement);
+ @NotNull
public abstract LocalQuickFixOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method, @NotNull PsiClassType exceptionClass, boolean shouldThrow, boolean showContainingClass);
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddDefaultConstructorFix(@NotNull PsiClass aClass);
@Nullable
- public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddConstructorFix(@NotNull PsiClass aClass, @PsiModifier.ModifierConstant String modifier);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddConstructorFix(@NotNull PsiClass aClass, @PsiModifier.ModifierConstant @NotNull String modifier);
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createMethodParameterTypeFix(@NotNull PsiMethod method, int index, @NotNull PsiType newType, boolean fixWholeHierarchy);
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createMakeClassInterfaceFix(@NotNull PsiClass aClass);
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createMakeClassInterfaceFix(@NotNull PsiClass aClass, final boolean makeInterface);
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createExtendsListFix(@NotNull PsiClass aClass, @NotNull PsiClassType typeToExtendFrom, boolean toAdd);
+ @NotNull
public abstract LocalQuickFixAndIntentionActionOnPsiElement createRemoveUnusedParameterFix(@NotNull PsiParameter parameter);
+ @NotNull
public abstract IntentionAction createRemoveUnusedVariableFix(@NotNull PsiVariable variable);
@Nullable
public abstract IntentionAction createCreateClassOrPackageFix(@NotNull PsiElement context, @NotNull String qualifiedName, final boolean createClass, final String superClass);
@Nullable
public abstract IntentionAction createCreateClassOrInterfaceFix(@NotNull PsiElement context, @NotNull String qualifiedName, final boolean createClass, final String superClass);
- public abstract IntentionAction createCreateFieldOrPropertyFix(final PsiClass aClass, final String name, final PsiType type, final PropertyMemberType targetMember, final PsiAnnotation... annotations);
+ @NotNull
+ public abstract IntentionAction createCreateFieldOrPropertyFix(@NotNull PsiClass aClass, @NotNull String name, @NotNull PsiType type, @NotNull PropertyMemberType targetMember, @NotNull PsiAnnotation... annotations);
}
diff --git a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java
index 88a5c55..51ae01f 100644
--- a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java
+++ b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java
@@ -25,7 +25,7 @@
import java.io.File;
public abstract class JavaSdk extends SdkType implements JavaSdkType, ApplicationComponent {
- public JavaSdk(@NonNls String name) {
+ public JavaSdk(@NotNull @NonNls String name) {
super(name);
}
diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
index cfd68e9..03ec968 100644
--- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
+++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
@@ -139,11 +139,11 @@
return configureByFile(vFile, projectFile);
}
- protected PsiFile configureByText(final FileType fileType, @NonNls final String text) throws Exception {
+ protected PsiFile configureByText(@NotNull FileType fileType, @NonNls final String text) throws Exception {
return configureByText(fileType, text, null);
}
- protected PsiFile configureByText(final FileType fileType, @NonNls final String text, @Nullable String _extension) throws Exception {
+ protected PsiFile configureByText(@NotNull final FileType fileType, @NonNls final String text, @Nullable String _extension) throws Exception {
final String extension = _extension == null ? fileType.getDefaultExtension():_extension;
File dir = createTempDirectory();
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java
index 83b1ce2..fdc84ab 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java
@@ -16,6 +16,8 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.DataInputOutputUtil;
+import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Opcodes;
@@ -235,7 +237,7 @@
this.myContext = context;
myFileName = fn;
mySuperClass = TypeRepr.createClassType(context, sup);
- myInterfaces = (Set<TypeRepr.AbstractType>)TypeRepr.createClassType(context, i, new HashSet<TypeRepr.AbstractType>());
+ myInterfaces = (Set<TypeRepr.AbstractType>)TypeRepr.createClassType(context, i, new THashSet<TypeRepr.AbstractType>(1));
myFields = f;
myMethods = m;
this.myAnnotationTargets = targets;
@@ -250,41 +252,45 @@
super(in);
try {
this.myContext = context;
- myFileName = in.readInt();
+ myFileName = DataInputOutputUtil.readINT(in);
mySuperClass = (TypeRepr.ClassType)TypeRepr.externalizer(context).read(in);
- myInterfaces = (Set<TypeRepr.AbstractType>)RW.read(TypeRepr.externalizer(context), new HashSet<TypeRepr.AbstractType>(), in);
- myFields = (Set<FieldRepr>)RW.read(FieldRepr.externalizer(context), new HashSet<FieldRepr>(), in);
- myMethods = (Set<MethodRepr>)RW.read(MethodRepr.externalizer(context), new HashSet<MethodRepr>(), in);
+ myInterfaces = (Set<TypeRepr.AbstractType>)RW.read(TypeRepr.externalizer(context), new THashSet<TypeRepr.AbstractType>(1), in);
+ myFields = (Set<FieldRepr>)RW.read(FieldRepr.externalizer(context), new THashSet<FieldRepr>(), in);
+ myMethods = (Set<MethodRepr>)RW.read(MethodRepr.externalizer(context), new THashSet<MethodRepr>(), in);
myAnnotationTargets = (Set<ElemType>)RW.read(UsageRepr.AnnotationUsage.elementTypeExternalizer, EnumSet.noneOf(ElemType.class), in);
- final String s = in.readUTF();
+ final String s = RW.readUTF(in);
myRetentionPolicy = s.length() == 0 ? null : RetentionPolicy.valueOf(s);
- myOuterClassName = in.readInt();
- myIsLocal = in.readBoolean();
- myIsAnonymous = in.readBoolean();
- myUsages =(Set<UsageRepr.Usage>)RW.read(UsageRepr.externalizer(context), new HashSet<UsageRepr.Usage>(), in);
+ myOuterClassName = DataInputOutputUtil.readINT(in);
+ int flags = DataInputOutputUtil.readINT(in);
+ myIsLocal = (flags & LOCAL_MASK) != 0;
+ myIsAnonymous = (flags & ANONYMOUS_MASK) != 0;
+ myUsages =(Set<UsageRepr.Usage>)RW.read(UsageRepr.externalizer(context), new THashSet<UsageRepr.Usage>(), in);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
+ private static final int LOCAL_MASK = 1;
+ private static final int ANONYMOUS_MASK = 2;
+
@Override
public void save(final DataOutput out) {
try {
super.save(out);
- out.writeInt(myFileName);
+ DataInputOutputUtil.writeINT(out, myFileName);
mySuperClass.save(out);
RW.save(myInterfaces, out);
RW.save(myFields, out);
RW.save(myMethods, out);
RW.save(myAnnotationTargets, UsageRepr.AnnotationUsage.elementTypeExternalizer, out);
- out.writeUTF(myRetentionPolicy == null ? "" : myRetentionPolicy.toString());
- out.writeInt(myOuterClassName);
- out.writeBoolean(myIsLocal);
- out.writeBoolean(myIsAnonymous);
+ RW.writeUTF(out, myRetentionPolicy == null ? "" : myRetentionPolicy.toString());
+ DataInputOutputUtil.writeINT(out, myOuterClassName);
+ DataInputOutputUtil.writeINT(out, (myIsLocal ? LOCAL_MASK:0) | (myIsAnonymous ? ANONYMOUS_MASK : 0));
+
RW.save(myUsages, UsageRepr.externalizer(myContext), out);
}
catch (IOException e) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java
index ebcb39a..98dffab 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java
@@ -16,6 +16,8 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.openapi.util.Pair;
+import gnu.trove.THashMap;
+import gnu.trove.THashSet;
import gnu.trove.TIntHashSet;
import org.jetbrains.asm4.*;
import org.jetbrains.asm4.signature.SignatureReader;
@@ -302,14 +304,14 @@
myAnonymousClassFlag.set(false);
}
- private final Set<MethodRepr> myMethods = new HashSet<MethodRepr>();
- private final Set<FieldRepr> myFields = new HashSet<FieldRepr>();
- private final Set<UsageRepr.Usage> myUsages = new HashSet<UsageRepr.Usage>();
+ private final Set<MethodRepr> myMethods = new THashSet<MethodRepr>();
+ private final Set<FieldRepr> myFields = new THashSet<FieldRepr>();
+ private final Set<UsageRepr.Usage> myUsages = new THashSet<UsageRepr.Usage>();
private final Set<ElemType> myTargets = EnumSet.noneOf(ElemType.class);
private RetentionPolicy myRetentionPolicy = null;
- final Map<TypeRepr.ClassType, TIntHashSet> myAnnotationArguments = new HashMap<TypeRepr.ClassType, TIntHashSet>();
- final Map<TypeRepr.ClassType, Set<ElemType>> myAnnotationTargets = new HashMap<TypeRepr.ClassType, Set<ElemType>>();
+ final Map<TypeRepr.ClassType, TIntHashSet> myAnnotationArguments = new THashMap<TypeRepr.ClassType, TIntHashSet>();
+ final Map<TypeRepr.ClassType, Set<ElemType>> myAnnotationTargets = new THashMap<TypeRepr.ClassType, Set<ElemType>>();
public ClassCrawler(final int fn) {
super(Opcodes.ASM4);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMaplet.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMaplet.java
deleted file mode 100644
index 3488352..0000000
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMaplet.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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 org.jetbrains.jps.builders.java.dependencyView;
-
-import com.intellij.util.Processor;
-import com.intellij.util.containers.SLRUCache;
-import com.intellij.util.io.DataExternalizer;
-import com.intellij.util.io.KeyDescriptor;
-import com.intellij.util.io.PersistentHashMap;
-import gnu.trove.TIntIntProcedure;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * @author: db
- * Date: 05.11.11
- */
-public class IntIntPersistentMaplet extends IntIntMaplet {
- private static final Object NULL_OBJ = new Object();
- private static final int CACHE_SIZE = 512;
- private final PersistentHashMap<Integer, Integer> myMap;
- private final SLRUCache<Integer, Object> myCache;
-
- public IntIntPersistentMaplet(final File file, final KeyDescriptor<Integer> k) {
- try {
- myMap = new PersistentHashMap<Integer, Integer>(file, k, new DataExternalizer<Integer>() {
- @Override
- public void save(DataOutput out, Integer value) throws IOException {
- out.writeInt(value);
- }
-
- @Override
- public Integer read(DataInput in) throws IOException {
- return in.readInt();
- }
- });
- myCache = new SLRUCache<Integer, Object>(CACHE_SIZE, CACHE_SIZE) {
- @NotNull
- @Override
- public Object createValue(Integer key) {
- try {
- final Integer v1 = myMap.get(key);
- return v1 == null? NULL_OBJ : v1;
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- };
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public boolean containsKey(final int key) {
- try {
- return myMap.containsMapping(key);
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int get(final int key) {
- final Object obj = myCache.get(key);
- return obj == NULL_OBJ? 0 : (Integer)obj;
- }
-
- @Override
- public void put(final int key, final int value) {
- try {
- myCache.remove(key);
- myMap.put(key, value);
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void putAll(final IntIntMaplet m) {
- m.forEachEntry(new TIntIntProcedure() {
- @Override
- public boolean execute(int key, int value) {
- put(key, value);
- return true;
- }
- });
- }
-
- @Override
- public void remove(final int key) {
- try {
- myCache.remove(key);
- myMap.remove(key);
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void close() {
- try {
- myCache.clear();
- myMap.close();
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- public void flush(boolean memoryCachesOnly) {
- if (memoryCachesOnly) {
- if (myMap.isDirty()) {
- myMap.dropMemoryCaches();
- }
- }
- else {
- myMap.force();
- }
- }
-
- @Override
- public void forEachEntry(final TIntIntProcedure proc) {
- try {
- myMap.processKeysWithExistingMapping(new Processor<Integer>() {
- @Override
- public boolean process(Integer key) {
- try {
- final Integer value = myMap.get(key);
- return value == null? proc.execute(key, -1) : proc.execute(key, value);
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- });
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMultiMaplet.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMultiMaplet.java
index 1d724cf..f37ce8f 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMultiMaplet.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/IntIntPersistentMultiMaplet.java
@@ -19,6 +19,7 @@
import com.intellij.util.Processor;
import com.intellij.util.containers.SLRUCache;
import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.DataInputOutputUtil;
import com.intellij.util.io.KeyDescriptor;
import com.intellij.util.io.PersistentHashMap;
import gnu.trove.TIntHashSet;
@@ -98,7 +99,7 @@
@Override
public boolean execute(int value) {
try {
- out.writeInt(value);
+ DataInputOutputUtil.writeINT(out, value);
}
catch (IOException e) {
exRef.set(e);
@@ -125,7 +126,7 @@
myCache.remove(key);
myMap.appendData(key, new PersistentHashMap.ValueDataAppender() {
public void append(final DataOutput out) throws IOException {
- out.writeInt(value);
+ DataInputOutputUtil.writeINT(out, value);
}
});
}
@@ -260,7 +261,7 @@
@Override
public boolean execute(int elem) {
try {
- out.writeInt(elem);
+ DataInputOutputUtil.writeINT(out, elem);
}
catch (IOException e) {
exRef.set(e);
@@ -280,7 +281,7 @@
final TIntHashSet result = new TIntHashSet();
final DataInputStream stream = (DataInputStream)in;
while (stream.available() > 0) {
- result.add(in.readInt());
+ result.add(DataInputOutputUtil.readINT(in));
}
return result;
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
index f81f6c1..346b65b 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
@@ -52,7 +52,8 @@
private static final float DEFAULT_SET_LOAD_FACTOR = 0.98f;
private static final CollectionFactory<ClassRepr> ourClassSetConstructor = new CollectionFactory<ClassRepr>() {
public Set<ClassRepr> create() {
- return new HashSet<ClassRepr>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
+ // for IDEA codebase on average there is no more than 2.5 classes out of one source file, so we use smaller estimate
+ return new THashSet<ClassRepr>(5, DEFAULT_SET_LOAD_FACTOR);
}
};
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java
index 62d8118..b358e11 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java
@@ -16,16 +16,15 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.DataInputOutputUtil;
+import gnu.trove.THashSet;
import org.jetbrains.asm4.Type;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.PrintStream;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.*;
/**
* @author: db
@@ -127,7 +126,9 @@
final String[] e,
final Object value) {
super(a, s, n, TypeRepr.getType(context, Type.getReturnType(d)), value);
- myExceptions = (Set<TypeRepr.AbstractType>)TypeRepr.createClassType(context, e, new HashSet<TypeRepr.AbstractType>());
+ Set<TypeRepr.AbstractType> typeCollection =
+ e != null ? new THashSet<TypeRepr.AbstractType>(e.length) : Collections.<TypeRepr.AbstractType>emptySet();
+ myExceptions = (Set<TypeRepr.AbstractType>)TypeRepr.createClassType(context, e, typeCollection);
myArgumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(d));
}
@@ -135,9 +136,9 @@
super(context, in);
try {
final DataExternalizer<TypeRepr.AbstractType> externalizer = TypeRepr.externalizer(context);
- final int size = in.readInt();
+ final int size = DataInputOutputUtil.readINT(in);
myArgumentTypes = RW.read(externalizer, in, new TypeRepr.AbstractType[size]);
- myExceptions = (Set<TypeRepr.AbstractType>)RW.read(externalizer, new HashSet<TypeRepr.AbstractType>(), in);
+ myExceptions = (Set<TypeRepr.AbstractType>)RW.read(externalizer, new THashSet<TypeRepr.AbstractType>(0), in);
}
catch (IOException e) {
throw new RuntimeException(e);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Proto.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Proto.java
index 593128e..62e0ebf 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Proto.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Proto.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.jps.builders.java.dependencyView;
+import com.intellij.util.io.DataInputOutputUtil;
import org.jetbrains.asm4.Opcodes;
import java.io.DataInput;
@@ -39,9 +40,9 @@
protected Proto(final DataInput in) {
try {
- access = in.readInt();
- signature = in.readInt();
- name = in.readInt();
+ access = DataInputOutputUtil.readINT(in);
+ signature = DataInputOutputUtil.readINT(in);
+ name = DataInputOutputUtil.readINT(in);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -51,9 +52,9 @@
@Override
public void save(final DataOutput out) {
try {
- out.writeInt(access);
- out.writeInt(signature);
- out.writeInt(name);
+ DataInputOutputUtil.writeINT(out, access);
+ DataInputOutputUtil.writeINT(out, signature);
+ DataInputOutputUtil.writeINT(out, name);
}
catch (IOException e) {
throw new RuntimeException(e);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ProtoMember.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ProtoMember.java
index ff430e0..fb3cb47 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ProtoMember.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ProtoMember.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.jps.builders.java.dependencyView;
+import com.intellij.util.io.DataInputOutputUtil;
import org.jetbrains.asm4.Type;
import java.io.DataInput;
@@ -52,11 +53,11 @@
try {
switch (in.readByte()) {
case STRING:
- return in.readUTF();
+ return RW.readUTF(in);
case NONE:
return null;
case INTEGER:
- return in.readInt();
+ return DataInputOutputUtil.readINT(in);
case LONG:
return in.readLong();
case FLOAT:
@@ -64,7 +65,7 @@
case DOUBLE:
return in.readDouble();
case TYPE :
- return Type.getType(in.readUTF());
+ return Type.getType(RW.readUTF(in));
}
}
catch (IOException e) {
@@ -94,11 +95,12 @@
try {
if (myValue instanceof String) {
out.writeByte(STRING);
- out.writeUTF((String)myValue);
+ String value = (String)myValue;
+ RW.writeUTF(out, value);
}
else if (myValue instanceof Integer) {
out.writeByte(INTEGER);
- out.writeInt(((Integer)myValue).intValue());
+ DataInputOutputUtil.writeINT(out, ((Integer)myValue).intValue());
}
else if (myValue instanceof Long) {
out.writeByte(LONG);
@@ -114,7 +116,7 @@
}
else if (myValue instanceof Type) {
out.writeByte(TYPE);
- out.writeUTF(((Type)myValue).getDescriptor());
+ RW.writeUTF(out, ((Type)myValue).getDescriptor());
}
else {
out.writeByte(NONE);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/RW.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/RW.java
index 4387181..f9d32b0 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/RW.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/RW.java
@@ -16,6 +16,8 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.DataInputOutputUtil;
+import com.intellij.util.io.IOUtil;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
@@ -27,17 +29,31 @@
* Date: 29.01.11
*/
public class RW {
+ private static final byte[] ourStringBuffer = IOUtil.allocReadWriteUTFBuffer();
+
private RW() {
}
+ protected static String readUTF(DataInput in) throws IOException {
+ synchronized (ourStringBuffer) {
+ return IOUtil.readUTFFast(ourStringBuffer, in);
+ }
+ }
+
+ protected static void writeUTF(DataOutput out, String value) throws IOException {
+ synchronized (ourStringBuffer) {
+ IOUtil.writeUTFFast(ourStringBuffer, out, value);
+ }
+ }
+
public interface Savable {
void save(DataOutput out);
}
public static <X extends Savable> void save(final X[] x, final DataOutput out) {
try {
- out.writeInt(x.length);
+ DataInputOutputUtil.writeINT(out, x.length);
for (Savable s : x) {
s.save(out);
}
@@ -49,12 +65,12 @@
public static <X> void save(final TIntHashSet x, final DataOutput out) {
try {
- out.writeInt(x.size());
+ DataInputOutputUtil.writeINT(out, x.size());
x.forEach(new TIntProcedure() {
@Override
public boolean execute(int value) {
try {
- out.writeInt(value);
+ DataInputOutputUtil.writeINT(out, value);
return true;
}
catch (IOException e) {
@@ -70,7 +86,7 @@
public static <X> void save(final Collection<X> x, final DataExternalizer<X> e, final DataOutput out) {
try {
- out.writeInt(x.size());
+ DataInputOutputUtil.writeINT(out, x.size());
for (X y : x) {
e.save(out, y);
@@ -85,7 +101,7 @@
try {
final int size = x.size();
- out.writeInt(size);
+ DataInputOutputUtil.writeINT(out, size);
for (X s : x) {
s.save(out);
@@ -111,10 +127,10 @@
public static TIntHashSet read(final TIntHashSet acc, final DataInput in) {
try {
- final int size = in.readInt();
+ final int size = DataInputOutputUtil.readINT(in);
for (int i = 0; i<size; i++) {
- acc.add(in.readInt());
+ acc.add(DataInputOutputUtil.readINT(in));
}
return acc;
@@ -126,7 +142,7 @@
public static <X> Collection<X> read(final DataExternalizer<X> e, final Collection<X> acc, final DataInput in) {
try {
- final int size = in.readInt();
+ final int size = DataInputOutputUtil.readINT(in);
for (int i = 0; i<size; i++) {
acc.add(e.read(in));
@@ -143,32 +159,6 @@
void write(BufferedWriter w);
}
- public static <T extends Comparable> void writeln(final BufferedWriter w, final Collection<T> c, final ToWritable<T> t) {
- if (c == null) {
- writeln(w, "0");
- return;
- }
-
- writeln(w, Integer.toString(c.size()));
-
- for (T e : c) {
- t.convert(e).write(w);
- }
- }
-
- public static void writeln(final BufferedWriter w, final Collection<? extends Writable> c) {
- if (c == null) {
- writeln(w, "0");
- return;
- }
-
- writeln(w, Integer.toString(c.size()));
-
- for (Writable e : c) {
- e.write(w);
- }
- }
-
public interface ToWritable<T> {
Writable convert(T x);
}
@@ -202,51 +192,6 @@
}
};
- public static Reader<String> myStringReader = new Reader<String>() {
- public String read(final BufferedReader r) {
- try {
- return r.readLine();
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- };
-
- public static <T> Collection<T> readMany(final BufferedReader r, final Reader<T> c, final Collection<T> acc) {
- final int size = readInt(r);
-
- for (int i = 0; i < size; i++) {
- acc.add(c.read(r));
- }
-
- return acc;
- }
-
- public static String lookString(final BufferedReader r) {
- try {
- r.mark(256);
- final String s = r.readLine();
- r.reset();
-
- return s;
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static void readTag(final BufferedReader r, final String tag) {
- try {
- final String s = r.readLine();
-
- if (!s.equals(tag)) System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\"");
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
public static String readString(final BufferedReader r) {
try {
return r.readLine();
@@ -267,31 +212,4 @@
return 0;
}
}
-
- public static int readInt(final BufferedReader r) {
- final String s = readString(r);
-
- try {
- return Integer.parseInt(s);
- }
- catch (Exception n) {
- System.err.println("Parsing error: expected integer, but found \"" + s + "\"");
- return 0;
- }
- }
-
- public static String readStringAttribute(final BufferedReader r, final String tag) {
- try {
- final String s = r.readLine();
-
- if (s.startsWith(tag)) return s.substring(tag.length());
-
- System.err.println("Parsing error: expected \"" + tag + "\", but found \"" + s + "\"");
-
- return null;
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java
index 3a9fb53..b341eae 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java
@@ -17,6 +17,7 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.DataInputOutputUtil;
import org.jetbrains.asm4.Type;
import java.io.DataInput;
@@ -64,7 +65,7 @@
public void save(final DataOutput out) {
try {
out.writeByte(PRIMITIVE_TYPE);
- out.writeInt(type);
+ DataInputOutputUtil.writeINT(out, type);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -77,7 +78,7 @@
PrimitiveType(final DataInput in) {
try {
- type = in.readInt();
+ type = DataInputOutputUtil.readINT(in);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -175,8 +176,8 @@
ClassType(final DependencyContext context, final DataInput in) {
try {
- className = in.readInt();
- final int size = in.readInt();
+ className = DataInputOutputUtil.readINT(in);
+ final int size = DataInputOutputUtil.readINT(in);
if (size == 0) {
typeArgs = EMPTY_TYPE_ARRAY;
}
@@ -217,8 +218,8 @@
public void save(final DataOutput out) {
try {
out.writeByte(CLASS_TYPE);
- out.writeInt(className);
- out.writeInt(typeArgs.length);
+ DataInputOutputUtil.writeINT(out, className);
+ DataInputOutputUtil.writeINT(out, typeArgs.length);
for (AbstractType t : typeArgs) {
t.save(out);
}
@@ -241,18 +242,6 @@
return acc;
}
- public static Collection<AbstractType> createClassType(final DependencyContext context,
- final Collection<String> args,
- final Collection<AbstractType> acc) {
- if (args != null) {
- for (String a : args) {
- acc.add(createClassType(context, context.get(a)));
- }
- }
-
- return acc;
- }
-
public static ClassType createClassType(final DependencyContext context, final int s) {
return (ClassType)context.getType(new ClassType(s));
}
@@ -277,6 +266,7 @@
}
public static AbstractType[] getType(final DependencyContext context, final Type[] t) {
+ if(t.length == 0) return AbstractType.EMPTY_TYPE_ARRAY;
final AbstractType[] r = new AbstractType[t.length];
for (int i = 0; i < r.length; i++) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java
index abe9df3..f5201a7 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java
@@ -16,6 +16,7 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.DataInputOutputUtil;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
import org.jetbrains.asm4.Type;
@@ -77,8 +78,8 @@
private FMUsage(final DataInput in) {
try {
- myName = in.readInt();
- myOwner = in.readInt();
+ myName = DataInputOutputUtil.readINT(in);
+ myOwner = DataInputOutputUtil.readINT(in);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -88,8 +89,8 @@
protected final void save(final byte tag, final DataOutput out) {
try {
out.writeByte(tag);
- out.writeInt(myName);
- out.writeInt(myOwner);
+ DataInputOutputUtil.writeINT(out, myName);
+ DataInputOutputUtil.writeINT(out, myOwner);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -215,7 +216,8 @@
super(in);
try {
final DataExternalizer<TypeRepr.AbstractType> externalizer = TypeRepr.externalizer(context);
- myArgumentTypes = RW.read(externalizer, in, new TypeRepr.AbstractType[in.readInt()]);
+ int argumentTypes = DataInputOutputUtil.readINT(in);
+ myArgumentTypes = RW.read(externalizer, in, argumentTypes != 0 ? new TypeRepr.AbstractType[argumentTypes]: TypeRepr.AbstractType.EMPTY_TYPE_ARRAY);
myReturnType = externalizer.read(in);
}
catch (IOException e) {
@@ -284,7 +286,7 @@
public MetaMethodUsage(final DataInput in) {
super(in);
try {
- myArity = in.readInt();
+ myArity = DataInputOutputUtil.readINT(in);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -295,7 +297,7 @@
public void save(final DataOutput out) {
save(METAMETHOD_USAGE, out);
try {
- out.writeInt(myArity);
+ DataInputOutputUtil.writeINT(out, myArity);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -348,7 +350,7 @@
private ClassUsage(final DataInput in) {
try {
- myClassName = in.readInt();
+ myClassName = DataInputOutputUtil.readINT(in);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -359,7 +361,7 @@
public void save(final DataOutput out) {
try {
out.writeByte(CLASS_USAGE);
- out.writeInt(myClassName);
+ DataInputOutputUtil.writeINT(out, myClassName);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -405,7 +407,7 @@
public void save(final DataOutput out) {
try {
out.writeByte(CLASS_AS_GENERIC_BOUND_USAGE);
- out.writeInt(myClassName);
+ DataInputOutputUtil.writeINT(out, myClassName);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -427,7 +429,7 @@
private ClassExtendsUsage(final DataInput in) {
try {
- myClassName = in.readInt();
+ myClassName = DataInputOutputUtil.readINT(in);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -438,7 +440,7 @@
public void save(final DataOutput out) {
try {
out.writeByte(CLASS_EXTENDS_USAGE);
- out.writeInt(myClassName);
+ DataInputOutputUtil.writeINT(out, myClassName);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -481,7 +483,7 @@
public void save(final DataOutput out) {
try {
out.writeByte(CLASS_NEW_USAGE);
- out.writeInt(myClassName);
+ DataInputOutputUtil.writeINT(out, myClassName);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -503,12 +505,12 @@
public static final DataExternalizer<ElemType> elementTypeExternalizer = new DataExternalizer<ElemType>() {
@Override
public void save(final DataOutput out, final ElemType value) throws IOException {
- out.writeInt(value.ordinal());
+ DataInputOutputUtil.writeINT(out, value.ordinal());
}
@Override
public ElemType read(final DataInput in) throws IOException {
- final int ordinal = in.readInt();
+ final int ordinal = DataInputOutputUtil.readINT(in);
for (ElemType value : ElemType.values()) {
if (value.ordinal() == ordinal) {
return value;
@@ -682,11 +684,6 @@
return context.getUsage(new ClassAsGenericBoundUsage(name));
}
-
- public static Usage createClassExtendsUsage(final DependencyContext context, final int name) {
- return context.getUsage(new ClassExtendsUsage(name));
- }
-
public static Usage createClassNewUsage(final DependencyContext context, final int name) {
return context.getUsage(new ClassNewUsage(name));
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java
index 3285a21..63e5380 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java
@@ -142,7 +142,7 @@
}
private static Set<JpsModule> getDependentModulesRecursively(final JpsModule module, final JpsJavaClasspathKind kind) {
- return JpsJavaExtensionService.dependencies(module).includedIn(kind).recursively().exportedOnly().getModules();
+ return JpsJavaExtensionService.dependencies(module).includedIn(kind).recursivelyExportedOnly().getModules();
}
public static void processFilesToRecompile(CompileContext context, ModuleChunk chunk, FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget> processor) throws IOException {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
index 3c9ac5b..1a0ce3b 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
@@ -41,7 +41,7 @@
* Date: 10/7/11
*/
public class BuildDataManager implements StorageOwner {
- private static final int VERSION = 19;
+ private static final int VERSION = 20;
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String SRC_TO_FORM_STORAGE = "src-form";
private static final String MAPPINGS_STORAGE = "mappings";
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaDependenciesEnumerator.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaDependenciesEnumerator.java
index 78d6d62..82cec24 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaDependenciesEnumerator.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaDependenciesEnumerator.java
@@ -16,31 +16,97 @@
package org.jetbrains.jps.model.java;
import com.intellij.openapi.util.Condition;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.module.JpsDependenciesEnumerator;
import org.jetbrains.jps.model.module.JpsDependencyElement;
/**
+ * Interface for convenient processing dependencies of a java module or a java project. Allows to process {@link org.jetbrains.jps.model.module.JpsDependencyElement}s and collect classes
+ * and source roots.
+ * <p/>
+ * Use {@link org.jetbrains.jps.model.java.JpsJavaExtensionService#dependencies(org.jetbrains.jps.model.module.JpsModule)} to process dependencies of a module
+ * and use {@link org.jetbrains.jps.model.java.JpsJavaExtensionService#dependencies(org.jetbrains.jps.model.JpsProject)} to process dependencies of all modules in a project.<p>
+ *
+ * Note that all configuration methods modify {@link org.jetbrains.jps.model.module.JpsDependenciesEnumerator} instance instead of creating a new one.
+ *
* @author nik
*/
public interface JpsJavaDependenciesEnumerator extends JpsDependenciesEnumerator {
+ /**
+ * Skip test dependencies
+ *
+ * @return this instance
+ */
+ @NotNull
JpsJavaDependenciesEnumerator productionOnly();
+
+ /**
+ * Skip runtime-only dependencies
+ *
+ * @return this instance
+ */
+ @NotNull
JpsJavaDependenciesEnumerator compileOnly();
+
+ /**
+ * Skip compile-only dependencies
+ *
+ * @return this instance
+ */
+ @NotNull
JpsJavaDependenciesEnumerator runtimeOnly();
+
+ /**
+ * Skip not exported dependencies. If this method is called after {@link #recursively()} direct non-exported dependencies won't be skipped
+ *
+ * @return this instance
+ */
+ @NotNull
JpsJavaDependenciesEnumerator exportedOnly();
- JpsJavaDependenciesEnumerator withoutLibraries();
- JpsJavaDependenciesEnumerator withoutDepModules();
- JpsJavaDependenciesEnumerator withoutSdk();
- JpsJavaDependenciesEnumerator withoutModuleSourceEntries();
-
+ @NotNull
@Override
JpsJavaDependenciesEnumerator recursively();
+ /**
+ * Process all direct dependencies and recursively process transitive dependencies which marked with 'exported'
+ *
+ * @return this instance
+ */
+ @NotNull
+ JpsJavaDependenciesEnumerator recursivelyExportedOnly();
+
+
+ @NotNull
+ JpsJavaDependenciesEnumerator withoutLibraries();
+ @NotNull
+ JpsJavaDependenciesEnumerator withoutDepModules();
+ @NotNull
+ JpsJavaDependenciesEnumerator withoutSdk();
+ @NotNull
+ JpsJavaDependenciesEnumerator withoutModuleSourceEntries();
+
+ @NotNull
@Override
- JpsJavaDependenciesEnumerator satisfying(Condition<JpsDependencyElement> condition);
+ JpsJavaDependenciesEnumerator satisfying(@NotNull Condition<JpsDependencyElement> condition);
- JpsJavaDependenciesEnumerator includedIn(JpsJavaClasspathKind classpathKind);
+ /**
+ * Process only dependencies which should be included in the classpath specified by {@code classpathKind} parameter
+ * @param classpathKind
+ * @return this instance
+ */
+ @NotNull
+ JpsJavaDependenciesEnumerator includedIn(@NotNull JpsJavaClasspathKind classpathKind);
+ /**
+ * @return enumerator for processing classes roots of the dependencies
+ */
+ @NotNull
JpsJavaDependenciesRootsEnumerator classes();
+
+ /**
+ * @return enumerator for processing source roots of the dependencies
+ */
+ @NotNull
JpsJavaDependenciesRootsEnumerator sources();
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependenciesEnumerator.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependenciesEnumerator.java
index c31ab23..d310247 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependenciesEnumerator.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependenciesEnumerator.java
@@ -17,23 +17,63 @@
import com.intellij.openapi.util.Condition;
import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.library.JpsLibrary;
import java.util.Set;
/**
+ * Interface for convenient processing dependencies of a module or a project
+ * <p/>
+ * Use {@link org.jetbrains.jps.model.java.JpsJavaDependenciesEnumerator JpsJavaDependenciesEnumerator} for java-specific dependencies processing
+ * <p/>
+ * Note that all configuration methods modify {@link org.jetbrains.jps.model.module.JpsDependenciesEnumerator} instance instead of creating a new one.
+ *
* @author nik
*/
public interface JpsDependenciesEnumerator {
+ @NotNull
JpsDependenciesEnumerator withoutLibraries();
+ @NotNull
JpsDependenciesEnumerator withoutDepModules();
+ @NotNull
JpsDependenciesEnumerator withoutSdk();
+ @NotNull
JpsDependenciesEnumerator withoutModuleSourceEntries();
- JpsDependenciesEnumerator recursively();
- JpsDependenciesEnumerator satisfying(Condition<JpsDependencyElement> condition);
+ /**
+ * Recursively process modules on which the module depends
+ *
+ * @return this instance
+ */
+ @NotNull
+ JpsDependenciesEnumerator recursively();
+
+ /**
+ * Process only dependencies which satisfies the specified condition
+ *
+ * @param condition filtering condition
+ * @return this instance
+ */
+ @NotNull
+ JpsDependenciesEnumerator satisfying(@NotNull Condition<JpsDependencyElement> condition);
+
+ /**
+ * @return all modules processed by enumerator
+ */
+ @NotNull
Set<JpsModule> getModules();
+
+ /**
+ * @return all libraries processed by enumerator
+ */
+ @NotNull
Set<JpsLibrary> getLibraries();
- void processModules(Consumer<JpsModule> consumer);
+ /**
+ * Runs <code>consumer.consume()</code> for each module processed by this enumerator
+ *
+ * @param consumer consumer
+ */
+ void processModules(@NotNull Consumer<JpsModule> consumer);
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRoot.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRoot.java
index 713b18d..87af190 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRoot.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRoot.java
@@ -35,6 +35,9 @@
<P extends JpsElement> JpsTypedModuleSourceRoot<P> asTyped(@NotNull JpsModuleSourceRootType<P> type);
@NotNull
+ JpsTypedModuleSourceRoot<?> asTyped();
+
+ @NotNull
JpsElement getProperties();
@NotNull
diff --git a/jps/model-impl/src/com/intellij/openapi/fileTypes/WildcardFileNameMatcher.java b/jps/model-impl/src/com/intellij/openapi/fileTypes/WildcardFileNameMatcher.java
index afbaaaf..8e22fe2 100644
--- a/jps/model-impl/src/com/intellij/openapi/fileTypes/WildcardFileNameMatcher.java
+++ b/jps/model-impl/src/com/intellij/openapi/fileTypes/WildcardFileNameMatcher.java
@@ -40,6 +40,7 @@
myMatcher = PatternUtil.fromMask(pattern).matcher("");
}
+ @Override
public boolean matches(final String filename) {
synchronized (myMatcher) {
myMatcher.reset(filename);
@@ -55,6 +56,7 @@
mySuffix = suffix;
}
+ @Override
public boolean matches(final String filename) {
return filename.endsWith(mySuffix);
}
@@ -67,6 +69,7 @@
myPrefix = prefix;
}
+ @Override
public boolean matches(final String filename) {
return filename.startsWith(myPrefix);
}
@@ -79,6 +82,7 @@
myInfix = infix;
}
+ @Override
public boolean matches(final String filename) {
return filename.contains(myInfix);
}
@@ -108,10 +112,12 @@
return new RegexpMatcher(pattern);
}
+ @Override
public boolean accept(@NotNull String fileName) {
return myMatcher.matches(fileName);
}
+ @Override
@NonNls
@NotNull
public String getPresentableString() {
diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaDependenciesEnumeratorImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaDependenciesEnumeratorImpl.java
index 17edcce..c3ee736 100644
--- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaDependenciesEnumeratorImpl.java
+++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaDependenciesEnumeratorImpl.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.jps.model.java.impl;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.java.*;
import org.jetbrains.jps.model.library.JpsOrderRootType;
import org.jetbrains.jps.model.module.JpsDependencyElement;
@@ -44,24 +45,28 @@
myHandlers = handlers != null ? handlers : Collections.<JpsJavaDependenciesEnumerationHandler>emptyList();
}
+ @NotNull
@Override
public JpsJavaDependenciesEnumerator productionOnly() {
myProductionOnly = true;
return this;
}
+ @NotNull
@Override
public JpsJavaDependenciesEnumerator compileOnly() {
myCompileOnly = true;
return this;
}
+ @NotNull
@Override
public JpsJavaDependenciesEnumerator runtimeOnly() {
myRuntimeOnly = true;
return this;
}
+ @NotNull
@Override
public JpsJavaDependenciesEnumerator exportedOnly() {
if (myRecursively) {
@@ -73,17 +78,26 @@
return this;
}
+ @NotNull
@Override
- public JpsJavaDependenciesEnumerator includedIn(JpsJavaClasspathKind classpathKind) {
+ public JpsJavaDependenciesEnumerator recursivelyExportedOnly() {
+ return recursively().exportedOnly();
+ }
+
+ @NotNull
+ @Override
+ public JpsJavaDependenciesEnumerator includedIn(@NotNull JpsJavaClasspathKind classpathKind) {
myClasspathKind = classpathKind;
return this;
}
+ @NotNull
@Override
public JpsJavaDependenciesRootsEnumerator classes() {
return new JpsJavaDependenciesRootsEnumeratorImpl(this, JpsOrderRootType.COMPILED);
}
+ @NotNull
@Override
public JpsJavaDependenciesRootsEnumerator sources() {
return new JpsJavaDependenciesRootsEnumeratorImpl(this, JpsOrderRootType.SOURCES);
diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesEnumeratorBase.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesEnumeratorBase.java
index 86e248e..c6dee7b 100644
--- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesEnumeratorBase.java
+++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesEnumeratorBase.java
@@ -20,6 +20,7 @@
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.library.JpsLibrary;
import org.jetbrains.jps.model.module.*;
@@ -43,36 +44,42 @@
myRootModules = rootModules;
}
+ @NotNull
@Override
public Self withoutLibraries() {
myWithoutLibraries = true;
return self();
}
+ @NotNull
@Override
public Self withoutDepModules() {
myWithoutDepModules = true;
return self();
}
+ @NotNull
@Override
public Self withoutSdk() {
myWithoutSdk = true;
return self();
}
+ @NotNull
@Override
public Self withoutModuleSourceEntries() {
myWithoutModuleSourceEntries = true;
return self();
}
+ @NotNull
@Override
- public Self satisfying(Condition<JpsDependencyElement> condition) {
+ public Self satisfying(@NotNull Condition<JpsDependencyElement> condition) {
myCondition = condition;
return self();
}
+ @NotNull
@Override
public Self recursively() {
myRecursively = true;
@@ -81,6 +88,7 @@
protected abstract Self self();
+ @NotNull
@Override
public Set<JpsModule> getModules() {
Set<JpsModule> result = new HashSet<JpsModule>();
@@ -89,7 +97,7 @@
}
@Override
- public void processModules(final Consumer<JpsModule> consumer) {
+ public void processModules(@NotNull final Consumer<JpsModule> consumer) {
processDependencies(new Processor<JpsDependencyElement>() {
@Override
public boolean process(JpsDependencyElement dependencyElement) {
@@ -167,6 +175,7 @@
return myRootModules.contains(module);
}
+ @NotNull
@Override
public Set<JpsLibrary> getLibraries() {
Set<JpsLibrary> libraries = new HashSet<JpsLibrary>();
diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootImpl.java
index 90369b8..7ba971b 100644
--- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootImpl.java
+++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootImpl.java
@@ -62,6 +62,12 @@
return myRootType.equals(type) ? (JpsTypedModuleSourceRoot<P>)this : null;
}
+ @NotNull
+ @Override
+ public JpsTypedModuleSourceRoot<?> asTyped() {
+ return this;
+ }
+
@Override
public JpsElementType<?> getType() {
return myRootType;
diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsDependenciesEnumeratorTest.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsDependenciesEnumeratorTest.java
index 744077a..95f3a63 100644
--- a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsDependenciesEnumeratorTest.java
+++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsDependenciesEnumeratorTest.java
@@ -177,7 +177,7 @@
assertClassRoots(orderEntries(myModule).withoutSdk(), getAsmJar());
assertClassRoots(orderEntries(myModule).withoutSdk().recursively(), getAsmJar(), getJDomJar());
- assertClassRoots(orderEntries(myModule).withoutSdk().recursively().exportedOnly(), getAsmJar());
+ assertClassRoots(orderEntries(myModule).withoutSdk().recursivelyExportedOnly(), getAsmJar());
assertClassRoots(orderEntries(myModule).withoutSdk().exportedOnly().recursively());
}
diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java
index e5adc22..62f76ff 100644
--- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java
+++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java
@@ -178,7 +178,7 @@
rootModelElement.addContent(contentElement);
for (JpsModuleSourceRoot root : sourceRoots) {
if (FileUtil.startsWith(root.getUrl(), url)) {
- saveSourceRoot(contentElement, (JpsTypedModuleSourceRoot<?>)root);
+ saveSourceRoot(contentElement, root.asTyped().getUrl(), root.asTyped());
}
}
for (String excludedUrl : excludedUrls) {
@@ -241,9 +241,11 @@
}
}
- public static <P extends JpsElement> void saveSourceRoot(Element contentElement, JpsTypedModuleSourceRoot<P> root) {
+ public static <P extends JpsElement> void saveSourceRoot(@NotNull Element contentElement,
+ final @NotNull String rootUrl,
+ @NotNull JpsTypedModuleSourceRoot<P> root) {
Element sourceElement = new Element(SOURCE_FOLDER_TAG);
- sourceElement.setAttribute(URL_ATTRIBUTE, root.getUrl());
+ sourceElement.setAttribute(URL_ATTRIBUTE, rootUrl);
JpsModuleSourceRootPropertiesSerializer<P> serializer = getSerializer(root.getRootType());
if (serializer != null) {
String typeId = serializer.getTypeId();
diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleSourceRootPropertiesSerializerImpl.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleSourceRootPropertiesSerializerImpl.java
new file mode 100644
index 0000000..706ef83
--- /dev/null
+++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleSourceRootPropertiesSerializerImpl.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.jps.model.serialization.module;
+
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+
+/**
+ * @author nik
+ */
+public class JpsModuleSourceRootPropertiesSerializerImpl extends JpsModuleSourceRootPropertiesSerializer<JpsDummyElement> {
+ public JpsModuleSourceRootPropertiesSerializerImpl(JpsModuleSourceRootType<JpsDummyElement> type, String typeId) {
+ super(type, typeId);
+ }
+
+ @Override
+ public JpsDummyElement loadProperties(@NotNull Element sourceRootTag) {
+ return JpsElementFactory.getInstance().createDummyElement();
+ }
+
+ @Override
+ public void saveProperties(@NotNull JpsDummyElement properties, @NotNull Element sourceRootTag) {
+ }
+}
diff --git a/lib/netty-all.jar b/lib/netty-all.jar
index 847efe5..96f6241 100644
--- a/lib/netty-all.jar
+++ b/lib/netty-all.jar
Binary files differ
diff --git a/lib/src/netty-all-sources.jar b/lib/src/netty-all-sources.jar
index 07ac406..1a8e749 100644
--- a/lib/src/netty-all-sources.jar
+++ b/lib/src/netty-all-sources.jar
Binary files differ
diff --git a/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java
index 179d0d3..d1dabcb 100644
--- a/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java
+++ b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java
@@ -62,7 +62,6 @@
addAdditionalClassPath(classpath);
UrlClassLoader newClassLoader = UrlClassLoader.build()
.urls(filterClassPath(classpath))
- .nativeLibs("IdeaWin32", "focusKiller", "jumpListBridge")
.allowLock().useCache().get();
// prepare plugins
diff --git a/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java b/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java
index 5a41d24..c1f7618 100644
--- a/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java
+++ b/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java
@@ -94,4 +94,5 @@
public abstract void startRunInjectors(@NotNull Document hostDocument, boolean synchronously);
public abstract void enumerate(@NotNull PsiElement host, @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor);
+ public abstract void enumerateEx(@NotNull PsiElement host, @NotNull PsiFile containingFile, boolean probeUp, @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor);
}
diff --git a/platform/core-api/src/com/intellij/psi/ElementManipulators.java b/platform/core-api/src/com/intellij/psi/ElementManipulators.java
index 9f91e0e..098a204 100644
--- a/platform/core-api/src/com/intellij/psi/ElementManipulators.java
+++ b/platform/core-api/src/com/intellij/psi/ElementManipulators.java
@@ -60,6 +60,7 @@
return manipulator == null ? TextRange.from(0, element.getTextLength()) : manipulator.getRangeInElement(element);
}
+ @NotNull
public static String getValueText(final PsiElement element) {
final TextRange valueTextRange = getValueTextRange(element);
if (valueTextRange.isEmpty()) return "";
diff --git a/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java b/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java
index e5e0e96..1714e90 100644
--- a/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java
+++ b/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java
@@ -17,7 +17,9 @@
import com.intellij.diagnostic.PluginException;
import com.intellij.ide.plugins.PluginManagerCore;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.lang.UrlClassLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,37 +30,40 @@
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
+import java.util.ListIterator;
/**
* @author Eugene Zhuravlev
* @since 6.03.2003
*/
-@SuppressWarnings({"UseOfSystemOutOrSystemErr"})
public class PluginClassLoader extends UrlClassLoader {
private final ClassLoader[] myParents;
private final PluginId myPluginId;
private final String myPluginVersion;
- private final File myLibDirectory;
+ private final List<String> myLibDirectories;
public PluginClassLoader(@NotNull List<URL> urls,
@NotNull ClassLoader[] parents,
- final PluginId pluginId,
- final String version,
- final File pluginRoot) {
+ PluginId pluginId,
+ String version,
+ File pluginRoot) {
super(build().urls(urls).allowLock().useCache());
myParents = parents;
myPluginId = pluginId;
myPluginVersion = version;
-
- //noinspection HardCodedStringLiteral
- final File file = new File(pluginRoot, "lib");
- myLibDirectory = file.exists()? file : null;
+ myLibDirectories = ContainerUtil.newSmartList();
+ File libDir = new File(pluginRoot, "lib");
+ if (libDir.exists()) {
+ myLibDirectories.add(libDir.getAbsolutePath());
+ }
}
// Changed sequence in which classes are searched, this is essential if plugin uses library,
// a different version of which is used in IDEA.
+ @Override
public Class loadClass(@NotNull String name, final boolean resolve) throws ClassNotFoundException {
Class c = loadClassInsideSelf(name);
@@ -156,46 +161,50 @@
return new CompoundEnumeration<URL>(resources);
}
- @Override
- protected String findLibrary(String libName) {
- if (myLibDirectory == null) {
- return null;
- }
- final File libraryFile = new File(myLibDirectory, System.mapLibraryName(libName));
- return libraryFile.exists()? libraryFile.getAbsolutePath() : null;
+ @SuppressWarnings("UnusedDeclaration")
+ public void addLibDirectories(@NotNull Collection<String> libDirectories) {
+ myLibDirectories.addAll(libDirectories);
}
+ @Override
+ protected String findLibrary(String libName) {
+ if (!myLibDirectories.isEmpty()) {
+ String libFileName = System.mapLibraryName(libName);
+ ListIterator<String> i = myLibDirectories.listIterator(myLibDirectories.size());
+ while (i.hasPrevious()) {
+ File libFile = new File(i.previous(), libFileName);
+ if (libFile.exists()) {
+ return libFile.getAbsolutePath();
+ }
+ }
+ }
+
+ return null;
+ }
private static URL fetchResource(ClassLoader cl, String resourceName) {
- //protected URL findResource(String s)
try {
- //noinspection HardCodedStringLiteral
final Method findResourceMethod = getFindResourceMethod(cl.getClass(), "findResource");
return (URL)findResourceMethod.invoke(cl, resourceName);
}
catch (Exception e) {
- e.printStackTrace();
+ Logger.getInstance(PluginClassLoader.class).error(e);
return null;
}
}
private static Enumeration fetchResources(ClassLoader cl, String resourceName) {
- //protected Enumeration findResources(String s) throws IOException
try {
- //noinspection HardCodedStringLiteral
final Method findResourceMethod = getFindResourceMethod(cl.getClass(), "findResources");
- if (findResourceMethod == null) {
- return null;
- }
- return (Enumeration)findResourceMethod.invoke(cl, resourceName);
+ return findResourceMethod == null ? null : (Enumeration)findResourceMethod.invoke(cl, resourceName);
}
catch (Exception e) {
- e.printStackTrace();
+ Logger.getInstance(PluginClassLoader.class).error(e);
return null;
}
}
- private static Method getFindResourceMethod(final Class clClass, final String methodName) {
+ private static Method getFindResourceMethod(final Class<?> clClass, final String methodName) {
try {
final Method declaredMethod = clClass.getDeclaredMethod(methodName, String.class);
declaredMethod.setAccessible(true);
@@ -214,6 +223,7 @@
return myPluginId;
}
+ @Override
public String toString() {
return "PluginClassLoader[" + myPluginId + ", " + myPluginVersion + "]";
}
diff --git a/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java b/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java
index c0529ac..23b42f9 100644
--- a/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java
@@ -517,7 +517,7 @@
final String componentKey = config.getInterfaceClass();
myDelegate = new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(componentKey, implementationClass, null, true)) {
@Override
- public Object getComponentInstance(PicoContainer picoContainer) throws PicoInitializationException, PicoIntrospectionException {
+ public Object getComponentInstance(PicoContainer picoContainer) throws PicoInitializationException, PicoIntrospectionException, ProcessCanceledException {
ProgressIndicator indicator = getProgressIndicator();
if (indicator != null) {
indicator.checkCanceled();
diff --git a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java
index 52c6c1b..dc3fff5 100644
--- a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java
+++ b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -513,14 +513,14 @@
@Override
public int getStartOffset() {
final PsiElement resolved = retrieve();
- if (resolved == null) throw new PsiInvalidElementAccessException(null);
+ if (resolved == null) throw new PsiInvalidElementAccessException(null, "Element type: " + myElementType.toString() + "; " + myVirtualFile);
return resolved.getTextRange().getStartOffset();
}
@Override
public int getEndOffset() {
final PsiElement resolved = retrieve();
- if (resolved == null) throw new PsiInvalidElementAccessException(null);
+ if (resolved == null) throw new PsiInvalidElementAccessException(null, "Element type: " + myElementType.toString() + "; " + myVirtualFile);
return resolved.getTextRange().getEndOffset();
}
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
index d081d55..8e46a2f 100644
--- a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
+++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.extensions.impl;
import com.intellij.openapi.extensions.*;
+import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.util.pico.AssignableToComponentAdapter;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Element;
@@ -64,8 +65,12 @@
}
@Override
- public Object getComponentInstance(final PicoContainer container) throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
- //assert myContainer == container : "Different containers: " + myContainer + " - " + container;
+ public Object getComponentInstance(final PicoContainer container)
+ throws PicoInitializationException,
+ PicoIntrospectionException,
+ AssignabilityRegistrationException,
+ NotConcreteRegistrationException,
+ ProcessCanceledException {
if (myComponentInstance == null) {
if (Element.class.equals(getComponentImplementation())) {
myComponentInstance = myExtensionElement;
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionsAreaImpl.java b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionsAreaImpl.java
index 81b1d28..2ddb8fb 100644
--- a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionsAreaImpl.java
+++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionsAreaImpl.java
@@ -169,7 +169,7 @@
// has content
if (!extensionElement.getContent().isEmpty()) return true;
// has custom attributes
- for (Attribute attribute : (List<Attribute>)extensionElement.getAttributes()) {
+ for (Attribute attribute : extensionElement.getAttributes()) {
final String name = attribute.getName();
if (!"implementation".equals(name) && !"id".equals(name) && !"order".equals(name)) {
return true;
@@ -405,6 +405,7 @@
return extensionPoint;
}
+ @NotNull
@Override
@SuppressWarnings({"unchecked"})
public <T> ExtensionPoint<T> getExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName) {
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ModuleAwareContentRoot.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ModuleAwareContentRoot.java
index 789203e..8479bfc 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ModuleAwareContentRoot.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ModuleAwareContentRoot.java
@@ -6,6 +6,8 @@
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
/**
* @author Denis Zhdanov
@@ -77,6 +79,14 @@
return myDelegate.addSourceFolder(file, isTestSource, packagePrefix);
}
+ @NotNull
+ @Override
+ public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull VirtualFile file,
+ @NotNull JpsModuleSourceRootType<P> type,
+ @NotNull P properties) {
+ return myDelegate.addSourceFolder(file, type, properties);
+ }
+
@Override
public SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource) {
return myDelegate.addSourceFolder(url, isTestSource);
diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/AbstractExternalSystemTest.groovy b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/AbstractExternalSystemTest.groovy
index de72751..75cf210 100644
--- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/AbstractExternalSystemTest.groovy
+++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/AbstractExternalSystemTest.groovy
@@ -20,6 +20,7 @@
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.externalSystem.ExternalSystemManager
import com.intellij.openapi.externalSystem.model.DataNode
+import com.intellij.openapi.externalSystem.model.ProjectSystemId
import com.intellij.openapi.externalSystem.model.project.ProjectData
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalProjectBuilder.groovy b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalProjectBuilder.groovy
index f80d50d..b0480ac 100644
--- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalProjectBuilder.groovy
+++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalProjectBuilder.groovy
@@ -17,6 +17,7 @@
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.ProjectKeys
+import com.intellij.openapi.externalSystem.model.ProjectSystemId
import com.intellij.openapi.externalSystem.model.project.*
import com.intellij.openapi.externalSystem.model.task.TaskData
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
@@ -58,14 +59,16 @@
protected Object createNode(Object name, Map attributes) {
switch (name) {
case 'project':
- ProjectData projectData = new ProjectData(TEST_EXTERNAL_SYSTEM_ID, projectDir.path, projectDir.path)
+ ProjectSystemId projectSystemId = attributes.projectSystemId ?: TEST_EXTERNAL_SYSTEM_ID
+ ProjectData projectData = new ProjectData(projectSystemId, projectDir.path, projectDir.path)
projectData.name = attributes.name ?: 'project'
projectNode = new DataNode<ProjectData>(ProjectKeys.PROJECT, projectData, null)
return projectNode
case 'module':
+ ProjectSystemId projectSystemId = attributes.projectSystemId ?: TEST_EXTERNAL_SYSTEM_ID
String moduleFilePath = attributes.moduleFilePath ?: projectDir.path
String externalConfigPath = attributes.externalConfigPath ?: projectDir.path
- ModuleData moduleData = new ModuleData(TEST_EXTERNAL_SYSTEM_ID,
+ ModuleData moduleData = new ModuleData(projectSystemId,
ModuleTypeId.JAVA_MODULE,
attributes.name ?: name as String,
moduleFilePath,
@@ -80,7 +83,8 @@
return parentNode.createChild(ProjectKeys.LIBRARY_DEPENDENCY, data)
case 'task':
DataNode<ExternalConfigPathAware> parentNode = current as DataNode
- TaskData data = new TaskData(TEST_EXTERNAL_SYSTEM_ID, attributes.name, parentNode.data.linkedExternalProjectPath, null)
+ ProjectSystemId projectSystemId = attributes.projectSystemId ?: TEST_EXTERNAL_SYSTEM_ID
+ TaskData data = new TaskData(projectSystemId, attributes.name, parentNode.data.linkedExternalProjectPath, null)
return parentNode.createChild(ProjectKeys.TASK, data)
case 'contentRoot':
DataNode<ModuleData> parentNode = current as DataNode
diff --git a/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java b/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java
index 7a22237..75d09a3 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java
@@ -16,7 +16,9 @@
package com.intellij.psi.search.searches;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.search.SearchScope;
@@ -80,7 +82,12 @@
}
public SearchScope getScope() {
- final SearchScope accessScope = PsiSearchHelper.SERVICE.getInstance(myElement.getProject()).getUseScope(myElement);
+ final SearchScope accessScope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
+ @Override
+ public SearchScope compute() {
+ return PsiSearchHelper.SERVICE.getInstance(myElement.getProject()).getUseScope(myElement);
+ }
+ });
return myScope.intersectWith(accessScope);
}
}
diff --git a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java
index 9260714..ef1395e 100644
--- a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java
+++ b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java
@@ -27,6 +27,7 @@
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
+import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -150,6 +151,7 @@
void registerFileTypesUsedForIndexing(@NotNull Consumer<FileType> fileTypeSink);
}
- // TODO: remove once changes becomes permamnent
- public static final boolean ourEnableTracingOfKeyHashToVirtualFileMapping = ApplicationManager.getApplication().isInternal();
+ // TODO: remove once changes becomes permanent
+ public static final boolean ourEnableTracingOfKeyHashToVirtualFileMapping =
+ SystemProperties.getBooleanProperty("idea.enable.tracing.keyhash2virtualfile", true);
}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java
index 6be87f7..f9e8f09 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -205,6 +205,13 @@
}
/**
+ * Allow autoPopup to appear after custom symbol
+ */
+ public boolean invokeAutoPopup(@NotNull PsiElement position, char typeChar) {
+ return false;
+ }
+
+ /**
* Invoked in a read action in parallel to the completion process. Used to calculate the replacement offset
* (see {@link com.intellij.codeInsight.completion.CompletionInitializationContext#setReplacementOffset(int)})
* if it takes too much time to spend it in {@link #beforeCompletion(CompletionInitializationContext)},
@@ -216,7 +223,7 @@
*/
public void duringCompletion(@NotNull CompletionInitializationContext context) {
}
-
+
/**
* @param actionId
* @return String representation of action shortcut. Useful while advertising something
diff --git a/platform/lang-api/src/com/intellij/execution/filters/RegexpFilter.java b/platform/lang-api/src/com/intellij/execution/filters/RegexpFilter.java
index 1f05008..74828fa 100644
--- a/platform/lang-api/src/com/intellij/execution/filters/RegexpFilter.java
+++ b/platform/lang-api/src/com/intellij/execution/filters/RegexpFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -37,17 +37,16 @@
@NonNls public static final String COLUMN_MACROS = "$COLUMN$";
@NonNls private static final String FILE_PATH_REGEXP = "((?:\\p{Alpha}\\:)?[0-9 a-z_A-Z\\-\\\\./]+)";
- private static final String NUMBER_REGEXP = "([0-9]+)";
+ @NonNls private static final String NUMBER_REGEXP = "([0-9]+)";
+ @NonNls private static final String FILE_STR = "file";
+ @NonNls private static final String LINE_STR = "line";
+ @NonNls private static final String COLUMN_STR = "column";
private final int myFileRegister;
private final int myLineRegister;
private final int myColumnRegister;
-
private final Pattern myPattern;
private final Project myProject;
- @NonNls private static final String FILE_STR = "file";
- @NonNls private static final String LINE_STR = "line";
- @NonNls private static final String COLUMN_STR = "column";
public RegexpFilter(Project project, @NonNls String expression) {
myProject = project;
@@ -104,17 +103,17 @@
myPattern = Pattern.compile(expression, Pattern.MULTILINE);
}
+ @SuppressWarnings("ResultOfMethodCallIgnored")
public static void validate(String expression) {
if (expression == null || expression.trim().isEmpty()) {
throw new InvalidExpressionException("expression == null or empty");
}
- expression = substituteMacrosesWithRegexps(expression);
-
+ expression = substituteMacrosWithRegexps(expression);
Pattern.compile(expression, Pattern.MULTILINE);
}
- private static String substituteMacrosesWithRegexps(String expression) {
+ private static String substituteMacrosWithRegexps(String expression) {
int filePathIndex = expression.indexOf(FILE_PATH_MACROS);
int lineIndex = expression.indexOf(LINE_MACROS);
int columnIndex = expression.indexOf(COLUMN_MACROS);
@@ -136,21 +135,18 @@
}
@Override
- public Result applyFilter(final String line, final int entireLength) {
-
- final Matcher matcher = myPattern.matcher(line);
- if (matcher.find()) {
- return createResult(matcher, entireLength - line.length());
+ public Result applyFilter(String line, int entireLength) {
+ Matcher matcher = myPattern.matcher(line);
+ if (!matcher.find()) {
+ return null;
}
- return null;
- }
-
- private Result createResult(final Matcher matcher, final int entireLen) {
- final String filePath = matcher.group(myFileRegister);
+ String filePath = matcher.group(myFileRegister);
+ if (filePath == null) {
+ return null;
+ }
String lineNumber = "0";
-
if (myLineRegister != -1) {
lineNumber = matcher.group(myLineRegister);
}
@@ -160,32 +156,29 @@
columnNumber = matcher.group(myColumnRegister);
}
- int line = 0;
+ int line1 = 0;
int column = 0;
try {
- line = Integer.parseInt(lineNumber);
+ line1 = Integer.parseInt(lineNumber);
column = Integer.parseInt(columnNumber);
} catch (NumberFormatException e) {
- // Do nothing, so that line and column will remain at their initial
- // zero values.
+ // Do nothing, so that line and column will remain at their initial zero values.
}
- if (line > 0) line -= 1;
+ if (line1 > 0) line1 -= 1;
if (column > 0) column -= 1;
// Calculate the offsets relative to the entire text.
- final int highlightStartOffset = entireLen + matcher.start(myFileRegister);
+ final int highlightStartOffset = entireLength - line.length() + matcher.start(myFileRegister);
final int highlightEndOffset = highlightStartOffset + filePath.length();
-
- final HyperlinkInfo info = createOpenFileHyperlink(filePath, line, column);
+ final HyperlinkInfo info = createOpenFileHyperlink(filePath, line1, column);
return new Result(highlightStartOffset, highlightEndOffset, info);
}
@Nullable
protected HyperlinkInfo createOpenFileHyperlink(String fileName, final int line, final int column) {
fileName = fileName.replace(File.separatorChar, '/');
- final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(fileName);
- if (file == null) return null;
- return new OpenFileHyperlinkInfo(myProject, file, line, column);
+ VirtualFile file = LocalFileSystem.getInstance().findFileByPath(fileName);
+ return file != null ? new OpenFileHyperlinkInfo(myProject, file, line, column) : null;
}
public static String[] getMacrosName() {
diff --git a/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java b/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java
index bd20378..3236b16 100644
--- a/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java
+++ b/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java
@@ -62,23 +62,14 @@
public static class QuickFixInfo {
public final IntentionAction quickFix;
+ @NotNull
public final TextRange textRange;
- public final List<IntentionAction> options;
public final HighlightDisplayKey key;
- @Deprecated
- public QuickFixInfo(final IntentionAction quickFix, final TextRange textRange, final List<IntentionAction> options, String displayName) {
- key = null;
- this.quickFix = quickFix;
- this.textRange = textRange;
- this.options = options;
- }
-
- public QuickFixInfo(@NotNull IntentionAction fix, final TextRange range, @Nullable final HighlightDisplayKey key) {
+ public QuickFixInfo(@NotNull IntentionAction fix, @NotNull TextRange range, @Nullable final HighlightDisplayKey key) {
this.key = key;
quickFix = fix;
textRange = range;
- options = null;
}
@Override
@@ -99,7 +90,7 @@
* @see AnnotationHolder#createWarningAnnotation
* @see AnnotationHolder#createInfoAnnotation
*/
- public Annotation(final int startOffset, final int endOffset, final HighlightSeverity severity, final String message, String tooltip) {
+ public Annotation(final int startOffset, final int endOffset, @NotNull HighlightSeverity severity, final String message, String tooltip) {
assert startOffset <= endOffset : startOffset + ":" + endOffset;
assert startOffset >= 0 : "Start offset must not be negative: " +startOffset;
myStartOffset = startOffset;
@@ -140,24 +131,6 @@
* @param fix the quick fix implementation.
* @param range the text range (relative to the document) where the quick fix is available.
*/
- @Deprecated
- public void registerFix(@NotNull IntentionAction fix, TextRange range, List<IntentionAction> options, String displayName) {
- if (range == null) {
- range = new TextRange(myStartOffset, myEndOffset);
- }
- if (myQuickFixes == null) {
- myQuickFixes = new ArrayList<QuickFixInfo>();
- }
- myQuickFixes.add(new QuickFixInfo(fix, range, options, displayName));
- }
-
- /**
- * Registers a quick fix for the annotation which is only available on a particular range of text
- * within the annotation.
- *
- * @param fix the quick fix implementation.
- * @param range the text range (relative to the document) where the quick fix is available.
- */
public void registerFix(@NotNull IntentionAction fix, @Nullable TextRange range, @Nullable final HighlightDisplayKey key) {
if (range == null) {
range = new TextRange(myStartOffset, myEndOffset);
@@ -242,6 +215,7 @@
*
* @return the annotation severity.
*/
+ @NotNull
public HighlightSeverity getSeverity() {
return mySeverity;
}
@@ -263,6 +237,7 @@
*
* @return the text attribute key used for highlighting
*/
+ @NotNull
public TextAttributesKey getTextAttributes() {
if (myEnforcedAttributesKey != null) return myEnforcedAttributesKey;
diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java
index b20f1f7..e5aa799 100644
--- a/platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java
+++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java
@@ -68,7 +68,7 @@
@Override
@Nullable
- public String getVersionString(Sdk sdk) {
+ public String getVersionString(@NotNull Sdk sdk) {
return getVersionString(sdk.getHomePath());
}
@@ -99,15 +99,15 @@
@Override
@Nullable
- public SdkAdditionalData loadAdditionalData(Sdk currentSdk, Element additional) {
+ public SdkAdditionalData loadAdditionalData(@NotNull Sdk currentSdk, Element additional) {
return loadAdditionalData(additional);
}
-
- public SdkType(@NonNls String name) {
+ public SdkType(@NotNull @NonNls String name) {
myName = name;
}
+ @NotNull
@Override
public String getName() {
return myName;
diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/SimpleJavaSdkType.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/SimpleJavaSdkType.java
index 41b5876..9db9794 100644
--- a/platform/lang-api/src/com/intellij/openapi/projectRoots/SimpleJavaSdkType.java
+++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/SimpleJavaSdkType.java
@@ -20,6 +20,7 @@
import com.intellij.openapi.projectRoots.impl.SdkVersionUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -55,24 +56,24 @@
}
@Override
- public void saveAdditionalData(SdkAdditionalData additionalData, Element additional) {
+ public void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional) {
}
@Override
- public String getBinPath(Sdk sdk) {
+ public String getBinPath(@NotNull Sdk sdk) {
return getConvertedHomePath(sdk) + "bin";
}
@Override
@NonNls
- public String getToolsPath(Sdk sdk) {
+ public String getToolsPath(@NotNull Sdk sdk) {
final String versionString = sdk.getVersionString();
final boolean isJdk1_x = versionString != null && (versionString.contains("1.0") || versionString.contains("1.1"));
return getConvertedHomePath(sdk) + "lib" + File.separator + (isJdk1_x? "classes.zip" : "tools.jar");
}
@Override
- public String getVMExecutablePath(Sdk sdk) {
+ public String getVMExecutablePath(@NotNull Sdk sdk) {
return getBinPath(sdk) + File.separator + VM_EXE_NAME;
}
diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/impl/UnknownSdkType.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/impl/UnknownSdkType.java
index 98633e3..2b06e87 100644
--- a/platform/lang-api/src/com/intellij/openapi/projectRoots/impl/UnknownSdkType.java
+++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/impl/UnknownSdkType.java
@@ -19,6 +19,7 @@
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.*;
import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.HashMap;
@@ -35,11 +36,12 @@
/**
* @param typeName the name of the SDK type that this SDK serves as a plug for
*/
- private UnknownSdkType(String typeName) {
+ private UnknownSdkType(@NotNull String typeName) {
super(typeName);
}
- public static UnknownSdkType getInstance(String typeName) {
+ @NotNull
+ public static UnknownSdkType getInstance(@NotNull String typeName) {
UnknownSdkType instance = ourTypeNameToInstanceMap.get(typeName);
if (instance == null) {
instance = new UnknownSdkType(typeName);
@@ -86,7 +88,7 @@
}
@Override
- public void saveAdditionalData(SdkAdditionalData additionalData, Element additional) {
+ public void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional) {
}
@Override
diff --git a/platform/lang-api/src/com/intellij/refactoring/classMembers/AbstractMemberInfoModel.java b/platform/lang-api/src/com/intellij/refactoring/classMembers/AbstractMemberInfoModel.java
new file mode 100644
index 0000000..2869d0d
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/refactoring/classMembers/AbstractMemberInfoModel.java
@@ -0,0 +1,50 @@
+package com.intellij.refactoring.classMembers;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Nikolay.Tropin
+ * 8/23/13
+ */
+public abstract class AbstractMemberInfoModel<T extends PsiElement, M extends MemberInfoBase<T>> implements MemberInfoModel<T, M> {
+
+ @Override
+ public boolean isMemberEnabled(M member) {
+ return true;
+ }
+
+ @Override
+ public boolean isCheckedWhenDisabled(M member) {
+ return false;
+ }
+
+ @Override
+ public boolean isAbstractEnabled(M member) {
+ return false;
+ }
+
+ @Override
+ public boolean isAbstractWhenDisabled(M member) {
+ return false;
+ }
+
+ @Override
+ public Boolean isFixedAbstract(M member) {
+ return null;
+ }
+
+ @Override
+ public int checkForProblems(@NotNull M member) {
+ return OK;
+ }
+
+ @Override
+ public String getTooltipText(M member) {
+ return null;
+ }
+
+ @Override
+ public void memberInfoChanged(MemberInfoChange<T, M> event) {
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/application/options/ModuleAwareProjectConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/ModuleAwareProjectConfigurable.java
index f28bc87..51499b6 100644
--- a/platform/lang-impl/src/com/intellij/application/options/ModuleAwareProjectConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/application/options/ModuleAwareProjectConfigurable.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2013 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.application.options;
import com.intellij.openapi.module.Module;
@@ -6,10 +21,12 @@
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
+import com.intellij.openapi.util.Condition;
import com.intellij.platform.ModuleAttachProcessor;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -49,6 +66,10 @@
return myHelpTopic;
}
+ protected boolean isSuitableForModule(@NotNull Module module) {
+ return true;
+ }
+
@Override
public JComponent createComponent() {
if (myProject.isDefault()) {
@@ -58,7 +79,12 @@
return configurable.createComponent();
}
}
- final List<Module> modules = ModuleAttachProcessor.getSortedModules(myProject);
+ final List<Module> modules = ContainerUtil.filter(ModuleAttachProcessor.getSortedModules(myProject), new Condition<Module>() {
+ @Override
+ public boolean value(Module module) {
+ return isSuitableForModule(module);
+ }
+ });
if (modules.size() == 1) {
Module module = modules.get(0);
final T configurable = createModuleConfigurable(module);
@@ -98,6 +124,7 @@
return null;
}
+ @NotNull
protected abstract T createModuleConfigurable(Module module);
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java b/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java
index a289831..4048ad8 100644
--- a/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java
+++ b/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java
@@ -15,7 +15,11 @@
*/
package com.intellij.codeEditor.printing;
+import com.intellij.CommonBundle;
import com.intellij.ide.highlighter.HighlighterFactory;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationType;
+import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
@@ -155,6 +159,10 @@
LOG.info("Cancelled");
printerJob.cancel();
}
+ catch (PrinterException e) {
+ Notifications.Bus.notify(new Notification("Print", CommonBundle.getErrorTitle(), e.getMessage(), NotificationType.ERROR));
+ LOG.warn(e);
+ }
catch (Exception e) {
LOG.error(e);
}
@@ -170,7 +178,7 @@
if (isRecursive) {
for (PsiDirectory directory : psiDirectory.getSubdirectories()) {
if (!Project.DIRECTORY_STORE_FOLDER.equals(directory.getName())) {
- addToPsiFileList(directory, filesList, isRecursive);
+ addToPsiFileList(directory, filesList, true);
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/LayoutCodeDialog.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/LayoutCodeDialog.java
index c461c9e0..3914ce6 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/LayoutCodeDialog.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/LayoutCodeDialog.java
@@ -27,7 +27,6 @@
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.arrangement.Rearranger;
-import com.intellij.util.ui.OptionsDialog;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -202,7 +201,7 @@
updateState();
}
});
- return OptionsDialog.addDoNotShowCheckBox(southPanel, myDoNotAskMeCheckBox);
+ return DialogWrapper.addDoNotShowCheckBox(southPanel, myDoNotAskMeCheckBox);
}
@NotNull
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
index 1062bd4..2b3368f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
@@ -46,6 +46,7 @@
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
@@ -209,7 +210,7 @@
@NotNull TextEditor textEditor,
@NotNull int[] toIgnore,
boolean canChangeDocument,
- @Nullable Runnable callbackWhileWaiting) {
+ @Nullable Runnable callbackWhileWaiting) throws ProcessCanceledException {
assert myInitialized;
assert !myDisposed;
Application application = ApplicationManager.getApplication();
@@ -240,13 +241,7 @@
try {
while (progress.isRunning()) {
try {
- if (progress.isCanceled() && progress.isRunning()) {
- // write action sneaked in the AWT. restart
- waitForTermination();
- Throwable savedException = PassExecutorService.getSavedException(progress);
- if (savedException != null) throw savedException;
- return runPasses(file, document, textEditor, toIgnore, canChangeDocument, callbackWhileWaiting);
- }
+ progress.checkCanceled();
if (callbackWhileWaiting != null) {
callbackWhileWaiting.run();
}
@@ -292,7 +287,7 @@
waitForTermination();
}
- private void waitForTermination() {
+ void waitForTermination() {
myPassExecutorService.cancelAll(true);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
index f704286..013db8f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
@@ -120,7 +120,7 @@
boolean updateAll) {
this(project, file, document, startOffset, endOffset, updateAll, new ProperTextRange(0,document.getTextLength()), null);
}
- public GeneralHighlightingPass(@NotNull Project project,
+ GeneralHighlightingPass(@NotNull Project project,
@NotNull PsiFile file,
@NotNull Document document,
int startOffset,
@@ -385,9 +385,9 @@
final TextRange fixedTextRange = getFixedTextRange(documentWindow, startOffset);
addPatchedInfos(info, injectedPsi, documentWindow, injectedLanguageManager, fixedTextRange, outInfos);
}
- holder.clear();
+ int injectedStart = holder.size();
highlightInjectedSyntax(injectedPsi, holder);
- for (int i = 0; i < holder.size(); i++) {
+ for (int i = injectedStart; i < holder.size(); i++) {
HighlightInfo info = holder.get(i);
final int startOffset = info.startOffset;
final TextRange fixedTextRange = getFixedTextRange(documentWindow, startOffset);
@@ -523,7 +523,7 @@
}
}
- private void highlightInjectedSyntax(final PsiFile injectedPsi, HighlightInfoHolder holder) {
+ private void highlightInjectedSyntax(@NotNull PsiFile injectedPsi, @NotNull HighlightInfoHolder holder) {
List<Trinity<IElementType, SmartPsiElementPointer<PsiLanguageInjectionHost>, TextRange>> tokens = InjectedLanguageUtil
.getHighlightTokens(injectedPsi);
if (tokens == null) return;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
index 1c61666..5ce6e13 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
@@ -17,7 +17,6 @@
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
-import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.IntentionManager;
import com.intellij.codeInspection.*;
@@ -36,10 +35,7 @@
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.codeInsight.daemon.GutterMark;
import com.intellij.openapi.editor.markup.TextAttributes;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Segment;
-import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.PsiElement;
@@ -55,6 +51,7 @@
import javax.swing.*;
import java.awt.*;
+import java.util.Iterator;
import java.util.List;
public class HighlightInfo implements Segment {
@@ -73,8 +70,8 @@
public final int startOffset;
public final int endOffset;
- public int fixStartOffset;
- public int fixEndOffset;
+ private int fixStartOffset;
+ private int fixEndOffset;
RangeMarker fixMarker; // null means it the same as highlighter
private final String description;
@@ -84,7 +81,7 @@
final int navigationShift;
- RangeHighlighterEx highlighter;
+ volatile RangeHighlighterEx highlighter; // modified in EDT only
public List<Pair<IntentionActionDescriptor, TextRange>> quickFixActionRanges;
public List<Pair<IntentionActionDescriptor, RangeMarker>> quickFixActionMarkers;
@@ -100,6 +97,11 @@
private static final int FILE_LEVEL_ANNOTATION_FLAG = 4;
private static final int NEEDS_UPDATE_ON_TYPING_FLAG = 5;
+ @NotNull
+ ProperTextRange getFixTextRange() {
+ return new ProperTextRange(fixStartOffset, fixEndOffset);
+ }
+
public void setFromInjection(boolean fromInjection) {
setFlag(FROM_INJECTION_FLAG, fromInjection);
}
@@ -652,14 +654,16 @@
return info;
}
+ public static final String ANNOTATOR_INSPECTION_SHORT_NAME = "Annotator";
+
private static void appendFixes(@Nullable TextRange fixedRange, @NotNull HighlightInfo info, List<Annotation.QuickFixInfo> fixes) {
if (fixes != null) {
for (final Annotation.QuickFixInfo quickFixInfo : fixes) {
TextRange range = fixedRange != null ? fixedRange : quickFixInfo.textRange;
HighlightDisplayKey key = quickFixInfo.key != null
? quickFixInfo.key
- : HighlightDisplayKey.find(DefaultHighlightVisitorBasedInspection.AnnotatorBasedInspection.ANNOTATOR_SHORT_NAME);
- QuickFixAction.registerQuickFixAction(info, range, quickFixInfo.quickFix, key);
+ : HighlightDisplayKey.find(ANNOTATOR_INSPECTION_SHORT_NAME);
+ info.registerFix(quickFixInfo.quickFix, null, HighlightDisplayKey.getDisplayNameByKey(key), range, key);
}
}
}
@@ -821,7 +825,7 @@
ContainerUtil.addAll(newOptions, ContainerUtil.map(suppressActions, new Function<SuppressQuickFix, IntentionAction>() {
@Override
public IntentionAction fun(SuppressQuickFix fix) {
- return InspectionManagerEx.convertBatchToSuppressIntentionAction(fix);
+ return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction(fix);
}
}));
}
@@ -888,4 +892,32 @@
if (!highlighter.isValid()) return "";
return highlighter.getDocument().getText(TextRange.create(highlighter));
}
+
+ public void registerFix(@Nullable IntentionAction action,
+ @Nullable List<IntentionAction> options,
+ @Nullable String displayName,
+ @Nullable TextRange fixRange,
+ @Nullable HighlightDisplayKey key) {
+ if (action == null) return;
+ if (fixRange == null) fixRange = new TextRange(startOffset, endOffset);
+ if (quickFixActionRanges == null) {
+ quickFixActionRanges = ContainerUtil.createLockFreeCopyOnWriteList();
+ }
+ IntentionActionDescriptor desc = new IntentionActionDescriptor(action, options, displayName, null, key, getProblemGroup());
+ quickFixActionRanges.add(Pair.create(desc, fixRange));
+ fixStartOffset = Math.min (fixStartOffset, fixRange.getStartOffset());
+ fixEndOffset = Math.max (fixEndOffset, fixRange.getEndOffset());
+ if (action instanceof HintAction) {
+ setHint(true);
+ }
+ }
+
+ public void unregisterQuickFix(@NotNull Condition<IntentionAction> condition) {
+ for (Iterator<Pair<IntentionActionDescriptor, TextRange>> it = quickFixActionRanges.iterator(); it.hasNext();) {
+ Pair<IntentionActionDescriptor, TextRange> pair = it.next();
+ if (condition.value(pair.first.getAction())) {
+ it.remove();
+ }
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
index 9cc91a3..2470e0d 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
@@ -681,7 +681,7 @@
if (((ProblemDescriptorBase)descriptor).getEnforcedTextAttributes() != null) {
needEmptyAction = false;
}
- if (needEmptyAction && emptyActionRegistered.add(Pair.create(new TextRange(highlightInfo.fixStartOffset, highlightInfo.fixEndOffset), tool.getShortName()))) {
+ if (needEmptyAction && emptyActionRegistered.add(Pair.<TextRange, String>create(highlightInfo.getFixTextRange(), tool.getShortName()))) {
EmptyIntentionAction emptyIntentionAction = new EmptyIntentionAction(tool.getDisplayName());
QuickFixAction.registerQuickFixAction(highlightInfo, emptyIntentionAction, key);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java
index e30b8e0..6484893 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java
@@ -18,7 +18,6 @@
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
-import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.intention.AbstractIntentionAction;
import com.intellij.codeInsight.intention.IntentionAction;
@@ -40,6 +39,7 @@
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
+import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -50,6 +50,7 @@
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PairProcessor;
@@ -74,6 +75,62 @@
private volatile boolean myShowBulb;
private volatile boolean myHasToRecreate;
+ @NotNull
+ public static List<HighlightInfo.IntentionActionDescriptor> getAvailableActions(@NotNull final Editor editor, @NotNull final PsiFile file, final int passId) {
+ final int offset = editor.getCaretModel().getOffset();
+ final Project project = file.getProject();
+
+ final List<HighlightInfo.IntentionActionDescriptor> result = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
+ DaemonCodeAnalyzerImpl.processHighlightsNearOffset(editor.getDocument(), project, HighlightSeverity.INFORMATION, offset, true, new Processor<HighlightInfo>() {
+ @Override
+ public boolean process(HighlightInfo info) {
+ addAvailableActionsForGroups(info, editor, file, result, passId, offset);
+ return true;
+ }
+ });
+ return result;
+ }
+
+ private static void addAvailableActionsForGroups(@NotNull HighlightInfo info,
+ @NotNull Editor editor,
+ @NotNull PsiFile file,
+ @NotNull List<HighlightInfo.IntentionActionDescriptor> outList,
+ int group,
+ int offset) {
+ if (info.quickFixActionMarkers == null) return;
+ if (group != -1 && group != info.getGroup()) return;
+ Editor injectedEditor = null;
+ PsiFile injectedFile = null;
+ for (Pair<HighlightInfo.IntentionActionDescriptor, RangeMarker> pair : info.quickFixActionMarkers) {
+ HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
+ RangeMarker range = pair.second;
+ if (!range.isValid()) continue;
+ int start = range.getStartOffset();
+ int end = range.getEndOffset();
+ final Project project = file.getProject();
+ if (start > offset || offset > end) {
+ continue;
+ }
+ Editor editorToUse;
+ PsiFile fileToUse;
+ if (info.isFromInjection()) {
+ if (injectedEditor == null) {
+ injectedFile = InjectedLanguageUtil.findInjectedPsiNoCommit(file, offset);
+ injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
+ }
+ editorToUse = injectedEditor;
+ fileToUse = injectedFile;
+ }
+ else {
+ editorToUse = editor;
+ fileToUse = file;
+ }
+ if (actionInGroup.getAction().isAvailable(project, editorToUse, fileToUse)) {
+ outList.add(actionInGroup);
+ }
+ }
+ }
+
public static class IntentionsInfo {
public final List<HighlightInfo.IntentionActionDescriptor> intentionsToShow = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
public final List<HighlightInfo.IntentionActionDescriptor> errorFixesToShow = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
@@ -114,7 +171,7 @@
myEditor = editor;
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
-
+
myFile = documentManager.getPsiFile(myEditor.getDocument());
assert myFile != null : FileDocumentManager.getInstance().getFile(myEditor.getDocument());
}
@@ -202,7 +259,7 @@
int offset = hostEditor.getCaretModel().getOffset();
Project project = hostFile.getProject();
- List<HighlightInfo.IntentionActionDescriptor> fixes = QuickFixAction.getAvailableActions(hostEditor, hostFile, passIdToShowIntentionsFor);
+ List<HighlightInfo.IntentionActionDescriptor> fixes = getAvailableActions(hostEditor, hostFile, passIdToShowIntentionsFor);
final DaemonCodeAnalyzer codeAnalyzer = DaemonCodeAnalyzer.getInstance(project);
final Document hostDocument = hostEditor.getDocument();
HighlightInfo infoAtCursor = ((DaemonCodeAnalyzerImpl)codeAnalyzer).findHighlightByOffset(hostDocument, offset, true);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java
index 4e41c37..e2d5df0 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java
@@ -449,11 +449,11 @@
}
info.quickFixActionMarkers = ContainerUtil.createLockFreeCopyOnWriteList(list);
}
- if (finalInfoRange.equalsToRange(info.fixStartOffset, info.fixEndOffset)) {
+ ProperTextRange fixRange = info.getFixTextRange();
+ if (finalInfoRange.equals(fixRange)) {
info.fixMarker = null; // null means it the same as highlighter'
}
else {
- TextRange fixRange = new TextRange(info.fixStartOffset, info.fixEndOffset);
info.fixMarker = getOrCreate(document, ranges2markersCache, fixRange);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixAction.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixAction.java
index 6525bea..671f58b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixAction.java
@@ -17,25 +17,14 @@
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
-import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.codeInspection.HintAction;
-import com.intellij.lang.annotation.HighlightSeverity;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.RangeMarker;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
-import com.intellij.util.Processor;
-import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -54,114 +43,27 @@
registerQuickFixAction(info, null, action);
}
- public static void registerQuickFixActions(@Nullable final HighlightInfo info, @NotNull final Collection<? extends IntentionAction> actions) {
- for (IntentionAction action : actions) {
- registerQuickFixAction(info, action);
- }
- }
-
/** This is used by TeamCity plugin */
@Deprecated
- public static void registerQuickFixAction(@Nullable HighlightInfo info, @Nullable IntentionAction action, @Nullable List<IntentionAction> options, @Nullable String displayName) {
- doRegister(info, action, options, displayName, null, null);
+ public static void registerQuickFixAction(@Nullable HighlightInfo info,
+ @Nullable IntentionAction action,
+ @Nullable List<IntentionAction> options,
+ @Nullable String displayName) {
+ if (info == null) return;
+ info.registerFix(action, options, displayName, null, null);
}
- private static void doRegister(@Nullable HighlightInfo info,
- @Nullable IntentionAction action,
- @Nullable List<IntentionAction> options,
- @Nullable String displayName,
- @Nullable TextRange fixRange,
- @Nullable HighlightDisplayKey key) {
- if (info == null || action == null) return;
- if (fixRange == null) fixRange = new TextRange(info.startOffset, info.endOffset);
- if (info.quickFixActionRanges == null) {
- info.quickFixActionRanges = ContainerUtil.createLockFreeCopyOnWriteList();
- }
- HighlightInfo.IntentionActionDescriptor desc = new HighlightInfo.IntentionActionDescriptor(action, options, displayName, null, key, info.getProblemGroup());
- info.quickFixActionRanges.add(Pair.create(desc, fixRange));
- info.fixStartOffset = Math.min (info.fixStartOffset, fixRange.getStartOffset());
- info.fixEndOffset = Math.max (info.fixEndOffset, fixRange.getEndOffset());
- if (action instanceof HintAction) {
- info.setHint(true);
- }
- }
public static void registerQuickFixAction(@Nullable HighlightInfo info,
@Nullable TextRange fixRange,
@Nullable IntentionAction action,
@Nullable final HighlightDisplayKey key) {
- doRegister(info, action, null, HighlightDisplayKey.getDisplayNameByKey(key), fixRange, key);
+ if (info == null) return;
+ info.registerFix(action, null, HighlightDisplayKey.getDisplayNameByKey(key), fixRange, key);
}
public static void registerQuickFixAction(@Nullable HighlightInfo info, @Nullable TextRange fixRange, @Nullable IntentionAction action) {
- doRegister(info, action, null, null, fixRange, null);
- }
-
- public static void unregisterQuickFixAction(@NotNull HighlightInfo info, Condition<IntentionAction> condition) {
- for (Iterator<Pair<HighlightInfo.IntentionActionDescriptor, TextRange>> it = info.quickFixActionRanges.iterator(); it.hasNext();) {
- Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair = it.next();
- if (condition.value(pair.first.getAction())) {
- it.remove();
- }
- }
- }
-
- /**
- * Is invoked inside atomic action.
- */
- @NotNull
- public static List<HighlightInfo.IntentionActionDescriptor> getAvailableActions(@NotNull final Editor editor, @NotNull final PsiFile file, final int passId) {
- final int offset = editor.getCaretModel().getOffset();
- final Project project = file.getProject();
-
- final List<HighlightInfo.IntentionActionDescriptor> result = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
- DaemonCodeAnalyzerImpl.processHighlightsNearOffset(editor.getDocument(), project, HighlightSeverity.INFORMATION, offset, true, new Processor<HighlightInfo>() {
- @Override
- public boolean process(HighlightInfo info) {
- addAvailableActionsForGroups(info, editor, file, result, passId, offset);
- return true;
- }
- });
- return result;
- }
-
- private static void addAvailableActionsForGroups(@NotNull HighlightInfo info,
- @NotNull Editor editor,
- @NotNull PsiFile file,
- @NotNull List<HighlightInfo.IntentionActionDescriptor> outList,
- int group,
- int offset) {
- if (info.quickFixActionMarkers == null) return;
- if (group != -1 && group != info.getGroup()) return;
- Editor injectedEditor = null;
- PsiFile injectedFile = null;
- for (Pair<HighlightInfo.IntentionActionDescriptor, RangeMarker> pair : info.quickFixActionMarkers) {
- HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
- RangeMarker range = pair.second;
- if (!range.isValid()) continue;
- int start = range.getStartOffset();
- int end = range.getEndOffset();
- final Project project = file.getProject();
- if (start > offset || offset > end) {
- continue;
- }
- Editor editorToUse;
- PsiFile fileToUse;
- if (info.isFromInjection()) {
- if (injectedEditor == null) {
- injectedFile = InjectedLanguageUtil.findInjectedPsiNoCommit(file, offset);
- injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
- }
- editorToUse = injectedEditor;
- fileToUse = injectedFile;
- }
- else {
- editorToUse = editor;
- fileToUse = file;
- }
- if (actionInGroup.getAction().isAvailable(project, editorToUse, fileToUse)) {
- outList.add(actionInGroup);
- }
- }
+ if (info == null) return;
+ info.registerFix(action, null, null, fixRange, null);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixActionRegistrarImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixActionRegistrarImpl.java
index 3890dd4..3a44379 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixActionRegistrarImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixActionRegistrarImpl.java
@@ -45,7 +45,7 @@
@Override
public void unregister(@NotNull Condition<IntentionAction> condition) {
if (myInfo != null) {
- QuickFixAction.unregisterQuickFixAction(myInfo, condition);
+ myInfo.unregisterQuickFix(condition);
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
index 3892391..80aec67 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -19,6 +19,7 @@
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.completion.CompletionContributor;
import com.intellij.codeInsight.highlighting.BraceMatcher;
import com.intellij.codeInsight.highlighting.BraceMatchingUtil;
import com.intellij.codeInsight.highlighting.NontrivialBraceMatcher;
@@ -61,6 +62,7 @@
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
public class TypedHandler extends TypedActionHandlerBase {
@@ -173,7 +175,7 @@
}
if (!handled) {
- autoPopupCompletion(editor, charTyped, project);
+ autoPopupCompletion(editor, charTyped, project, file);
autoPopupParameterInfo(editor, charTyped, project, file);
}
@@ -248,12 +250,26 @@
}
}
- public static void autoPopupCompletion(Editor editor, char charTyped, Project project) {
- if (charTyped == '.') {
+ public static void autoPopupCompletion(Editor editor, char charTyped, Project project, PsiFile file) {
+ if (charTyped == '.' || isAutoPopup(editor, file, charTyped)) {
AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, null);
}
}
+ private static boolean isAutoPopup(Editor editor, PsiFile file, char charTyped) {
+ final int offset = editor.getCaretModel().getOffset() - 1;
+ if (offset >= 0) {
+ final PsiElement element = file.findElementAt(offset);
+ if (element != null) {
+ final List<CompletionContributor> list = CompletionContributor.forLanguage(element.getLanguage());
+ for (CompletionContributor contributor : list) {
+ if (contributor.invokeAutoPopup(element, charTyped)) return true;
+ }
+ }
+ }
+ return false;
+ }
+
private static boolean isInsideStringLiteral(final Editor editor, final PsiFile file) {
int offset = editor.getCaretModel().getOffset();
PsiElement element = file.findElementAt(offset);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java
index 9d0a8d4..be95eed 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -118,7 +118,7 @@
}
lookup.hide();
- TypedHandler.autoPopupCompletion(editor, charTyped, project);
+ TypedHandler.autoPopupCompletion(editor, charTyped, project, file);
return Result.CONTINUE;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java b/platform/lang-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java
new file mode 100644
index 0000000..d90efd7
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInspection/SuppressIntentionActionFromFix.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2013 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.codeInspection;
+
+import com.intellij.codeInsight.daemon.impl.actions.AbstractBatchSuppressByNoInspectionCommentFix;
+import com.intellij.codeInspection.*;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+
+public class SuppressIntentionActionFromFix extends SuppressIntentionAction {
+ private final SuppressQuickFix myFix;
+
+ private SuppressIntentionActionFromFix(@NotNull SuppressQuickFix fix) {
+ myFix = fix;
+ }
+
+ @NotNull
+ public static SuppressIntentionAction convertBatchToSuppressIntentionAction(@NotNull final SuppressQuickFix fix) {
+ return new SuppressIntentionActionFromFix(fix);
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
+ PsiElement container = myFix instanceof AbstractBatchSuppressByNoInspectionCommentFix
+ ? ((AbstractBatchSuppressByNoInspectionCommentFix )myFix).getContainer(element) : null;
+ boolean caretWasBeforeStatement = editor != null && container != null && editor.getCaretModel().getOffset() == container.getTextRange().getStartOffset();
+ InspectionManager inspectionManager = InspectionManager.getInstance(project);
+ ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(element, element, "", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false);
+ myFix.applyFix(project, descriptor);
+
+ if (caretWasBeforeStatement) {
+ editor.getCaretModel().moveToOffset(container.getTextRange().getStartOffset());
+ }
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
+ return myFix.isAvailable(project, element);
+ }
+
+ @NotNull
+ @Override
+ public String getText() {
+ return myFix.getName();
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return myFix.getFamilyName();
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ModuleRunConfigurationManager.java b/platform/lang-impl/src/com/intellij/execution/impl/ModuleRunConfigurationManager.java
index 2610b38..b17e2f0 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/ModuleRunConfigurationManager.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/ModuleRunConfigurationManager.java
@@ -28,8 +28,10 @@
import com.intellij.openapi.project.ModuleAdapter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -37,6 +39,7 @@
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -51,19 +54,23 @@
public final class ModuleRunConfigurationManager extends ModuleAdapter implements ModuleComponent, PersistentStateComponent<Element> {
private static final Logger LOG = Logger.getInstance(ModuleRunConfigurationManager.class);
@NonNls static final String COMPONENT_NAME = "ModuleRunConfigurationManager";
-
- final Object myRemoverKey;
+ @NotNull
+ private final Condition<RunnerAndConfigurationSettings> myModuleConfigCondition = new Condition<RunnerAndConfigurationSettings>() {
+ @Override
+ public boolean value(@Nullable RunnerAndConfigurationSettings settings) {
+ return settings != null && usesMyModule(settings.getConfiguration());
+ }
+ };
@NotNull
private final Module myModule;
@NotNull
- final RunManagerImpl myManager;
+ private final RunManagerImpl myManager;
@Nullable
private List<Element> myUnloadedElements = null;
public ModuleRunConfigurationManager(@NotNull final Module module, @NotNull final RunManagerImpl runManager) {
myModule = module;
myManager = runManager;
- myRemoverKey = new Object();
}
@Override
@@ -118,6 +125,11 @@
}
}
+ @NotNull
+ private Collection<? extends RunnerAndConfigurationSettings> getModuleRunConfigurationSettings() {
+ return ContainerUtil.filter(myManager.getConfigurationSettings(), myModuleConfigCondition);
+ }
+
private boolean usesMyModule(RunConfiguration config) {
return config instanceof ModuleBasedConfiguration
&& myModule.equals(((ModuleBasedConfiguration)config).getConfigurationModule().getModule());
@@ -125,7 +137,7 @@
public void writeExternal(@NotNull final Element element) throws WriteExternalException {
LOG.debug("writeExternal(" + myModule + ")");
- for (final RunnerAndConfigurationSettings settings : myManager.getExternalSettings(myRemoverKey)) {
+ for (final RunnerAndConfigurationSettings settings : getModuleRunConfigurationSettings()) {
myManager.addConfigurationElement(element, settings);
}
if (myUnloadedElements != null) {
@@ -142,7 +154,7 @@
final List children = element.getChildren();
for (final Object child : children) {
- final RunnerAndConfigurationSettings configuration = myManager.loadConfiguration(myRemoverKey, (Element)child, true);
+ final RunnerAndConfigurationSettings configuration = myManager.loadConfiguration((Element)child, true);
if (configuration == null && Comparing.strEqual(element.getName(), RunManagerImpl.CONFIGURATION)) {
if (myUnloadedElements == null) myUnloadedElements = new ArrayList<Element>(2);
myUnloadedElements.add(element);
@@ -168,9 +180,12 @@
}
@Override
- public void moduleRemoved(Project project, Module module) {
+ public void beforeModuleRemoved(Project project, Module module) {
if (myModule.equals(module)) {
- myManager.removeExternalSettings(myRemoverKey);
+ LOG.debug("time to remove something from project (" + project + ")");
+ for (final RunnerAndConfigurationSettings settings : getModuleRunConfigurationSettings()) {
+ myManager.removeConfiguration(settings);
+ }
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java
index f645686..2143665 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -23,6 +23,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector;
import com.intellij.openapi.util.*;
import com.intellij.ui.IconDeferrer;
import com.intellij.util.EventDispatcher;
@@ -49,8 +50,6 @@
new HashMap<String, RunnerAndConfigurationSettings>();
private final Map<String, RunnerAndConfigurationSettings> myConfigurations =
new LinkedHashMap<String, RunnerAndConfigurationSettings>(); // template configurations are not included here
- final Map<Object, List<RunnerAndConfigurationSettings>> myExternalSettings =
- new java.util.HashMap<Object, List<RunnerAndConfigurationSettings>>();
private final Map<String, Boolean> mySharedConfigurations = new TreeMap<String, Boolean>();
private final Map<RunConfiguration, List<BeforeRunTask>> myConfigurationToBeforeTasksMap = new WeakHashMap<RunConfiguration, List<BeforeRunTask>>();
@@ -224,11 +223,6 @@
}
@NotNull
- public List<RunnerAndConfigurationSettings> getExternalSettings(@NotNull Object key) {
- return myExternalSettings.containsKey(key) ? myExternalSettings.get(key) : Collections.<RunnerAndConfigurationSettings>emptyList();
- }
-
- @NotNull
@Override
public List<RunnerAndConfigurationSettings> getAllSettings() {
return Collections.unmodifiableList(new ArrayList<RunnerAndConfigurationSettings>(getSortedConfigurations()));
@@ -403,9 +397,6 @@
@Override
public void removeConfiguration(@Nullable RunnerAndConfigurationSettings settings) {
if (settings == null) return;
- for (Map.Entry<Object, List<RunnerAndConfigurationSettings>> entry : myExternalSettings.entrySet()) {
- if (entry.getValue().remove(settings)) break;
- }
for (Iterator<RunnerAndConfigurationSettings> it = getSortedConfigurations().iterator(); it.hasNext(); ) {
final RunnerAndConfigurationSettings configuration = it.next();
@@ -786,21 +777,8 @@
fireRunConfigurationsRemoved(configurations);
}
- public void removeExternalSettings(@NotNull Object removerKey) {
- List<RunnerAndConfigurationSettings> settingsList = getExternalSettings(removerKey);
- for (RunnerAndConfigurationSettings each : settingsList) {
- removeConfiguration(each);
- }
- myExternalSettings.remove(removerKey);
- }
-
@Nullable
public RunnerAndConfigurationSettings loadConfiguration(final Element element, boolean isShared) throws InvalidDataException {
- return loadConfiguration(null, element, isShared);
- }
-
- @Nullable
- public RunnerAndConfigurationSettings loadConfiguration(@Nullable final Object removerKey, final Element element, boolean isShared) throws InvalidDataException {
final RunnerAndConfigurationSettingsImpl settings = new RunnerAndConfigurationSettingsImpl(this);
settings.readExternal(element);
ConfigurationFactory factory = settings.getFactory();
@@ -808,13 +786,6 @@
return null;
}
- if (removerKey !=null) {
- if (!myExternalSettings.containsKey(removerKey)) {
- myExternalSettings.put(removerKey, new ArrayList<RunnerAndConfigurationSettings>());
- }
- myExternalSettings.get(removerKey).add(settings);
- }
-
final Element methodsElement = element.getChild(METHOD);
final List<BeforeRunTask> tasks = readStepsBeforeRun(methodsElement, settings);
if (settings.isTemplate()) {
@@ -857,7 +828,15 @@
@Nullable
public ConfigurationFactory getFactory(final String typeName, String factoryName) {
+ return getFactory(typeName, factoryName, false);
+ }
+
+ @Nullable
+ public ConfigurationFactory getFactory(final String typeName, String factoryName, boolean checkUnknown) {
final ConfigurationType type = myTypesByName.get(typeName);
+ if (type == null && checkUnknown && typeName != null) {
+ UnknownFeaturesCollector.getInstance(myProject).registerUnknownRunConfiguration(typeName);
+ }
if (factoryName == null) {
factoryName = type != null ? type.getConfigurationFactories()[0].getName() : null;
}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java
index f0d6aa1e..55bdd85 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -188,7 +188,7 @@
private ConfigurationFactory getFactory(final Element element) {
final String typeName = element.getAttributeValue(CONFIGURATION_TYPE_ATTRIBUTE);
String factoryName = element.getAttributeValue(FACTORY_NAME_ATTRIBUTE);
- return myManager.getFactory(typeName, factoryName);
+ return myManager.getFactory(typeName, factoryName, !myIsTemplate);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/find/actions/CompositeActiveComponent.java b/platform/lang-impl/src/com/intellij/find/actions/CompositeActiveComponent.java
index 8697eb0..a06fb74 100644
--- a/platform/lang-impl/src/com/intellij/find/actions/CompositeActiveComponent.java
+++ b/platform/lang-impl/src/com/intellij/find/actions/CompositeActiveComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -28,7 +28,8 @@
public CompositeActiveComponent(@NotNull ActiveComponent... components) {
myComponents = components;
- myComponent = new JPanel(new FlowLayout());
+ myComponent = new JPanel(new FlowLayout(FlowLayout.CENTER, 2, 0));
+ myComponent.setBorder(null);
myComponent.setOpaque(false);
for (ActiveComponent component : components) {
myComponent.add(component.getComponent());
diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
index 02e99eb..1572fd3 100644
--- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
+++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -636,31 +636,14 @@
return processIcon;
}
};
- builder.setCommandButton(new CompositeActiveComponent(spinningProgress, settingsButton));
+ final DefaultActionGroup pinGroup = new DefaultActionGroup();
+ final ActiveComponent pin = createPinButton(descriptor, usageView, options, popup, pinGroup);
+ builder.setCommandButton(new CompositeActiveComponent(spinningProgress, settingsButton, pin));
DefaultActionGroup toolbar = new DefaultActionGroup();
usageView.addFilteringActions(toolbar);
- toolbar.add(UsageGroupingRuleProviderImpl.createGroupByFileStructureAction(usageView));
- toolbar.add(new AnAction("Open Find Usages Toolwindow", "Show all usages in a separate toolwindow", AllIcons.Toolwindows.ToolWindowFind) {
- {
- AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES);
- setShortcutSet(action.getShortcutSet());
- }
- @Override
- public void actionPerformed(AnActionEvent e) {
- hideHints();
- popup[0].cancel();
- FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(usageView.getProject())).getFindUsagesManager();
- FindUsagesManager.SearchData data = new FindUsagesManager.SearchData();
- data.myOptions = options;
- List<SmartPsiElementPointer<PsiElement>> plist = descriptor.getAllElementPointers();
-
- data.myElements = plist.toArray(new SmartPsiElementPointer[plist.size()]);
- findUsagesManager.rerunAndRecallFromHistory(data);
- }
- });
-
+ toolbar.add(UsageGroupingRuleProviderImpl.createGroupByFileStructureAction(usageView));
ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.USAGE_VIEW_TOOLBAR, toolbar, true);
actionToolbar.setReservePlaceAutoPopupIcon(false);
final JComponent toolBar = actionToolbar.getComponent();
@@ -679,9 +662,56 @@
action.registerCustomShortcutSet(action.getShortcutSet(), content);
}
+ for (AnAction action : pinGroup.getChildren(null)) {
+ action.unregisterCustomShortcutSet(usageView.getComponent());
+ action.registerCustomShortcutSet(action.getShortcutSet(), content);
+ }
+
return popup[0];
}
+ private ActiveComponent createPinButton(final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
+ final UsageViewImpl usageView,
+ final FindUsagesOptions options, final JBPopup[] popup, DefaultActionGroup pinGroup) {
+ final AnAction pinAction =
+ new AnAction("Open Find Usages Toolwindow", "Show all usages in a separate toolwindow", AllIcons.General.AutohideOff) {
+ {
+ AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES);
+ setShortcutSet(action.getShortcutSet());
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ hideHints();
+ popup[0].cancel();
+ FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(usageView.getProject())).getFindUsagesManager();
+ FindUsagesManager.SearchData data = new FindUsagesManager.SearchData();
+ data.myOptions = options;
+ List<SmartPsiElementPointer<PsiElement>> plist = descriptor.getAllElementPointers();
+
+ data.myElements = plist.toArray(new SmartPsiElementPointer[plist.size()]);
+ findUsagesManager.rerunAndRecallFromHistory(data);
+ }
+ };
+ pinGroup.add(pinAction);
+ final ActionToolbar pinToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.USAGE_VIEW_TOOLBAR, pinGroup, true);
+ pinToolbar.setReservePlaceAutoPopupIcon(false);
+ final JComponent pinToolBar = pinToolbar.getComponent();
+ pinToolBar.setBorder(null);
+ pinToolBar.setOpaque(false);
+
+ return new ActiveComponent() {
+ @Override
+ public void setActive(boolean active) {
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return pinToolBar;
+ }
+ };
+ }
+
@NotNull
private static String getFullTitle(@NotNull List<Usage> usages,
@NotNull String title,
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
index 7febef7..4847d13 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
@@ -24,6 +24,7 @@
import com.intellij.find.*;
import com.intellij.find.findUsages.FindUsagesManager;
import com.intellij.find.impl.livePreview.SearchResults;
+import com.intellij.ide.highlighter.custom.CustomFileHighlighter;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.ParserDefinition;
@@ -48,6 +49,7 @@
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
+import com.intellij.openapi.fileTypes.impl.AbstractFileType;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
@@ -437,53 +439,65 @@
lang = ((LanguageFileType)ftype).getLanguage();
}
- if(lang == null) return NOT_FOUND_RESULT;
-
CommentsLiteralsSearchData data = model.getUserData(ourCommentsLiteralsSearchDataKey);
if (data == null || !Comparing.equal(data.lastFile, file)) {
- SyntaxHighlighter lexer = getHighlighter(file, lang);
+ SyntaxHighlighter lexer;
TokenSet tokensOfInterest = TokenSet.EMPTY;
- final Language finalLang = lang;
- Set<Language> relevantLanguages = ApplicationManager.getApplication().runReadAction(new Computable<Set<Language>>() {
- @Override
- public Set<Language> compute() {
- THashSet<Language> result = new THashSet<Language>();
+ Set<Language> relevantLanguages = null;
+ if (lang != null) {
+ lexer = getHighlighter(file, lang);
+ final Language finalLang = lang;
+ relevantLanguages = ApplicationManager.getApplication().runReadAction(new Computable<Set<Language>>() {
+ @Override
+ public Set<Language> compute() {
+ THashSet<Language> result = new THashSet<Language>();
- for(Project project:ProjectManager.getInstance().getOpenProjects()) {
- FileViewProvider viewProvider = PsiManager.getInstance(project).findViewProvider(file);
- if (viewProvider != null) {
- result.addAll(viewProvider.getLanguages());
- break;
+ for(Project project: ProjectManager.getInstance().getOpenProjects()) {
+ FileViewProvider viewProvider = PsiManager.getInstance(project).findViewProvider(file);
+ if (viewProvider != null) {
+ result.addAll(viewProvider.getLanguages());
+ break;
+ }
}
+
+ if (result.isEmpty()) {
+ result.add(finalLang);
+ }
+ return result;
+ }
+ });
+
+ for (Language relevantLanguage:relevantLanguages) {
+ tokensOfInterest = addTokenTypesForLanguage(model, relevantLanguage, tokensOfInterest);
+ }
+
+ if(model.isInStringLiteralsOnly()) {
+ // TODO: xml does not have string literals defined so we add XmlAttributeValue element type as convenience
+ final Lexer xmlLexer = getHighlighter(null, Language.findLanguageByID("XML")).getHighlightingLexer();
+ final String marker = "xxx";
+ xmlLexer.start("<a href=\"" + marker+ "\" />");
+
+ while (!marker.equals(xmlLexer.getTokenText())) {
+ xmlLexer.advance();
+ if (xmlLexer.getTokenType() == null) break;
}
- if (result.isEmpty()) {
- result.add(finalLang);
+ IElementType convenienceXmlAttrType = xmlLexer.getTokenType();
+ if (convenienceXmlAttrType != null) {
+ tokensOfInterest = TokenSet.orSet(tokensOfInterest, TokenSet.create(convenienceXmlAttrType));
}
- return result;
}
- });
-
- for (Language relevantLanguage:relevantLanguages) {
- tokensOfInterest = addTokenTypesForLanguage(model, relevantLanguage, tokensOfInterest);
- }
-
- if(model.isInStringLiteralsOnly()) {
- // TODO: xml does not have string literals defined so we add XmlAttributeValue element type as convenience
- final Lexer xmlLexer = getHighlighter(null, Language.findLanguageByID("XML")).getHighlightingLexer();
- final String marker = "xxx";
- xmlLexer.start("<a href=\"" + marker+ "\" />");
-
- while (!marker.equals(xmlLexer.getTokenText())) {
- xmlLexer.advance();
- if (xmlLexer.getTokenType() == null) break;
+ } else if (ftype instanceof AbstractFileType) {
+ if (model.isInCommentsOnly()) {
+ tokensOfInterest = TokenSet.create(CustomHighlighterTokenType.LINE_COMMENT, CustomHighlighterTokenType.MULTI_LINE_COMMENT);
}
-
- IElementType convenienceXmlAttrType = xmlLexer.getTokenType();
- if (convenienceXmlAttrType != null) {
- tokensOfInterest = TokenSet.orSet(tokensOfInterest, TokenSet.create(convenienceXmlAttrType));
+ if (model.isInStringLiteralsOnly()) {
+ tokensOfInterest = TokenSet.orSet(tokensOfInterest, TokenSet.create(CustomHighlighterTokenType.STRING, CustomHighlighterTokenType.SINGLE_QUOTED_STRING));
}
+ lexer = new CustomFileHighlighter(((AbstractFileType)ftype).getSyntaxTable());
+ } else {
+ return NOT_FOUND_RESULT;
}
Matcher matcher = model.isRegularExpressions() ? compileRegExp(model, ""):null;
@@ -493,7 +507,7 @@
}
final Lexer lexer = data.highlighter.getHighlightingLexer();
- lexer.start(text, data.startOffset, text.length(), 0);
+ lexer.start(text, model.isForward() && data.startOffset < offset ? data.startOffset : 0, text.length(), 0);
IElementType tokenType;
TokenSet tokens = data.tokensOfInterest;
@@ -506,21 +520,40 @@
if (lexer.getState() == 0) lastGoodOffset = lexer.getTokenStart();
final TextAttributesKey[] keys = data.highlighter.getTokenHighlights(tokenType);
- if (tokens.contains(tokenType) || (model.isInStringLiteralsOnly() && isHighlightedAsString(keys))) {
+
+ if (tokens.contains(tokenType) ||
+ (model.isInStringLiteralsOnly() && isHighlightedAsString(keys)) ||
+ (model.isInCommentsOnly() && isHighlightedAsDocComment(keys))
+ ) {
int start = lexer.getTokenStart();
- if (start >= offset || !scanningForward) {
+ while(true) {
FindResultImpl findResult = null;
if (data.searcher != null) {
int i = data.searcher.scan(text, textArray, start, lexer.getTokenEnd());
- if (i != -1) findResult = new FindResultImpl(i, i + model.getStringToFind().length());
+
+ if (i != -1 && i >= start) {
+ final int matchEnd = i + model.getStringToFind().length();
+ if (start >= offset || !scanningForward)
+ findResult = new FindResultImpl(i, matchEnd);
+ else {
+ start = matchEnd;
+ continue;
+ }
+ }
} else {
data.matcher.reset(text.subSequence(start, lexer.getTokenEnd()));
if (data.matcher.find()) {
- int matchStart = data.matcher.start();
- findResult = new FindResultImpl(start + matchStart, start + data.matcher.end());
+ final int matchEnd = start + data.matcher.end();
+ if (start >= offset || !scanningForward) {
+ findResult = new FindResultImpl(start + data.matcher.start(), matchEnd);
+ }
+ else {
+ start = matchEnd;
+ continue;
+ }
}
}
@@ -529,10 +562,14 @@
data.startOffset = lastGoodOffset;
return findResult;
} else {
- if (start >= offset) return prevFindResult;
+
+ if (findResult.getStartOffset() >= offset) return prevFindResult;
prevFindResult = findResult;
+ start = findResult.getEndOffset();
+ continue;
}
}
+ break;
}
} else {
Language tokenLang = tokenType.getLanguage();
@@ -549,6 +586,19 @@
return prevFindResult;
}
+ private static boolean isHighlightedAsDocComment(TextAttributesKey... keys) {
+ for (TextAttributesKey key : keys) {
+ if (key == DefaultLanguageHighlighterColors.DOC_COMMENT || key == SyntaxHighlighterColors.DOC_COMMENT) {
+ return true;
+ }
+ final TextAttributesKey fallbackAttributeKey = key.getFallbackAttributeKey();
+ if (fallbackAttributeKey != null && isHighlightedAsDocComment(fallbackAttributeKey)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private static boolean isHighlightedAsString(TextAttributesKey... keys) {
for (TextAttributesKey key : keys) {
if (key == DefaultLanguageHighlighterColors.STRING || key == SyntaxHighlighterColors.STRING) {
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
index a02e77f..cbdb43e 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -24,6 +24,7 @@
import com.intellij.ide.ui.search.BooleanOptionDescription;
import com.intellij.ide.ui.search.OptionDescription;
import com.intellij.ide.ui.search.SearchableOptionsRegistrarImpl;
+import com.intellij.ide.util.DefaultPsiElementCellRenderer;
import com.intellij.ide.util.gotoByName.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
@@ -33,6 +34,7 @@
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.SearchableConfigurable;
@@ -42,9 +44,9 @@
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.ComponentPopupBuilder;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
@@ -55,11 +57,13 @@
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.*;
import com.intellij.ui.border.CustomLineBorder;
+import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.OnOffButton;
import com.intellij.util.Alarm;
@@ -80,6 +84,7 @@
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
+import java.lang.reflect.Field;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -98,14 +103,30 @@
private String[] myActions;
private Component myFocusComponent;
private JBPopup myPopup;
+ private int myLeftWidth;
+ private SearchListModel myListModel = new SearchListModel();
+ private TitleIndexes myTitleIndexes;
private Map<String, String> myConfigurables = new HashMap<String, String>();
private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, ApplicationManager.getApplication());
- private JList myList = new JList(); //don't use JBList here!!! todo[kb]
+ private JBList myList = new JBList(myListModel) {
+ {
+ setOpaque(false);
+ }
+ @Override
+ protected void paintComponent(Graphics g) {
+ g.setColor(getTitlePanelBackground());
+ g.fillRect(0, 0, myLeftWidth - 1, getHeight());
+ g.setColor(getSeparatorColor());
+ g.drawLine(myLeftWidth-1, 0, myLeftWidth-1, getHeight());
+ super.paintComponent(g);
+ }
+ };
private AnActionEvent myActionEvent;
private Component myContextComponent;
private CalcThread myCalcThread;
private static AtomicBoolean ourShiftCanBeUsed = new AtomicBoolean(false);
+ private ArrayList<VirtualFile> myAlreadyAddedFiles = new ArrayList<VirtualFile>();
static {
IdeEventQueue.getInstance().addPostprocessor(new IdeEventQueue.EventDispatcher() {
@@ -117,10 +138,11 @@
return false;
}
}, null);
-
}
private int myTopHitsCount;
+ private int myInitialWidth;
+ private int myInitialHeight;
public SearchEverywhereAction() {
createSearchField();
@@ -155,25 +177,16 @@
@Override
protected void textChanged(DocumentEvent e) {
final String pattern = editor.getText();
+ final int len = pattern.trim().length();
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
- if (StringUtil.isEmpty(pattern.trim())) {
- //noinspection SSBasedInspection
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- if (myPopup != null && myPopup.isVisible()) {
- myPopup.cancel();
- }
- }
- });
- return;
+ if (field != null && field.getTextEditor().hasFocus()) {
+ rebuildList(pattern);
}
- rebuildList(pattern);
}
- }, Registry.intValue("ide.goto.rebuild.delay"));
+ }, /*Registry.intValue("ide.goto.rebuild.delay")*/ len == 1 ? 400 : len == 2 ? 300 : len == 3 ? 250 : 30);
}
});
editor.addFocusListener(new FocusAdapter() {
@@ -181,7 +194,7 @@
public void focusGained(FocusEvent e) {
field.setText("");
field.getTextEditor().setForeground(UIUtil.getLabelForeground());
-
+ myTitleIndexes = new TitleIndexes();
editor.setColumns(25);
myFocusComponent = e.getOppositeComponent();
//noinspection SSBasedInspection
@@ -193,6 +206,11 @@
parent.repaint();
}
});
+ if (myPopup != null && myPopup.isVisible()) {
+ myPopup.cancel();
+ myPopup = null;
+ }
+ rebuildList("");
}
@Override
@@ -205,7 +223,10 @@
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
- if (keyCode == KeyEvent.VK_ESCAPE && (myPopup == null || !myPopup.isVisible())) {
+ if (keyCode == KeyEvent.VK_ESCAPE) {
+ if (myPopup != null && myPopup.isVisible()) {
+ myPopup.cancel();
+ }
IdeFocusManager focusManager = IdeFocusManager.findInstanceByComponent(editor);
focusManager.requestDefaultFocus(true);
}
@@ -225,13 +246,7 @@
myCalcThread = null;
}
myAlarm.cancelAllRequests();
- myList.setModel(new DefaultListModel());
- myClassModel = null;
- myFileModel = null;
- myActionModel = null;
- myClasses = null;
- myFiles = null;
- myActions = null;
+ myListModel.clear();
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@@ -254,31 +269,35 @@
}
AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
- if (value instanceof PsiElement) {
- NavigationUtil.activateFileWithPsiElement((PsiElement)value, true);
- return;
- } else if (isVirtualFile(value)) {
- OpenFileDescriptor navigatable = new OpenFileDescriptor(project, (VirtualFile)value);
- if (navigatable.canNavigate()) {
- navigatable.navigate(true);
+ if (value instanceof PsiElement) {
+ NavigationUtil.activateFileWithPsiElement((PsiElement)value, true);
return;
}
- } else {
- focusManager.requestDefaultFocus(true);
- IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() {
- @Override
- public void run() {
- if (value instanceof BooleanOptionDescription) {
- final BooleanOptionDescription option = (BooleanOptionDescription)value;
- option.setOptionState(!option.isOptionEnabled());
- } else {
- GotoActionAction.openOptionOrPerformAction(value, pattern, project, myContextComponent ,myActionEvent);
- }
+ else if (isVirtualFile(value)) {
+ OpenFileDescriptor navigatable = new OpenFileDescriptor(project, (VirtualFile)value);
+ if (navigatable.canNavigate()) {
+ navigatable.navigate(true);
+ return;
}
- });
- return;
+ }
+ else {
+ focusManager.requestDefaultFocus(true);
+ IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() {
+ @Override
+ public void run() {
+ if (value instanceof BooleanOptionDescription) {
+ final BooleanOptionDescription option = (BooleanOptionDescription)value;
+ option.setOptionState(!option.isOptionEnabled());
+ }
+ else {
+ GotoActionAction.openOptionOrPerformAction(value, pattern, project, myContextComponent, myActionEvent);
+ }
+ }
+ });
+ return;
+ }
}
- } finally {
+ finally {
token.finish();
}
focusManager.requestDefaultFocus(true);
@@ -291,6 +310,7 @@
final Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(field.getTextEditor()));
assert project != null;
+ myRenderer.myProject = project;
myCalcThread = new CalcThread(project, pattern);
myCalcThread.start();
}
@@ -339,7 +359,9 @@
}
};
private String myLocationString;
+ private DefaultPsiElementCellRenderer myPsiRenderer = new DefaultPsiElementCellRenderer();
private Icon myLocationIcon;
+ private Project myProject;
private JPanel myMainPanel = new JPanel(new BorderLayout());
private JLabel myTitle = new JLabel();
private JPanel myLeftPanel = new JPanel(new BorderLayout()) {
@@ -353,11 +375,6 @@
return new Dimension(myLeftWidth, super.getPreferredSize().height);
}
};
- private int myLeftWidth;
-
- public void setLeftWidth(int width) {
- myLeftWidth = width;
- }
@Override
public void clear() {
@@ -377,7 +394,16 @@
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
- Component cmp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ Component cmp;
+ PsiFile file;
+ myLocationString = null;
+ if (value instanceof VirtualFile && myProject != null && (file = PsiManager.getInstance(myProject).findFile((VirtualFile)value)) != null) {
+ cmp = new GotoFileCellRenderer(list.getWidth()).getListCellRendererComponent(list, file, index, isSelected, cellHasFocus);
+ } else if (value instanceof PsiElement) {
+ cmp = myPsiRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ } else {
+ cmp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ }
if (myLocationString != null || value instanceof BooleanOptionDescription) {
final JPanel panel = new JPanel(new BorderLayout());
panel.add(cmp, BorderLayout.CENTER);
@@ -386,7 +412,8 @@
final OnOffButton button = new OnOffButton();
button.setSelected(((BooleanOptionDescription)value).isOptionEnabled());
rightComponent = button;
- } else {
+ }
+ else {
rightComponent = myLocation.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
panel.add(rightComponent, BorderLayout.EAST);
@@ -394,55 +421,15 @@
}
cmp.setBackground(isSelected ? UIUtil.getListSelectionBackground() : getRightBackground());
- String title = getTitle(index, value, index == 0 ? null : list.getModel().getElementAt(index -1));
+ String title = myTitleIndexes.getTitle(index);
myTitle.setText(title == null ? "" : title);
myLeftPanel.removeAll();
- myLeftPanel.setBackground(new JBColor(Gray._242, JBColor.background()));
+ myLeftPanel.setBackground(getTitlePanelBackground());
myMainPanel.removeAll();
myLeftPanel.add(myTitle, BorderLayout.EAST);
myMainPanel.add(myLeftPanel, BorderLayout.WEST);
myMainPanel.add(cmp, BorderLayout.CENTER);
return myMainPanel;
- }
-
- private Color getRightBackground() {
- return UIUtil.isUnderAquaLookAndFeel() ? Gray._236 : UIUtil.getListBackground();
- }
-
-
- private String getTitle(int index, Object value, Object prevValue) {
- if (index == 0 && myTopHitsCount > 0) {
- return myTopHitsCount == 1 ? "Top Hit" : "Top Hits";
- }
- if (index < myTopHitsCount) {
- return null;
- }
- if (index == myTopHitsCount) {
- prevValue = null;
- }
- String gotoClass = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoClass"));
- gotoClass = StringUtil.isEmpty(gotoClass) ? "Classes" : "Classes (" + gotoClass + ")";
- String gotoFile = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoFile"));
- gotoFile = StringUtil.isEmpty(gotoFile) ? "Files" : "Files (" + gotoFile + ")";
- String gotoAction = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoAction"));
- gotoAction = StringUtil.isEmpty(gotoAction) ? "Actions" : "Actions (" + gotoAction + ")";
- String gotoSettings = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("ShowSettings"));
- gotoSettings = StringUtil.isEmpty(gotoAction) ? "Preferences" : "Preferences (" + gotoSettings + ")";
- String toolWindows = "Tool Windows";
- if (prevValue == null) { // firstElement
- if (value instanceof PsiElement)return gotoClass;
- if (isVirtualFile(value))return gotoFile;
- if (isToolWindowAction(value)) return toolWindows;
- if (isSetting(value)) return gotoSettings;
- if (isActionValue(value))return gotoAction;
- return gotoSettings;
- } else {
- if (!isVirtualFile(prevValue) && isVirtualFile(value)) return gotoFile;
- if (!isSetting(prevValue) && isSetting(value)) return gotoSettings;
- if (!isToolWindowAction(prevValue) && isToolWindowAction(value)) return toolWindows;
- if ((!isActionValue(prevValue) || isToolWindowAction(prevValue)) && isActionValue(value)) return gotoAction;
- }
- return null;
}
@Override
@@ -457,7 +444,8 @@
}
else if (isVirtualFile(value)) {
append(((VirtualFile)value).getName());
- } else if (isActionValue(value)) {
+ }
+ else if (isActionValue(value)) {
final Map.Entry actionWithParentGroup = value instanceof Map.Entry ? (Map.Entry)value : null;
final AnAction anAction = actionWithParentGroup == null ? (AnAction)value : (AnAction)actionWithParentGroup.getKey();
final Presentation templatePresentation = anAction.getTemplatePresentation();
@@ -514,7 +502,7 @@
while (index < model.getSize()) {
Object el = model.getElementAt(index);
Object prev = index == 0 ? null : model.getElementAt(index - 1);
- String title = getTitle(index, el, prev);
+ String title = myTitleIndexes.getTitle(index);
if (title != null) {
myTitle.setText(title);
myLeftWidth = Math.max(myLeftWidth, myTitle.getPreferredSize().width);
@@ -522,10 +510,10 @@
index++;
}
- myLeftWidth += 10;
+ //myLeftWidth += 10;
myTitle.setForeground(Gray._122);
myTitle.setAlignmentY(BOTTOM_ALIGNMENT);
- myLeftPanel.setBorder(new CompoundBorder(new CustomLineBorder(new JBColor(Gray._206, Gray._75), 0,0,0,1), new EmptyBorder(0,0,0,5)));
+ myLeftPanel.setBorder(new CompoundBorder(new CustomLineBorder(getSeparatorColor(), 0, 0, 0, 1), new EmptyBorder(0, 0, 0, 5)));
}
private Font getTitleFont() {
@@ -533,6 +521,18 @@
}
}
+ private static JBColor getTitlePanelBackground() {
+ return new JBColor(Gray._242, JBColor.background());
+ }
+
+ private static Color getRightBackground() {
+ return UIUtil.isUnderAquaLookAndFeel() ? Gray._236 : UIUtil.getListBackground();
+ }
+
+ private static JBColor getSeparatorColor() {
+ return new JBColor(Gray._206, Gray._75);
+ }
+
private static boolean isActionValue(Object o) {
return o instanceof Map.Entry || o instanceof AnAction;
}
@@ -545,6 +545,7 @@
return o instanceof VirtualFile;
}
+ @SuppressWarnings("SSBasedInspection")
private class CalcThread implements Runnable {
private final Project project;
private final String pattern;
@@ -557,84 +558,243 @@
@Override
public void run() {
+ //noinspection SSBasedInspection
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ myTitleIndexes.clear();
+ myListModel.clear();
+ myAlreadyAddedFiles.clear();
+ }
+ });
if (pattern.trim().length() == 0) {
+ buildModelFromRecentFiles();
+ updatePopup();
return;
}
+ checkModelsUpToDate();
+ buildTopHit(pattern);
+ buildRecentFiles(pattern);
+ updatePopup();
+ AccessToken readLock = ApplicationManager.getApplication().acquireReadActionLock();
+ try {
+ buildClasses(pattern);
+ } finally {readLock.finish();}
+ updatePopup();
+ readLock = ApplicationManager.getApplication().acquireReadActionLock();
+ try {
+ buildFiles(pattern);
+ } finally {readLock.finish();}
+ buildActionsAndSettings(pattern);
+ updatePopup();
+ }
+
+ private void buildActionsAndSettings(String pattern) {
+ final Set<AnAction> actions = new HashSet<AnAction>();
+ final Set<Object> settings = new HashSet<Object>();
+ final HashSet<AnAction> toolWindows = new HashSet<AnAction>();
+
+ List<MatchResult> matches = collectResults(pattern, myActions, myActionModel);
+
+ for (MatchResult o : matches) {
+ //if (actionsCount > 15) break;
+ myProgressIndicator.checkCanceled();
+ Object[] objects = myActionModel.getElementsByName(o.elementName, true, pattern);
+ for (Object object : objects) {
+ myProgressIndicator.checkCanceled();
+ if (isSetting(object)) {
+ settings.add(object);
+ }
+ else if (isToolWindowAction(object)) {
+ toolWindows.add((AnAction)((Map.Entry)object).getKey());
+ }
+ else if (isActionValue(object)) {
+ actions.add((AnAction)((Map.Entry)object).getKey());
+ }
+ if (actions.size() + settings.size() + toolWindows.size() > 15) break;
+ }
+ }
+
+ myProgressIndicator.checkCanceled();
+
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (myProgressIndicator.isCanceled()) return;
+ if (toolWindows.size() > 0) {
+ myTitleIndexes.toolWindows = myListModel.size();
+ for (Object toolWindow : toolWindows) {
+ myListModel.addElement(toolWindow);
+ }
+ }
+ if (actions.size() > 0) {
+ myTitleIndexes.actions = myListModel.size();
+ for (Object action : actions) {
+ myListModel.addElement(action);
+ }
+ }
+ if (settings.size() > 0) {
+ myTitleIndexes.settings = myListModel.size();
+ for (Object setting : settings) {
+ myListModel.addElement(setting);
+ }
+ }
+ }
+ });
+ }
+
+ private void buildFiles(String pattern) {
+ int filesCounter = 0;
+ List<MatchResult> matches = collectResults(pattern, myFiles, myFileModel);
+ final List<VirtualFile> files = new ArrayList<VirtualFile>();
+
+ for (MatchResult o : matches) {
+ if (filesCounter > 15) break;
+ Object[] objects = myFileModel.getElementsByName(o.elementName, false, pattern, myProgressIndicator);
+ for (Object object : objects) {
+ if (!myListModel.contains(object)) {
+ if (object instanceof PsiFile) {
+ object = ((PsiFile)object).getVirtualFile();
+ }
+ if (object instanceof VirtualFile &&
+ !myAlreadyAddedFiles.contains((VirtualFile)object) &&
+ !((VirtualFile)object).isDirectory()) {
+ files.add((VirtualFile)object);
+ filesCounter++;
+ }
+ }
+ if (filesCounter > 15) break;
+ }
+ }
+
+ myProgressIndicator.checkCanceled();
+
+ if (files.size() > 0) {
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (!myProgressIndicator.isCanceled()) {
+ myTitleIndexes.files = myListModel.size();
+ for (Object file : files) {
+ myListModel.addElement(file);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ private void buildClasses(String pattern) {
+ int clsCounter = 0;
+ List<MatchResult> matches = collectResults(pattern, myClasses, myClassModel);
+ final List<Object> classes = new ArrayList<Object>();
+ for (MatchResult matchResult : matches) {
+ if (clsCounter > 15) break;
+
+ Object[] objects = myClassModel.getElementsByName(matchResult.elementName, false, pattern, myProgressIndicator);
+ for (Object object : objects) {
+ if (!myListModel.contains(object)) {
+ if (object instanceof PsiElement) {
+ VirtualFile file = PsiUtilCore.getVirtualFile((PsiElement)object);
+ if (file != null) {
+ if (myAlreadyAddedFiles.contains(file)) {
+ continue;
+ }
+ else {
+ myAlreadyAddedFiles.add(file);
+ }
+ }
+ }
+ classes.add(object);
+ clsCounter++;
+
+ if (clsCounter > 15) break;
+ }
+ }
+ }
+
+ myProgressIndicator.checkCanceled();
+
+ if (classes.size() > 0) {
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (!myProgressIndicator.isCanceled()) {
+ myTitleIndexes.classes = myListModel.size();
+ for (Object cls : classes) {
+ myListModel.addElement(cls);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ private void buildRecentFiles(String pattern) {
+ final MinusculeMatcher matcher = new MinusculeMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE);
+ final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
+ for (VirtualFile file : ArrayUtil.reverseArray(EditorHistoryManager.getInstance(project).getFiles())) {
+ if (StringUtil.isEmptyOrSpaces(pattern) || matcher.matches(file.getName())) {
+ if (!files.contains(file)) {
+ files.add(file);
+ }
+ }
+ if (files.size() > 15) break;
+ }
+
+ if (files.size() > 0) {
+ myAlreadyAddedFiles.addAll(files);
+
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (!myProgressIndicator.isCanceled()) {
+ myTitleIndexes.recentFiles = myListModel.size();
+ for (Object file : files) {
+ myListModel.addElement(file);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ private void buildTopHit(String pattern) {
+ final List<Object> elements = new ArrayList<Object>();
+ final Consumer<Object> consumer = new Consumer<Object>() {
+ @Override
+ public void consume(Object o) {
+ if (isSetting(o) || isVirtualFile(o) || isActionValue(o) || o instanceof PsiElement) {
+ elements.add(o);
+ }
+ }
+ };
+
+ for (SearchTopHitProvider provider : SearchTopHitProvider.EP_NAME.getExtensions()) {
+ myProgressIndicator.checkCanceled();
+ provider.consumeTopHits(pattern, consumer);
+ }
+ if (elements.size() > 0) {
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (!myProgressIndicator.isCanceled()) {
+ myTitleIndexes.topHit = myListModel.size();
+ for (Object element : elements) {
+ myListModel.addElement(element);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ private void checkModelsUpToDate() {
if (myClassModel == null) {
myClassModel = new GotoClassModel2(project);
myFileModel = new GotoFileModel(project);
- myActionModel = new GotoActionModel(project, myFocusComponent) {
- @Override
- public boolean matches(@NotNull String name, @NotNull String pattern) {
- final AnAction anAction = ActionManager.getInstance().getAction(name);
- if (anAction == null) return true;
- return NameUtil.buildMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE).matches(
- anAction.getTemplatePresentation().getText());
- }
-
- @NotNull
- @Override
- public Object[] getElementsByName(String id, boolean checkBoxState, String pattern) {
- final HashMap<AnAction, String> map = new HashMap<AnAction, String>();
- final AnAction act = myActionManager.getAction(id);
- if (act != null) {
- map.put(act, myActionsMap.get(act));
- if (checkBoxState) {
- final Set<String> ids = ((ActionManagerImpl)myActionManager).getActionIds();
- for (AnAction action : map.keySet()) { //do not add already included actions
- ids.remove(getActionId(action));
- }
- if (ids.contains(id)) {
- final AnAction anAction = myActionManager.getAction(id);
- map.put(anAction, null);
- }
- }
- }
- Object[] objects = map.entrySet().toArray(new Map.Entry[map.size()]);
- if (Comparing.strEqual(id, SETTINGS_KEY)) {
- final Set<String> words = myIndex.getProcessedWords(pattern);
- Set<OptionDescription> optionDescriptions = null;
- final String actionManagerName = myActionManager.getComponentName();
- for (String word : words) {
- final Set<OptionDescription> descriptions = ((SearchableOptionsRegistrarImpl)myIndex).getAcceptableDescriptions(word);
- if (descriptions != null) {
- for (Iterator<OptionDescription> iterator = descriptions.iterator(); iterator.hasNext(); ) {
- OptionDescription description = iterator.next();
- if (actionManagerName.equals(description.getPath())) {
- iterator.remove();
- }
- }
- if (!descriptions.isEmpty()) {
- if (optionDescriptions == null) {
- optionDescriptions = descriptions;
- }
- else {
- optionDescriptions.retainAll(descriptions);
- }
- }
- } else {
- optionDescriptions = null;
- break;
- }
- }
- if (optionDescriptions != null && !optionDescriptions.isEmpty()) {
- Set<String> currentHits = new HashSet<String>();
- for (Iterator<OptionDescription> iterator = optionDescriptions.iterator(); iterator.hasNext(); ) {
- OptionDescription description = iterator.next();
- final String hit = description.getHit();
- if (hit == null || !currentHits.add(hit.trim())) {
- iterator.remove();
- }
- }
- final Object[] descriptions = optionDescriptions.toArray();
- Arrays.sort(descriptions);
- objects = ArrayUtil.mergeArrays(objects, descriptions);
- }
- }
- return objects;
- }
- };
+ myActionModel = createActionModel();
myClasses = myClassModel.getNames(false);
myFiles = myFileModel.getNames(false);
myActions = myActionModel.getNames(true);
@@ -642,153 +802,106 @@
fillConfigurablesIds(null, new IdeConfigurablesGroup().getConfigurables());
fillConfigurablesIds(null, new ProjectConfigurablesGroup(project).getConfigurables());
}
- int clsCounter = 0;
- int filesCounter = 0;
- int actionsCount = 0;
- final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
- try {
- List<MatchResult> classes = collectResults(pattern, myClasses, myClassModel);
- List<MatchResult> files = collectResults(pattern, myFiles, myFileModel);
- List<MatchResult> actions = collectResults(pattern, myActions, myActionModel);
- DefaultListModel listModel = new DefaultListModel();
- Set<VirtualFile> alreadyAddedFiles = new HashSet<VirtualFile>();
+ }
- for (MatchResult o : classes) {
- if (clsCounter > 15) break;
+ private void buildModelFromRecentFiles() {
+ buildRecentFiles("");
+ }
- Object[] objects = myClassModel.getElementsByName(o.elementName, false, pattern, myProgressIndicator);
- for (Object object : objects) {
- if (!listModel.contains(object)) {
- listModel.addElement(object);
- clsCounter++;
- if (object instanceof PsiElement) {
- VirtualFile file = PsiUtilCore.getVirtualFile((PsiElement)object);
- if (file != null) {
- alreadyAddedFiles.add(file);
+ private GotoActionModel createActionModel() {
+ return new GotoActionModel(project, myFocusComponent) {
+ @Override
+ public boolean matches(@NotNull String name, @NotNull String pattern) {
+ final AnAction anAction = ActionManager.getInstance().getAction(name);
+ if (anAction == null) return true;
+ return NameUtil.buildMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE).matches(
+ anAction.getTemplatePresentation().getText());
+ }
+
+ @NotNull
+ @Override
+ public Object[] getElementsByName(String id, boolean checkBoxState, String pattern) {
+ final HashMap<AnAction, String> map = new HashMap<AnAction, String>();
+ final AnAction act = myActionManager.getAction(id);
+ if (act != null) {
+ map.put(act, myActionsMap.get(act));
+ if (checkBoxState) {
+ final Set<String> ids = ((ActionManagerImpl)myActionManager).getActionIds();
+ for (AnAction action : map.keySet()) { //do not add already included actions
+ ids.remove(getActionId(action));
+ }
+ if (ids.contains(id)) {
+ final AnAction anAction = myActionManager.getAction(id);
+ map.put(anAction, null);
+ }
+ }
+ }
+ Object[] objects = map.entrySet().toArray(new Map.Entry[map.size()]);
+ if (Comparing.strEqual(id, SETTINGS_KEY)) {
+ final Set<String> words = myIndex.getProcessedWords(pattern);
+ Set<OptionDescription> optionDescriptions = null;
+ final String actionManagerName = myActionManager.getComponentName();
+ for (String word : words) {
+ final Set<OptionDescription> descriptions = ((SearchableOptionsRegistrarImpl)myIndex).getAcceptableDescriptions(word);
+ if (descriptions != null) {
+ for (Iterator<OptionDescription> iterator = descriptions.iterator(); iterator.hasNext(); ) {
+ OptionDescription description = iterator.next();
+ if (actionManagerName.equals(description.getPath())) {
+ iterator.remove();
+ }
+ }
+ if (!descriptions.isEmpty()) {
+ if (optionDescriptions == null) {
+ optionDescriptions = descriptions;
+ }
+ else {
+ optionDescriptions.retainAll(descriptions);
+ }
}
}
- if (clsCounter > 15) break;
- }
- }
- }
- for (MatchResult o : files) {
- if (filesCounter > 15) break;
- Object[] objects = myFileModel.getElementsByName(o.elementName, false, pattern, myProgressIndicator);
- for (Object object : objects) {
- if (!listModel.contains(object)) {
- if (object instanceof PsiFile) {
- object = ((PsiFile)object).getVirtualFile();
- }
- if (object instanceof VirtualFile && !alreadyAddedFiles.contains((VirtualFile)object) && !((VirtualFile)object).isDirectory()) {
- listModel.addElement(object);
- filesCounter++;
+ else {
+ optionDescriptions = null;
+ break;
}
}
- if (filesCounter > 15) break;
- }
- }
-
- final Set<AnAction> addedActions = new HashSet<AnAction>();
- final List<Object> actionsAndSettings = new ArrayList<Object>();
- for (MatchResult o : actions) {
- //if (actionsCount > 15) break;
- myProgressIndicator.checkCanceled();
- Object[] objects = myActionModel.getElementsByName(o.elementName, true, pattern);
- for (Object object : objects) {
- myProgressIndicator.checkCanceled();
- if (isActionValue(object)) {
- final AnAction action = (AnAction)((Map.Entry)object).getKey();
- if (!addedActions.add(action)) continue;
+ if (optionDescriptions != null && !optionDescriptions.isEmpty()) {
+ Set<String> currentHits = new HashSet<String>();
+ for (Iterator<OptionDescription> iterator = optionDescriptions.iterator(); iterator.hasNext(); ) {
+ OptionDescription description = iterator.next();
+ final String hit = description.getHit();
+ if (hit == null || !currentHits.add(hit.trim())) {
+ iterator.remove();
+ }
+ }
+ final Object[] descriptions = optionDescriptions.toArray();
+ Arrays.sort(descriptions);
+ objects = ArrayUtil.mergeArrays(objects, descriptions);
}
- actionsAndSettings.add(object);
- actionsCount++;
- //if (actionsCount > 15) break;
}
+ return objects;
}
-
- Collections.sort(actionsAndSettings, new Comparator<Object>() {
- @Override
- public int compare(Object o1, Object o2) {
- final boolean b1 = isSetting(o1);
- final boolean b2 = isSetting(o2);
- final boolean t1 = isToolWindowAction(o1);
- final boolean t2 = isToolWindowAction(o2);
- return t1 == t2 ? b1 == b2 ? 0 : b1 ? 1 : -1 : t1 ? -1 : 1;
- }
- });
-
- for (Object actionOrSetting : actionsAndSettings) {
- listModel.addElement(actionOrSetting);
- }
-
- updateModel(listModel);
- }
- finally {
- token.finish();
- }
+ };
}
@SuppressWarnings("SSBasedInspection")
- private void updateModel(final DefaultListModel listModel) {
+ private void updatePopup() {
+ myProgressIndicator.checkCanceled();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
myProgressIndicator.checkCanceled();
- final DataContext dataContext = DataManager.getInstance().getDataContext(myContextComponent);
- int settings = 0;
- int actions = 0;
- final DefaultListModel model = new DefaultListModel();
+ myListModel.update();
+ myList.revalidate();
+ myList.repaint();
- final String pattern = field.getText();
- final Consumer<Object> consumer = new Consumer<Object>() {
- @Override
- public void consume(Object o) {
- if (isSetting(o) || isVirtualFile(o) || isActionValue(o) || o instanceof PsiElement) {
- model.addElement(o);
- }
- }
- };
-
- for (SearchTopHitProvider provider : SearchTopHitProvider.EP_NAME.getExtensions()) {
- provider.consumeTopHits(pattern, consumer);
- }
-
- myTopHitsCount = model.size();
-
- for (Object o : listModel.toArray()) {
- if (model.contains(o)) {
- continue;
- }
-
- if (isSetting(o)) {
- if (settings < 15) {
- settings++;
- model.addElement(o);
- }
- } else if (isActionValue(o)) {
- if (actions < 15) {
- final AnAction action = (AnAction)((Map.Entry)o).getKey();
-
- if (model.contains(action)) {
- continue;
- }
-
- final AnActionEvent event = GotoActionModel.updateActionBeforeShow(action, dataContext);
- if (event.getPresentation().isEnabledAndVisible()) {
- actions++;
- model.addElement(action);
- }
- }
- } else {
- model.addElement(o);
- }
- }
- myList.setModel(model);
myRenderer.recalculateWidth();
if (myPopup == null || !myPopup.isVisible()) {
final ActionCallback callback = ListDelegationUtil.installKeyboardDelegation(field.getTextEditor(), myList);
- final PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(myList);
- myPopup = builder.setRequestFocus(false).createPopup();
+ final ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(new JBScrollPane(myList), null);
+ myInitialWidth = myInitialHeight = 0;
+ myPopup = builder.setRequestFocus(false)
+ .setCancelKeyEnabled(false)
+ .createPopup();
Disposer.register(myPopup, new Disposable() {
@Override
public void dispose() {
@@ -802,21 +915,24 @@
myPopup.cancel();
}
}, myPopup);
- } else {
+ }
+ else {
myList.revalidate();
myList.repaint();
}
ListScrollingUtil.ensureSelectionExists(myList);
if (myList.getModel().getSize() == 0) {
- myPopup.cancel();
- } else {
+ //rebuildList("");
+ }
+ else {
final Dimension size = myList.getPreferredSize();
Dimension sz = new Dimension(Math.max(field.getWidth(), size.width), size.height);
if (sz.width > 800 || sz.height > 800) {
final int extra = new JBScrollPane().getVerticalScrollBar().getWidth();
sz = new Dimension(Math.min(800, Math.max(field.getWidth(), size.width + extra)), Math.min(800, size.height + extra));
sz.width += 16;
- } else {
+ }
+ else {
sz.height++;
sz.height++;
sz.width++;
@@ -909,4 +1025,83 @@
}
}
}
+
+ static class TitleIndexes {
+ int topHit;
+ int recentFiles;
+ int classes;
+ int files;
+ int actions;
+ int settings;
+ int toolWindows;
+
+ final String gotoClassTitle;
+ final String gotoFileTitle;
+ final String gotoActionTitle;
+ final String gotoSettingsTitle;
+ final String gotoRecentFilesTitle;
+ static final String toolWindowsTitle = "Tool Windows";
+
+ TitleIndexes() {
+ String gotoClass = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoClass"));
+ gotoClassTitle = StringUtil.isEmpty(gotoClass) ? "Classes" : "Classes (" + gotoClass + ")";
+ String gotoFile = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoFile"));
+ gotoFileTitle = StringUtil.isEmpty(gotoFile) ? "Files" : "Files (" + gotoFile + ")";
+ String gotoAction = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoAction"));
+ gotoActionTitle = StringUtil.isEmpty(gotoAction) ? "Actions" : "Actions (" + gotoAction + ")";
+ String gotoSettings = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("ShowSettings"));
+ gotoSettingsTitle = StringUtil.isEmpty(gotoAction) ? "Preferences" : "Preferences (" + gotoSettings + ")";
+ String gotoRecentFiles = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("RecentFiles"));
+ gotoRecentFilesTitle = StringUtil.isEmpty(gotoRecentFiles) ? "Recent Files" : "Recent Files (" + gotoRecentFiles + ")";
+ }
+
+ String getTitle(int index) {
+ if (index == topHit) return index == 0 ? "Top Hit" : "Top Hits";
+ if (index == recentFiles) return gotoRecentFilesTitle;
+ if (index == classes) return gotoClassTitle;
+ if (index == files) return gotoFileTitle;
+ if (index == toolWindows) return toolWindowsTitle;
+ if (index == actions) return gotoActionTitle;
+ if (index == settings) return gotoSettingsTitle;
+ return null;
+ }
+
+ public void clear() {
+ topHit = -1;
+ recentFiles = -1;
+ classes = -1;
+ files = -1;
+ actions = -1;
+ settings = -1;
+ toolWindows = -1;
+ }
+ }
+
+ private static class SearchListModel extends DefaultListModel {
+ Vector myDelegate;
+
+ private SearchListModel() {
+ super();
+ try {
+ final Field field = DefaultListModel.class.getDeclaredField("delegate");
+ field.setAccessible(true);
+ myDelegate = (Vector)field.get(this);
+ }
+ catch (NoSuchFieldException e) {
+
+ }
+ catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void addElement(Object obj) {
+ myDelegate.add(obj);
+ }
+
+ public void update() {
+ fireContentsChanged(this, 0, getSize() - 1);
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkExcludeRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkExcludeRootAction.java
index 1096a06..e00fd3b 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkExcludeRootAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkExcludeRootAction.java
@@ -17,24 +17,23 @@
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
-public class MarkExcludeRootAction extends MarkRootAction {
- public MarkExcludeRootAction() {
- super(false, true);
- }
-
+public class MarkExcludeRootAction extends MarkRootActionBase {
@Override
public void actionPerformed(AnActionEvent e) {
- VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
- String message = vFiles.length == 1 ? FileUtil.toSystemDependentName(vFiles [0].getPath()) : vFiles.length + " selected files";
- final int rc = Messages
- .showOkCancelDialog(e.getData(PlatformDataKeys.PROJECT), getPromptText(message), "Mark as Excluded", Messages.getQuestionIcon());
+ VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
+
+ String message = files.length == 1 ? FileUtil.toSystemDependentName(files[0].getPath()) : files.length + " selected files";
+ final int rc = Messages.showOkCancelDialog(e.getData(PlatformDataKeys.PROJECT), getPromptText(message), "Mark as Excluded",
+ Messages.getQuestionIcon());
if (rc != 0) {
return;
}
@@ -45,4 +44,13 @@
return "Are you sure you would like to exclude " + message +
" from the project?\nYou can restore excluded directories later using the Project Structure dialog.";
}
+
+ protected void modifyRoots(VirtualFile vFile, ContentEntry entry) {
+ entry.addExcludeFolder(vFile);
+ }
+
+ @Override
+ protected boolean isEnabled(@NotNull RootsSelection selection) {
+ return true;
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkJavaSourceRootAction.java
similarity index 64%
copy from plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java
copy to platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkJavaSourceRootAction.java
index 6830246..5e7c25a 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkJavaSourceRootAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,13 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn.properties;
+package com.intellij.ide.projectView.actions;
+
+import org.jetbrains.jps.model.java.JavaSourceRootType;
/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/12/12
- * Time: 8:40 PM
- */
-public class SvnPropDetailsProvider {
+* @author nik
+*/
+public class MarkJavaSourceRootAction extends MarkSourceRootAction {
+ public MarkJavaSourceRootAction() {
+ super(JavaSourceRootType.SOURCE);
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java
deleted file mode 100644
index bfdf291..0000000
--- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2000-2010 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.ide.projectView.actions;
-
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.project.DumbAwareAction;
-import com.intellij.openapi.roots.*;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author yole
- */
-public class MarkRootAction extends DumbAwareAction {
- private final boolean myMarkAsTestSources;
- private final boolean myMarkAsExcluded;
- private final boolean myUnmark;
-
- public MarkRootAction() {
- myMarkAsTestSources = false;
- myMarkAsExcluded = false;
- myUnmark = false;
- }
-
- protected MarkRootAction(boolean markAsTestSources, boolean markAsExcluded) {
- myMarkAsTestSources = markAsTestSources;
- myMarkAsExcluded = markAsExcluded;
- myUnmark = false;
- }
-
- protected MarkRootAction(boolean unmark) {
- myMarkAsTestSources = false;
- myMarkAsExcluded = false;
- myUnmark = true;
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- Module module = e.getData(LangDataKeys.MODULE);
- VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
- if (module == null || vFiles == null) {
- return;
- }
- final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
- for (VirtualFile vFile : vFiles) {
- ContentEntry entry = findContentEntry(model, vFile);
- if (entry != null) {
- final SourceFolder[] sourceFolders = entry.getSourceFolders();
- for (SourceFolder sourceFolder : sourceFolders) {
- if (Comparing.equal(sourceFolder.getFile(), vFile)) {
- entry.removeSourceFolder(sourceFolder);
- break;
- }
- }
- if (!myUnmark) {
- if (myMarkAsExcluded) {
- entry.addExcludeFolder(vFile);
- }
- else {
- entry.addSourceFolder(vFile, myMarkAsTestSources);
- }
- }
- }
- }
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- model.commit();
- }
- });
- }
-
- @Nullable
- public static ContentEntry findContentEntry(@NotNull ModuleRootModel model, @NotNull VirtualFile vFile) {
- final ContentEntry[] contentEntries = model.getContentEntries();
- for (ContentEntry contentEntry : contentEntries) {
- final VirtualFile contentEntryFile = contentEntry.getFile();
- if (contentEntryFile != null && VfsUtilCore.isAncestor(contentEntryFile, vFile, false)) {
- return contentEntry;
- }
- }
- return null;
- }
-
- @Override
- public void update(AnActionEvent e) {
- boolean enabled = canMark(e, myMarkAsTestSources || myMarkAsExcluded || myUnmark, !myMarkAsTestSources || myMarkAsExcluded || myUnmark,
- myMarkAsExcluded, null);
- e.getPresentation().setVisible(enabled);
- e.getPresentation().setEnabled(enabled);
- }
-
- public static boolean canMark(AnActionEvent e,
- boolean acceptSourceRoot,
- boolean acceptTestSourceRoot,
- boolean acceptInSourceContent,
- @Nullable Ref<Boolean> rootType) {
- Module module = e.getData(LangDataKeys.MODULE);
- VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
- if (module == null || vFiles == null) {
- return false;
- }
- final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex();
- for (VirtualFile vFile : vFiles) {
- if (!vFile.isDirectory()) {
- return false;
- }
- if (!fileIndex.isInContent(vFile)) {
- return false;
- }
- if (Comparing.equal(fileIndex.getSourceRootForFile(vFile), vFile)) {
- boolean isTestSourceRoot = fileIndex.isInTestSourceContent(vFile);
- if (acceptSourceRoot && !isTestSourceRoot) {
- if (rootType != null) rootType.set(true);
- return true;
- }
- if (acceptTestSourceRoot && isTestSourceRoot) {
- if (rootType != null) rootType.set(false);
- return true;
- }
- }
- if (fileIndex.isInSourceContent(vFile) && !acceptInSourceContent) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java
new file mode 100644
index 0000000..91dfe92
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2000-2010 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.ide.projectView.actions;
+
+import com.intellij.ide.projectView.impl.ProjectRootsUtil;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author yole
+ */
+public abstract class MarkRootActionBase extends DumbAwareAction {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ Module module = e.getData(LangDataKeys.MODULE);
+ VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
+ if (module == null || vFiles == null) {
+ return;
+ }
+ final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
+ for (VirtualFile vFile : vFiles) {
+ ContentEntry entry = findContentEntry(model, vFile);
+ if (entry != null) {
+ final SourceFolder[] sourceFolders = entry.getSourceFolders();
+ for (SourceFolder sourceFolder : sourceFolders) {
+ if (Comparing.equal(sourceFolder.getFile(), vFile)) {
+ entry.removeSourceFolder(sourceFolder);
+ break;
+ }
+ }
+ modifyRoots(vFile, entry);
+ }
+ }
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ model.commit();
+ }
+ });
+ }
+
+ protected abstract void modifyRoots(VirtualFile vFile, ContentEntry entry);
+
+ @Nullable
+ public static ContentEntry findContentEntry(@NotNull ModuleRootModel model, @NotNull VirtualFile vFile) {
+ final ContentEntry[] contentEntries = model.getContentEntries();
+ for (ContentEntry contentEntry : contentEntries) {
+ final VirtualFile contentEntryFile = contentEntry.getFile();
+ if (contentEntryFile != null && VfsUtilCore.isAncestor(contentEntryFile, vFile, false)) {
+ return contentEntry;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ RootsSelection selection = getSelection(e);
+ boolean enabled = (!selection.mySelectedRoots.isEmpty() || !selection.mySelectedFiles.isEmpty()) && isEnabled(selection);
+ e.getPresentation().setVisible(enabled);
+ e.getPresentation().setEnabled(enabled);
+ }
+
+ protected abstract boolean isEnabled(@NotNull RootsSelection selection);
+
+ protected static RootsSelection getSelection(AnActionEvent e) {
+ Module module = e.getData(LangDataKeys.MODULE);
+ VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
+ if (module == null || files == null) {
+ return RootsSelection.EMPTY;
+ }
+
+ RootsSelection selection = new RootsSelection();
+ final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex();
+ for (VirtualFile file : files) {
+ if (!file.isDirectory()) {
+ return RootsSelection.EMPTY;
+ }
+ if (!fileIndex.isInContent(file)) {
+ return RootsSelection.EMPTY;
+ }
+ SourceFolder folder;
+ if (Comparing.equal(fileIndex.getSourceRootForFile(file), file) && ((folder = ProjectRootsUtil.findSourceFolder(module, file)) != null)) {
+ selection.mySelectedRoots.add(folder);
+ }
+ else {
+ selection.mySelectedFiles.add(file);
+ if (fileIndex.isInSourceContent(file)) {
+ selection.myHaveSelectedFilesUnderSourceRoots = true;
+ }
+ }
+ }
+ return selection;
+ }
+
+ protected static class RootsSelection {
+ public static final RootsSelection EMPTY = new RootsSelection();
+
+ public List<SourceFolder> mySelectedRoots = new ArrayList<SourceFolder>();
+ public List<VirtualFile> mySelectedFiles = new ArrayList<VirtualFile>();
+ public boolean myHaveSelectedFilesUnderSourceRoots;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java
new file mode 100644
index 0000000..0d8e37b
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2013 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.ide.projectView.actions;
+
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+
+/**
+ * @author nik
+ */
+public class MarkSourceRootAction extends MarkRootActionBase {
+ private final JpsModuleSourceRootType<?> myRootType;
+
+ public MarkSourceRootAction(@NotNull JpsModuleSourceRootType<?> type) {
+ myRootType = type;
+ }
+
+ protected void modifyRoots(VirtualFile vFile, ContentEntry entry) {
+ addSourceFolder(vFile, entry, myRootType);
+ }
+
+ @Override
+ protected boolean isEnabled(@NotNull RootsSelection selection) {
+ if (selection.myHaveSelectedFilesUnderSourceRoots) {
+ return false;
+ }
+
+ if (!selection.mySelectedFiles.isEmpty()) {
+ return true;
+ }
+
+ for (SourceFolder root : selection.mySelectedRoots) {
+ if (!myRootType.equals(root.getRootType())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static <P extends JpsElement> void addSourceFolder(VirtualFile vFile, ContentEntry entry,
+ JpsModuleSourceRootType<P> markAsRootType) {
+ entry.addSourceFolder(vFile, markAsRootType, ((JpsElementTypeWithDefaultProperties<P>)markAsRootType).createDefaultProperties());
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkTestSourceRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkTestSourceRootAction.java
index b308ed2..ea0c20b8 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkTestSourceRootAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkTestSourceRootAction.java
@@ -15,11 +15,13 @@
*/
package com.intellij.ide.projectView.actions;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+
/**
* @author yole
*/
-public class MarkTestSourceRootAction extends MarkRootAction {
+public class MarkTestSourceRootAction extends MarkSourceRootAction {
public MarkTestSourceRootAction() {
- super(true, false);
+ super(JavaSourceRootType.TEST_SOURCE);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/UnmarkRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/UnmarkRootAction.java
index ca122bc..d16f91a 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/UnmarkRootAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/UnmarkRootAction.java
@@ -16,30 +16,53 @@
package com.intellij.ide.projectView.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.roots.ui.configuration.ModuleSourceRootEditHandler;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+
+import java.util.Set;
/**
* @author yole
*/
-public class UnmarkRootAction extends MarkRootAction {
- public UnmarkRootAction() {
- super(true);
- }
+public class UnmarkRootAction extends MarkRootActionBase {
+ private static final Logger LOG = Logger.getInstance(UnmarkRootAction.class);
@Override
public void update(AnActionEvent e) {
- Ref<Boolean> rootType = new Ref<Boolean>();
- boolean enabled = canMark(e, true, true, false, rootType);
- if (rootType.get() == null) {
- enabled = false;
+ super.update(e);
+ RootsSelection selection = getSelection(e);
+ Set<JpsModuleSourceRootType<?>> selectedRootTypes = new HashSet<JpsModuleSourceRootType<?>>();
+ for (SourceFolder root : selection.mySelectedRoots) {
+ selectedRootTypes.add(root.getRootType());
}
- else if (rootType.get()) {
- e.getPresentation().setText("Unmark as Source Root");
+
+ if (!selectedRootTypes.isEmpty()) {
+ String text;
+ if (selectedRootTypes.size() == 1) {
+ JpsModuleSourceRootType<?> type = selectedRootTypes.iterator().next();
+ ModuleSourceRootEditHandler<?> handler = ModuleSourceRootEditHandler.findEditHandler(type);
+ LOG.assertTrue(handler != null, type);
+ text = "Unmark as " + handler.getRootTypeName() + " " + StringUtil.pluralize("Root", selection.mySelectedRoots.size());
+ }
+ else {
+ text = "Unmark Roots";
+ }
+ e.getPresentation().setText(text);
}
- else {
- e.getPresentation().setText("Unmark as Test Source Root");
- }
- e.getPresentation().setVisible(enabled);
- e.getPresentation().setEnabled(enabled);
+ }
+
+ @Override
+ protected boolean isEnabled(@NotNull RootsSelection selection) {
+ return selection.mySelectedFiles.isEmpty() && !selection.mySelectedRoots.isEmpty();
+ }
+
+ protected void modifyRoots(VirtualFile vFile, ContentEntry entry) {
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiTreeAnchorizer.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiTreeAnchorizer.java
index aa34383..809c41c 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiTreeAnchorizer.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiTreeAnchorizer.java
@@ -58,9 +58,14 @@
}
@Override
@Nullable
- public Object retrieveElement(Object pointer) {
+ public Object retrieveElement(final Object pointer) {
if (pointer instanceof SmartPointerWrapper) {
- return ((SmartPointerWrapper)pointer).myPointer.getElement();
+ return ApplicationManager.getApplication().runReadAction(new Computable<Object>() {
+ @Override
+ public Object compute() {
+ return ((SmartPointerWrapper)pointer).myPointer.getElement();
+ }
+ });
}
return super.retrieveElement(pointer);
diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
index 4d02873..0fe520a 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,11 @@
import com.intellij.ide.DefaultTreeExpander;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.TreeExpander;
+import com.intellij.ide.structureView.StructureView;
+import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.structureView.StructureViewModel;
import com.intellij.ide.structureView.StructureViewTreeElement;
+import com.intellij.ide.structureView.impl.StructureViewComposite;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
import com.intellij.ide.structureView.newStructureView.TreeModelWrapper;
@@ -37,6 +40,9 @@
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.impl.EditorImpl;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
@@ -45,10 +51,12 @@
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
import com.intellij.ui.*;
import com.intellij.ui.popup.AbstractPopup;
import com.intellij.ui.popup.PopupUpdateProcessor;
@@ -93,6 +101,7 @@
private final StructureViewModel myTreeModel;
private final StructureViewModel myBaseTreeModel;
private final TreeStructureActionsOwner myTreeActionsOwner;
+ private PsiFile myPsiFile;
private JBPopup myPopup;
@NonNls private static final String narrowDownPropertyKey = "FileStructurePopup.narrowDown";
@@ -112,6 +121,7 @@
private boolean myInitialNodeIsLeaf;
private final List<Pair<String, JCheckBox>> myTriggeredCheckboxes = new ArrayList<Pair<String, JCheckBox>>();
private final TreeExpander myTreeExpander;
+ private StructureView myStructureView;
public FileStructurePopup(StructureViewModel structureViewModel,
@@ -124,13 +134,32 @@
//Stop code analyzer to speedup EDT
DaemonCodeAnalyzer.getInstance(myProject).disableUpdateByTimer(this);
-
IdeFocusManager.getInstance(myProject).typeAheadUntil(myTreeHasBuilt);
- myBaseTreeModel = structureViewModel;
+
+ //long l = System.currentTimeMillis();
+ if (editor instanceof EditorImpl) {
+ VirtualFile file = ((EditorImpl)editor).getVirtualFile();
+ FileEditor fileEditor = FileEditorManager.getInstance(myProject).getSelectedEditor(file);
+ if (fileEditor != null) {
+ StructureViewBuilder builder = fileEditor.getStructureViewBuilder();
+ myPsiFile = PsiManager.getInstance(project).findFile(file);
+ if (builder != null && myPsiFile != null) {
+ myStructureView = builder.createStructureView(fileEditor, project);
+ Disposer.register(this, myStructureView);
+ }
+ }
+ }
+ //System.out.println(System.currentTimeMillis() - l);
+ if (myStructureView instanceof StructureViewComposite) {
+ StructureViewComposite.StructureViewDescriptor[] views = ((StructureViewComposite)myStructureView).getStructureViews();
+ myBaseTreeModel = new StructureViewCompositeModel(myPsiFile, views);
+ } else {
+ myBaseTreeModel = structureViewModel;
+ }
Disposer.register(this, auxDisposable);
if (applySortAndFilter) {
myTreeActionsOwner = new TreeStructureActionsOwner(myBaseTreeModel);
- myTreeModel = new TreeModelWrapper(structureViewModel, myTreeActionsOwner);
+ myTreeModel = new TreeModelWrapper(myBaseTreeModel, myTreeActionsOwner);
}
else {
myTreeActionsOwner = null;
@@ -274,7 +303,7 @@
});
myTree.getEmptyText().setText("Loading...");
final Point location = DimensionService.getInstance().getLocation(getDimensionServiceKey(), myProject);
- if (location != null) {
+ if (location != null && myEditor != null) {
myPopup.showInScreenCoordinates(myEditor.getContentComponent(), location);
} else {
myPopup.showCenteredInCurrentWindow(myProject);
@@ -306,6 +335,7 @@
}
});
+ //noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
@@ -350,6 +380,7 @@
myAbstractTreeBuilder.refilter(null, false, false).doWhenProcessed(new Runnable() {
@Override
public void run() {
+ //noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
@@ -401,6 +432,28 @@
Set<PsiElement> parents = getAllParents(element);
FilteringTreeStructure.FilteringNode node = (FilteringTreeStructure.FilteringNode)myAbstractTreeBuilder.getRootElement();
+ if (node != null && myStructureView instanceof StructureViewComposite) {
+ parents.remove(element.getContainingFile());
+ final List<FilteringTreeStructure.FilteringNode> fileNodes = node.children();
+
+ for (FilteringTreeStructure.FilteringNode fileNode : fileNodes) {
+ final FilteringTreeStructure.FilteringNode found = findNode(parents, fileNode);
+ if (found != null && found != fileNode) {
+ return found;
+ }
+ }
+ } else {
+ final FilteringTreeStructure.FilteringNode found = findNode(parents, node);
+ if (found == null) {
+ TreeUtil.selectFirstNode(myTree);
+ }
+ return found;
+ }
+ TreeUtil.selectFirstNode(myTree);
+ return null;
+ }
+
+ private FilteringTreeStructure.FilteringNode findNode(Set<PsiElement> parents, FilteringTreeStructure.FilteringNode node) {
while (node != null) {
boolean changed = false;
for (FilteringTreeStructure.FilteringNode n : node.children()) {
@@ -420,7 +473,6 @@
return node;
}
}
- TreeUtil.selectFirstNode(myTree);
return null;
}
@@ -457,6 +509,7 @@
@Override
public void dispose() {
+
}
@NonNls
@@ -475,6 +528,10 @@
return (PsiElement)elementAtCursor;
}
+ if (myEditor != null) {
+ return psiFile.getViewProvider().findElementAt(myEditor.getCaretModel().getOffset());
+ }
+
return null;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/StructureViewCompositeModel.java b/platform/lang-impl/src/com/intellij/ide/util/StructureViewCompositeModel.java
new file mode 100644
index 0000000..565ba5f
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/util/StructureViewCompositeModel.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2000-2013 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.ide.util;
+
+import com.intellij.ide.structureView.StructureViewModelBase;
+import com.intellij.ide.structureView.StructureViewTreeElement;
+import com.intellij.ide.structureView.impl.StructureViewComposite;
+import com.intellij.ide.util.treeView.smartTree.TreeElement;
+import com.intellij.navigation.ItemPresentation;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.ArrayList;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class StructureViewCompositeModel extends StructureViewModelBase {
+ public StructureViewCompositeModel(PsiFile file, StructureViewComposite.StructureViewDescriptor[] views) {
+ super(file, createRootNode(file, views));
+ }
+
+ private static StructureViewTreeElement createRootNode(final PsiFile file, final StructureViewComposite.StructureViewDescriptor[] views) {
+ return new StructureViewTreeElement() {
+ @Override
+ public Object getValue() {
+ return file;
+ }
+
+ @Override
+ public void navigate(boolean requestFocus) {
+ file.navigate(requestFocus);
+ }
+
+ @Override
+ public boolean canNavigate() {
+ return file.canNavigate();
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return file.canNavigateToSource();
+ }
+
+ @Override
+ public ItemPresentation getPresentation() {
+ return file.getPresentation();
+ }
+
+ @Override
+ public TreeElement[] getChildren() {
+ ArrayList<TreeElement> elements = new ArrayList<TreeElement>();
+ for (StructureViewComposite.StructureViewDescriptor view : views) {
+ elements.add(createTreeElementFromView(file, view));
+ }
+ return elements.toArray(new TreeElement[elements.size()]);
+ }
+ };
+ }
+
+ private static TreeElement createTreeElementFromView(final PsiFile file, final StructureViewComposite.StructureViewDescriptor view) {
+ return new StructureViewTreeElement() {
+ @Override
+ public Object getValue() {
+ return view;
+ }
+
+ @Override
+ public void navigate(boolean requestFocus) {
+ file.navigate(requestFocus);
+ }
+
+ @Override
+ public boolean canNavigate() {
+ return file.canNavigate();
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return file.canNavigateToSource();
+ }
+
+ @Override
+ public ItemPresentation getPresentation() {
+ return new ItemPresentation() {
+ @Nullable
+ @Override
+ public String getPresentableText() {
+ return view.title;
+ }
+
+ @Nullable
+ @Override
+ public String getLocationString() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Icon getIcon(boolean unused) {
+ return view.icon;
+ }
+ };
+ }
+
+ @Override
+ public TreeElement[] getChildren() {
+ return view.structureView.getTreeModel().getRoot().getChildren();
+ }
+ };
+ }
+}
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 9903fbd..a9395e7 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
@@ -155,6 +155,7 @@
private ShortcutSet myCheckBoxShortcut;
protected boolean myInitIsDone;
static final boolean ourLoadNamesEachTime = FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
+ private boolean myFixLostTyping = true;
public boolean checkDisposed() {
if (myDisposedFlag && myPostponedOkAction != null && !myPostponedOkAction.isProcessed()) {
@@ -436,12 +437,12 @@
final JComponent toolbarComponent = actionToolbar.getComponent();
toolbarComponent.setBorder(null);
- hBox.add(toolbarComponent);
-
if (myToolArea == null) {
myToolArea = new JLabel(EmptyIcon.create(1, 24));
}
hBox.add(myToolArea);
+ hBox.add(toolbarComponent);
+
myTextFieldPanel.add(caption2Tools);
final ActionMap actionMap = new ActionMap();
@@ -544,7 +545,7 @@
myTextField.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
- clearPosponedOkAction(false);
+ clearPostponedOkAction(false);
rebuildList(false);
}
});
@@ -751,7 +752,7 @@
cancelListUpdater();
close(ok);
- clearPosponedOkAction(ok);
+ clearPostponedOkAction(ok);
}
finally {
myListModel.clear();
@@ -777,8 +778,12 @@
return false;
}
- protected static boolean isToFixLostTyping() {
- return Registry.is("actionSystem.fixLostTyping");
+ public void setFixLostTyping(boolean fixLostTyping) {
+ myFixLostTyping = fixLostTyping;
+ }
+
+ protected boolean isToFixLostTyping() {
+ return myFixLostTyping && Registry.is("actionSystem.fixLostTyping");
}
private synchronized void ensureNamesLoaded(boolean checkboxState) {
@@ -1017,7 +1022,7 @@
myTextField.setForeground(JBColor.red);
myListUpdater.cancelAll();
hideList();
- clearPosponedOkAction(false);
+ clearPostponedOkAction(false);
return;
}
@@ -1163,12 +1168,12 @@
if (getChosenElement() != null) {
doClose(true);
}
- clearPosponedOkAction(checkDisposed());
+ clearPostponedOkAction(checkDisposed());
}
}
}
- private void clearPosponedOkAction(boolean success) {
+ private void clearPostponedOkAction(boolean success) {
if (myPostponedOkAction != null) {
if (success) {
myPostponedOkAction.setDone();
@@ -1194,10 +1199,12 @@
}
protected List<Object> getChosenElements() {
- if (myListIsUpToDate) {
- List<Object> values = new ArrayList<Object>(Arrays.asList(myList.getSelectedValues()));
- values.remove(EXTRA_ELEM);
- values.remove(NON_PREFIX_SEPARATOR);
+
+ List<Object> values = new ArrayList<Object>(Arrays.asList(myList.getSelectedValues()));
+ values.remove(EXTRA_ELEM);
+ values.remove(NON_PREFIX_SEPARATOR);
+
+ if (myListIsUpToDate || !values.isEmpty()) {
return values;
}
@@ -1516,13 +1523,12 @@
return;
}
- final String cardToShow;
if (elements.isEmpty() && !myCheckboxState) {
myScopeExpanded = true;
myCheckboxState = true;
calculation.run();
}
- cardToShow = elements.isEmpty() ? NOT_FOUND_CARD : myScopeExpanded ? NOT_FOUND_IN_PROJECT_CARD : CHECK_BOX_CARD;
+ final String cardToShow = elements.isEmpty() ? NOT_FOUND_CARD : myScopeExpanded ? NOT_FOUND_IN_PROJECT_CARD : CHECK_BOX_CARD;
showCard(cardToShow, 0);
final Set<Object> filtered = filter(elements);
@@ -1562,8 +1568,8 @@
}
}
);
- long end = System.currentTimeMillis();
if (ContributorsBasedGotoByModel.LOG.isDebugEnabled()) {
+ long end = System.currentTimeMillis();
ContributorsBasedGotoByModel.LOG.debug("addElementsByPattern("+pattern+"): "+(end-start)+"ms; "+elements.size()+" elements");
}
}
@@ -1629,7 +1635,7 @@
private abstract class ShowFindUsagesAction extends AnAction {
public ShowFindUsagesAction() {
- super(ACTION_NAME, ACTION_NAME, AllIcons.Actions.Find);
+ super(ACTION_NAME, ACTION_NAME, AllIcons.General.AutohideOff);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java
index c993b85..a2ec3ae4 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java
@@ -299,6 +299,16 @@
}
@Override
+ public JComponent getPermanentHeaderComponent() {
+ return myDelegate.getPermanentHeaderComponent();
+ }
+
+ @Override
+ public void setPermanentHeaderComponent(JComponent component) {
+ myDelegate.setPermanentHeaderComponent(component);
+ }
+
+ @Override
@NotNull
public JComponent getContentComponent() {
return myDelegate.getContentComponent();
diff --git a/platform/lang-impl/src/com/intellij/openapi/module/WebModuleConfigurationEditorProvider.java b/platform/lang-impl/src/com/intellij/openapi/module/WebModuleConfigurationEditorProvider.java
index a65052d..fd1b91d 100644
--- a/platform/lang-impl/src/com/intellij/openapi/module/WebModuleConfigurationEditorProvider.java
+++ b/platform/lang-impl/src/com/intellij/openapi/module/WebModuleConfigurationEditorProvider.java
@@ -26,6 +26,6 @@
if (!WebModuleTypeBase.isWebModule(module)) {
return ModuleConfigurationEditor.EMPTY;
}
- return new ModuleConfigurationEditor[]{new CommonContentEntriesEditor(module.getName(), state, false, false)};
+ return new ModuleConfigurationEditor[]{new CommonContentEntriesEditor(module.getName(), state)};
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java
index c828e23..3a5c3ec 100644
--- a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkTableImpl.java
@@ -209,15 +209,15 @@
@Override
public SdkTypeId getDefaultSdkType() {
- return UnknownSdkType.getInstance(null);
+ return UnknownSdkType.getInstance("");
}
@Override
- public SdkTypeId getSdkTypeByName(String sdkTypeName) {
+ public SdkTypeId getSdkTypeByName(@NotNull String sdkTypeName) {
return findSdkTypeByName(sdkTypeName);
}
- public static SdkTypeId findSdkTypeByName(String sdkTypeName) {
+ public static SdkTypeId findSdkTypeByName(@NotNull String sdkTypeName) {
final SdkType[] allSdkTypes = SdkType.getAllTypes();
for (final SdkType type : allSdkTypes) {
if (type.getName().equals(sdkTypeName)) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java
index af1c338..76ebc10 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java
@@ -43,9 +43,11 @@
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.roots.ToolbarPanel;
import com.intellij.util.Consumer;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
import javax.swing.border.Border;
@@ -77,16 +79,16 @@
private final String myModuleName;
private final ModulesProvider myModulesProvider;
private final ModuleConfigurationState myState;
- private final boolean myCanMarkSources;
- private final boolean myCanMarkTestSources;
+ private final List<ModuleSourceRootEditHandler<?>> myEditHandlers = new ArrayList<ModuleSourceRootEditHandler<?>>();
- public CommonContentEntriesEditor(String moduleName, final ModuleConfigurationState state, boolean canMarkSources, boolean canMarkTestSources) {
+ public CommonContentEntriesEditor(String moduleName, final ModuleConfigurationState state, JpsModuleSourceRootType<?>... rootTypes) {
super(state);
myState = state;
myModuleName = moduleName;
- myCanMarkSources = canMarkSources;
- myCanMarkTestSources = canMarkTestSources;
myModulesProvider = state.getModulesProvider();
+ for (JpsModuleSourceRootType<?> type : rootTypes) {
+ ContainerUtil.addIfNotNull(myEditHandlers, ModuleSourceRootEditHandler.findEditHandler(type));
+ }
final VirtualFileManagerAdapter fileManagerListener = new VirtualFileManagerAdapter() {
@Override
public void afterRefreshFinish(boolean asynchronous) {
@@ -125,6 +127,10 @@
return NAME;
}
+ protected final List<ModuleSourceRootEditHandler<?>> getEditHandlers() {
+ return myEditHandlers;
+ }
+
@Override
public void disposeUIResources() {
if (myRootTreeEditor != null) {
@@ -197,7 +203,7 @@
}
protected ContentEntryTreeEditor createContentEntryTreeEditor(Project project) {
- return new ContentEntryTreeEditor(project, myCanMarkSources, myCanMarkTestSources);
+ return new ContentEntryTreeEditor(project, myEditHandlers);
}
protected void addAdditionalSettingsToPanel(final JPanel mainPanel) {
@@ -229,7 +235,7 @@
}
protected ContentEntryEditor createContentEntryEditor(String contentEntryUrl) {
- return new ContentEntryEditor(contentEntryUrl, myCanMarkSources, myCanMarkTestSources) {
+ return new ContentEntryEditor(contentEntryUrl, myEditHandlers) {
@Override
protected ModifiableRootModel getModel() {
return CommonContentEntriesEditor.this.getModel();
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java
index f6adae4..705df24 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java
@@ -25,12 +25,18 @@
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.java.JavaSourceRootProperties;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
-import java.util.EventListener;
+import java.util.*;
+import java.util.List;
/**
* @author Eugene Zhuravlev
@@ -43,24 +49,27 @@
private JPanel myMainPanel;
protected EventDispatcher<ContentEntryEditorListener> myEventDispatcher;
private final String myContentEntryUrl;
- protected final boolean myCanMarkSources;
- protected final boolean myCanMarkTestSources;
+ private final List<ModuleSourceRootEditHandler<?>> myEditHandlers;
public interface ContentEntryEditorListener extends EventListener{
+
void editingStarted(@NotNull ContentEntryEditor editor);
void beforeEntryDeleted(@NotNull ContentEntryEditor editor);
void sourceFolderAdded(@NotNull ContentEntryEditor editor, SourceFolder folder);
- void sourceFolderRemoved(@NotNull ContentEntryEditor editor, VirtualFile file, boolean isTestSource);
+ void sourceFolderRemoved(@NotNull ContentEntryEditor editor, VirtualFile file);
void folderExcluded(@NotNull ContentEntryEditor editor, VirtualFile file);
void folderIncluded(@NotNull ContentEntryEditor editor, VirtualFile file);
void navigationRequested(@NotNull ContentEntryEditor editor, VirtualFile file);
- void packagePrefixSet(@NotNull ContentEntryEditor editor, @NotNull SourceFolder folder);
+ void sourceRootPropertiesChanged(@NotNull ContentEntryEditor editor, @NotNull SourceFolder folder);
}
- public ContentEntryEditor(final String contentEntryUrl, boolean canMarkSources, boolean canMarkTestSources) {
- myContentEntryUrl = contentEntryUrl;
- myCanMarkSources = canMarkSources;
- myCanMarkTestSources = canMarkTestSources;
+ public ContentEntryEditor(String url, List<ModuleSourceRootEditHandler<?>> editHandlers) {
+ myContentEntryUrl = url;
+ myEditHandlers = editHandlers;
+ }
+
+ protected final List<ModuleSourceRootEditHandler<?>> getEditHandlers() {
+ return myEditHandlers;
}
public String getContentEntryUrl() {
@@ -145,10 +154,9 @@
}
@Override
- public void setPackagePrefix(@NotNull SourceFolder folder, @NotNull String prefix) {
- folder.setPackagePrefix(prefix);
+ public void onSourceRootPropertiesChanged(@NotNull SourceFolder folder) {
update();
- myEventDispatcher.getMulticaster().packagePrefixSet(this, folder);
+ myEventDispatcher.getMulticaster().sourceRootPropertiesChanged(this, folder);
}
public void addContentEntryEditorListener(ContentEntryEditorListener listener) {
@@ -188,7 +196,7 @@
}
protected ContentRootPanel createContentRootPane() {
- return new ContentRootPanel(this, myCanMarkSources, myCanMarkTestSources) {
+ return new ContentRootPanel(this, myEditHandlers) {
@Override
protected ContentEntry getContentEntry() {
return ContentEntryEditor.this.getContentEntry();
@@ -198,16 +206,19 @@
@Nullable
public SourceFolder addSourceFolder(@NotNull final VirtualFile file, boolean isTestSource, String packagePrefix) {
+ return addSourceFolder(file, isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE,
+ JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(packagePrefix)));
+ }
+
+ @Nullable
+ public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull final VirtualFile file, final JpsModuleSourceRootType<P> rootType,
+ final P properties) {
final ContentEntry contentEntry = getContentEntry();
if (contentEntry != null) {
- final SourceFolder sourceFolder = contentEntry.addSourceFolder(file, isTestSource, packagePrefix);
- try {
- return sourceFolder;
- }
- finally {
- myEventDispatcher.getMulticaster().sourceFolderAdded(this, sourceFolder);
- update();
- }
+ final SourceFolder sourceFolder = contentEntry.addSourceFolder(file, rootType, properties);
+ myEventDispatcher.getMulticaster().sourceFolderAdded(this, sourceFolder);
+ update();
+ return sourceFolder;
}
return null;
@@ -224,7 +235,7 @@
doRemoveSourceFolder(sourceFolder);
}
finally {
- myEventDispatcher.getMulticaster().sourceFolderRemoved(this, sourceFolder.getFile(), sourceFolder.isTestSource());
+ myEventDispatcher.getMulticaster().sourceFolderRemoved(this, sourceFolder.getFile());
update();
}
}
@@ -268,14 +279,10 @@
}
}
- public boolean isSource(@NotNull final VirtualFile file) {
- final SourceFolder sourceFolder = getSourceFolder(file);
- return sourceFolder != null && !sourceFolder.isTestSource();
- }
-
- public boolean isTestSource(@NotNull final VirtualFile file) {
- final SourceFolder sourceFolder = getSourceFolder(file);
- return sourceFolder != null && sourceFolder.isTestSource();
+ @Nullable
+ public JpsModuleSourceRootType<?> getRootType(@NotNull VirtualFile file) {
+ SourceFolder folder = getSourceFolder(file);
+ return folder != null ? folder.getRootType() : null;
}
public boolean isExcluded(@NotNull final VirtualFile file) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditorListenerAdapter.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditorListenerAdapter.java
index e21475f..2b4b9b9 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditorListenerAdapter.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditorListenerAdapter.java
@@ -39,7 +39,7 @@
}
@Override
- public void sourceFolderRemoved(@NotNull ContentEntryEditor editor, VirtualFile file, boolean isTestSource) {
+ public void sourceFolderRemoved(@NotNull ContentEntryEditor editor, VirtualFile file) {
}
@Override
@@ -55,6 +55,6 @@
}
@Override
- public void packagePrefixSet(@NotNull ContentEntryEditor editor, @NotNull SourceFolder folder) {
+ public void sourceRootPropertiesChanged(@NotNull ContentEntryEditor editor, @NotNull SourceFolder folder) {
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeCellRenderer.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeCellRenderer.java
index 267755b..44834bb 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeCellRenderer.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeCellRenderer.java
@@ -28,16 +28,21 @@
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
+import java.util.List;
public class ContentEntryTreeCellRenderer extends NodeRenderer {
protected final ContentEntryTreeEditor myTreeEditor;
+ private final List<ModuleSourceRootEditHandler<?>> myEditHandlers;
- public ContentEntryTreeCellRenderer(@NotNull final ContentEntryTreeEditor treeEditor) {
+ public ContentEntryTreeCellRenderer(@NotNull final ContentEntryTreeEditor treeEditor, List<ModuleSourceRootEditHandler<?>> editHandlers) {
myTreeEditor = treeEditor;
+ myEditHandlers = editHandlers;
}
@Override
@@ -86,7 +91,7 @@
final SourceFolder[] sourceFolders = entry.getSourceFolders();
for (SourceFolder sourceFolder : sourceFolders) {
if (file.equals(sourceFolder.getFile())) {
- return IconSet.getSourceRootIcon(sourceFolder.isTestSource());
+ return IconSet.getSourceRootIcon(sourceFolder.getRootType(), myEditHandlers);
}
}
@@ -98,10 +103,20 @@
if (currentRoot != null && VfsUtilCore.isAncestor(sourcePath, currentRoot, false)) {
continue;
}
- icon = IconSet.getSourceFolderIcon(sourceFolder.isTestSource());
+ icon = getSourceFolderIcon(sourceFolder.getRootType());
currentRoot = sourcePath;
}
}
return icon;
}
+
+ @Nullable
+ private Icon getSourceFolderIcon(JpsModuleSourceRootType<?> type) {
+ for (ModuleSourceRootEditHandler<?> handler : myEditHandlers) {
+ if (handler.getRootType().equals(type)) {
+ return handler.getFolderUnderRootIcon();
+ }
+ }
+ return null;
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java
index b414046..a3b8356 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryTreeEditor.java
@@ -41,7 +41,6 @@
import com.intellij.openapi.roots.ui.configuration.actions.ToggleSourcesStateAction;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.ScrollPaneFactory;
@@ -59,6 +58,7 @@
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.Comparator;
+import java.util.List;
/**
* @author Eugene Zhuravlev
@@ -67,21 +67,19 @@
*/
public class ContentEntryTreeEditor {
private final Project myProject;
- private final boolean myCanMarkSources;
- private final boolean myCanMarkTestSources;
- protected Tree myTree;
+ private final List<ModuleSourceRootEditHandler<?>> myEditHandlers;
+ protected final Tree myTree;
private FileSystemTreeImpl myFileSystemTree;
private final JPanel myTreePanel;
private final DefaultMutableTreeNode EMPTY_TREE_ROOT = new DefaultMutableTreeNode(ProjectBundle.message("module.paths.empty.node"));
- protected DefaultActionGroup myEditingActionsGroup;
+ protected final DefaultActionGroup myEditingActionsGroup;
private ContentEntryEditor myContentEntryEditor;
private final MyContentEntryEditorListener myContentEntryEditorListener = new MyContentEntryEditorListener();
private final FileChooserDescriptor myDescriptor;
- public ContentEntryTreeEditor(Project project, boolean canMarkSources, boolean canMarkTestSources) {
+ public ContentEntryTreeEditor(Project project, List<ModuleSourceRootEditHandler<?>> editHandlers) {
myProject = project;
- myCanMarkSources = canMarkSources;
- myCanMarkTestSources = canMarkTestSources;
+ myEditHandlers = editHandlers;
myTree = new Tree();
myTree.setRootVisible(true);
myTree.setShowsRootHandles(true);
@@ -101,21 +99,24 @@
}
protected void createEditingActions() {
- if (myCanMarkSources) {
- ToggleSourcesStateAction markSourcesAction = new ToggleSourcesStateAction(myTree, this, false);
- markSourcesAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.ALT_MASK)), myTree);
- myEditingActionsGroup.add(markSourcesAction);
- }
-
- if (myCanMarkTestSources) {
- setupTestsAction();
+ for (ModuleSourceRootEditHandler<?> editor : myEditHandlers) {
+ ToggleSourcesStateAction action = new ToggleSourcesStateAction(myTree, this, editor);
+ CustomShortcutSet shortcutSet = editor.getMarkRootShortcutSet();
+ if (shortcutSet != null) {
+ action.registerCustomShortcutSet(shortcutSet, myTree);
+ }
+ myEditingActionsGroup.add(action);
}
setupExcludedAction();
}
+ protected List<ModuleSourceRootEditHandler<?>> getEditHandlers() {
+ return myEditHandlers;
+ }
+
protected TreeCellRenderer getContentEntryCellRenderer() {
- return new ContentEntryTreeCellRenderer(this);
+ return new ContentEntryTreeCellRenderer(this, myEditHandlers);
}
/**
@@ -225,7 +226,7 @@
}
@Override
- public void sourceFolderRemoved(@NotNull ContentEntryEditor editor, VirtualFile file, boolean isTestSource) {
+ public void sourceFolderRemoved(@NotNull ContentEntryEditor editor, VirtualFile file) {
update();
}
@@ -240,7 +241,7 @@
}
@Override
- public void packagePrefixSet(@NotNull ContentEntryEditor editor, @NotNull SourceFolder folder) {
+ public void sourceRootPropertiesChanged(@NotNull ContentEntryEditor editor, @NotNull SourceFolder folder) {
update();
}
}
@@ -289,12 +290,6 @@
}
}
- protected void setupTestsAction() {
- ToggleSourcesStateAction markTestsAction = new ToggleSourcesStateAction(myTree, this, true);
- markTestsAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.ALT_MASK)), myTree);
- myEditingActionsGroup.add(markTestsAction);
- }
-
protected void setupExcludedAction() {
ToggleExcludedStateAction toggleExcludedAction = new ToggleExcludedStateAction(myTree, this);
myEditingActionsGroup.add(toggleExcludedAction);
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java
index be14b1e..b423bec 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java
@@ -22,6 +22,7 @@
import com.intellij.openapi.roots.ContentFolder;
import com.intellij.openapi.roots.ExcludeFolder;
import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.roots.impl.SourceFolderImpl;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -36,28 +37,27 @@
import com.intellij.ui.roots.ResizingWrapper;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.util.containers.MultiMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.*;
import java.util.List;
-import java.util.Map;
/**
* @author Eugene Zhuravlev
* Date: Jan 19, 2004
*/
public abstract class ContentRootPanel extends JPanel {
- protected static final Color SOURCES_COLOR = new JBColor(new Color(0x0A50A1), DarculaColors.BLUE);
- protected static final Color TESTS_COLOR = new Color(0x008C2E);
- protected static final Color EXCLUDED_COLOR = new JBColor(new Color(0x992E00), DarculaColors.RED);
+ private static final Color EXCLUDED_COLOR = new JBColor(new Color(0x992E00), DarculaColors.RED);
private static final Color SELECTED_HEADER_COLOR = new JBColor(new Color(0xDEF2FF), UIUtil.getPanelBackground().darker());
private static final Color HEADER_COLOR = new JBColor(new Color(0xF5F5F5), Gray._82);
private static final Color SELECTED_CONTENT_COLOR = new Color(0xF0F9FF);
@@ -65,24 +65,22 @@
private static final Color UNSELECTED_TEXT_COLOR = Gray._51;
protected final ActionCallback myCallback;
+ private final List<ModuleSourceRootEditHandler<?>> myModuleSourceRootEditHandlers;
private JComponent myHeader;
private JComponent myBottom;
private final Map<JComponent, Color> myComponentToForegroundMap = new HashMap<JComponent, Color>();
- private final boolean myCanMarkSources;
- private final boolean myCanMarkTestSources;
public interface ActionCallback {
void deleteContentEntry();
void deleteContentFolder(ContentEntry contentEntry, ContentFolder contentFolder);
void navigateFolder(ContentEntry contentEntry, ContentFolder contentFolder);
- void setPackagePrefix(@NotNull SourceFolder folder, @NotNull String prefix);
+ void onSourceRootPropertiesChanged(@NotNull SourceFolder folder);
}
- public ContentRootPanel(ActionCallback callback, boolean canMarkSources, boolean canMarkTestSources) {
+ public ContentRootPanel(ActionCallback callback, List<ModuleSourceRootEditHandler<?>> moduleSourceRootEditHandlers) {
super(new GridBagLayout());
myCallback = callback;
- myCanMarkSources = canMarkSources;
- myCanMarkTestSources = canMarkTestSources;
+ myModuleSourceRootEditHandlers = moduleSourceRootEditHandlers;
}
@Nullable
@@ -102,10 +100,9 @@
}
protected void addFolderGroupComponents() {
- final List<ContentFolder> sources = new ArrayList<ContentFolder>();
- final List<ContentFolder> testSources = new ArrayList<ContentFolder>();
final List<ContentFolder> excluded = new ArrayList<ContentFolder>();
final SourceFolder[] sourceFolders = getContentEntry().getSourceFolders();
+ MultiMap<JpsModuleSourceRootType<?>, SourceFolder> folderByType = new MultiMap<JpsModuleSourceRootType<?>, SourceFolder>();
for (SourceFolder folder : sourceFolders) {
if (folder.isSynthetic()) {
continue;
@@ -114,12 +111,7 @@
if (folderFile != null && (isExcluded(folderFile) || isUnderExcludedDirectory(folderFile))) {
continue;
}
- if (folder.isTestSource()) {
- testSources.add(folder);
- }
- else {
- sources.add(folder);
- }
+ folderByType.putValue(folder.getRootType(), folder);
}
final ExcludeFolder[] excludeFolders = getContentEntry().getExcludeFolders();
@@ -129,18 +121,21 @@
}
}
- if (!sources.isEmpty() && myCanMarkSources) {
- final JComponent sourcesComponent = createFolderGroupComponent(ProjectBundle.message("module.paths.sources.group"), sources.toArray(new ContentFolder[sources.size()]),
- SOURCES_COLOR);
- this.add(sourcesComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 10, 0), 0, 0));
+ Insets insets = new Insets(0, 0, 10, 0);
+ GridBagConstraints constraints = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, insets, 0, 0);
+ for (ModuleSourceRootEditHandler<?> editor : myModuleSourceRootEditHandlers) {
+ Collection<SourceFolder> folders = folderByType.get(editor.getRootType());
+ if (folders.isEmpty()) continue;
+
+ ContentFolder[] foldersArray = folders.toArray(new ContentFolder[folders.size()]);
+ final JComponent sourcesComponent = createFolderGroupComponent(editor.getRootsGroupTitle(), foldersArray, editor.getRootsGroupColor(), editor);
+ add(sourcesComponent, constraints);
}
- if (!testSources.isEmpty() && myCanMarkTestSources) {
- final JComponent testSourcesComponent = createFolderGroupComponent(ProjectBundle.message("module.paths.test.sources.group"), testSources.toArray(new ContentFolder[testSources.size()]), TESTS_COLOR);
- this.add(testSourcesComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 10, 0), 0, 0));
- }
+
if (!excluded.isEmpty()) {
- final JComponent excludedComponent = createFolderGroupComponent(ProjectBundle.message("module.paths.excluded.group"), excluded.toArray(new ContentFolder[excluded.size()]), EXCLUDED_COLOR);
- this.add(excludedComponent, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 10, 0), 0, 0));
+ final JComponent excludedComponent = createFolderGroupComponent(ProjectBundle.message("module.paths.excluded.group"), excluded.toArray(new ContentFolder[excluded.size()]), EXCLUDED_COLOR,
+ null);
+ this.add(excludedComponent, constraints);
}
}
@@ -167,23 +162,28 @@
return panel;
}
- protected JComponent createFolderGroupComponent(String title, ContentFolder[] folders, Color foregroundColor) {
+ protected JComponent createFolderGroupComponent(String title,
+ ContentFolder[] folders,
+ Color foregroundColor,
+ @Nullable ModuleSourceRootEditHandler<?> editor) {
final JPanel panel = new JPanel(new GridLayoutManager(folders.length, 3, new Insets(1, 17, 0, 2), 0, 1));
panel.setOpaque(false);
for (int idx = 0; idx < folders.length; idx++) {
final ContentFolder folder = folders[idx];
final int verticalPolicy = idx == folders.length - 1? GridConstraints.SIZEPOLICY_CAN_GROW : GridConstraints.SIZEPOLICY_FIXED;
- panel.add(createFolderComponent(folder, foregroundColor), new GridConstraints(idx, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, verticalPolicy, null, null, null));
+ panel.add(createFolderComponent(folder, foregroundColor, editor), new GridConstraints(idx, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, verticalPolicy, null, null, null));
int column = 1;
int colspan = 2;
- JComponent additionalComponent = createAdditionalComponent(folder);
- if (additionalComponent != null) {
- panel.add(additionalComponent, new GridConstraints(idx, column++, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, verticalPolicy, null, null, null));
- colspan = 1;
+ if (editor != null) {
+ JComponent additionalComponent = createRootPropertiesEditor(editor, (SourceFolder)folder);
+ if (additionalComponent != null) {
+ panel.add(additionalComponent, new GridConstraints(idx, column++, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, verticalPolicy, null, null, null));
+ colspan = 1;
+ }
}
- panel.add(createFolderDeleteComponent(folder), new GridConstraints(idx, column, 1, colspan, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, verticalPolicy, null, null, null));
+ panel.add(createFolderDeleteComponent(folder, editor), new GridConstraints(idx, column, 1, colspan, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, verticalPolicy, null, null, null));
}
final JLabel titleLabel = new JLabel(title);
@@ -202,7 +202,7 @@
}
@Nullable
- protected JComponent createAdditionalComponent(ContentFolder folder) {
+ protected JComponent createRootPropertiesEditor(ModuleSourceRootEditHandler<?> editor, SourceFolder folder) {
return null;
}
@@ -211,16 +211,14 @@
myComponentToForegroundMap.put(component, foreground);
}
- private JComponent createFolderComponent(final ContentFolder folder, Color foreground) {
+ private <P extends JpsElement> JComponent createFolderComponent(final ContentFolder folder, Color foreground, ModuleSourceRootEditHandler<P> editor) {
final VirtualFile folderFile = folder.getFile();
final VirtualFile contentEntryFile = getContentEntry().getFile();
- final String packagePrefix = folder instanceof SourceFolder? ((SourceFolder)folder).getPackagePrefix() : "";
+ final String properties = folder instanceof SourceFolderImpl? StringUtil.notNullize(
+ editor.getPropertiesString((P)((SourceFolderImpl)folder).getJpsElement().getProperties())) : "";
if (folderFile != null && contentEntryFile != null) {
String path = folderFile.equals(contentEntryFile)? "." : VfsUtilCore.getRelativePath(folderFile, contentEntryFile, File.separatorChar);
- if (!packagePrefix.isEmpty()) {
- path = path + " (" + packagePrefix + ")";
- }
- HoverHyperlinkLabel hyperlinkLabel = new HoverHyperlinkLabel(path, foreground);
+ HoverHyperlinkLabel hyperlinkLabel = new HoverHyperlinkLabel(path + properties, foreground);
hyperlinkLabel.setMinimumSize(new Dimension(0, 0));
hyperlinkLabel.addHyperlinkListener(new HyperlinkListener() {
@Override
@@ -233,10 +231,7 @@
}
else {
String path = toRelativeDisplayPath(folder.getUrl(), getContentEntry().getUrl());
- if (!packagePrefix.isEmpty()) {
- path = path + " (" + packagePrefix + ")";
- }
- final JLabel pathLabel = new JLabel(path);
+ final JLabel pathLabel = new JLabel(path + properties);
pathLabel.setOpaque(false);
pathLabel.setForeground(Color.RED);
@@ -244,13 +239,11 @@
}
}
- private JComponent createFolderDeleteComponent(final ContentFolder folder) {
+ private JComponent createFolderDeleteComponent(final ContentFolder folder, @Nullable ModuleSourceRootEditHandler<?> editor) {
final String tooltipText;
if (folder.getFile() != null && getContentEntry().getFile() != null) {
- if (folder instanceof SourceFolder) {
- tooltipText = ((SourceFolder)folder).isTestSource()
- ? ProjectBundle.message("module.paths.unmark.tests.tooltip")
- : ProjectBundle.message("module.paths.unmark.source.tooltip");
+ if (editor != null) {
+ tooltipText = editor.getUnmarkRootActionName();
}
else if (folder instanceof ExcludeFolder) {
tooltipText = ProjectBundle.message("module.paths.include.excluded.tooltip");
@@ -313,7 +306,7 @@
protected static String toRelativeDisplayPath(String url, String ancestorUrl) {
if (!StringUtil.endsWithChar(ancestorUrl, '/')) {
- ancestorUrl = ancestorUrl + "/";
+ ancestorUrl += "/";
}
if (url.startsWith(ancestorUrl)) {
return url.substring(ancestorUrl.length()).replace('/', File.separatorChar);
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/IconSet.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/IconSet.java
index a70f2e0..e4f0c67 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/IconSet.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/IconSet.java
@@ -17,8 +17,11 @@
package com.intellij.openapi.roots.ui.configuration;
import com.intellij.icons.AllIcons;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
+import java.util.List;
/**
* @author Eugene Zhuravlev
@@ -31,7 +34,13 @@
return isTestSource ? AllIcons.Modules.TestRoot : AllIcons.Modules.SourceRoot;
}
- public static Icon getSourceFolderIcon(boolean isTestSource) {
- return isTestSource ? AllIcons.Modules.TestSourceFolder : AllIcons.Modules.SourceFolder;
+ @Nullable
+ public static Icon getSourceRootIcon(JpsModuleSourceRootType<?> type, List<ModuleSourceRootEditHandler<?>> handlers) {
+ for (ModuleSourceRootEditHandler<?> handler : handlers) {
+ if (handler.getRootType().equals(type)) {
+ return handler.getRootIcon();
+ }
+ }
+ return null;
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaModuleSourceRootEditHandler.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaModuleSourceRootEditHandler.java
new file mode 100644
index 0000000..305802f
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaModuleSourceRootEditHandler.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2013 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.openapi.roots.ui.configuration;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.CustomShortcutSet;
+import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.ui.DarculaColors;
+import com.intellij.ui.JBColor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+/**
+ * @author nik
+ */
+public class JavaModuleSourceRootEditHandler extends JavaSourceRootEditHandlerBase {
+ private static final Color SOURCES_COLOR = new JBColor(new Color(0x0A50A1), DarculaColors.BLUE);
+
+ public JavaModuleSourceRootEditHandler() {
+ super(JavaSourceRootType.SOURCE);
+ }
+
+ @NotNull
+ @Override
+ public String getRootTypeName() {
+ return ProjectBundle.message("module.toggle.sources.action");
+ }
+
+ @NotNull
+ @Override
+ public String getRootsGroupTitle() {
+ return ProjectBundle.message("module.paths.sources.group");
+ }
+
+ @NotNull
+ @Override
+ public Icon getRootIcon() {
+ return AllIcons.Modules.SourceRoot;
+ }
+
+ @Nullable
+ @Override
+ public Icon getFolderUnderRootIcon() {
+ return AllIcons.Modules.SourceFolder;
+ }
+
+ @Override
+ public CustomShortcutSet getMarkRootShortcutSet() {
+ return new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.ALT_MASK));
+ }
+
+ @NotNull
+ @Override
+ public Color getRootsGroupColor() {
+ return SOURCES_COLOR;
+ }
+
+ @NotNull
+ @Override
+ public String getUnmarkRootActionName() {
+ return ProjectBundle.message("module.paths.unmark.source.tooltip");
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java
new file mode 100644
index 0000000..a2aa899
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootEditHandlerBase.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2013 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.openapi.roots.ui.configuration;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.ui.roots.IconActionComponent;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.JpsSimpleElement;
+import org.jetbrains.jps.model.java.JavaSourceRootProperties;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author nik
+ */
+public abstract class JavaSourceRootEditHandlerBase extends ModuleSourceRootEditHandler<JpsSimpleElement<JavaSourceRootProperties>> {
+ public JavaSourceRootEditHandlerBase(JpsModuleSourceRootType<JpsSimpleElement<JavaSourceRootProperties>> rootType) {
+ super(rootType);
+ }
+
+ @NotNull
+ @Override
+ public JpsSimpleElement<JavaSourceRootProperties> createDefaultProperties() {
+ return JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties());
+ }
+
+ @Nullable
+ @Override
+ public String getPropertiesString(@NotNull JpsSimpleElement<JavaSourceRootProperties> properties) {
+ String packagePrefix = properties.getData().getPackagePrefix();
+ return packagePrefix.isEmpty() ? null : " (" + packagePrefix + ")";
+ }
+
+ @Nullable
+ @Override
+ public JComponent createPropertiesEditor(@NotNull final SourceFolder folder,
+ @NotNull final JComponent parentComponent,
+ @NotNull final ContentRootPanel.ActionCallback callback) {
+ final IconActionComponent iconComponent = new IconActionComponent(AllIcons.Modules.SetPackagePrefix,
+ AllIcons.Modules.SetPackagePrefixRollover,
+ ProjectBundle.message("module.paths.package.prefix.tooltip"), new Runnable() {
+ @Override
+ public void run() {
+ final String message = ProjectBundle.message("module.paths.package.prefix.prompt",
+ ContentRootPanel.toRelativeDisplayPath(folder.getUrl(), folder.getContentEntry().getUrl() + ":"));
+ final String prefix = Messages.showInputDialog(parentComponent, message,
+ ProjectBundle.message("module.paths.package.prefix.title"),
+ Messages.getQuestionIcon(), folder.getPackagePrefix(), null);
+ if (prefix != null) {
+ folder.setPackagePrefix(prefix);
+ callback.onSourceRootPropertiesChanged(folder);
+ }
+ }
+ });
+ final JPanel panel = new JPanel(new BorderLayout());
+ panel.setOpaque(false);
+ panel.add(iconComponent, BorderLayout.CENTER);
+ panel.add(Box.createHorizontalStrut(3), BorderLayout.EAST);
+ return panel;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaTestSourceRootEditHandler.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaTestSourceRootEditHandler.java
new file mode 100644
index 0000000..3ae4fbb
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/JavaTestSourceRootEditHandler.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2013 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.openapi.roots.ui.configuration;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.CustomShortcutSet;
+import com.intellij.openapi.project.ProjectBundle;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+/**
+ * @author nik
+ */
+public class JavaTestSourceRootEditHandler extends JavaSourceRootEditHandlerBase {
+ private static final Color TESTS_COLOR = new Color(0x008C2E);
+
+ public JavaTestSourceRootEditHandler() {
+ super(JavaSourceRootType.TEST_SOURCE);
+ }
+
+
+ @NotNull
+ @Override
+ public String getRootTypeName() {
+ return ProjectBundle.message("module.toggle.test.sources.action");
+ }
+
+ @NotNull
+ @Override
+ public String getRootsGroupTitle() {
+ return ProjectBundle.message("module.paths.test.sources.group");
+ }
+
+ @NotNull
+ @Override
+ public Icon getRootIcon() {
+ return AllIcons.Modules.TestRoot;
+ }
+
+ @Nullable
+ @Override
+ public Icon getFolderUnderRootIcon() {
+ return AllIcons.Modules.TestSourceFolder;
+ }
+
+ @Override
+ public CustomShortcutSet getMarkRootShortcutSet() {
+ return new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.ALT_MASK));
+ }
+
+ @NotNull
+ @Override
+ public Color getRootsGroupColor() {
+ return TESTS_COLOR;
+ }
+
+ @NotNull
+ @Override
+ public String getUnmarkRootActionName() {
+ return ProjectBundle.message("module.paths.unmark.tests.tooltip");
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java
new file mode 100644
index 0000000..86cb5f9
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleSourceRootEditHandler.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2000-2013 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.openapi.roots.ui.configuration;
+
+import com.intellij.openapi.actionSystem.CustomShortcutSet;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.roots.SourceFolder;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author nik
+ */
+public abstract class ModuleSourceRootEditHandler<P extends JpsElement> {
+ public static final ExtensionPointName<ModuleSourceRootEditHandler> EP_NAME = ExtensionPointName.create("com.intellij.projectStructure.sourceRootEditHandler");
+ private final JpsModuleSourceRootType<P> myRootType;
+
+ protected ModuleSourceRootEditHandler(JpsModuleSourceRootType<P> rootType) {
+ myRootType = rootType;
+ }
+
+ @Nullable
+ public static ModuleSourceRootEditHandler<?> findEditHandler(JpsModuleSourceRootType<?> type) {
+ for (ModuleSourceRootEditHandler editor : EP_NAME.getExtensions()) {
+ if (editor.getRootType().equals(type)) {
+ return editor;
+ }
+ }
+ return null;
+ }
+
+ public final JpsModuleSourceRootType<P> getRootType() {
+ return myRootType;
+ }
+
+ @NotNull
+ public abstract String getRootTypeName();
+
+ @NotNull
+ public abstract Icon getRootIcon();
+
+ @Nullable
+ public abstract Icon getFolderUnderRootIcon();
+
+ @Nullable
+ public abstract CustomShortcutSet getMarkRootShortcutSet();
+
+ @NotNull
+ public abstract String getRootsGroupTitle();
+
+ @NotNull
+ public abstract Color getRootsGroupColor();
+
+
+ @NotNull
+ public abstract String getUnmarkRootActionName();
+
+ @NotNull
+ public abstract P createDefaultProperties();
+
+ @Nullable
+ public String getPropertiesString(@NotNull P properties) {
+ return null;
+ }
+
+ @Nullable
+ public JComponent createPropertiesEditor(@NotNull SourceFolder folder, @NotNull JComponent parentComponent,
+ @NotNull ContentRootPanel.ActionCallback callback) {
+ return null;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/PlatformContentEntriesConfigurable.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/PlatformContentEntriesConfigurable.java
index 998310b..a818b4b 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/PlatformContentEntriesConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/PlatformContentEntriesConfigurable.java
@@ -11,6 +11,7 @@
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
import java.awt.*;
@@ -21,16 +22,14 @@
*/
public class PlatformContentEntriesConfigurable implements Configurable {
private final Module myModule;
- private final boolean myCanMarkSources;
- private final boolean myCanMarkTestSources;
+ private final JpsModuleSourceRootType<?>[] myRootTypes;
private final JPanel myTopPanel = new JPanel(new BorderLayout());
private ModifiableRootModel myModifiableModel;
private CommonContentEntriesEditor myEditor;
- public PlatformContentEntriesConfigurable(final Module module, boolean canMarkSources, boolean canMarkTestSources) {
+ public PlatformContentEntriesConfigurable(final Module module, JpsModuleSourceRootType<?>... rootTypes) {
myModule = module;
- myCanMarkSources = canMarkSources;
- myCanMarkTestSources = canMarkTestSources;
+ myRootTypes = rootTypes;
}
@Override
@@ -69,7 +68,7 @@
return DefaultFacetsProvider.INSTANCE;
}
};
- myEditor = new CommonContentEntriesEditor(myModule.getName(), moduleConfigurationState, myCanMarkSources, myCanMarkTestSources) {
+ myEditor = new CommonContentEntriesEditor(myModule.getName(), moduleConfigurationState, myRootTypes) {
@Override
protected List<ContentEntry> addContentEntries(VirtualFile[] files) {
List<ContentEntry> entries = super.addContentEntries(files);
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java
index 6a3daf44..3fae3c6 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ToggleSourcesStateAction.java
@@ -16,14 +16,16 @@
package com.intellij.openapi.roots.ui.configuration.actions;
-import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.roots.impl.SourceFolderImpl;
import com.intellij.openapi.roots.ui.configuration.ContentEntryEditor;
import com.intellij.openapi.roots.ui.configuration.ContentEntryTreeEditor;
+import com.intellij.openapi.roots.ui.configuration.ModuleSourceRootEditHandler;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.jps.model.JpsElement;
import javax.swing.*;
@@ -31,25 +33,18 @@
* @author Eugene Zhuravlev
* @since Oct 14, 2003
*/
-public class ToggleSourcesStateAction extends ContentEntryEditingAction {
+public class ToggleSourcesStateAction<P extends JpsElement> extends ContentEntryEditingAction {
private final ContentEntryTreeEditor myEntryTreeEditor;
- private final boolean myEditTestSources;
+ private final ModuleSourceRootEditHandler<P> myEditHandler;
- public ToggleSourcesStateAction(JTree tree, ContentEntryTreeEditor entryEditor, boolean editTestSources) {
+ public ToggleSourcesStateAction(JTree tree, ContentEntryTreeEditor entryEditor, ModuleSourceRootEditHandler<P> editHandler) {
super(tree);
myEntryTreeEditor = entryEditor;
- myEditTestSources = editTestSources;
+ myEditHandler = editHandler;
final Presentation templatePresentation = getTemplatePresentation();
- if (editTestSources) {
- templatePresentation.setText(ProjectBundle.message("module.toggle.test.sources.action"));
- templatePresentation.setDescription(ProjectBundle.message("module.toggle.test.sources.action.description"));
- templatePresentation.setIcon(AllIcons.Modules.TestRoot);
- }
- else {
- templatePresentation.setText(ProjectBundle.message("module.toggle.sources.action"));
- templatePresentation.setDescription(ProjectBundle.message("module.toggle.sources.action.description"));
- templatePresentation.setIcon(AllIcons.Modules.SourceRoot);
- }
+ templatePresentation.setText(editHandler.getRootTypeName());
+ templatePresentation.setDescription(ProjectBundle.message("module.toggle.sources.action.description", editHandler.getRootType()));
+ templatePresentation.setIcon(editHandler.getRootIcon());
}
@Override
@@ -58,7 +53,7 @@
if (selectedFiles.length == 0) return false;
final ContentEntryEditor editor = myEntryTreeEditor.getContentEntryEditor();
- return myEditTestSources ? editor.isTestSource(selectedFiles[0]) : editor.isSource(selectedFiles[0]);
+ return myEditHandler.getRootType().equals(editor.getRootType(selectedFiles[0]));
}
@Override
@@ -71,20 +66,23 @@
final SourceFolder sourceFolder = contentEntryEditor.getSourceFolder(selectedFile);
if (isSelected) {
if (sourceFolder == null) { // not marked yet
- contentEntryEditor.addSourceFolder(selectedFile, myEditTestSources, "");
+ P properties = myEditHandler.createDefaultProperties();
+ contentEntryEditor.addSourceFolder(selectedFile, myEditHandler.getRootType(), properties);
}
- else {
- if (myEditTestSources != sourceFolder.isTestSource()) {
- final String packagePrefix = sourceFolder.getPackagePrefix();
- contentEntryEditor.removeSourceFolder(sourceFolder);
- contentEntryEditor.addSourceFolder(selectedFile, myEditTestSources, packagePrefix);
+ else if (!myEditHandler.getRootType().equals(sourceFolder.getRootType())) {
+ P properties;
+ if (myEditHandler.getRootType().getClass().equals(sourceFolder.getRootType().getClass())) {
+ properties = (P)((SourceFolderImpl)sourceFolder).getJpsElement().getProperties().getBulkModificationSupport().createCopy();
}
+ else {
+ properties = myEditHandler.createDefaultProperties();
+ }
+ contentEntryEditor.removeSourceFolder(sourceFolder);
+ contentEntryEditor.addSourceFolder(selectedFile, myEditHandler.getRootType(), properties);
}
}
- else {
- if (sourceFolder != null) { // already marked
- contentEntryEditor.removeSourceFolder(sourceFolder);
- }
+ else if (sourceFolder != null) { // already marked
+ contentEntryEditor.removeSourceFolder(sourceFolder);
}
}
}
@@ -92,7 +90,6 @@
@Override
public void update(final AnActionEvent e) {
super.update(e);
- final Presentation presentation = e.getPresentation();
- presentation.setText(ProjectBundle.message(myEditTestSources ? "module.toggle.test.sources.action" : "module.toggle.sources.action"));
+ e.getPresentation().setText(myEditHandler.getRootTypeName());
}
}
diff --git a/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java b/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java
index e5d6452..54c461c 100644
--- a/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java
+++ b/platform/lang-impl/src/com/intellij/pom/wrappers/PsiEventWrapperAspect.java
@@ -32,7 +32,6 @@
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.PsiTreeChangeEventImpl;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
-import com.intellij.psi.impl.source.tree.CompositeElement;
import java.util.Collections;
@@ -107,7 +106,6 @@
psiEvent.setOffset(treeElement.getStartOffset());
psiEvent.setParent(psiChild);
psiEvent.setOldLength(changeByChild.getOldLength());
- psiEvent.setGenericChange(treeElement instanceof CompositeElement);
manager.childrenChanged(psiEvent);
break;
case ChangeInfo.REMOVED:
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java
index 88d3dd2..66f6a65 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java
@@ -403,6 +403,14 @@
InjectedLanguageUtil.enumerate(host, visitor);
}
+ @Override
+ public void enumerateEx(@NotNull PsiElement host,
+ @NotNull PsiFile containingFile,
+ boolean probeUp,
+ @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) {
+ InjectedLanguageUtil.enumerate(host, containingFile, probeUp, visitor);
+ }
+
private final Map<Class,MultiHostInjector[]> myInjectorsClone = new HashMap<Class, MultiHostInjector[]>();
@TestOnly
public static void pushInjectors(@NotNull Project project) {
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index c381c79..572a23b 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -388,6 +388,10 @@
FileUtil.delete(IndexInfrastructure.getIndexRootDir(name));
IndexInfrastructure.rewriteVersion(versionFile, version);
}
+
+ initIndexStorage(extension, version, versionFile);
+
+ // save versions at last, they must be saved after initIndexVersion as it also can rewrite version
Map<FileType, Integer> versionMap = extension.getVersionMap();
for (Map.Entry<FileType, Integer> entry : versionMap.entrySet()) {
ID stubId = IndexInfrastructure.getStubId(name, entry.getKey());
@@ -398,7 +402,6 @@
IndexInfrastructure.rewriteVersion(file, stubVersion);
}
}
- initIndexStorage(extension, version, versionFile);
return versionChanged;
}
diff --git a/platform/lang-impl/testSources/com/intellij/execution/impl/ModuleRunConfigurationManagerTest.java b/platform/lang-impl/testSources/com/intellij/execution/impl/ModuleRunConfigurationManagerTest.java
index 943cbbf..d5906e5 100644
--- a/platform/lang-impl/testSources/com/intellij/execution/impl/ModuleRunConfigurationManagerTest.java
+++ b/platform/lang-impl/testSources/com/intellij/execution/impl/ModuleRunConfigurationManagerTest.java
@@ -68,7 +68,6 @@
createSettings("other-module-run", new MyModuleBasedConfiguration("other-module-run-config", getProject(), getModule())),
mySettings
);
- myManager.myManager.myExternalSettings.put(myManager.myRemoverKey, Collections.singletonList(mySettings));
myConfigurations = Collections.unmodifiableCollection(configs);
}
@@ -108,13 +107,13 @@
public void testBeforeOtherModuleRemoved() throws Exception {
myRemovedSettings.clear();
- myManager.moduleRemoved(getProject(), getModule());
+ myManager.beforeModuleRemoved(getProject(), getModule());
assertEmpty("No settings should be removed", myRemovedSettings);
}
public void testBeforeMyModuleRemoved() throws Exception {
myRemovedSettings.clear();
- myManager.moduleRemoved(getProject(), myModule);
+ myManager.beforeModuleRemoved(getProject(), myModule);
assertSameElements("one run config should be removed", myRemovedSettings, Collections.singleton(mySettings));
}
diff --git a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java
index a24f6c7..d38f86e 100644
--- a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java
+++ b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java
@@ -272,6 +272,7 @@
}
Runnable runnable = new Runnable() {
+ @Override
public void run() {
Messages.showMessageDialog(message, title, Messages.getErrorIcon());
}
@@ -320,6 +321,7 @@
if (!currentTimestamp.equals(previousTimestamp)) {
final Ref<Boolean> extract = new Ref<Boolean>();
Runnable r = new Runnable() {
+ @Override
public void run() {
final ConfirmExtractDialog dialog = new ConfirmExtractDialog();
if (dialog.isToBeShown()) {
@@ -336,10 +338,10 @@
try {
GuiUtils.runOrInvokeAndWait(r);
}
- catch (InvocationTargetException e) {
+ catch (InvocationTargetException ignored) {
extract.set(false);
}
- catch (InterruptedException e) {
+ catch (InterruptedException ignored) {
extract.set(false);
}
@@ -359,8 +361,10 @@
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
public void run() {
new Task.Backgroundable(null, "Extracting files...", true) {
+ @Override
public void run(@NotNull final ProgressIndicator indicator) {
final int size = zipFile.size();
final int[] counter = new int[]{0};
@@ -374,6 +378,7 @@
myImportantOnly = importantOnly;
}
+ @Override
public boolean accept(@NotNull File dir, @NotNull String name) {
indicator.checkCanceled();
boolean result = myImportantOnly == myImportantDirs.contains(dir);
@@ -426,24 +431,29 @@
init();
}
+ @Override
protected boolean isToBeShown() {
return getGeneralSettingsInstance().isConfirmExtractFiles();
}
+ @Override
protected void setToBeShown(boolean value, boolean onOk) {
getGeneralSettingsInstance().setConfirmExtractFiles(value);
}
+ @Override
protected boolean shouldSaveOptionsOnCancel() {
return true;
}
+ @Override
@NotNull
protected Action[] createActions() {
setOKButtonText(CommonBundle.getYesButtonText());
return new Action[]{getOKAction(), getCancelAction()};
}
+ @Override
protected JComponent createCenterPanel() {
JPanel panel = new JPanel(new BorderLayout());
String message = "The files are inside an archive, do you want them to be extracted?";
diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeNode.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeNode.java
index b66cebe..d722c2c 100644
--- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeNode.java
+++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -141,7 +141,7 @@
return myParentDescriptor;
}
- public T getValue() {
+ public final T getValue() {
if (myValue == null) {
return null;
}
diff --git a/platform/platform-api/src/com/intellij/ui/SimpleColoredText.java b/platform/platform-api/src/com/intellij/ui/SimpleColoredText.java
index 392314f..a9e007c 100644
--- a/platform/platform-api/src/com/intellij/ui/SimpleColoredText.java
+++ b/platform/platform-api/src/com/intellij/ui/SimpleColoredText.java
@@ -18,10 +18,12 @@
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.util.ArrayList;
-public class SimpleColoredText {
+public class SimpleColoredText implements ColoredTextContainer {
private final ArrayList<String> myTexts;
private final ArrayList<SimpleTextAttributes> myAttributes;
private String myCachedToString = null;
@@ -36,12 +38,21 @@
append(fragment, attributes);
}
+ @Override
public void append(@NotNull String fragment, @NotNull SimpleTextAttributes attributes){
myTexts.add(fragment);
myCachedToString = null;
myAttributes.add(attributes);
}
+ @Override
+ public void setIcon(@Nullable Icon icon) {
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ }
+
public void clear() {
myTexts.clear();
myCachedToString = null;
diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java
index 56bab6e..05c5a1a 100644
--- a/platform/platform-api/src/com/intellij/util/Alarm.java
+++ b/platform/platform-api/src/com/intellij/util/Alarm.java
@@ -255,17 +255,7 @@
private Request(@NotNull final Runnable task, @Nullable ModalityState modalityState, long delayMillis) {
synchronized (LOCK) {
- myTask = new Runnable() {
- @Override
- public void run() {
- try {
- task.run();
- }
- catch (Exception e) {
- LOG.error("Exception in task " + task, e);
- }
- }
- };
+ myTask = task;
myModalityState = modalityState;
myDelay = delayMillis;
}
@@ -296,10 +286,15 @@
if (myThreadToUse == ThreadToUse.SWING_THREAD && !isEdt()) {
//noinspection SSBasedInspection
- SwingUtilities.invokeLater(task);
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ QueueProcessor.runSafely(task);
+ }
+ });
}
else {
- task.run();
+ QueueProcessor.runSafely(task);
}
}
};
diff --git a/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java b/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java
index 4def957e..5e76ac1 100644
--- a/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java
+++ b/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java
@@ -30,13 +30,12 @@
import java.util.regex.Pattern;
/**
-* Created with IntelliJ IDEA.
-* User: Irina.Chernushina
-* Date: 1/30/13
-* Time: 5:24 PM
+* @author Irina.Chernushina
+* @since 1/30/13
*/
public class IdeaWideProxySelector extends ProxySelector {
private final static Logger LOG = Logger.getInstance("#com.intellij.util.net.IdeaWideProxySelector");
+
private final HttpConfigurable myHttpConfigurable;
private final AtomicReference<ProxySelector> myPacProxySelector = new AtomicReference<ProxySelector>();
@@ -47,53 +46,67 @@
@Override
public List<Proxy> select(@NotNull URI uri) {
LOG.debug("IDEA-wide proxy selector asked for " + uri.toString());
- final String scheme = uri.getScheme();
- if (! ("http".equals(scheme) || "https".equals(scheme))) {
- LOG.debug("IDEA-wide proxy selector returns no proxies: not http/https scheme: " + scheme);
+
+ String scheme = uri.getScheme();
+ if (!("http".equals(scheme) || "https".equals(scheme))) {
+ LOG.debug("No proxy: not http/https scheme: " + scheme);
return CommonProxy.NO_PROXY_LIST;
}
+
if (myHttpConfigurable.USE_HTTP_PROXY) {
if (isProxyException(uri)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("IDEA-wide proxy selector detected that uri matches proxy exceptions: uri: " + uri.toString() +
- ", proxy exceptions string: '" + myHttpConfigurable.PROXY_EXCEPTIONS + "'");
- }
+ LOG.debug("No proxy: URI '", uri, "' matches proxy exceptions [", myHttpConfigurable.PROXY_EXCEPTIONS, "]");
return CommonProxy.NO_PROXY_LIST;
}
- final Proxy proxy = new Proxy(myHttpConfigurable.PROXY_TYPE_IS_SOCKS ? Proxy.Type.SOCKS : Proxy.Type.HTTP,
- new InetSocketAddress(myHttpConfigurable.PROXY_HOST, myHttpConfigurable.PROXY_PORT));
- LOG.debug("IDEA-wide proxy selector returns defined proxy: " + proxy);
+
+ if (myHttpConfigurable.PROXY_PORT < 0 || myHttpConfigurable.PROXY_PORT > 65535) {
+ LOG.debug("No proxy: invalid port: " + myHttpConfigurable.PROXY_PORT);
+ return CommonProxy.NO_PROXY_LIST;
+ }
+
+ Proxy.Type type = myHttpConfigurable.PROXY_TYPE_IS_SOCKS ? Proxy.Type.SOCKS : Proxy.Type.HTTP;
+ Proxy proxy = new Proxy(type, new InetSocketAddress(myHttpConfigurable.PROXY_HOST, myHttpConfigurable.PROXY_PORT));
+ LOG.debug("Defined proxy: ", proxy);
myHttpConfigurable.LAST_ERROR = null;
return Collections.singletonList(proxy);
- } else if (myHttpConfigurable.USE_PROXY_PAC) {
+ }
+
+ if (myHttpConfigurable.USE_PROXY_PAC) {
ProxySelector pacProxySelector = myPacProxySelector.get();
if (pacProxySelector == null) {
- final ProxySearch proxySearch = ProxySearch.getDefaultProxySearch();
+ ProxySearch proxySearch = ProxySearch.getDefaultProxySearch();
proxySearch.setPacCacheSettings(32, 10 * 60 * 1000); // Cache 32 urls for up to 10 min.
pacProxySelector = proxySearch.getProxySelector();
-
myPacProxySelector.lazySet(pacProxySelector);
}
if (pacProxySelector != null) {
- final List<Proxy> select = pacProxySelector.select(uri);
- LOG.debug("IDEA-wide proxy selector found autodetected proxies: " + select);
+ List<Proxy> select = pacProxySelector.select(uri);
+ LOG.debug("Autodetected proxies: ", select);
return select;
}
- LOG.debug("IDEA-wide proxy selector found no autodetected proxies");
+ else {
+ LOG.debug("No proxies detected");
+ }
}
+
return CommonProxy.NO_PROXY_LIST;
}
private boolean isProxyException(URI uri) {
String uriHost = uri.getHost();
- if (StringUtil.isEmptyOrSpaces(uriHost)) return false;
- if (StringUtil.isEmptyOrSpaces(myHttpConfigurable.PROXY_EXCEPTIONS)) return false;
- final List<String> hosts = StringUtil.split(myHttpConfigurable.PROXY_EXCEPTIONS, ",");
- for (String hostPattern : hosts) {
- final String regexpPattern = StringUtil.escapeToRegexp(hostPattern.trim()).replace("\\*", ".*");
- if (Pattern.compile(regexpPattern).matcher(uriHost).matches()) return true;
+ if (StringUtil.isEmptyOrSpaces(uriHost) || StringUtil.isEmptyOrSpaces(myHttpConfigurable.PROXY_EXCEPTIONS)) {
+ return false;
}
+
+ List<String> hosts = StringUtil.split(myHttpConfigurable.PROXY_EXCEPTIONS, ",");
+ for (String hostPattern : hosts) {
+ String regexpPattern = StringUtil.escapeToRegexp(hostPattern.trim()).replace("\\*", ".*");
+ if (Pattern.compile(regexpPattern).matcher(uriHost).matches()) {
+ return true;
+ }
+ }
+
return false;
}
@@ -104,6 +117,7 @@
LOG.debug("generic proxy credentials (if were saved) removed");
return;
}
+
final InetSocketAddress isa = sa instanceof InetSocketAddress ? (InetSocketAddress) sa : null;
if (myHttpConfigurable.USE_HTTP_PROXY && isa != null && Comparing.equal(myHttpConfigurable.PROXY_HOST, isa.getHostName())) {
LOG.debug("connection failed message passed to http configurable");
diff --git a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java
index 6d8b97d..e5b2689 100644
--- a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java
+++ b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java
@@ -34,6 +34,7 @@
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.plaf.TreeUI;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.*;
import java.awt.*;
@@ -943,8 +944,16 @@
}
public static boolean isOverSelection(@NotNull final JTree tree, @NotNull final Point point) {
- TreePath path = tree.getPathForLocation(point.x, point.y);
- return path != null && tree.getSelectionModel().isPathSelected(path);
+ TreePath path = tree.getClosestPathForLocation(point.x, point.y);
+ if (path == null || !tree.getSelectionModel().isPathSelected(path)) return false;
+ TreeUI ui = tree.getUI();
+ Rectangle bounds;
+ if (ui instanceof WideSelectionTreeUI) {
+ bounds = ((WideSelectionTreeUI)ui).getWidePathBounds(tree, path);
+ } else {
+ bounds = tree.getPathBounds(path);
+ }
+ return bounds != null && bounds.contains(point);
}
public static void dropSelectionButUnderPoint(@NotNull JTree tree, @NotNull Point treePoint) {
diff --git a/platform/platform-api/src/org/jetbrains/ide/BinaryRequestHandler.java b/platform/platform-api/src/org/jetbrains/ide/BinaryRequestHandler.java
new file mode 100644
index 0000000..f8e2f4c
--- /dev/null
+++ b/platform/platform-api/src/org/jetbrains/ide/BinaryRequestHandler.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.ide;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import io.netty.channel.ChannelInboundHandler;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.UUID;
+
+public abstract class BinaryRequestHandler {
+ public static final ExtensionPointName<BinaryRequestHandler> EP_NAME = ExtensionPointName.create("com.intellij.binaryRequestHandler");
+
+ @NotNull
+ /**
+ * You can use uuidgen on Mac OS X to generate UUID
+ */
+ public abstract UUID getId();
+
+ public abstract ChannelInboundHandler getInboundHandler();
+}
\ No newline at end of file
diff --git a/platform/platform-api/src/org/jetbrains/ide/BuiltInServerManager.java b/platform/platform-api/src/org/jetbrains/ide/BuiltInServerManager.java
index e152dc0..e0689dd 100644
--- a/platform/platform-api/src/org/jetbrains/ide/BuiltInServerManager.java
+++ b/platform/platform-api/src/org/jetbrains/ide/BuiltInServerManager.java
@@ -17,13 +17,9 @@
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.extensions.ExtensionPointName;
import org.jetbrains.annotations.Nullable;
public abstract class BuiltInServerManager {
- // Your handler will be instantiated on first user request
- public static final ExtensionPointName<HttpRequestHandler> EP_NAME = ExtensionPointName.create("com.intellij.httpRequestHandler");
-
public static BuiltInServerManager getInstance() {
return ServiceManager.getService(BuiltInServerManager.class);
}
diff --git a/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java b/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java
index 5368582..f58a7e4e 100644
--- a/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java
+++ b/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.ide;
+import com.intellij.openapi.extensions.ExtensionPointName;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
@@ -23,6 +24,9 @@
import java.io.IOException;
public abstract class HttpRequestHandler {
+ // Your handler will be instantiated on first user request
+ public static final ExtensionPointName<HttpRequestHandler> EP_NAME = ExtensionPointName.create("com.intellij.httpRequestHandler");
+
public boolean isSupported(FullHttpRequest request) {
return request.getMethod() == HttpMethod.GET || request.getMethod() == HttpMethod.HEAD;
}
diff --git a/platform/platform-impl/platform-impl.iml b/platform/platform-impl/platform-impl.iml
index 6cc1c8a..c88e8c9 100644
--- a/platform/platform-impl/platform-impl.iml
+++ b/platform/platform-impl/platform-impl.iml
@@ -38,6 +38,7 @@
<orderEntry type="module" module-name="jps-model-impl" />
<orderEntry type="module" module-name="analysis-impl" />
<orderEntry type="library" name="jayatana" level="project" />
+ <orderEntry type="library" name="gson" level="project" />
</component>
</module>
diff --git a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
index 0b84ea5..a58aaa1 100644
--- a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
+++ b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java
@@ -89,9 +89,7 @@
if (outputTypeFilter.value(outputType)) {
final String text = event.getText();
outputBuilder.append(text);
- if (LOG.isDebugEnabled()) {
- LOG.debug(text);
- }
+ LOG.debug(text);
}
}
});
@@ -116,34 +114,19 @@
@Nullable VirtualFile scriptFile,
String[] parameters,
@Nullable Charset charset) throws ExecutionException {
- ExecutionException ex;
- try {
- return doExecute(exePath, workingDirectory, scriptFile, parameters, charset);
- }
- catch (ExecutionException e) {
- ex = e;
- }
- boolean rerun = SystemInfo.isMac;
- if (rerun) {
+ if (SystemInfo.isMac) {
File exeFile = new File(exePath);
- rerun = !exeFile.isAbsolute();
- }
- if (rerun) {
- File originalExeFile = PathEnvironmentVariableUtil.findInOriginalPath(exePath);
- rerun = originalExeFile == null;
- }
- if (rerun) {
- File exeFile = PathEnvironmentVariableUtil.findInPath(exePath);
- if (exeFile != null) {
- try {
- return doExecute(exeFile.getAbsolutePath(), workingDirectory, scriptFile, parameters, charset);
- } catch (ExecutionException e) {
- LOG.info("Standby command failed too", e);
- throw ex;
+ if (!exeFile.isAbsolute() && !exePath.contains(File.separator)) {
+ File originalResolvedExeFile = PathEnvironmentVariableUtil.findInOriginalPath(exePath);
+ if (originalResolvedExeFile == null) {
+ File resolvedExeFile = PathEnvironmentVariableUtil.findInPath(exePath);
+ if (resolvedExeFile != null) {
+ exePath = resolvedExeFile.getAbsolutePath();
+ }
}
}
}
- throw ex;
+ return doExecute(exePath, workingDirectory, scriptFile, parameters, charset);
}
@NotNull
@@ -164,8 +147,8 @@
commandLine.setWorkDirectory(workingDirectory);
}
- LOG.debug("Command line: " + commandLine.getCommandLineString());
- LOG.debug("Command line env: " + commandLine.getEnvironment());
+ LOG.debug("Command line: ", commandLine.getCommandLineString());
+ LOG.debug("Command line env: ", commandLine.getEnvironment());
if (charset == null) {
charset = ObjectUtils.notNull(EncodingManager.getInstance().getDefaultCharset(), CharsetToolkit.UTF8_CHARSET);
@@ -190,8 +173,7 @@
@Nullable String workingDirectory,
long timeout,
Condition<Key> scriptOutputType,
- @NonNls String... parameters)
- throws ExecutionException {
+ @NonNls String... parameters) throws ExecutionException {
final OSProcessHandler processHandler = execute(exePathString, workingDirectory, scriptFile, parameters);
ScriptOutput output = new ScriptOutput(scriptOutputType);
@@ -202,19 +184,19 @@
LOG.warn("Process did not complete in " + timeout / 1000 + "s");
throw new ExecutionException(ExecutionBundle.message("script.execution.timeout", String.valueOf(timeout / 1000)));
}
- LOG.debug("script output: " + output.myFilteredOutput);
+ LOG.debug("script output: ", output.myFilteredOutput);
return output;
}
public static class ScriptOutput extends ProcessAdapter {
private final Condition<Key> myScriptOutputType;
public final StringBuilder myFilteredOutput;
- public final StringBuilder myMergedOutput;
+ public final StringBuffer myMergedOutput;
private ScriptOutput(Condition<Key> scriptOutputType) {
myScriptOutputType = scriptOutputType;
myFilteredOutput = new StringBuilder();
- myMergedOutput = new StringBuilder();
+ myMergedOutput = new StringBuffer();
}
public String getFilteredOutput() {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/AboutDialog.java b/platform/platform-impl/src/com/intellij/ide/actions/AboutDialog.java
index 9b7e754..86a1e73 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/AboutDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/AboutDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -193,7 +193,9 @@
myLines.add(new AboutBoxLine(""));
final Properties properties = System.getProperties();
- myLines.add(new AboutBoxLine(IdeBundle.message("aboutbox.jdk", properties.getProperty("java.version", "unknown")), true, null));
+ final String javaVersion = properties.getProperty("java.runtime.version", properties.getProperty("java.version", "unknown"));
+ final String arch = properties.getProperty("os.arch", "");
+ myLines.add(new AboutBoxLine(IdeBundle.message("aboutbox.jdk", javaVersion, arch), true, null));
appendLast();
myLines.add(new AboutBoxLine(IdeBundle.message("aboutbox.vm", properties.getProperty("java.vm.name", "unknown"),
properties.getProperty("java.vendor", "unknown"))));
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java
index 2883afa..b28c831 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -18,16 +18,9 @@
import com.intellij.CommonBundle;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
-import com.intellij.notification.Notification;
-import com.intellij.notification.NotificationListener;
-import com.intellij.notification.NotificationType;
-import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
-import com.intellij.openapi.application.ApplicationNamesInfo;
-import com.intellij.openapi.application.ex.ApplicationEx;
-import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.ui.DialogWrapper;
@@ -35,12 +28,8 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.net.IOExceptionDialog;
-import com.intellij.xml.util.XmlStringUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.event.HyperlinkEvent;
import java.io.IOException;
import java.util.*;
@@ -162,7 +151,7 @@
}
if (needToRestart) {
- notifyPluginsWereInstalled(list.size() == 1 ? list.get(0).getName() : null);
+ PluginManagerMain.notifyPluginsWereInstalled(list.size() == 1 ? list.get(0).getName() : null);
}
}
}
@@ -268,33 +257,6 @@
}
}
- private static void notifyPluginsWereInstalled(@Nullable String pluginName) {
- final ApplicationEx app = ApplicationManagerEx.getApplicationEx();
- final boolean restartCapable = app.isRestartCapable();
- String message =
- restartCapable ? IdeBundle.message("message.idea.restart.required", ApplicationNamesInfo.getInstance().getFullProductName())
- : IdeBundle.message("message.idea.shutdown.required", ApplicationNamesInfo.getInstance().getFullProductName());
- message += "<br><a href=";
- message += restartCapable ? "\"restart\">Restart now" : "\"shutdown\">Shutdown";
- message += "</a>";
- Notifications.Bus.notify(new Notification("Plugins Lifecycle Group",
- pluginName != null ? "Plugin \'" + pluginName + "\' was successfully installed" : "Plugins were installed",
- XmlStringUtil.wrapInHtml(message), NotificationType.INFORMATION,
- new NotificationListener() {
- @Override
- public void hyperlinkUpdate(@NotNull Notification notification,
- @NotNull HyperlinkEvent event) {
- notification.expire();
- if (restartCapable) {
- app.restart(true);
- }
- else {
- app.exit(true);
- }
- }
- }));
- }
-
public PluginTable getPluginTable() {
return host.getPluginTable();
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java
index 9eb33fb..7b93211 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java
@@ -21,10 +21,17 @@
import com.intellij.ide.IdeBundle;
import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationListener;
+import com.intellij.notification.NotificationType;
+import com.intellij.notification.Notifications;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.ex.ApplicationEx;
+import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.*;
import com.intellij.openapi.project.DumbAwareAction;
@@ -37,6 +44,7 @@
import com.intellij.util.concurrency.SwingWorker;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.UiNotifyConnector;
+import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -294,7 +302,7 @@
public static boolean downloadPlugins(final List<PluginNode> plugins,
final List<IdeaPluginDescriptor> allPlugins,
final Runnable onSuccess,
- final Runnable cleanup) throws IOException {
+ @Nullable final Runnable cleanup) throws IOException {
final boolean[] result = new boolean[1];
try {
ProgressManager.getInstance().run(new Task.Backgroundable(null, IdeBundle.message("progress.download.plugins"), true, PluginManagerUISettings.getInstance()) {
@@ -307,7 +315,7 @@
}
}
finally {
- cleanup.run();
+ if (cleanup != null) cleanup.run();
}
}
});
@@ -514,6 +522,36 @@
return false;
}
+
+ public static void notifyPluginsWereInstalled(@Nullable String pluginName) {
+ final ApplicationEx app = ApplicationManagerEx.getApplicationEx();
+ final boolean restartCapable = app.isRestartCapable();
+ String message =
+ restartCapable ? IdeBundle.message("message.idea.restart.required", ApplicationNamesInfo.getInstance().getFullProductName())
+ : IdeBundle.message("message.idea.shutdown.required", ApplicationNamesInfo.getInstance().getFullProductName());
+ message += "<br><a href=";
+ message += restartCapable ? "\"restart\">Restart now" : "\"shutdown\">Shutdown";
+ message += "</a>";
+ Notifications.Bus.notify(new Notification("Plugins Lifecycle Group",
+ pluginName != null
+ ? "Plugin \'" + pluginName + "\' was successfully installed"
+ : "Plugins were installed",
+ XmlStringUtil.wrapInHtml(message), NotificationType.INFORMATION,
+ new NotificationListener() {
+ @Override
+ public void hyperlinkUpdate(@NotNull Notification notification,
+ @NotNull HyperlinkEvent event) {
+ notification.expire();
+ if (restartCapable) {
+ app.restart(true);
+ }
+ else {
+ app.exit(true);
+ }
+ }
+ }));
+ }
+
protected class SortByStatusAction extends ToggleAction {
protected SortByStatusAction(final String title) {
diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
index 2417910..33ef82f 100644
--- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
+++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
@@ -30,6 +30,7 @@
import com.intellij.util.Consumer;
import com.intellij.util.EnvironmentUtil;
import com.intellij.util.SnappyInitializer;
+import com.intellij.util.lang.UrlClassLoader;
import com.intellij.util.text.DateFormatUtilRt;
import com.sun.jna.Native;
import org.jetbrains.annotations.NonNls;
@@ -246,7 +247,7 @@
if (SystemInfo.isWin2kOrNewer && !Main.isHeadless()) {
try {
- System.loadLibrary("focusKiller");
+ UrlClassLoader.loadPlatformLibrary("focusKiller");
log.info("Using \"FocusKiller\" library to prevent focus stealing.");
}
catch (Throwable t) {
@@ -273,7 +274,7 @@
ApplicationNamesInfo namesInfo = ApplicationNamesInfo.getInstance();
log.info("IDE: " + namesInfo.getFullProductName() + " (build #" + appInfo.getBuild() + ", " +
DateFormatUtilRt.formatBuildDate(appInfo.getBuildDate()) + ")");
- log.info("OS: " + SystemInfoRt.OS_NAME + " (" + SystemInfoRt.OS_VERSION + ")");
+ log.info("OS: " + SystemInfoRt.OS_NAME + " (" + SystemInfoRt.OS_VERSION + ", " + SystemInfo.OS_ARCH + ")");
log.info("JRE: " + System.getProperty("java.runtime.version", "-") + " (" + System.getProperty("java.vendor", "-") + ")");
log.info("JVM: " + System.getProperty("java.vm.version", "-") + " (" + System.getProperty("java.vm.name", "-") + ")");
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java
index 87c4b7f..81f7870 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java
@@ -57,6 +57,10 @@
EditorHighlighter getHighlighter();
+ JComponent getPermanentHeaderComponent();
+
+ void setPermanentHeaderComponent(JComponent component);
+
void setHighlighter(@NotNull EditorHighlighter highlighter);
void setColorsScheme(@NotNull EditorColorsScheme scheme);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/RangeHighlighterEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/RangeHighlighterEx.java
index 767b5f9..abf776a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/RangeHighlighterEx.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/RangeHighlighterEx.java
@@ -19,13 +19,14 @@
* User: max
* Date: Jun 10, 2002
* Time: 5:54:59 PM
- * To change template for new interface use
+ * To change template for new interface use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.openapi.editor.ex;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
+import org.jetbrains.annotations.NotNull;
public interface RangeHighlighterEx extends RangeHighlighter, RangeMarkerEx {
boolean isAfterEndOfLine();
@@ -37,5 +38,5 @@
@Override
long getId();
- void setTextAttributes(TextAttributes textAttributes);
+ void setTextAttributes(@NotNull TextAttributes textAttributes);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
index c4bb90b..4c09c61 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
@@ -41,9 +41,9 @@
import java.util.List;
public class EditorUtil {
-
+
private static final Logger LOG = Logger.getInstance("#" + EditorUtil.class.getName());
-
+
private EditorUtil() { }
public static int getLastVisualLineColumnNumber(@NotNull Editor editor, final int line) {
@@ -136,14 +136,14 @@
result += calcColumnNumber(editor, softWrap.getText(), softWrapStartOffset, softWrapEndOffset);
return result;
}
-
+
CharSequence editorInfo;
if (editor instanceof EditorImpl) {
editorInfo = ((EditorImpl)editor).dumpState();
}
else {
editorInfo = "editor's class: " + editor.getClass()
- + ", all soft wraps: " + editor.getSoftWrapModel().getSoftWrapsForRange(0, document.getTextLength())
+ + ", all soft wraps: " + editor.getSoftWrapModel().getSoftWrapsForRange(0, document.getTextLength())
+ ", fold regions: " + Arrays.toString(editor.getFoldingModel().getAllFoldRegions());
}
LogMessageEx.error(LOG, "Can't calculate last visual column", String.format(
@@ -151,7 +151,7 @@
+ "the target logical line: %s. Editor info: %s",
line, resultLogLine, resVisStart, resVisEnd, softWraps, editorInfo
));
-
+
return resVisEnd.column;
}
@@ -294,36 +294,43 @@
"Starting calcSoftWrapUnawareOffset(). Target range: [%d; %d), target column number to map: %d, tab size: %d, "
+ "x: %d, current column: %d%n", start, end, columnNumber, tabSize, x, currentColumn[0]));
}
-
+
// The main problem in a calculation is that target text may contain tabulation symbols and every such symbol may take different
// number of logical columns to represent. E.g. it takes two columns if tab size is four and current column is two; three columns
// if tab size is four and current column is one etc. So, first of all we check if there are tabulation symbols at the target
// text fragment.
boolean useOptimization = true;
- boolean hasNonTabs = false;
- boolean hasTabs = false;
- int scanEndOffset = Math.min(end, start + columnNumber - currentColumn[0] + 1);
- for (int i = start; i < scanEndOffset; i++) {
- char c = text.charAt(i);
- if (debugBuffer != null) {
- debugBuffer.append(String.format("Found symbol '%c' at the offset %d%n", c, i));
- }
- if (c == '\t') {
- hasTabs = true;
- if (hasNonTabs) {
- useOptimization = false;
- break;
+ boolean hasTabs;
+ if ((editor instanceof EditorImpl) && !((EditorImpl)editor).hasTabs()) {
+ hasTabs = false;
+ useOptimization = true;
+ }
+ else {
+ boolean hasNonTabs = false;
+ hasTabs = false;
+ int scanEndOffset = Math.min(end, start + columnNumber - currentColumn[0] + 1);
+ for (int i = start; i < scanEndOffset; i++) {
+ char c = text.charAt(i);
+ if (debugBuffer != null) {
+ debugBuffer.append(String.format("Found symbol '%c' at the offset %d%n", c, i));
}
- }
- else {
- hasNonTabs = true;
+ if (c == '\t') {
+ hasTabs = true;
+ if (hasNonTabs) {
+ useOptimization = false;
+ break;
+ }
+ }
+ else {
+ hasNonTabs = true;
+ }
}
}
if (debugBuffer != null) {
debugBuffer.append(String.format("Has tabs: %b, use optimisation: %b%n", hasTabs, useOptimization));
}
-
+
// Perform optimized processing if possible. 'Optimized' here means the processing when we exactly know how many logical
// columns are occupied by tabulation symbols.
if (useOptimization) {
@@ -454,16 +461,23 @@
SoftWrap softWrap = editor.getSoftWrapModel().getSoftWrap(start);
useOptimization = softWrap == null;
}
+ boolean hasTabs = true;
if (useOptimization) {
- boolean hasNonTabs = false;
- for (int i = start; i < offset; i++) {
- if (text.charAt(i) == '\t') {
- if (hasNonTabs) {
- useOptimization = false;
- break;
+ if ((editor instanceof EditorImpl) && !((EditorImpl)editor).hasTabs()) {
+ hasTabs = false;
+ }
+ else {
+ boolean hasNonTabs = false;
+ for (int i = start; i < offset; i++) {
+ if (text.charAt(i) == '\t') {
+ if (hasNonTabs) {
+ useOptimization = false;
+ break;
+ }
}
- } else {
- hasNonTabs = true;
+ else {
+ hasNonTabs = true;
+ }
}
}
}
@@ -471,27 +485,26 @@
if (editor == null || useOptimization) {
int shift = 0;
- for (int i = start; i < offset; i++) {
- char c = text.charAt(i);
- if (c == '\n' || c == '\r') {
- String editorInfo = editor instanceof EditorImpl ? ". Editor info: " + ((EditorImpl)editor).dumpState() : "";
- String documentInfo;
- if (text instanceof Dumpable) {
- documentInfo = ((Dumpable)text).dumpState();
- }
- else {
- documentInfo = "Text holder class: " + text.getClass();
- }
- LogMessageEx.error(
- LOG, "detected incorrect offset -> column number calculation",
- String.format(
- "Symbol: '%c', its index: %d, given start: %d, given offset: %d, given tab size: %d. %s%s",
- c, i, start, offset, tabSize, documentInfo, editorInfo
- )
- );
+ Document document = editor == null ? null : editor.getDocument();
+ if (document != null && start < offset-1 && document.getLineNumber(start) != document.getLineNumber(offset-1)) {
+ String editorInfo = editor instanceof EditorImpl ? ". Editor info: " + ((EditorImpl)editor).dumpState() : "";
+ String documentInfo;
+ if (text instanceof Dumpable) {
+ documentInfo = ((Dumpable)text).dumpState();
}
- if (c == '\t') {
- shift += getTabLength(i + shift - start, tabSize) - 1;
+ else {
+ documentInfo = "Text holder class: " + text.getClass();
+ }
+ LogMessageEx.error(
+ LOG, "detected incorrect offset -> column number calculation",
+ "start: " + start + ", given offset: " + offset+", given tab size: " + tabSize + ". "+documentInfo+ editorInfo);
+ }
+ if (hasTabs) {
+ for (int i = start; i < offset; i++) {
+ char c = text.charAt(i);
+ if (c == '\t') {
+ shift += getTabLength(i + shift - start, tabSize) - 1;
+ }
}
}
return offset - start + shift;
@@ -580,7 +593,7 @@
char c = text.charAt(i);
int prevX = x;
switch (c) {
- case '\t':
+ case '\t':
x = nextTabStop(x, editor);
result += columnsNumber(x - prevX, spaceSize);
break;
@@ -666,10 +679,10 @@
/**
* Delegates to the {@link #calcSurroundingRange(Editor, VisualPosition, VisualPosition)} with the
* {@link CaretModel#getVisualPosition() caret visual position} as an argument.
- *
+ *
* @param editor target editor
* @return surrounding logical positions
- * @see #calcSurroundingRange(Editor, VisualPosition, VisualPosition)
+ * @see #calcSurroundingRange(Editor, VisualPosition, VisualPosition)
*/
public static Pair<LogicalPosition, LogicalPosition> calcCaretLineRange(@NotNull Editor editor) {
return calcSurroundingRange(editor, editor.getCaretModel().getVisualPosition(), editor.getCaretModel().getVisualPosition());
@@ -719,7 +732,7 @@
}
line = foldEndLine;
}
-
+
LogicalPosition second = editor.visualToLogicalPosition(new VisualPosition(end.line, 0));
for (
@@ -739,7 +752,7 @@
}
line = foldEndLine;
}
-
+
if (second.line >= document.getLineCount()) {
second = editor.offsetToLogicalPosition(document.getTextLength());
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index 840fbde..fcef9aa 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -152,6 +152,7 @@
@NotNull private final EditorComponentImpl myEditorComponent;
@NotNull private final EditorGutterComponentImpl myGutterComponent;
private final TraceableDisposable myTraceableDisposable = new TraceableDisposable(new Throwable());
+ private volatile boolean hasTabs; // optimisation flag: when editor contains no tabs it is dramatically easier to calculate positions
static {
ComplementaryFontsRegistry.getFontAbleToDisplay(' ', 0, 0, UIManager.getFont("Label.font").getFamily()); // load costly font info
@@ -518,6 +519,7 @@
}
});
}
+ updateHasTabsFlag(document.getCharsSequence());
}
public static boolean isPresentationMode(Project project) {
@@ -1693,6 +1695,16 @@
Point caretLocation = visualPositionToXY(getCaretModel().getVisualPosition());
int scrollOffset = caretLocation.y - myCaretUpdateVShift;
getScrollingModel().scrollVertically(scrollOffset);
+ updateHasTabsFlag(e.getNewFragment());
+ }
+
+ private void updateHasTabsFlag(CharSequence newChars) {
+ if (!hasTabs) {
+ hasTabs = StringUtil.contains(newChars, 0, newChars.length(), '\t');
+ }
+ }
+ public boolean hasTabs() {
+ return hasTabs;
}
public boolean isScrollToCaret() {
@@ -1930,7 +1942,7 @@
@Override
public void setHeaderComponent(JComponent header) {
myHeaderPanel.removeAll();
- header = header == null ? getUserData(PERMANENT_HEADER) : header;
+ header = header == null ? getPermanentHeaderComponent() : header;
if (header != null) {
myHeaderPanel.add(header);
}
@@ -1940,13 +1952,23 @@
@Override
public boolean hasHeaderComponent() {
- return myHeaderPanel.getComponentCount() > 0;
+ JComponent header = getHeaderComponent();
+ return header != null && header != getPermanentHeaderComponent();
+ }
+
+ @Nullable
+ public JComponent getPermanentHeaderComponent() {
+ return getUserData(PERMANENT_HEADER);
+ }
+
+ public void setPermanentHeaderComponent(@Nullable JComponent component) {
+ putUserData(PERMANENT_HEADER, component);
}
@Override
@Nullable
public JComponent getHeaderComponent() {
- if (hasHeaderComponent()) {
+ if (myHeaderPanel.getComponentCount() > 0) {
return (JComponent)myHeaderPanel.getComponent(0);
}
return null;
@@ -2464,7 +2486,7 @@
// there then.
VisualPosition selectionStartPosition = getSelectionModel().getSelectionStartPosition();
VisualPosition selectionEndPosition = getSelectionModel().getSelectionEndPosition();
- if (selectionStartPosition == null || selectionEndPosition == null || selectionStartPosition.equals(selectionEndPosition)) {
+ if (selectionStartPosition.equals(selectionEndPosition)) {
return;
}
@@ -2525,7 +2547,7 @@
// there then.
VisualPosition selectionStartPosition = getSelectionModel().getSelectionStartPosition();
VisualPosition selectionEndPosition = getSelectionModel().getSelectionEndPosition();
- if (selectionStartPosition == null || selectionEndPosition == null || selectionStartPosition.equals(selectionEndPosition)) {
+ if (selectionStartPosition.equals(selectionEndPosition)) {
return;
}
@@ -3968,8 +3990,9 @@
int x = myGutterComponent.convertX(e.getX());
- if (x >= myGutterComponent.getLineNumberAreaOffset() &&
- x < myGutterComponent.getLineNumberAreaOffset() + myGutterComponent.getLineNumberAreaWidth()) {
+ int lineNumberAreaOffset = EditorGutterComponentImpl.getLineNumberAreaOffset();
+ if (x >= lineNumberAreaOffset &&
+ x < lineNumberAreaOffset + myGutterComponent.getLineNumberAreaWidth()) {
return EditorMouseEventArea.LINE_NUMBERS_AREA;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
index 051fdbf..25803d9 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
@@ -359,7 +359,7 @@
// currently there are 6 of them and restoration does not happen very often so just iteration is enough
if (type == PlainTextFileType.INSTANCE && !fileTypeName.equals(type.getName())) {
for (FileType fileType: getRegisteredFileTypes()) {
- if (fileType.equals(fileType.getName())) {
+ if (fileTypeName.equals(fileType.getName())) {
return fileType;
}
}
@@ -367,10 +367,6 @@
return type;
}
- private static class FileTypeDetectorHolder {
- private static final FileTypeDetector[] FILE_TYPE_DETECTORS = Extensions.getExtensions(FileTypeDetector.EP_NAME);
- }
-
private static final AtomicInteger DETECTED_COUNT = new AtomicInteger();
private static final int DETECT_BUFFER_SIZE = 8192;
@@ -403,8 +399,9 @@
else {
text = null;
}
+
FileType detected = null;
- for (FileTypeDetector detector : FileTypeDetectorHolder.FILE_TYPE_DETECTORS) {
+ for (FileTypeDetector detector : Extensions.getExtensions(FileTypeDetector.EP_NAME)) {
detected = detector.detect(file, byteSequence, text);
if (detected != null) break;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
index cc6a59b..6cca11c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
@@ -698,6 +698,7 @@
JScrollPane scroll = ScrollPaneFactory.createScrollPane(c);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
+ scroll.getVerticalScrollBar().setUnitIncrement(10);
scroll.setBorder(null);
add(scroll, BorderLayout.CENTER);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/DetectedPluginsPanel.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/DetectedPluginsPanel.java
index 6e7b914..b7be05b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/DetectedPluginsPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/DetectedPluginsPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -44,7 +44,7 @@
private static JEditorPane myDescriptionPanel = new JEditorPane();
- protected DetectedPluginsPanel() {
+ public DetectedPluginsPanel() {
super(PluginDownloader.class);
final JTable entryTable = getEntryTable();
entryTable.setTableHeader(null);
@@ -111,20 +111,24 @@
}
public boolean isChecked(final PluginDownloader downloader) {
- return !UpdateChecker.getDisabledToUpdatePlugins().contains(downloader.getPluginId());
+ return !getSkippedPlugins().contains(downloader.getPluginId());
}
public void setChecked(final PluginDownloader downloader, final boolean checked) {
if (checked) {
- UpdateChecker.getDisabledToUpdatePlugins().remove(downloader.getPluginId());
+ getSkippedPlugins().remove(downloader.getPluginId());
} else {
- UpdateChecker.getDisabledToUpdatePlugins().add(downloader.getPluginId());
+ getSkippedPlugins().add(downloader.getPluginId());
}
for (Listener listener : myListeners) {
listener.stateChanged();
}
}
+ protected Set<String> getSkippedPlugins() {
+ return UpdateChecker.getDisabledToUpdatePlugins();
+ }
+
public void addStateListener(Listener l) {
myListeners.add(l);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
new file mode 100644
index 0000000..24615ca
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2000-2013 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.openapi.updateSettings.impl.pluginsAdvertisement;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.intellij.ide.plugins.*;
+import com.intellij.notification.*;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationInfo;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.startup.StartupActivity;
+import com.intellij.openapi.updateSettings.impl.PluginDownloader;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.net.HttpConfigurable;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.event.HyperlinkEvent;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class PluginsAdvertiser implements StartupActivity {
+ private static final Logger LOG = Logger.getInstance("#" + PluginsAdvertiser.class.getName());
+
+ public static List<PluginId> retrieve(UnknownFeature unknownFeature) {
+ final String featureType = unknownFeature.getFeatureType();
+ final String implementationName = unknownFeature.getImplementationName();
+ final String buildNumber = ApplicationInfo.getInstance().getBuild().asString();
+ final String pluginRepositoryUrl = "http://plugins.jetbrains.com/feature/getImplementations?" +
+ "featureType=" + featureType +
+ "&implementationName=" + implementationName +
+ "&build=" + buildNumber;
+ try {
+ HttpURLConnection connection = HttpConfigurable.getInstance().openHttpConnection(pluginRepositoryUrl);
+ connection.connect();
+ final InputStreamReader streamReader = new InputStreamReader(connection.getInputStream());
+ try {
+ final JsonElement jsonRootElement = new JsonParser().parse(streamReader);
+ final List<PluginId> result = new ArrayList<PluginId>();
+ for (JsonElement jsonElement : jsonRootElement.getAsJsonArray()) {
+ final JsonObject jsonObject = jsonElement.getAsJsonObject();
+ final JsonElement pluginId = jsonObject.get("pluginId");
+ result.add(PluginId.getId(StringUtil.unquoteString(pluginId.toString())));
+ }
+ return result;
+ }
+ finally {
+ streamReader.close();
+ }
+ }
+ catch (IOException e) {
+ LOG.info(e);
+ return null;
+ }
+ }
+
+ @Override
+ public void runActivity(@NotNull final Project project) {
+ final UnknownFeaturesCollector collectorSuggester = UnknownFeaturesCollector.getInstance(project);
+ final Set<UnknownFeature> unknownFeatures = collectorSuggester.getUnknownFeatures();
+ if (unknownFeatures.isEmpty()) return;
+ final Runnable runnable = new Runnable() {
+ public void run() {
+ final Application application = ApplicationManager.getApplication();
+ if (application.isUnitTestMode() || application.isHeadlessEnvironment()) return;
+ ProgressManager.getInstance().run(new Task.Backgroundable(project, "Search for non-bundled plugins in plugin repository...") {
+ private final Set<PluginDownloader> myPlugins = new HashSet<PluginDownloader>();
+ private List<IdeaPluginDescriptor> myAllPlugins;
+
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ int idx = 0;
+ final Set<PluginId> ids = new HashSet<PluginId>();
+ for (UnknownFeature feature : unknownFeatures) {
+ indicator.setText("Searching for: " + feature.getFeatureType());
+ final List<PluginId> pluginId = retrieve(feature);
+ if (pluginId != null) {
+ //do not suggest to download disabled plugins
+ final List<String> disabledPlugins = PluginManagerCore.getDisabledPlugins();
+ for (PluginId id : pluginId) {
+ if (!disabledPlugins.contains(id.getIdString())) {
+ ids.add(id);
+ }
+ }
+ }
+ indicator.setFraction(idx++ / unknownFeatures.size());
+ }
+
+ try {
+ myAllPlugins = RepositoryHelper.loadPluginsFromRepository(indicator);
+ for (IdeaPluginDescriptor loadedPlugin : myAllPlugins) {
+ if (ids.contains(loadedPlugin.getPluginId())) {
+ myPlugins.add(PluginDownloader.createDownloader(loadedPlugin));
+ }
+ }
+ }
+ catch (Exception ignore) {
+ //no notification to show
+ }
+ }
+
+ @Override
+ public void onSuccess() {
+ if (!myPlugins.isEmpty()) {
+ final String displayId = "Plugins Suggestion";
+ new NotificationGroup(displayId, NotificationDisplayType.STICKY_BALLOON, true)
+ .createNotification(displayId, "Features covered by non-bundled plugins are detected.<br>" +
+ "<a href=\"configure\">Configure plugins...</a><br>" +
+ "<a href=\"ignore\">Ignore All</a>", NotificationType.INFORMATION, new NotificationListener() {
+ @Override
+ public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
+ if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+ final String description = event.getDescription();
+ if ("ignore".equals(description)) {
+ for (UnknownFeature feature : unknownFeatures) {
+ collectorSuggester.ignoreFeature(feature);
+ }
+ } else if ("configure".equals(description)) {
+ LOG.assertTrue(myAllPlugins != null);
+ new PluginsAdvertiserDialog(myProject, myPlugins.toArray(new PluginDownloader[myPlugins.size()]), myAllPlugins).show();
+ }
+ notification.expire();
+ }
+ }
+ }).notify(project);
+ }
+ }
+ });
+ }
+ };
+
+ SwingUtilities.invokeLater(runnable);
+ }
+}
+
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserDialog.java
new file mode 100644
index 0000000..a092d2a
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserDialog.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2000-2013 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.openapi.updateSettings.impl.pluginsAdvertisement;
+
+import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.PluginManagerMain;
+import com.intellij.ide.plugins.PluginNode;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.updateSettings.impl.DetectedPluginsPanel;
+import com.intellij.openapi.updateSettings.impl.PluginDownloader;
+import com.intellij.ui.TableUtil;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+* User: anna
+*/
+public class PluginsAdvertiserDialog extends DialogWrapper {
+ private static final Logger LOG = Logger.getInstance("#" + PluginsAdvertiserDialog.class.getName());
+
+ private final PluginDownloader[] myUploadedPlugins;
+ private final List<IdeaPluginDescriptor> myAllPlugins;
+ private final HashSet<String> mySkippedPlugins = new HashSet<String>();
+
+ PluginsAdvertiserDialog(@Nullable Project project, PluginDownloader[] plugins, List<IdeaPluginDescriptor> allPlugins) {
+ super(project);
+ myUploadedPlugins = plugins;
+ myAllPlugins = allPlugins;
+ setTitle("Choose Plugins to Install");
+ init();
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ final DetectedPluginsPanel foundPluginsPanel = new DetectedPluginsPanel() {
+ @Override
+ protected Set<String> getSkippedPlugins() {
+ return mySkippedPlugins;
+ }
+ };
+
+ for (PluginDownloader uploadedPlugin : myUploadedPlugins) {
+ foundPluginsPanel.add(uploadedPlugin);
+ }
+ TableUtil.ensureSelectionExists(foundPluginsPanel.getEntryTable());
+ return foundPluginsPanel;
+ }
+
+ @Override
+ protected void doOKAction() {
+ final List<PluginNode> nodes = new ArrayList<PluginNode>();
+ for (PluginDownloader downloader : myUploadedPlugins) {
+ if (!mySkippedPlugins.contains(downloader.getPluginId())) {
+ final PluginNode pluginNode = PluginDownloader.createPluginNode(null, downloader);
+ if (pluginNode != null) {
+ nodes.add(pluginNode);
+ }
+ }
+ }
+ try {
+ PluginManagerMain.downloadPlugins(nodes, myAllPlugins, new Runnable() {
+ @Override
+ public void run() {
+ PluginManagerMain.notifyPluginsWereInstalled(null);
+ }
+ }, null);
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ super.doOKAction();
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/UnknownFeature.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/UnknownFeature.java
new file mode 100644
index 0000000..13640ef
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/UnknownFeature.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2013 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.openapi.updateSettings.impl.pluginsAdvertisement;
+
+/**
+ * User: anna
+ */
+public class UnknownFeature {
+ private final String myFeatureType;
+ private final String myImplementationName;
+
+ public UnknownFeature(String featureType, String implementationName) {
+ myFeatureType = featureType;
+ myImplementationName = implementationName;
+ }
+
+ public String getFeatureType() {
+ return myFeatureType;
+ }
+
+ public String getImplementationName() {
+ return myImplementationName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ UnknownFeature feature = (UnknownFeature)o;
+
+ if (!myFeatureType.equals(feature.myFeatureType)) return false;
+ if (!myImplementationName.equals(feature.myImplementationName)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myFeatureType.hashCode();
+ result = 31 * result + myImplementationName.hashCode();
+ return result;
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/UnknownFeaturesCollector.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/UnknownFeaturesCollector.java
new file mode 100644
index 0000000..0bd1410
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/UnknownFeaturesCollector.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2000-2013 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.openapi.updateSettings.impl.pluginsAdvertisement;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * User: anna
+ */
+@State(
+ name = "UnknownFeatures",
+ storages = {
+ @Storage(
+ file = StoragePathMacros.WORKSPACE_FILE
+ )}
+)
+public class UnknownFeaturesCollector implements PersistentStateComponent<Element> {
+ @NonNls private static final String FEATURE_ID = "featureType";
+ @NonNls private static final String IMPLEMENTATION_NAME = "implementationName";
+
+ private final Set<UnknownFeature> myUnknownFeatures = new HashSet<UnknownFeature>();
+ private final Set<UnknownFeature> myIgnoredUnknownFeatures = new HashSet<UnknownFeature>();
+
+ public static UnknownFeaturesCollector getInstance(Project project) {
+ return ServiceManager.getService(project, UnknownFeaturesCollector.class);
+ }
+
+ public void registerUnknownRunConfiguration(String configurationName) {
+ registerUnknownFeature("com.intellij.configurationType", configurationName);
+ }
+
+ public void registerUnknownFeature(String featureType, String implementationName) {
+ final UnknownFeature feature = new UnknownFeature(featureType, implementationName);
+ if (!myIgnoredUnknownFeatures.contains(feature)) {
+ myUnknownFeatures.add(feature);
+ }
+ }
+
+ public void ignoreFeature(UnknownFeature feature) {
+ myIgnoredUnknownFeatures.add(feature);
+ }
+
+ public Set<UnknownFeature> getUnknownFeatures() {
+ return myUnknownFeatures;
+ }
+
+ @Nullable
+ @Override
+ public Element getState() {
+ if (myIgnoredUnknownFeatures.isEmpty()) return null;
+
+ final Element ignored = new Element("ignored");
+ for (UnknownFeature feature : myIgnoredUnknownFeatures) {
+ final Element option = new Element("option");
+ option.setAttribute(FEATURE_ID, feature.getFeatureType());
+ option.setAttribute(IMPLEMENTATION_NAME, feature.getImplementationName());
+ ignored.addContent(option);
+ }
+ return ignored;
+ }
+
+ @Override
+ public void loadState(Element state) {
+ myIgnoredUnknownFeatures.clear();
+ for (Element element : state.getChildren()) {
+ myIgnoredUnknownFeatures.add(
+ new UnknownFeature(element.getAttributeValue(FEATURE_ID), element.getAttributeValue(IMPLEMENTATION_NAME)));
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java
index eb46fc8..7f0b5e8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,10 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
- * @author max
- */
package com.intellij.openapi.vfs.impl.jar;
import com.intellij.notification.NotificationGroup;
@@ -48,6 +44,9 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+/**
+ * @author max
+ */
public class JarHandler extends JarHandlerBase {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.jar.JarHandler");
@@ -111,6 +110,8 @@
private File getMirrorWithContentHash(File originalFile,
FileAttributes originalAttributes) {
File mirrorFile = null;
+ String jarDir = getJarsDir();
+
try {
String path = originalFile.getPath();
CacheLibraryInfo info = CacheLibraryInfo.ourCachedLibraryInfo.get(path);
@@ -120,7 +121,7 @@
if (originalAttributes.length == info.myFileLength &&
Math.abs(originalAttributes.lastModified - info.myModificationTime) <= FS_TIME_RESOLUTION
) {
- mirrorFile = new File(new File(getJarsDir()), info.mySnapshotPath);
+ mirrorFile = new File(new File(jarDir), info.mySnapshotPath);
mirrorFileAttributes = FileSystemUtil.getAttributes(mirrorFile);
if (mirrorFileAttributes != null &&
mirrorFileAttributes.length == originalAttributes.length &&
@@ -139,7 +140,7 @@
File tempJarFile = null;
try {
- tempJarFile = FileUtil.createTempFile(new File(getJarsDir()), originalFile.getName(), "", true, false);
+ tempJarFile = FileUtil.createTempFile(new File(jarDir), originalFile.getName(), "", true, false);
os = new DataOutputStream(new FileOutputStream(tempJarFile));
is = new FileInputStream(originalFile);
byte[] buffer = new byte[20 * 1024];
@@ -154,10 +155,13 @@
sha1.update(buffer, 0, read);
os.write(buffer, 0, read);
}
- } catch (IOException ex) {
- reportIOErrorWithJars(originalFile, mirrorFile != null ? mirrorFile:tempJarFile, ex);
+ }
+ catch (IOException ex) {
+ File target = mirrorFile != null ? mirrorFile : tempJarFile != null ? tempJarFile : new File(jarDir);
+ reportIOErrorWithJars(originalFile, target, ex);
return originalFile;
- } catch (NoSuchAlgorithmException ex) {
+ }
+ catch (NoSuchAlgorithmException ex) {
assert false;
return originalFile; // should never happen for sha1
}
@@ -167,7 +171,7 @@
}
byte[] digest = sha1.digest();
- mirrorFile = new File(new File(getJarsDir()), getSnapshotName(originalFile.getName(), digest));
+ mirrorFile = new File(new File(jarDir), getSnapshotName(originalFile.getName(), digest));
mirrorFileAttributes = FileSystemUtil.getAttributes(mirrorFile);
if (mirrorFileAttributes == null ||
@@ -193,7 +197,7 @@
CacheLibraryInfo.ourCachedLibraryInfo.force();
return mirrorFile;
} catch (IOException ex) {
- reportIOErrorWithJars(originalFile, mirrorFile != null ? mirrorFile: new File(getJarsDir(), originalFile.getName()), ex);
+ reportIOErrorWithJars(originalFile, mirrorFile != null ? mirrorFile: new File(jarDir, originalFile.getName()), ex);
return originalFile;
}
}
@@ -314,13 +318,13 @@
}
};
- private void reportIOErrorWithJars(File original, File mirror, IOException e) {
+ private void reportIOErrorWithJars(File original, File target, IOException e) {
LOG.warn(e);
- final String path = original.getPath();
- final String message = VfsBundle.message("jar.copy.error.message", path, mirror.getPath(), e.getMessage());
- ERROR_COPY_NOTIFICATION.getValue().createNotification(message, NotificationType.ERROR).notify(null);
-
+ String path = original.getPath();
myFileSystem.setNoCopyJarForPath(path);
+
+ String message = VfsBundle.message("jar.copy.error.message", path, target.getPath(), e.getMessage());
+ ERROR_COPY_NOTIFICATION.getValue().createNotification(message, NotificationType.ERROR).notify(null);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
index 19af1b1..09de7d3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
@@ -139,6 +139,8 @@
final boolean pureMouse1Event = (me.getModifiersEx() | button1) == button1;
if (pureMouse1Event && me.getClickCount() <= 1 && !me.isPopupTrigger()) {
final Point point = SwingUtilities.convertPoint(meComponent, me.getPoint(), myRootPane.getContentPane());
+ JMenuBar menuBar = myRootPane.getJMenuBar();
+ point.y += menuBar != null ? menuBar.getHeight() : 0;
final Component target =
SwingUtilities.getDeepestComponentAt(myRootPane.getContentPane().getParent(), point.x, point.y);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenUrlPsiReference.java b/platform/platform-impl/src/com/intellij/psi/impl/UrlPsiReference.java
similarity index 71%
rename from plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenUrlPsiReference.java
rename to platform/platform-impl/src/com/intellij/psi/impl/UrlPsiReference.java
index 12fd29d..9a52a56 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenUrlPsiReference.java
+++ b/platform/platform-impl/src/com/intellij/psi/impl/UrlPsiReference.java
@@ -13,33 +13,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.maven.dom.references;
+package com.intellij.psi.impl;
import com.intellij.ide.BrowserUtil;
-import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.impl.FakePsiElement;
+import com.intellij.psi.PsiReferenceBase;
import org.jetbrains.annotations.NotNull;
-public class MavenUrlPsiReference extends MavenPsiReference {
- public MavenUrlPsiReference(PsiElement element, String text, TextRange range) {
- super(element, text, range);
+public class UrlPsiReference extends PsiReferenceBase<PsiElement> {
+ public UrlPsiReference(PsiElement element) {
+ super(element);
}
public PsiElement resolve() {
return new FakePsiElement() {
public PsiElement getParent() {
- return myElement;
+ return getElement();
}
@Override
public String getName() {
- return myText;
+ return getValue();
}
@Override
public void navigate(boolean requestFocus) {
- BrowserUtil.launchBrowser(myText);
+ BrowserUtil.launchBrowser(getValue());
}
};
}
@@ -48,4 +47,9 @@
public Object[] getVariants() {
return EMPTY_ARRAY;
}
+
+ @Override
+ public boolean isSoft() {
+ return true;
+ }
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/ui/win/RecentProjectApplication.java b/platform/platform-impl/src/com/intellij/ui/win/RecentProjectApplication.java
new file mode 100644
index 0000000..9561c77
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/win/RecentProjectApplication.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2013 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.ui.win;
+
+import com.intellij.ide.impl.ProjectUtil;
+import com.intellij.openapi.diff.ApplicationStarterBase;
+
+
+/**
+ * @author Denis Fokin
+ */
+public class RecentProjectApplication extends ApplicationStarterBase {
+ public RecentProjectApplication() {
+ super("reopen", 1);
+ }
+
+ @Override
+ public String getUsageMessage() {
+ return String.format("This command is used for internal purpose only.");
+ }
+
+ @Override
+ protected void processCommand(String[] args) throws Exception {
+ ProjectUtil.openProject(args[1], null, false);
+ }
+}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java b/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java
index 12ad39f..3ba433a 100644
--- a/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java
+++ b/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java
@@ -16,6 +16,7 @@
package com.intellij.ui.win;
import com.intellij.idea.StartupUtil;
+import com.intellij.util.lang.UrlClassLoader;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -29,7 +30,7 @@
new WeakReference<Thread>(Thread.currentThread());
static {
- System.loadLibrary("jumpListBridge");
+ UrlClassLoader.loadPlatformLibrary("jumpListBridge");
}
private synchronized static void init() {
@@ -54,7 +55,12 @@
clearNative();
}
+ /**
+ * Use #clearNative method instead of passing empty array of tasks.
+ * @param tasks
+ */
public synchronized static void addTasks(final Task[] tasks) {
+ if (tasks.length == 0) return;
init();
checkThread();
addTasksNativeForCategory("Recent", tasks);
diff --git a/platform/platform-impl/src/com/intellij/ui/win/SocketControlHelper.java b/platform/platform-impl/src/com/intellij/ui/win/SocketControlHelper.java
index 84372bf..b2f7738 100644
--- a/platform/platform-impl/src/com/intellij/ui/win/SocketControlHelper.java
+++ b/platform/platform-impl/src/com/intellij/ui/win/SocketControlHelper.java
@@ -46,7 +46,7 @@
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
try {
- out.writeUTF(ACTIVATE_COMMAND + new File(".").getAbsolutePath() + "\0" + pathToProject);
+ out.writeUTF(ACTIVATE_COMMAND + new File(".").getAbsolutePath() + "\0" + "reopen" + "\0" + pathToProject);
out.flush();
String response = in.readUTF();
if (response.equals("ok")) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java b/platform/platform-impl/src/com/intellij/util/SingletonInstancesCache.java
similarity index 86%
rename from plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java
rename to platform/platform-impl/src/com/intellij/util/SingletonInstancesCache.java
index 7a9f055..5d7810b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java
+++ b/platform/platform-impl/src/com/intellij/util/SingletonInstancesCache.java
@@ -1,4 +1,4 @@
-package org.jetbrains.plugins.groovy.util;
+package com.intellij.util;
import com.intellij.util.containers.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
@@ -6,11 +6,11 @@
/**
* @author Sergey Evdokimov
*/
-public class ClassInstanceCache {
+public class SingletonInstancesCache {
private static final ConcurrentHashMap<String, Object> CACHE = new ConcurrentHashMap<String, Object>();
- private ClassInstanceCache() {
+ private SingletonInstancesCache() {
}
@SuppressWarnings("unchecked")
diff --git a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
index 85d70892..cff39b5 100644
--- a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
+++ b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
@@ -19,6 +19,7 @@
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.net.NetUtils;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
@@ -34,6 +35,7 @@
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.ServerSocket;
import java.util.Map;
public class BuiltInServer implements Disposable {
@@ -68,7 +70,7 @@
bootstrap.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(Channel channel) throws Exception {
- channel.pipeline().addLast(channelRegistrar, portUnificationServerHandler);
+ channel.pipeline().addLast(channelRegistrar, portUnificationServerHandler, ChannelExceptionHandler.getInstance());
}
});
}
@@ -79,7 +81,7 @@
protected void initChannel(Channel channel) throws Exception {
channel.pipeline().addLast(channelRegistrar);
NettyUtil.initHttpHandlers(channel.pipeline());
- channel.pipeline().addLast(handler);
+ channel.pipeline().addLast(handler, ChannelExceptionHandler.getInstance());
}
});
}
@@ -106,6 +108,23 @@
InetAddress loopbackAddress = NetUtils.getLoopbackAddress();
for (int i = 0; i < portsCount; i++) {
int port = firstPort + i;
+
+ // we check if any port free too
+ if (!SystemInfo.isLinux && (!SystemInfo.isWindows || SystemInfo.isWinVistaOrNewer)) {
+ try {
+ ServerSocket serverSocket = new ServerSocket();
+ try {
+ serverSocket.bind(new InetSocketAddress(port), 1);
+ }
+ finally {
+ serverSocket.close();
+ }
+ }
+ catch (IOException ignored) {
+ continue;
+ }
+ }
+
ChannelFuture future = bootstrap.bind(loopbackAddress, port).awaitUninterruptibly();
if (future.isSuccess()) {
channelRegistrar.add(future.channel());
diff --git a/platform/platform-impl/src/org/jetbrains/io/ChannelExceptionHandler.java b/platform/platform-impl/src/org/jetbrains/io/ChannelExceptionHandler.java
index 93def2e..54ba57f 100644
--- a/platform/platform-impl/src/org/jetbrains/io/ChannelExceptionHandler.java
+++ b/platform/platform-impl/src/org/jetbrains/io/ChannelExceptionHandler.java
@@ -18,6 +18,7 @@
import com.intellij.openapi.diagnostic.Logger;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.net.ConnectException;
@@ -26,6 +27,15 @@
public final class ChannelExceptionHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOG = Logger.getInstance(ChannelExceptionHandler.class);
+ private static final ChannelInboundHandler INSTANCE = new ChannelExceptionHandler();
+
+ private ChannelExceptionHandler() {
+ }
+
+ public static ChannelInboundHandler getInstance() {
+ return INSTANCE;
+ }
+
@Override
public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
// don't report about errors while connecting
diff --git a/platform/platform-impl/src/org/jetbrains/io/Decoder.java b/platform/platform-impl/src/org/jetbrains/io/Decoder.java
index 30052bd..c4ad246 100644
--- a/platform/platform-impl/src/org/jetbrains/io/Decoder.java
+++ b/platform/platform-impl/src/org/jetbrains/io/Decoder.java
@@ -21,7 +21,7 @@
import io.netty.channel.SimpleChannelInboundHandler;
import org.jetbrains.annotations.Nullable;
-public abstract class Decoder<I> extends SimpleChannelInboundHandler<I> {
+public abstract class Decoder extends SimpleChannelInboundHandler<ByteBuf> {
protected ByteBuf cumulation;
protected Decoder() {
diff --git a/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandler.java b/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandler.java
index e7809ac..305565a 100644
--- a/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandler.java
+++ b/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandler.java
@@ -29,7 +29,6 @@
import org.apache.sanselan.ImageFormat;
import org.apache.sanselan.ImageWriteException;
import org.apache.sanselan.Sanselan;
-import org.jetbrains.ide.BuiltInServerManager;
import org.jetbrains.ide.HttpRequestHandler;
import javax.swing.*;
@@ -52,7 +51,7 @@
prevHandlerAttribute.set(null);
}
- for (HttpRequestHandler handler : BuiltInServerManager.EP_NAME.getExtensions()) {
+ for (HttpRequestHandler handler : HttpRequestHandler.EP_NAME.getExtensions()) {
try {
if (handler.isSupported(request) && handler.process(urlDecoder, request, context)) {
prevHandlerAttribute.set(handler);
diff --git a/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java b/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java
index 86ae505..86dce36 100644
--- a/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java
+++ b/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java
@@ -20,8 +20,10 @@
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.oio.OioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.channel.socket.oio.OioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
@@ -111,6 +113,12 @@
return bootstrap;
}
+ public static Bootstrap nioClientBootstrap() {
+ Bootstrap bootstrap = new Bootstrap().group(new NioEventLoopGroup(1, PooledThreadExecutor.INSTANCE)).channel(NioSocketChannel.class);
+ bootstrap.option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true);
+ return bootstrap;
+ }
+
public static void initHttpHandlers(ChannelPipeline pipeline) {
pipeline.addLast(new HttpRequestDecoder(), new HttpObjectAggregator(1048576), new HttpResponseEncoder());
}
diff --git a/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java b/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
index 1169763..4a9b802 100644
--- a/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
+++ b/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
@@ -25,15 +25,17 @@
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.ide.BinaryRequestHandler;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.security.KeyStore;
import java.security.Security;
+import java.util.UUID;
@ChannelHandler.Sharable
-final class PortUnificationServerHandler extends Decoder<ByteBuf> {
+class PortUnificationServerHandler extends Decoder {
private static final AtomicNotNullLazyValue<SSLContext> SSL_SERVER_CONTEXT = new AtomicNotNullLazyValue<SSLContext>() {
@NotNull
@Override
@@ -86,22 +88,22 @@
}
}
- private void decode(ChannelHandlerContext context, ByteBuf buffer) throws Exception {
+ protected void decode(ChannelHandlerContext context, ByteBuf buffer) throws Exception {
ChannelPipeline pipeline = context.pipeline();
if (detectSsl && SslHandler.isEncrypted(buffer)) {
SSLEngine engine = SSL_SERVER_CONTEXT.getValue().createSSLEngine();
engine.setUseClientMode(false);
- pipeline.addLast(new SslHandler(engine), new ChunkedWriteHandler());
- pipeline.addLast(new PortUnificationServerHandler(delegatingHttpRequestHandler, false, detectGzip));
+ pipeline.addLast(new SslHandler(engine), new ChunkedWriteHandler(),
+ new PortUnificationServerHandler(delegatingHttpRequestHandler, false, detectGzip));
}
else {
int magic1 = buffer.getUnsignedByte(buffer.readerIndex());
int magic2 = buffer.getUnsignedByte(buffer.readerIndex() + 1);
if (detectGzip && magic1 == 31 && magic2 == 139) {
- pipeline.addLast(new JZlibEncoder(ZlibWrapper.GZIP), new JdkZlibDecoder(ZlibWrapper.GZIP));
- pipeline.addLast(new PortUnificationServerHandler(delegatingHttpRequestHandler, detectSsl, false));
+ pipeline.addLast(new JZlibEncoder(ZlibWrapper.GZIP), new JdkZlibDecoder(ZlibWrapper.GZIP),
+ new PortUnificationServerHandler(delegatingHttpRequestHandler, detectSsl, false));
}
- else {
+ else if (isHttp(magic1, magic2)) {
NettyUtil.initHttpHandlers(pipeline);
pipeline.addLast(delegatingHttpRequestHandler);
if (BuiltInServer.LOG.isDebugEnabled()) {
@@ -116,14 +118,66 @@
});
}
}
+ else if (magic1 == 'C' && magic2 == 'H') {
+ buffer.skipBytes(2);
+ pipeline.addLast(new CustomHandlerDelegator());
+ }
+ else {
+ BuiltInServer.LOG.warn("unknown request, first two bytes " + magic1 + " " + magic2);
+ context.close();
+ }
}
// must be after new channels handlers addition (netty bug?)
+ ensureThatExceptionHandlerIsLast(pipeline);
pipeline.remove(this);
context.fireChannelRead(buffer);
}
- @Override
- public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
- NettyUtil.log(cause, BuiltInServer.LOG);
+ private static void ensureThatExceptionHandlerIsLast(ChannelPipeline pipeline) {
+ ChannelInboundHandler exceptionHandler = ChannelExceptionHandler.getInstance();
+ if (pipeline.last() != exceptionHandler || pipeline.context(exceptionHandler) == null) {
+ return;
+ }
+
+ pipeline.remove(exceptionHandler);
+ pipeline.addLast(exceptionHandler);
+ }
+
+ private static boolean isHttp(int magic1, int magic2) {
+ return
+ magic1 == 'G' && magic2 == 'E' || // GET
+ magic1 == 'P' && magic2 == 'O' || // POST
+ magic1 == 'P' && magic2 == 'U' || // PUT
+ magic1 == 'H' && magic2 == 'E' || // HEAD
+ magic1 == 'O' && magic2 == 'P' || // OPTIONS
+ magic1 == 'P' && magic2 == 'A' || // PATCH
+ magic1 == 'D' && magic2 == 'E' || // DELETE
+ magic1 == 'T' && magic2 == 'R' || // TRACE
+ magic1 == 'C' && magic2 == 'O'; // CONNECT
+ }
+
+ private static class CustomHandlerDelegator extends Decoder {
+ private static final int UUID_LENGTH = 16;
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext context, ByteBuf message) throws Exception {
+ ByteBuf buffer = getBufferIfSufficient(message, UUID_LENGTH, context);
+ if (buffer == null) {
+ message.release();
+ }
+ else {
+ UUID uuid = new UUID(buffer.readLong(), buffer.readLong());
+ for (BinaryRequestHandler customHandler : BinaryRequestHandler.EP_NAME.getExtensions()) {
+ if (uuid.equals(customHandler.getId())) {
+ ChannelPipeline pipeline = context.pipeline();
+ pipeline.addLast(customHandler.getInboundHandler());
+ ensureThatExceptionHandlerIsLast(pipeline);
+ pipeline.remove(this);
+ context.fireChannelRead(buffer);
+ break;
+ }
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties
index dbfb892..e88bcf0 100644
--- a/platform/platform-resources-en/src/messages/IdeBundle.properties
+++ b/platform/platform-resources-en/src/messages/IdeBundle.properties
@@ -260,7 +260,7 @@
message.personal.license=Personal License
aboutbox.build.number=Build #{0}
aboutbox.build.date=, built on {0}
-aboutbox.jdk=JRE : {0}
+aboutbox.jdk=JRE : {0} {1}
aboutbox.vm=VM: {0} by {1}
aboutbox.maintenance.due=Entitled for free updates and upgrades until {0,date,MMMM dd, yyyy}
title.warning=Warning
diff --git a/platform/platform-resources-en/src/messages/VfsBundle.properties b/platform/platform-resources-en/src/messages/VfsBundle.properties
index 7e7bf75..9ea22a3 100644
--- a/platform/platform-resources-en/src/messages/VfsBundle.properties
+++ b/platform/platform-resources-en/src/messages/VfsBundle.properties
@@ -5,7 +5,7 @@
file.write.error=Cannot write to file {0}.
file.delete.root.error=Cannot delete root file {0}.
jar.copy.progress=Copying {0}...
-jar.copy.error.message=Cannot copy {0} to {1}.\nReason: {2}.
+jar.copy.error.message=Cannot copy ''{0}'' to ''{1}''.\nReason: {2}.
jar.copy.error.title=Error Copying File
jar.modification.not.supported.error=Cannot modify jar or zip file {0}
file.synchronize.progress=Synchronizing files...
diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
index 0d6e267..b9a857d 100644
--- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
@@ -780,6 +780,9 @@
<extensionPoint name="moduleRendererFactory" interface="com.intellij.ide.util.ModuleRendererFactory"/>
+ <extensionPoint name="projectStructure.sourceRootEditHandler"
+ interface="com.intellij.openapi.roots.ui.configuration.ModuleSourceRootEditHandler"/>
+
<extensionPoint name="toolsProvider" interface="com.intellij.tools.ToolsProvider"/>
<extensionPoint name="defaultHighlightingSettingProvider"
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index 59550dc..d2710f4 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -848,6 +848,9 @@
<applicationService serviceInterface="com.intellij.ide.util.treeView.TreeAnchorizer"
serviceImplementation="com.intellij.ide.projectView.impl.nodes.PsiTreeAnchorizer"/>
+ <projectStructure.sourceRootEditHandler implementation="com.intellij.openapi.roots.ui.configuration.JavaModuleSourceRootEditHandler"/>
+ <projectStructure.sourceRootEditHandler implementation="com.intellij.openapi.roots.ui.configuration.JavaTestSourceRootEditHandler"/>
+
<elementPreviewProvider implementation="com.intellij.codeInsight.preview.ElementPreviewHintProvider"/>
</extensions>
</idea-plugin>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
index bd4ff01..f8f0c6c 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
@@ -190,6 +190,7 @@
<extensionPoint name="pathMacroExpandableProtocol" beanClass="com.intellij.application.options.PathMacroExpandableProtocolBean"/>
<extensionPoint name="httpRequestHandler" interface="org.jetbrains.ide.HttpRequestHandler"/>
+ <extensionPoint name="binaryRequestHandler" interface="org.jetbrains.ide.BinaryRequestHandler"/>
<extensionPoint name="customPortServerManager" interface="org.jetbrains.ide.CustomPortServerManager"/>
<extensionPoint name="colorPickerListenerFactory" interface="com.intellij.ui.ColorPickerListenerFactory"/>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index 8c05bb9..8e19ac9 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -3,6 +3,7 @@
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<appStarter implementation="com.intellij.openapi.diff.DiffApplication"/>
<appStarter implementation="com.intellij.openapi.diff.MergeApplication"/>
+ <appStarter implementation="com.intellij.ui.win.RecentProjectApplication"/>
<appStarter implementation="com.intellij.help.impl.KeymapGenerator"/>
<applicationService serviceInterface="com.intellij.ide.util.PropertiesComponent"
@@ -307,5 +308,7 @@
implementationClass="com.intellij.codeStyle.InconsistentLineSeparatorsInspection"/>
<search.topHitProvider implementation="com.intellij.platform.DefaultPlatformTopHitProvider"/>
<search.topHitProvider implementation="com.intellij.ide.ui.UISimpleSettingsProvider"/>
+ <projectService serviceImplementation="com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector"/>
+ <postStartupActivity implementation="com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginsAdvertiser"/>
</extensions>
</idea-plugin>
diff --git a/platform/platform-resources/src/META-INF/XmlActions.xml b/platform/platform-resources/src/META-INF/XmlActions.xml
index 6d334dd..c727bd7 100644
--- a/platform/platform-resources/src/META-INF/XmlActions.xml
+++ b/platform/platform-resources/src/META-INF/XmlActions.xml
@@ -71,5 +71,13 @@
description="Generate a new XML tag according to schema information">
<add-to-group group-id="GenerateGroup" anchor="first"/>
</action>
+
+ <action id="OpenInBrowser" class="com.intellij.ide.browsers.OpenFileInDefaultBrowserAction"
+ text="Open in _Browser" description="Open a selected file in browser"
+ icon="AllIcons.Nodes.PpWeb">
+ <add-to-group group-id="ViewMenu" anchor="after" relative-to-action="ViewSource"/>
+ <add-to-group group-id="EditorPopupMenu" anchor="after" relative-to-action="CutCopyPasteGroup"/>
+ <add-to-group group-id="ProjectViewPopupMenu" anchor="after" relative-to-action="EditSource"/>
+ </action>
</actions>
</component>
diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml
index 769a2c2..ca2ddbc 100644
--- a/platform/platform-resources/src/META-INF/XmlPlugin.xml
+++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml
@@ -20,8 +20,8 @@
interface="com.intellij.xml.XmlExtension"/>
<extensionPoint name="xml.namespaceHelper"
interface="com.intellij.xml.XmlNamespaceHelper"/>
- <extensionPoint name="xml.tagNameProvider"
- interface="com.intellij.xml.XmlTagNameProvider"/>
+ <extensionPoint name="xml.completionExtension"
+ interface="com.intellij.xml.XmlCompletionExtension"/>
<extensionPoint name="xml.fileNSInfoProvider"
interface="com.intellij.psi.xml.XmlFileNSInfoProvider"/>
<extensionPoint name="xml.attributeDescriptorsProvider"
@@ -493,7 +493,7 @@
<xml.psiPolicy language="HTML" implementationClass="com.intellij.psi.impl.source.xml.behavior.EncodeEachSymbolPolicy"/>
<xml.psiPolicy language="XHTML" implementationClass="com.intellij.psi.impl.source.xml.behavior.EncodeEachSymbolPolicy"/>
- <xml.tagNameProvider implementation="com.intellij.psi.impl.source.xml.DefaultXmlTagNameProvider"/>
+ <xml.completionExtension implementation="com.intellij.psi.impl.source.xml.DefaultXmlCompletionExtension"/>
<xml.fileNSInfoProvider implementation="com.intellij.xml.util.HtmlFileNSInfoProvider"/>
<codeInsight.unresolvedReferenceQuickFixProvider
diff --git a/platform/platform-tests/platform-tests.iml b/platform/platform-tests/platform-tests.iml
index 74ebc8f..a2fe526 100644
--- a/platform/platform-tests/platform-tests.iml
+++ b/platform/platform-tests/platform-tests.iml
@@ -21,6 +21,7 @@
<orderEntry type="module" module-name="xdebugger-impl" scope="RUNTIME" />
<orderEntry type="module" module-name="xml-openapi" />
<orderEntry type="library" name="Groovy" level="project" />
+ <orderEntry type="library" name="Netty" level="project" />
</component>
</module>
diff --git a/platform/platform-tests/testSrc/META-INF/plugin.xml b/platform/platform-tests/testSrc/META-INF/plugin.xml
new file mode 100644
index 0000000..905cbe6
--- /dev/null
+++ b/platform/platform-tests/testSrc/META-INF/plugin.xml
@@ -0,0 +1,8 @@
+<idea-plugin>
+ <name>Platform Tests</name>
+ <id>org.jetbrains.platform.tests</id>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <binaryRequestHandler implementation="com.intellij.ide.BinaryRequestHandlerTest$MyBinaryRequestHandler"/>
+ </extensions>
+</idea-plugin>
\ No newline at end of file
diff --git a/platform/platform-tests/testSrc/com/intellij/execution/filters/RegexpFilterTest.java b/platform/platform-tests/testSrc/com/intellij/execution/filters/RegexpFilterTest.java
index 02568e7..84b77f17 100644
--- a/platform/platform-tests/testSrc/com/intellij/execution/filters/RegexpFilterTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/execution/filters/RegexpFilterTest.java
@@ -1,14 +1,33 @@
+/*
+ * Copyright 2000-2013 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.openapi.project.Project;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class RegexpFilterTest extends TestCase {
+import static org.junit.Assert.assertEquals;
+
+public class RegexpFilterTest {
private static final String FILE = RegexpFilter.FILE_PATH_MACROS;
private static final String LINE = RegexpFilter.LINE_MACROS;
private static final String COLUMN = RegexpFilter.COLUMN_MACROS;
+
private RegexpFilter myFilter;
+ @Test
public void test() {
createFilter(FILE);
String line = "C:\\Work\\SampleProjects\\makeOutput.cmd";
@@ -19,7 +38,8 @@
info.checkInfo(line, 0, 0);
}
- public void testFileLineComlumn() {
+ @Test
+ public void testFileLineColumn() {
createFilter(FILE + "x" + LINE + "y" + COLUMN);
String fileName = "C:\\file";
Filter.Result result = applyFilter(fileName + "x12y34");
@@ -29,6 +49,7 @@
info.checkInfo(fileName, 11, 33);
}
+ @Test
public void testFileLineColumnWithTail() {
createFilter(FILE + ":" + LINE + ":" + COLUMN + ".*");
String fileName = "C:/file";
@@ -39,15 +60,17 @@
info.checkInfo(fileName, 11, 33);
}
+ @Test
public void test4814() {
createFilter(FILE + ":" + LINE + ":" + COLUMN + ".*");
- String fileName = "C:/work/dev/C3C/V9_9_9_9/src/java/strata/pswitch/ss5e/dataSync/BFGParser.java";
+ String fileName = "C:/work/dev/C3C/V9_9_9_9/src/java/strata/p_switch/ss5e/dataSync/BFGParser.java";
String line = fileName + ":544:13:544:13:";
Filter.Result result = applyFilter(line);
HLInfo info = (HLInfo) result.hyperlinkInfo;
info.checkInfo(fileName, 543, 12);
}
+ @Test
public void testWithSpaces() {
createFilter("$FILE_PATH$\\s+\\($LINE$\\:$COLUMN$\\)");
String line = "C:\\d ir\\file.ext (1:2)message";
@@ -69,7 +92,9 @@
};
}
- public HyperlinkInfo createOpenFile(String fileName, int line, int comumn) {return new HLInfo(fileName, line, comumn); }
+ private static HyperlinkInfo createOpenFile(String fileName, int line, int column) {
+ return new HLInfo(fileName, line, column);
+ }
private static class HLInfo implements HyperlinkInfo {
public String myFileName;
diff --git a/platform/platform-tests/testSrc/com/intellij/ide/BinaryRequestHandlerTest.java b/platform/platform-tests/testSrc/com/intellij/ide/BinaryRequestHandlerTest.java
new file mode 100644
index 0000000..5f2f557
--- /dev/null
+++ b/platform/platform-tests/testSrc/com/intellij/ide/BinaryRequestHandlerTest.java
@@ -0,0 +1,134 @@
+package com.intellij.ide;
+
+import com.intellij.openapi.util.AsyncResult;
+import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.util.Consumer;
+import com.intellij.util.net.NetUtils;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandler;
+import io.netty.channel.ChannelInitializer;
+import io.netty.util.CharsetUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.ide.BinaryRequestHandler;
+import org.jetbrains.ide.BuiltInServerManager;
+import org.jetbrains.io.ChannelExceptionHandler;
+import org.jetbrains.io.Decoder;
+import org.jetbrains.io.NettyUtil;
+
+import java.util.UUID;
+
+public class BinaryRequestHandlerTest extends LightPlatformTestCase {
+ public void test() throws InterruptedException {
+ final String text = "Hello!";
+ final AsyncResult<String> result = new AsyncResult<String>();
+
+ Bootstrap bootstrap = NettyUtil.oioClientBootstrap().handler(new ChannelInitializer() {
+ @Override
+ protected void initChannel(Channel channel) throws Exception {
+ channel.pipeline().addLast(new Decoder() {
+ @Override
+ protected void channelRead0(ChannelHandlerContext context, ByteBuf message) throws Exception {
+ int requiredLength = 4 + text.length();
+ ByteBuf buffer = getBufferIfSufficient(message, requiredLength, context);
+ if (buffer == null) {
+ message.release();
+ }
+ else {
+ String response = buffer.toString(buffer.readerIndex(), requiredLength, CharsetUtil.UTF_8);
+ buffer.skipBytes(requiredLength);
+ buffer.release();
+ result.setDone(response);
+ }
+ }
+ }, ChannelExceptionHandler.getInstance());
+ }
+ });
+
+ int port = BuiltInServerManager.getInstance().waitForStart().getPort();
+ Channel channel = bootstrap.connect(NetUtils.getLoopbackAddress(), port).syncUninterruptibly().channel();
+ ByteBuf buffer = channel.alloc().buffer();
+ buffer.writeByte('C');
+ buffer.writeByte('H');
+ buffer.writeLong(MyBinaryRequestHandler.ID.getMostSignificantBits());
+ buffer.writeLong(MyBinaryRequestHandler.ID.getLeastSignificantBits());
+
+ ByteBuf message = Unpooled.copiedBuffer(text, CharsetUtil.UTF_8);
+ buffer.writeShort(message.readableBytes());
+
+ channel.write(buffer);
+ channel.writeAndFlush(message).syncUninterruptibly();
+
+ try {
+ result.doWhenRejected(new Consumer<String>() {
+ @Override
+ public void consume(String error) {
+ fail(error);
+ }
+ });
+
+ assertEquals("got-" + text, result.getResultSync(5000));
+ }
+ finally {
+ channel.close();
+ }
+ }
+
+ static class MyBinaryRequestHandler extends BinaryRequestHandler {
+ private static final UUID ID = UUID.fromString("E5068DD6-1DB7-437C-A3FC-3CA53B6E1AC9");
+
+ @NotNull
+ @Override
+ public UUID getId() {
+ return ID;
+ }
+
+ @Override
+ public ChannelInboundHandler getInboundHandler() {
+ return new MyDecoder();
+ }
+
+ private static class MyDecoder extends Decoder {
+ private State state = State.HEADER;
+ private int contentLength = -1;
+
+ private enum State {
+ HEADER, CONTENT
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext context, ByteBuf message) throws Exception {
+ while (true) {
+ switch (state) {
+ case HEADER: {
+ ByteBuf buffer = getBufferIfSufficient(message, 2, context);
+ if (buffer == null) {
+ message.release();
+ return;
+ }
+
+ contentLength = buffer.readUnsignedShort();
+ state = State.CONTENT;
+ }
+
+ case CONTENT: {
+ ByteBuf buffer = getBufferIfSufficient(message, contentLength, context);
+ if (buffer == null) {
+ message.release();
+ return;
+ }
+
+ String messageText = buffer.toString(buffer.readerIndex(), contentLength, CharsetUtil.UTF_8);
+ buffer.skipBytes(contentLength);
+ state = State.HEADER;
+ context.writeAndFlush(Unpooled.copiedBuffer("got-" + messageText, CharsetUtil.UTF_8));
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java b/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java
index 7082647..5a0ee9d 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -109,7 +109,7 @@
* @param module the module for which the list of dependent modules is requested.
* @return list of <i>modules that depend on</i> given module.
*
- * @see ModuleUtil#getAllDependentModules(Module)
+ * @see ModuleUtilCore#getAllDependentModules(Module)
*/
@NotNull public abstract List<Module> getModuleDependentModules(@NotNull Module module);
diff --git a/platform/projectModel-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java b/platform/projectModel-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java
index 0c97fd6..8fee9a1 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/projectRoots/ProjectJdkTable.java
@@ -19,6 +19,7 @@
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.util.messages.Topic;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.EventListener;
@@ -88,7 +89,7 @@
public abstract SdkTypeId getDefaultSdkType();
- public abstract SdkTypeId getSdkTypeByName(String name);
+ public abstract SdkTypeId getSdkTypeByName(@NotNull String name);
public abstract Sdk createSdk(final String name, final SdkTypeId sdkType);
diff --git a/platform/projectModel-api/src/com/intellij/openapi/projectRoots/SdkTypeId.java b/platform/projectModel-api/src/com/intellij/openapi/projectRoots/SdkTypeId.java
index b4ff275..bc4fd56 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/projectRoots/SdkTypeId.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/projectRoots/SdkTypeId.java
@@ -16,19 +16,21 @@
package com.intellij.openapi.projectRoots;
import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
public interface SdkTypeId {
+ @NotNull
String getName();
@Nullable
- String getVersionString(Sdk sdk);
+ String getVersionString(@NotNull Sdk sdk);
- void saveAdditionalData(SdkAdditionalData additionalData, Element additional);
+ void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional);
@Nullable
- SdkAdditionalData loadAdditionalData(Sdk currentSdk, Element additional);
+ SdkAdditionalData loadAdditionalData(@NotNull Sdk currentSdk, Element additional);
}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java
index d2e22de..c44cd90 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ContentEntry.java
@@ -18,6 +18,8 @@
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
/**
* Represents a module content root.
@@ -95,6 +97,10 @@
*/
SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource, @NotNull String packagePrefix);
+ @NotNull
+ <P extends JpsElement>
+ SourceFolder addSourceFolder(@NotNull VirtualFile file, @NotNull JpsModuleSourceRootType<P> type, @NotNull P properties);
+
/**
* Adds a source or test source root under the content root.
*
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/SourceFolder.java b/platform/projectModel-api/src/com/intellij/openapi/roots/SourceFolder.java
index 83fd86d..6dd2db4 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/SourceFolder.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/SourceFolder.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.roots;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
/**
* Represents a source or test source root under the content root of a module.
@@ -45,4 +46,7 @@
* @param packagePrefix the package prefix, or an empty string if the root has no package prefix.
*/
void setPackagePrefix(@NotNull String packagePrefix);
+
+ @NotNull
+ JpsModuleSourceRootType<?> getRootType();
}
diff --git a/platform/projectModel-impl/src/com/intellij/core/CoreProjectJdkTable.java b/platform/projectModel-impl/src/com/intellij/core/CoreProjectJdkTable.java
index ef055c0..7a7e885 100644
--- a/platform/projectModel-impl/src/com/intellij/core/CoreProjectJdkTable.java
+++ b/platform/projectModel-impl/src/com/intellij/core/CoreProjectJdkTable.java
@@ -19,6 +19,7 @@
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkTypeId;
import com.intellij.openapi.util.Comparing;
+import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@@ -99,7 +100,7 @@
}
@Override
- public SdkTypeId getSdkTypeByName(String name) {
+ public SdkTypeId getSdkTypeByName(@NotNull String name) {
return CoreSdkType.INSTANCE;
}
diff --git a/platform/projectModel-impl/src/com/intellij/core/CoreSdkType.java b/platform/projectModel-impl/src/com/intellij/core/CoreSdkType.java
index 3beedf6..63d86aa 100644
--- a/platform/projectModel-impl/src/com/intellij/core/CoreSdkType.java
+++ b/platform/projectModel-impl/src/com/intellij/core/CoreSdkType.java
@@ -19,6 +19,7 @@
import com.intellij.openapi.projectRoots.SdkAdditionalData;
import com.intellij.openapi.projectRoots.SdkTypeId;
import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
@@ -29,22 +30,23 @@
public static CoreSdkType INSTANCE = new CoreSdkType();
+ @NotNull
@Override
public String getName() {
return "";
}
@Override
- public String getVersionString(Sdk sdk) {
+ public String getVersionString(@NotNull Sdk sdk) {
return "";
}
@Override
- public void saveAdditionalData(SdkAdditionalData additionalData, Element additional) {
+ public void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional) {
}
@Override
- public SdkAdditionalData loadAdditionalData(Sdk currentSdk, Element additional) {
+ public SdkAdditionalData loadAdditionalData(@NotNull Sdk currentSdk, Element additional) {
return null;
}
}
diff --git a/platform/projectModel-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java b/platform/projectModel-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java
index 32fba97..752036e 100644
--- a/platform/projectModel-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java
+++ b/platform/projectModel-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java
@@ -105,4 +105,16 @@
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(psiFile.getProject()).getFileIndex();
return !projectFileIndex.isInSource(file) && !projectFileIndex.isInLibraryClasses(file);
}
+
+ @Nullable
+ public static SourceFolder findSourceFolder(@NotNull Module module, @NotNull VirtualFile root) {
+ for (ContentEntry entry : ModuleRootManager.getInstance(module).getContentEntries()) {
+ for (SourceFolder folder : entry.getSourceFolders()) {
+ if (root.equals(folder.getFile())) {
+ return folder;
+ }
+ }
+ }
+ return null;
+ }
}
\ No newline at end of file
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java
index 984b9f1..64d379a 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java
@@ -19,7 +19,10 @@
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ContentFolder;
+import com.intellij.openapi.roots.ExcludeFolder;
+import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
@@ -33,6 +36,12 @@
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.JpsSimpleElement;
+import org.jetbrains.jps.model.java.JavaSourceRootProperties;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer;
import java.util.*;
@@ -156,20 +165,30 @@
@Override
public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource) {
- assertCanAddFolder(file);
- return addSourceFolder(new SourceFolderImpl(file, isTestSource, this));
+ return addSourceFolder(file, isTestSource, SourceFolderImpl.DEFAULT_PACKAGE_PREFIX);
}
@Override
public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource, @NotNull String packagePrefix) {
+ JavaSourceRootType type = isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
+ JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(""));
+ return addSourceFolder(file, type, properties);
+ }
+
+ @Override
+ @NotNull
+ public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull VirtualFile file, @NotNull JpsModuleSourceRootType<P> type,
+ @NotNull P properties) {
assertCanAddFolder(file);
- return addSourceFolder(new SourceFolderImpl(file, isTestSource, packagePrefix, this));
+ return addSourceFolder(new SourceFolderImpl(file, JpsElementFactory.getInstance().createModuleSourceRoot(file.getUrl(), type, properties), this));
}
@Override
public SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource) {
assertFolderUnderMe(url);
- return addSourceFolder(new SourceFolderImpl(url, isTestSource, this));
+ JavaSourceRootType type = isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
+ JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(""));
+ return addSourceFolder(new SourceFolderImpl(JpsElementFactory.getInstance().createModuleSourceRoot(url, type, properties), this));
}
private SourceFolder addSourceFolder(SourceFolderImpl f) {
@@ -293,9 +312,7 @@
element.setAttribute(URL_ATTRIBUTE, myRoot.getUrl());
for (final SourceFolder sourceFolder : mySourceFolders) {
if (sourceFolder instanceof SourceFolderImpl) {
- final Element subElement = new Element(SourceFolderImpl.ELEMENT_NAME);
- ((SourceFolderImpl)sourceFolder).writeExternal(subElement);
- element.addContent(subElement);
+ JpsModuleRootModelSerializer.saveSourceRoot(element, sourceFolder.getUrl(), ((SourceFolderImpl)sourceFolder).getJpsElement().asTyped());
}
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java
index 71d8679..9c0f76f 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java
@@ -16,7 +16,6 @@
package com.intellij.openapi.roots.impl;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ContentFolder;
import com.intellij.openapi.roots.SourceFolder;
@@ -25,78 +24,85 @@
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.JpsSimpleElement;
+import org.jetbrains.jps.model.java.JavaSourceRootProperties;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+import org.jetbrains.jps.model.module.JpsTypedModuleSourceRoot;
import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer;
/**
* @author dsl
*/
public class SourceFolderImpl extends ContentFolderBaseImpl implements SourceFolder, ClonableContentFolder {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleSourceFolderImpl");
- private final boolean myIsTestSource;
+ private JpsModuleSourceRoot myJpsElement;
@NonNls public static final String ELEMENT_NAME = JpsModuleRootModelSerializer.SOURCE_FOLDER_TAG;
@NonNls public static final String TEST_SOURCE_ATTR = JpsModuleRootModelSerializer.IS_TEST_SOURCE_ATTRIBUTE;
- private String myPackagePrefix;
static final String DEFAULT_PACKAGE_PREFIX = "";
- SourceFolderImpl(@NotNull VirtualFile file, boolean isTestSource, @NotNull ContentEntryImpl contentEntry) {
- this(file, isTestSource, DEFAULT_PACKAGE_PREFIX, contentEntry);
- }
-
- SourceFolderImpl(@NotNull VirtualFile file, boolean isTestSource, @NotNull String packagePrefix, @NotNull ContentEntryImpl contentEntry) {
+ SourceFolderImpl(@NotNull VirtualFile file, @NotNull JpsModuleSourceRoot jpsElement, @NotNull ContentEntryImpl contentEntry) {
super(file, contentEntry);
- myIsTestSource = isTestSource;
- myPackagePrefix = packagePrefix;
+ myJpsElement = jpsElement;
}
- public SourceFolderImpl(@NotNull String url, boolean isTestSource, @NotNull ContentEntryImpl contentEntry) {
- super(url, contentEntry);
- myIsTestSource = isTestSource;
- myPackagePrefix = DEFAULT_PACKAGE_PREFIX;
+ public SourceFolderImpl(@NotNull JpsModuleSourceRoot jpsElement, @NotNull ContentEntryImpl contentEntry) {
+ super(jpsElement.getUrl(), contentEntry);
+ myJpsElement = jpsElement;
}
SourceFolderImpl(Element element, ContentEntryImpl contentEntry) throws InvalidDataException {
super(element, contentEntry);
- LOG.assertTrue(element.getName().equals(ELEMENT_NAME));
- final String testSource = element.getAttributeValue(TEST_SOURCE_ATTR);
- if (testSource == null) throw new InvalidDataException();
- myIsTestSource = Boolean.valueOf(testSource).booleanValue();
- final String packagePrefix = element.getAttributeValue(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE);
- if (packagePrefix != null) {
- myPackagePrefix = packagePrefix;
- }
- else {
- myPackagePrefix = DEFAULT_PACKAGE_PREFIX;
- }
+ myJpsElement = JpsModuleRootModelSerializer.loadSourceRoot(element);
}
private SourceFolderImpl(SourceFolderImpl that, ContentEntryImpl contentEntry) {
super(that, contentEntry);
- myIsTestSource = that.myIsTestSource;
- myPackagePrefix = that.myPackagePrefix;
+ myJpsElement = createCopy(that, that.myJpsElement.asTyped());
+ }
+
+ private static <P extends JpsElement> JpsModuleSourceRoot createCopy(SourceFolderImpl that, final JpsTypedModuleSourceRoot<P> jpsElement) {
+ return JpsElementFactory.getInstance().createModuleSourceRoot(that.getUrl(), jpsElement.getRootType(), (P)jpsElement.getProperties().getBulkModificationSupport().createCopy());
}
@Override
public boolean isTestSource() {
- return myIsTestSource;
+ return getRootType().equals(JavaSourceRootType.TEST_SOURCE);
}
@NotNull
@Override
public String getPackagePrefix() {
- return myPackagePrefix;
+ JpsSimpleElement<JavaSourceRootProperties> properties = getJavaProperties();
+ return properties != null ? properties.getData().getPackagePrefix() : DEFAULT_PACKAGE_PREFIX;
+ }
+
+ @Nullable
+ private JpsSimpleElement<JavaSourceRootProperties> getJavaProperties() {
+ if (myJpsElement.getRootType() == JavaSourceRootType.SOURCE) {
+ return myJpsElement.getProperties(JavaSourceRootType.SOURCE);
+ }
+ if (myJpsElement.getRootType() == JavaSourceRootType.TEST_SOURCE) {
+ return myJpsElement.getProperties(JavaSourceRootType.TEST_SOURCE);
+ }
+ return null;
}
@Override
public void setPackagePrefix(@NotNull String packagePrefix) {
- myPackagePrefix = packagePrefix;
+ JpsSimpleElement<JavaSourceRootProperties> properties = getJavaProperties();
+ if (properties != null) {
+ properties.setData(new JavaSourceRootProperties(packagePrefix));
+ }
}
- void writeExternal(Element element) {
- writeFolder(element, ELEMENT_NAME);
- element.setAttribute(TEST_SOURCE_ATTR, Boolean.toString(myIsTestSource));
- if (!DEFAULT_PACKAGE_PREFIX.equals(myPackagePrefix)) {
- element.setAttribute(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE, myPackagePrefix);
- }
+ @NotNull
+ @Override
+ public JpsModuleSourceRootType<?> getRootType() {
+ return myJpsElement.getRootType();
}
@Override
@@ -106,6 +112,10 @@
return new SourceFolderImpl(this, (ContentEntryImpl)contentEntry);
}
+ public JpsModuleSourceRoot getJpsElement() {
+ return myJpsElement;
+ }
+
@Override
public int compareTo(ContentFolderBaseImpl folder) {
if (!(folder instanceof SourceFolderImpl)) return -1;
@@ -113,8 +123,8 @@
int i = super.compareTo(folder);
if (i!= 0) return i;
- i = myPackagePrefix.compareTo(((SourceFolderImpl)folder).myPackagePrefix);
+ i = getPackagePrefix().compareTo(((SourceFolderImpl)folder).getPackagePrefix());
if (i!= 0) return i;
- return Boolean.valueOf(myIsTestSource).compareTo(((SourceFolderImpl)folder).myIsTestSource);
+ return Boolean.valueOf(isTestSource()).compareTo(((SourceFolderImpl)folder).isTestSource());
}
}
diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java
index b5b79c9..f2d76a3 100644
--- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java
+++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java
@@ -31,11 +31,14 @@
import com.intellij.project.model.impl.module.JpsRootModel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.JpsElement;
import org.jetbrains.jps.model.JpsElementFactory;
+import org.jetbrains.jps.model.JpsSimpleElement;
import org.jetbrains.jps.model.java.JavaSourceRootProperties;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.ArrayList;
import java.util.List;
@@ -141,10 +144,21 @@
return addSourceFolder(file.getUrl(), isTestSource, packagePrefix);
}
+ @NotNull
+ @Override
+ public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull VirtualFile file,
+ @NotNull JpsModuleSourceRootType<P> type,
+ @NotNull P properties) {
+ final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(file.getUrl(), type, properties);
+ final JpsSourceFolder sourceFolder = new JpsSourceFolder(sourceRoot, this);
+ mySourceFolders.add(sourceFolder);
+ return sourceFolder;
+ }
+
private SourceFolder addSourceFolder(final String url, boolean isTestSource, String packagePrefix) {
final JavaSourceRootType rootType = isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
- final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(url, rootType, JpsElementFactory.getInstance()
- .createSimpleElement(new JavaSourceRootProperties(packagePrefix)));
+ JpsSimpleElement<JavaSourceRootProperties> properties = JpsElementFactory.getInstance().createSimpleElement(new JavaSourceRootProperties(packagePrefix));
+ final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(url, rootType, properties);
final JpsSourceFolder sourceFolder = new JpsSourceFolder(sourceRoot, this);
mySourceFolders.add(sourceFolder);
return sourceFolder;
diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java
index 3092c36..8bd6a93a38 100644
--- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java
+++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java
@@ -22,6 +22,7 @@
import org.jetbrains.jps.model.java.JavaSourceRootProperties;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
/**
* @author nik
@@ -68,4 +69,10 @@
properties.setData(new JavaSourceRootProperties(packagePrefix));
}
}
+
+ @NotNull
+ @Override
+ public JpsModuleSourceRootType<?> getRootType() {
+ return mySourceRoot.getRootType();
+ }
}
diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties
index 370b8f0..a8eefc9 100644
--- a/platform/projectModel-impl/src/messages/ProjectBundle.properties
+++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties
@@ -173,9 +173,8 @@
module.toggle.excluded.action=Excluded
module.toggle.excluded.action.description=Include/Exclude directory from module
module.toggle.test.sources.action=Test Sources
-module.toggle.test.sources.action.description=Mark directory as a Test Sources root
module.toggle.sources.action=Sources
-module.toggle.sources.action.description=Mark directory as a Sources root
+module.toggle.sources.action.description=Mark directory as a {0} root
library.classes.node=Classes
library.javadocs.node=JavaDocs
library.empty.item=<empty library>
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java
index 7d61aff..8eeed5e 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java
@@ -55,6 +55,8 @@
private boolean myDurationIsCached = false; // is used for separating unknown and unset duration
private boolean myHasCriticalErrors = false;
private boolean myHasErrorsCached = false;
+ private boolean myHasPassedTests = false;
+ private boolean myHasPassedTestsCached = false;
@Nullable private String myStacktrace;
@@ -154,9 +156,37 @@
return myState.wasTerminated();
}
- @Override
+ boolean hasPassedTests() {
+ if (myHasPassedTestsCached) {
+ return myHasPassedTests;
+ }
+ boolean hasPassedTests = calcPassedTests();
+ boolean canCache = !myState.isInProgress();
+ if (canCache) {
+ myHasPassedTests = hasPassedTests;
+ myHasPassedTestsCached = true;
+ }
+ return hasPassedTests;
+ }
+
+ private boolean calcPassedTests() {
+ if (isPassed()) {
+ return true;
+ }
+ for (SMTestProxy child : getChildren()) {
+ if (child.hasPassedTests()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
public boolean isIgnored() {
- return myState.getMagnitude() == TestStateInfo.Magnitude.SKIPPED_INDEX;
+ if (hasPassedTests()) {
+ return false;
+ }
+ return myState.getMagnitude() == TestStateInfo.Magnitude.IGNORED_INDEX;
}
public boolean isPassed() {
diff --git a/platform/testFramework/src/com/intellij/testFramework/Timings.java b/platform/testFramework/src/com/intellij/testFramework/Timings.java
index f8ec372..cb94d32 100644
--- a/platform/testFramework/src/com/intellij/testFramework/Timings.java
+++ b/platform/testFramework/src/com/intellij/testFramework/Timings.java
@@ -122,7 +122,7 @@
return
" Timings: CPU=" + CPU_TIMING + " (" + (int)(CPU_TIMING*1.0/ ETALON_CPU_TIMING*100) + "% of the etalon)" +
", I/O=" + IO_TIMING + " (" + (int)(IO_TIMING*1.0/ ETALON_IO_TIMING*100) + "% of the etalon)" +
- ", total=" + MACHINE_TIMING + " ("+(int)(MACHINE_TIMING*1.0/ ETALON_TIMING*100) + "% of the etalon)" +
- ".";
+ ", total=" + MACHINE_TIMING + " ("+(int)(MACHINE_TIMING*1.0/ ETALON_TIMING*100) + "% of the etalon) " +
+ Runtime.getRuntime().availableProcessors() + " cores.";
}
}
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 7a181b8..3db5eb3 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
@@ -24,6 +24,7 @@
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
+import com.intellij.codeInsight.daemon.GutterMark;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
@@ -67,7 +68,6 @@
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
-import com.intellij.codeInsight.daemon.GutterMark;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.ExtensionPointName;
@@ -78,6 +78,7 @@
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
@@ -1284,6 +1285,8 @@
vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(getTempDirPath(), fileName));
}
+ prepareVirtualFile(vFile);
+
final Document document = FileDocumentManager.getInstance().getCachedDocument(vFile);
if (document != null) {
PsiDocumentManager.getInstance(getProject()).doPostponedOperationsAndUnblockDocument(document);
@@ -1374,6 +1377,9 @@
return myFile;
}
+ protected void prepareVirtualFile(@NotNull VirtualFile file) {
+ }
+
private void setupEditorForInjectedLanguage() {
Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
if (editor instanceof EditorWindow) {
@@ -1495,9 +1501,19 @@
ensureIndexesUpToDate(project);
DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project);
TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(editor);
- List<HighlightInfo> infos = codeAnalyzer.runPasses(file, editor.getDocument(), textEditor, toIgnore, canChangeDocument, null);
- infos.addAll(DaemonCodeAnalyzerImpl.getFileLevelHighlights(project, file));
- return infos;
+ ProcessCanceledException exception = null;
+ for (int i = 0; i < 100; i++) {
+ try {
+ List<HighlightInfo> infos = codeAnalyzer.runPasses(file, editor.getDocument(), textEditor, toIgnore, canChangeDocument, null);
+ infos.addAll(DaemonCodeAnalyzerImpl.getFileLevelHighlights(project, file));
+ return infos;
+ }
+ catch (ProcessCanceledException e) {
+ exception = e;
+ }
+ }
+ // unable to highlight after 100 retries
+ throw exception;
}
public static void ensureIndexesUpToDate(Project project) {
diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java
index 7107808..a4869d9 100644
--- a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java
+++ b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java
@@ -11,6 +11,7 @@
import com.intellij.util.continuation.ContinuationPause;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
import java.io.File;
import java.util.*;
@@ -66,6 +67,7 @@
afterUpdate.run();
}
+ @TestOnly
@Override
public boolean ensureUpToDate(boolean canBeCanceled) {
throw new UnsupportedOperationException();
diff --git a/platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java b/platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java
index 57f60f7..dac5a49 100644
--- a/platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java
+++ b/platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java
@@ -53,7 +53,9 @@
}
}
- throw new AssertionError(message);
+ AssertionError error = new AssertionError(message);
+ error.initCause(t);
+ throw error;
}
@Override
diff --git a/platform/util/src/com/intellij/openapi/diagnostic/Logger.java b/platform/util/src/com/intellij/openapi/diagnostic/Logger.java
index 3edd6cd..1bee158 100644
--- a/platform/util/src/com/intellij/openapi/diagnostic/Logger.java
+++ b/platform/util/src/com/intellij/openapi/diagnostic/Logger.java
@@ -59,6 +59,17 @@
public abstract void debug(@NonNls String message, @Nullable Throwable t);
+ public void debug(@NotNull String message, Object... details) {
+ if (isDebugEnabled()) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(message);
+ for (Object detail : details) {
+ sb.append(String.valueOf(detail));
+ }
+ debug(sb.toString());
+ }
+ }
+
public void info(@NotNull Throwable t) {
info(t.getMessage(), t);
}
@@ -102,19 +113,18 @@
public abstract void error(@NonNls String message, @Nullable Throwable t, @NonNls @NotNull String... details);
- public boolean assertTrue(boolean value, @NonNls Object message) {
+ public boolean assertTrue(boolean value, @Nullable @NonNls Object message) {
if (!value) {
- @NonNls StringBuilder resultMessage = new StringBuilder("Assertion failed");
- if (message != null) resultMessage.append(": ").append(message);
-
- error(resultMessage.toString(), new Throwable());
+ @NonNls String resultMessage = "Assertion failed";
+ if (message != null) resultMessage += ": " + message;
+ error(resultMessage, new Throwable());
}
return value;
}
public boolean assertTrue(boolean value) {
- return value || assertTrue(value, "");
+ return value || assertTrue(false, null);
}
public abstract void setLevel(Level level);
diff --git a/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java b/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java
index 4d89732..ce0ec3d 100644
--- a/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java
+++ b/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java
@@ -15,16 +15,12 @@
*/
package com.intellij.openapi.util.io.win32;
-import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.util.lang.UrlClassLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.Arrays;
-
/**
* Do not use this class directly.
*
@@ -38,36 +34,10 @@
private static final IdeaWin32 ourInstance;
static {
- boolean available = false;
- if (SystemInfo.isWin2kOrNewer) {
- String libName = SystemInfo.is64Bit ? "IdeaWin64.dll" : "IdeaWin32.dll";
- try {
- String path = PathManager.getBinPath() + "/" + libName;
- if (!new File(path).exists()) {
- path = PathManager.getHomePath() + "/community/bin/win/" + libName;
- if (!new File(path).exists()) {
- path = PathManager.getHomePath() + "/bin/win/" + libName;
- if (!new File(path).exists()) {
- path = PathManager.getHomePathFor(IdeaWin32.class) + "/bin/" + libName;
- if (!new File(path).exists()) {
- throw new FileNotFoundException("Native filesystem .dll is missing (path=" + PathManager.getBinPath() +
- " content=" + Arrays.toString(new File(PathManager.getBinPath()).list()) + ")");
- }
- }
- }
- }
- LOG.debug("Loading " + path);
- System.load(path);
- available = true;
- }
- catch (Throwable t) {
- LOG.error("Failed to load native filesystem for Windows", t);
- }
- }
-
IdeaWin32 instance = null;
- if (available) {
+ if (SystemInfo.isWin2kOrNewer) {
try {
+ UrlClassLoader.loadPlatformLibrary("IdeaWin32");
instance = new IdeaWin32();
LOG.info("Native filesystem for Windows is operational");
}
diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
index afafbaf..225a51f 100644
--- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
@@ -43,6 +43,7 @@
@NonNls private static final String VOWELS = "aeiouy";
@NonNls private static final Pattern EOL_SPLIT_PATTERN = Pattern.compile(" *(\r|\n|\r\n)+ *");
+ @NonNls private static final Pattern EOL_SPLIT_PATTERN_WITH_EMPTY = Pattern.compile(" *(\r|\n|\r\n) *");
public static final NotNullFunction<String, String> QUOTER = new NotNullFunction<String, String>() {
@Override
@@ -535,10 +536,16 @@
@NotNull
public static String escapeStringCharacters(@NotNull String s) {
StringBuilder buffer = new StringBuilder(s.length());
- escapeStringCharacters(s.length(), s, buffer);
+ escapeStringCharacters(s.length(), s, "\"", buffer);
return buffer.toString();
}
+ @NotNull
+ public static String escapeCharCharacters(@NotNull String s) {
+ StringBuilder buffer = new StringBuilder(s.length());
+ escapeStringCharacters(s.length(), s, "\'", buffer);
+ return buffer.toString();
+ }
@NotNull
public static String unescapeStringCharacters(@NotNull String s) {
@@ -2132,7 +2139,19 @@
*/
@NotNull
public static String[] splitByLines(@NotNull String string) {
- return EOL_SPLIT_PATTERN.split(string);
+ return splitByLines(string, true);
+ }
+
+ /**
+ * Splits string by lines. If several line separators are in a row corresponding empty lines
+ * are also added to result if {@code excludeEmptyStrings} is {@code false}.
+ *
+ * @param string String to split
+ * @return array of strings
+ */
+ @NotNull
+ public static String[] splitByLines(@NotNull String string, boolean excludeEmptyStrings) {
+ return (excludeEmptyStrings ? EOL_SPLIT_PATTERN : EOL_SPLIT_PATTERN_WITH_EMPTY).split(string);
}
@NotNull
diff --git a/platform/util/src/com/intellij/util/PatternUtil.java b/platform/util/src/com/intellij/util/PatternUtil.java
index 18f6245..7159a90 100644
--- a/platform/util/src/com/intellij/util/PatternUtil.java
+++ b/platform/util/src/com/intellij/util/PatternUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -18,6 +18,8 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
@@ -25,9 +27,6 @@
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.Nullable;
-
public class PatternUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.PatternUtil");
private static final HashMap<String, String> ourEscapeRules = new HashMap<String, String>();
@@ -50,17 +49,17 @@
}
private static void escape2(char symbol) {
- ourEscapeRules.put(""+symbol, "\\" + symbol);
+ ourEscapeRules.put(String.valueOf(symbol), "\\" + symbol);
}
public static String convertToRegex(String mask) {
- List<String> strings = StringUtil.split(mask,"\\");
- StringBuffer pattern = new StringBuffer();
+ List<String> strings = StringUtil.split(mask, "\\");
+ StringBuilder pattern = new StringBuilder();
String separator = "";
- for (String string:strings) {
+ for (String string : strings) {
string = StringUtil.replace(string, ".", "\\.");
- for (Map.Entry<String, String> e: ourEscapeRules.entrySet()) {
+ for (Map.Entry<String, String> e : ourEscapeRules.entrySet()) {
string = StringUtil.replace(string, e.getKey(), e.getValue());
}
pattern.append(separator);
@@ -74,7 +73,8 @@
// String pattern = mask.replaceAll("\\.", "\\.").replaceAll("\\*", ".*").replaceAll("\\?", ".");
try {
return Pattern.compile(convertToRegex(mask));
- } catch (PatternSyntaxException e) {
+ }
+ catch (PatternSyntaxException e) {
LOG.error(mask, e);
return Pattern.compile("");
}
diff --git a/platform/util/src/com/intellij/util/io/PagedFileStorage.java b/platform/util/src/com/intellij/util/io/PagedFileStorage.java
index 6067814..9faef08 100644
--- a/platform/util/src/com/intellij/util/io/PagedFileStorage.java
+++ b/platform/util/src/com/intellij/util/io/PagedFileStorage.java
@@ -98,7 +98,7 @@
private final byte[] myTypedIOBuffer;
private volatile boolean isDirty = false;
private final File myFile;
- protected long mySize = -1;
+ protected volatile long mySize = -1;
protected final int myPageSize;
protected final boolean myValuesAreBufferAligned;
@NonNls private static final String RW = "rw";
@@ -239,7 +239,7 @@
"buffer.limit=" + buffer.limit() + ", " +
"page=" + page + ", " +
"file=" + myFile.getName() + ", "+
- "file.length=" + mySize);
+ "file.length=" + length());
}
buffer.get(dst, o, page_len);
@@ -298,10 +298,10 @@
public void resize(int newSize) throws IOException {
int oldSize = (int)myFile.length();
- if (oldSize == newSize) return;
+ if (oldSize == newSize && oldSize == length()) return;
final long started = IOStatistics.DEBUG ? System.currentTimeMillis():0;
- myStorageLockContext.myStorageLock.invalidateBuffer((int)(myStorageIndex | (mySize / myPageSize)));
+ myStorageLockContext.myStorageLock.invalidateBuffer(myStorageIndex | (oldSize / myPageSize));
//unmapAll(); // we do not need it since all page alighned buffers can be reused
final long unmapAllFinished = IOStatistics.DEBUG ? System.currentTimeMillis():0;
@@ -322,6 +322,7 @@
private void resizeFile(int newSize) throws IOException {
RandomAccessFile raf = new RandomAccessFile(myFile, RW);
+ mySize = -1;
try {
raf.setLength(newSize);
}
@@ -345,10 +346,11 @@
}
public final long length() {
- if (mySize == -1) {
- mySize = myFile.length();
+ long size = mySize;
+ if (size == -1) {
+ mySize = size = myFile.length();
}
- return mySize;
+ return size;
}
private ByteBuffer getBuffer(int page) {
diff --git a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java
index 70a71f97..b6f9816 100644
--- a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java
+++ b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java
@@ -18,6 +18,7 @@
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.io.win32.IdeaWin32;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
@@ -31,7 +32,10 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
public class UrlClassLoader extends ClassLoader {
@NonNls static final String CLASS_EXTENSION = ".class";
@@ -43,7 +47,6 @@
private boolean myUseCache = false;
private boolean myAcceptUnescaped = false;
private boolean myPreload = true;
- private String[] myNativeLibs = null;
private Builder() { }
@@ -56,7 +59,6 @@
public Builder useCache(boolean useCache) { myUseCache = useCache; return this; }
public Builder allowUnescaped() { myAcceptUnescaped = true; return this; }
public Builder noPreload() { myPreload = false; return this; }
- public Builder nativeLibs(String... libNames) { myNativeLibs = libNames; return this; }
public UrlClassLoader get() { return new UrlClassLoader(this); }
}
@@ -66,7 +68,6 @@
private final List<URL> myURLs;
private final ClassPath myClassPath;
- private final Set<String> myNativeLibs;
/** @deprecated use {@link #build()} (to remove in IDEA 14) */
public UrlClassLoader(@NotNull ClassLoader parent) {
@@ -98,7 +99,6 @@
}
});
myClassPath = new ClassPath(myURLs, lockJars, useCache, allowUnescaped, preload);
- myNativeLibs = Collections.emptySet();
}
protected UrlClassLoader(@NotNull Builder builder) {
@@ -110,7 +110,6 @@
}
});
myClassPath = new ClassPath(myURLs, builder.myLockJars, builder.myUseCache, builder.myAcceptUnescaped, builder.myPreload);
- myNativeLibs = builder.myNativeLibs != null ? ContainerUtil.newHashSet(builder.myNativeLibs) : Collections.<String>emptySet();
}
public static URL internProtocol(@NotNull URL url) {
@@ -151,12 +150,6 @@
}
}
-
- @Override
- protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
- return super.loadClass(name, resolve);
- }
-
@Nullable
protected Class _findClass(@NotNull String name) {
Resource res = myClassPath.getResource(name.replace('.', '/').concat(CLASS_EXTENSION), false);
@@ -233,38 +226,22 @@
return myClassPath.getResources(name, true);
}
- @Override
- protected String findLibrary(String libName) {
- if (BinPathHolder.path != null && myNativeLibs.contains(libName)) {
- String fileName = mapLibraryName(libName);
- return BinPathHolder.path + File.separator + fileName;
- }
+ public static void loadPlatformLibrary(@NotNull String libName) {
+ String libFileName = mapLibraryName(libName);
+ String libPath = PathManager.getBinPath() + "/" + libFileName;
- return super.findLibrary(libName);
- }
-
- private static class BinPathHolder {
- private static final String path;
-
- static {
- String homePath = PathManager.getHomePath();
- if (new File(homePath, ".idea").exists()) {
- if (new File(homePath, "community").exists()) {
- homePath += File.separator + "community";
+ if (!new File(libPath).exists()) {
+ String platform = getPlatformName();
+ if (!new File(libPath = PathManager.getHomePath() + "/community/bin/" + platform + libFileName).exists()) {
+ if (!new File(libPath = PathManager.getHomePath() + "/bin/" + platform + libFileName).exists()) {
+ if (!new File(libPath = PathManager.getHomePathFor(IdeaWin32.class) + "/bin/" + libFileName).exists()) {
+ throw new UnsatisfiedLinkError("'" + libFileName + "' not found among " + Arrays.toString(new File(PathManager.getBinPath()).listFiles()));
+ }
}
-
- String libDir = null;
- String prefix = homePath + File.separator + "bin" + File.separator;
- if (SystemInfo.isWindows) libDir = prefix + "win";
- else if (SystemInfo.isMac) libDir = prefix + "mac";
- else if (SystemInfo.isLinux) libDir = prefix + "linux";
-
- path = libDir;
- }
- else {
- path = PathManager.getBinPath();
}
}
+
+ System.load(libPath);
}
private static String mapLibraryName(String libName) {
@@ -278,4 +255,11 @@
}
return fileName;
}
+
+ private static String getPlatformName() {
+ if (SystemInfo.isWindows) return "win/";
+ else if (SystemInfo.isMac) return "mac/";
+ else if (SystemInfo.isLinux) return "linux/";
+ else return "";
+ }
}
diff --git a/platform/util/src/com/intellij/util/ui/ListTableModel.java b/platform/util/src/com/intellij/util/ui/ListTableModel.java
index 3acc799..df39acc 100644
--- a/platform/util/src/com/intellij/util/ui/ListTableModel.java
+++ b/platform/util/src/com/intellij/util/ui/ListTableModel.java
@@ -193,7 +193,9 @@
public void addRows(@NotNull Collection<Item> items) {
myItems.addAll(items);
- fireTableRowsInserted(myItems.size() - items.size(), myItems.size() - 1);
+ if (!myItems.isEmpty()) {
+ fireTableRowsInserted(myItems.size() - items.size(), myItems.size() - 1);
+ }
}
public Object getItem(final int rowIndex) {
diff --git a/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java b/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
index 6b5e4ff..9e1ba5a 100644
--- a/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
+++ b/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
@@ -44,7 +44,7 @@
private static final Border LIST_BACKGROUND_PAINTER = UIManager.getBorder("List.sourceListBackgroundPainter");
private static final Border LIST_SELECTION_BACKGROUND_PAINTER = UIManager.getBorder("List.sourceListSelectionBackgroundPainter");
private static final Border LIST_FOCUSED_SELECTION_BACKGROUND_PAINTER = UIManager.getBorder("List.sourceListFocusedSelectionBackgroundPainter");
-
+
@NotNull private final Condition<Integer> myWideSelectionCondition;
private boolean myWideSelection;
private boolean myOldRepaintAllRowValue;
@@ -58,7 +58,7 @@
/**
* Creates new <code>WideSelectionTreeUI</code> object.
- *
+ *
* @param wideSelection flag that determines if wide selection should be used
* @param wideSelectionCondition strategy that determine if wide selection should be used for a target row (it's zero-based index
* is given to the condition as an argument)
@@ -80,7 +80,7 @@
final TreePath pressedPath = getClosestPathForLocation(tree, e.getX(), e.getY());
if (pressedPath != null) {
- Rectangle bounds = getPathBounds(tree, pressedPath);
+ Rectangle bounds = getWidePathBounds(tree, pressedPath);
if (e.getY() >= bounds.y + bounds.height) {
return;
@@ -98,6 +98,15 @@
}
};
+ public Rectangle getWidePathBounds(JTree tree, TreePath path) {
+ Rectangle bounds = super.getPathBounds(tree, path);
+ if (bounds != null && tree != null) {
+ bounds.x = 0;
+ bounds.width = tree.getWidth();
+ }
+ return bounds;
+ }
+
@Override
protected void completeUIInstall() {
super.completeUIInstall();
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
index b8150ce..16013cf 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
@@ -1459,10 +1459,12 @@
ourUpdateAlarm.get().execute(r);
}
- /**
- * Can be called only from not AWT thread; to do smthg after ChangeListManager refresh, call invokeAfterUpdate
- */
+ @TestOnly
public boolean ensureUpToDate(final boolean canBeCanceled) {
+ if (ApplicationManager.getApplication().isDispatchThread()) {
+ updateImmediately();
+ return true;
+ }
myVfsListener.flushDirt();
final EnsureUpToDateFromNonAWTThread worker = new EnsureUpToDateFromNonAWTThread(myProject);
worker.execute();
diff --git a/platform/xdebugger-api/src/com/intellij/chromeConnector/debugger/frame/XGroupingValuePresenter.java b/platform/xdebugger-api/src/com/intellij/chromeConnector/debugger/frame/XGroupingValuePresenter.java
new file mode 100644
index 0000000..63b2e98
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/chromeConnector/debugger/frame/XGroupingValuePresenter.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2013 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.chromeConnector.debugger.frame;
+
+import com.intellij.ui.ColoredTextContainer;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.xdebugger.frame.XValuePresenter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class XGroupingValuePresenter extends XValuePresenter {
+ public static final XGroupingValuePresenter INSTANCE = new XGroupingValuePresenter();
+
+ @Nullable
+ @Override
+ public SimpleTextAttributes getNameAttributes() {
+ return SimpleTextAttributes.REGULAR_ATTRIBUTES;
+ }
+
+ @Override
+ public void appendSeparator(@NotNull ColoredTextContainer text) {
+ }
+
+ @Override
+ public void append(@NotNull String value, @NotNull ColoredTextContainer text, boolean changed) {
+ }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java
index 1e9cf57..39a5091 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java
@@ -207,4 +207,12 @@
public void setLayoutCustomizer(@Nullable XDebugLayoutCustomizer layoutCustomizer) {
myLayoutCustomizer = layoutCustomizer;
}
-}
+
+ /**
+ * Add or not SortValuesAction (alphabetically sort)
+ * @todo this action should be moved to "Variables" as gear action
+ */
+ public boolean isValuesCustomSorted() {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/PrimitiveXValuePresenter.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/PrimitiveXValuePresenter.java
index 93890c0..68222d2 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/PrimitiveXValuePresenter.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/PrimitiveXValuePresenter.java
@@ -18,10 +18,11 @@
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.TextAttributesKey;
-import com.intellij.ui.SimpleColoredText;
+import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.SimpleTextAttributes;
+import org.jetbrains.annotations.NotNull;
-public class PrimitiveXValuePresenter implements XValuePresenter {
+public class PrimitiveXValuePresenter extends XValuePresenter {
public static final XValuePresenter KEYWORD = new PrimitiveXValuePresenter(DefaultLanguageHighlighterColors.KEYWORD);
public static final XValuePresenter NUMBER = new PrimitiveXValuePresenter(DefaultLanguageHighlighterColors.NUMBER);
@@ -32,7 +33,7 @@
}
@Override
- public void append(String value, SimpleColoredText text, boolean changed) {
+ public void append(@NotNull String value, @NotNull ColoredTextContainer text, boolean changed) {
text.append(value, SimpleTextAttributes.fromTextAttributes(EditorColorsManager.getInstance().getGlobalScheme().getAttributes(textAttributesKey)));
}
}
\ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/StringValuePresenter.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/StringValuePresenter.java
index c3ca0a5..ac5361e 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/StringValuePresenter.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/StringValuePresenter.java
@@ -18,12 +18,13 @@
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.JBColor;
-import com.intellij.ui.SimpleColoredText;
import com.intellij.ui.SimpleTextAttributes;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public class StringValuePresenter implements XValuePresenter {
+public class StringValuePresenter extends XValuePresenter {
public static final XValuePresenter DEFAULT = new StringValuePresenter(XValueNode.MAX_VALUE_LENGTH, "\"\\");
private final int maxLength;
@@ -35,21 +36,26 @@
}
@Override
- public void append(String value, SimpleColoredText text, boolean changed) {
+ public void append(@NotNull String value, @NotNull ColoredTextContainer text, boolean changed) {
SimpleTextAttributes attributes = SimpleTextAttributes.fromTextAttributes(EditorColorsManager.getInstance().getGlobalScheme().getAttributes(DefaultLanguageHighlighterColors.STRING));
text.append("\"", attributes);
doAppend(value, text, attributes);
text.append("\"", attributes);
}
- protected void doAppend(String value, SimpleColoredText text, SimpleTextAttributes attributes) {
+ protected void doAppend(@NotNull String value, @NotNull ColoredTextContainer text, @NotNull SimpleTextAttributes attributes) {
+ append(value, text, attributes, maxLength, additionalChars);
+ }
+
+ public static void append(@NotNull String value, @NotNull ColoredTextContainer text, @NotNull SimpleTextAttributes attributes, int maxLength, @Nullable String additionalChars) {
SimpleTextAttributes escapeAttributes = null;
int lastOffset = 0;
int length = maxLength == -1 ? value.length() : Math.min(value.length(), maxLength);
for (int i = 0; i < length; i++) {
char ch = value.charAt(i);
int additionalCharIndex = -1;
- if (ch == '\n' || ch == '\r' || ch == '\t' || ch == '\b' || ch == '\f' || (additionalChars != null && (additionalCharIndex = additionalChars.indexOf(ch)) != -1)) {
+ if (ch == '\n' || ch == '\r' || ch == '\t' || ch == '\b' || ch == '\f' || (additionalChars != null && (additionalCharIndex = additionalChars
+ .indexOf(ch)) != -1)) {
if (i > lastOffset) {
text.append(value.substring(lastOffset, i), attributes);
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XGroupingValue.java
similarity index 60%
copy from plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java
copy to platform/xdebugger-api/src/com/intellij/xdebugger/frame/XGroupingValue.java
index 7888121..2c44f94 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XGroupingValue.java
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.siyeh.ig.psiutils;
+package com.intellij.xdebugger.frame;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.ServerPageFile;
-import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.chromeConnector.debugger.frame.XGroupingValuePresenter;
+import org.jetbrains.annotations.NotNull;
-public class FileTypeUtils {
- public static boolean isInServerPageFile(PsiElement file) {
- return PsiUtilCore.getTemplateLanguageFile(file) instanceof ServerPageFile;
+public abstract class XGroupingValue extends XValue {
+ @Override
+ public final void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) {
+ node.setPresentation(null, null, XGroupingValuePresenter.INSTANCE, true);
}
-}
+}
\ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java
index b932b03..b079d7e 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java
@@ -49,8 +49,7 @@
void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @Nullable String value, boolean hasChildren);
/**
- * The same as {@link #setPresentation(javax.swing.Icon, String, String, boolean)} but also allows to
- * customize {@code separator} between name and value
+ * @deprecated use XVariableValuePresenter
*/
void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String separator, @NonNls @Nullable String value, boolean hasChildren);
@@ -65,18 +64,21 @@
* are escaped in the value. {@code valuePresenter} function doesn't affect 'Copy Value' action. It can be used to escape additional
* characters and/or surround value by quotes.
*
- * @see com.intellij.openapi.util.text.StringUtil#QUOTER
- * @see com.intellij.openapi.util.text.StringUtil#escaper
- * @see com.intellij.util.FunctionUtil#composition
+ * @deprecated use {@link XValuePresenter}
*/
void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String value,
@Nullable NotNullFunction<String, String> valuePresenter, boolean hasChildren);
+ void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String type,
+ @NonNls @NotNull String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean hasChildren);
+
void setPresentation(@Nullable Icon icon, @NonNls @Nullable String value, @Nullable XValuePresenter valuePresenter, boolean hasChildren);
/**
- * The same as {@link #setPresentation(javax.swing.Icon, String, String, com.intellij.util.NotNullFunction, boolean)} but also allows to
- * customize {@code separator} between name and value
+ * @deprecated use XVariableValuePresenter
*/
void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String separator, @NonNls @NotNull String value,
@Nullable NotNullFunction<String, String> valuePresenter, boolean hasChildren);
@@ -89,16 +91,4 @@
* @see #MAX_VALUE_LENGTH
*/
void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator);
-
- /**
- * @deprecated use {@link #setPresentation(javax.swing.Icon, String, String, boolean)} instead. Names for values should be passed to
- * {@link XCompositeNode#addChildren(XValueChildrenProvider, boolean)}
- */
- void setPresentation(@NonNls String name, @Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String value, boolean hasChildren);
-
- /**
- * @deprecated use {@link #setPresentation(javax.swing.Icon, String, String, String, boolean)} instead. Names for values should be passed to
- * {@link XCompositeNode#addChildren(XValueChildrenProvider, boolean)}
- */
- void setPresentation(@NonNls String name, @Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String separator, @NonNls @NotNull String value, boolean hasChildren);
-}
+}
\ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValuePresenter.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValuePresenter.java
index 68bc4e9..f5f7937 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValuePresenter.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValuePresenter.java
@@ -15,8 +15,24 @@
*/
package com.intellij.xdebugger.frame;
-import com.intellij.ui.SimpleColoredText;
+import com.intellij.ui.ColoredTextContainer;
+import com.intellij.ui.SimpleTextAttributes;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-public interface XValuePresenter {
- void append(String value, SimpleColoredText text, boolean changed);
+public abstract class XValuePresenter {
+ public void appendSeparator(@NotNull ColoredTextContainer text) {
+ text.append(" = ", SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+
+ public void append(@NotNull String value, @NotNull ColoredTextContainer text, boolean changed) {
+ }
+
+ @Nullable
+ /**
+ * if returns null, default value (depends on implementation) will be used
+ */
+ public SimpleTextAttributes getNameAttributes() {
+ return null;
+ }
}
\ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugLayoutCustomizer.java b/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugLayoutCustomizer.java
index f5a9ec3..fa02615 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugLayoutCustomizer.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/ui/XDebugLayoutCustomizer.java
@@ -11,7 +11,6 @@
* @author Sergey Simonchik
*/
public interface XDebugLayoutCustomizer {
-
/**
* Registers tab for the given {@code console}, that is returned by {@link com.intellij.xdebugger.XDebugProcess#createConsole()}.
*
@@ -27,4 +26,4 @@
* @param ui {@code RunnerLayoutUi} instance
*/
void registerAdditionalContent(@NotNull RunnerLayoutUi ui);
-}
+}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XSourcePositionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XSourcePositionImpl.java
index 06756b7..573c8fa 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XSourcePositionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XSourcePositionImpl.java
@@ -39,14 +39,17 @@
myOffset = offset;
}
+ @Override
public int getLine() {
return myLine;
}
+ @Override
public int getOffset() {
return myOffset;
}
+ @Override
@NotNull
public VirtualFile getFile() {
return myFile;
@@ -78,6 +81,7 @@
return new XSourcePositionImpl(file, line, offset);
}
+ @Override
@NotNull
public Navigatable createNavigatable(final @NotNull Project project) {
return myOffset != -1 ? new OpenFileDescriptor(project, myFile, myOffset) : new OpenFileDescriptor(project, myFile, getLine(), 0);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
index 1c24e82..e1598fb 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
@@ -24,15 +24,15 @@
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.AppUIUtil;
import com.intellij.ui.SimpleColoredText;
-import com.intellij.ui.SimpleTextAttributes;
-import com.intellij.util.NotNullFunction;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
-import com.intellij.xdebugger.frame.*;
+import com.intellij.xdebugger.frame.XFullValueEvaluator;
+import com.intellij.xdebugger.frame.XValue;
+import com.intellij.xdebugger.frame.XValuePlace;
+import com.intellij.xdebugger.frame.XValuePresenter;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint;
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType;
@@ -40,8 +40,7 @@
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.XEvaluationCallbackBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XValuePresenterAdapter;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -71,71 +70,52 @@
}
+ @Override
protected boolean canShowHint() {
return true;
}
+ @Override
protected void evaluateAndShowHint() {
myEvaluator.evaluate(myExpression, new XEvaluationCallbackBase() {
+ @Override
public void evaluated(@NotNull final XValue result) {
- result.computePresentation(new XValueNode() {
+ result.computePresentation(new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
@Override
- public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String value, boolean hasChildren) {
- setPresentation(icon, type, XDebuggerUIConstants.EQ_TEXT, value, hasChildren);
+ public void applyPresentation(@Nullable Icon icon,
+ @Nullable String type,
+ @Nullable String value,
+ @NotNull XValuePresenter valuePresenter,
+ boolean hasChildren,
+ boolean expand) {
+ if (isHintHidden()) return;
+
+ SimpleColoredText text = new SimpleColoredText();
+ text.append(myExpression, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
+ XValueNodeImpl.buildText(type, value, valuePresenter, text, false);
+ if (!hasChildren) {
+ showHint(HintUtil.createInformationLabel(text));
+ }
+ else if (getType() == ValueHintType.MOUSE_CLICK_HINT) {
+ showTree(result, myExpression);
+ }
+ else {
+ JComponent component = createExpandableHintComponent(text, new Runnable() {
+ @Override
+ public void run() {
+ showTree(result, myExpression);
+ }
+ });
+ showHint(component);
+ }
}
@Override
- public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String separator, @NonNls @NotNull String value,
- boolean hasChildren) {
- setPresentation(icon, type, separator, value, null, hasChildren);
- }
-
- @Override
- public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String value,
- @Nullable NotNullFunction<String, String> valuePresenter, boolean hasChildren) {
- setPresentation(icon, type, XDebuggerUIConstants.EQ_TEXT, value, valuePresenter, hasChildren);
- }
-
- @Override
- public void setGroupingPresentation(@Nullable Icon icon, @NonNls @Nullable String value, @Nullable XValuePresenter valuePresenter, boolean expand) {
- setPresentation(icon, value, valuePresenter, true);
- }
-
- @Override
- public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String value, @Nullable XValuePresenter valuePresenter, boolean hasChildren) {
- doSetPresentation(icon, null, XDebuggerUIConstants.EQ_TEXT, value, valuePresenter, hasChildren);
- }
-
- @Override
- public void setPresentation(@Nullable Icon icon, @NonNls @Nullable final String type, @NonNls @NotNull final String separator,
- @NonNls @NotNull final String value, @Nullable final NotNullFunction<String, String> valuePresenter, final boolean hasChildren) {
- doSetPresentation(icon, type, separator, value, valuePresenter == null ? null : new XValuePresenterAdapter(valuePresenter), hasChildren);
- }
-
- private void doSetPresentation(@Nullable Icon icon, @NonNls @Nullable final String type, @NonNls @NotNull final String separator,
- @NonNls @Nullable final String value, @Nullable final XValuePresenter valuePresenter, final boolean hasChildren) {
- AppUIUtil.invokeOnEdt(new Runnable() {
- public void run() {
- doShowHint(result, separator, value, type, valuePresenter == null ? XValueNodeImpl.DEFAULT_VALUE_PRESENTER : valuePresenter, hasChildren);
- }
- });
- }
-
- public void setPresentation(@NonNls final String name, @Nullable final Icon icon, @NonNls @Nullable final String type, @NonNls @NotNull final String value,
- final boolean hasChildren) {
- setPresentation(icon, type, value, hasChildren);
- }
-
- public void setPresentation(@NonNls final String name, @Nullable final Icon icon, @NonNls @Nullable final String type, @NonNls @NotNull final String separator,
- @NonNls @NotNull final String value,
- final boolean hasChildren) {
- setPresentation(icon, type, separator, value, hasChildren);
- }
-
public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
//todo[nik] implement?
}
+ @Override
public boolean isObsolete() {
//todo[nik]
return false;
@@ -143,40 +123,13 @@
}, XValuePlace.TOOLTIP);
}
+ @Override
public void errorOccurred(@NotNull final String errorMessage) {
LOG.debug("Cannot evaluate '" + myExpression + "':" + errorMessage);
}
}, myExpressionPosition);
}
- private void doShowHint(final XValue xValue, final String separator, final String value, String type,
- @NotNull XValuePresenter valuePresenter, final boolean hasChildren) {
- if (isHintHidden()) return;
-
- SimpleColoredText text = new SimpleColoredText();
- text.append(myExpression, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
- text.append(separator, SimpleTextAttributes.REGULAR_ATTRIBUTES);
- if (type != null) {
- text.append("{" + type + "} ", XDebuggerUIConstants.TYPE_ATTRIBUTES);
- }
- valuePresenter.append(value, text, false);
-
- if (!hasChildren) {
- showHint(HintUtil.createInformationLabel(text));
- }
- else if (getType() == ValueHintType.MOUSE_CLICK_HINT) {
- showTree(xValue, myExpression);
- }
- else {
- JComponent component = createExpandableHintComponent(text, new Runnable() {
- public void run() {
- showTree(xValue, myExpression);
- }
- });
- showHint(component);
- }
- }
-
private void showTree(final XValue value, final String name) {
XDebuggerTree tree = new XDebuggerTree(myDebugSession, myDebugSession.getDebugProcess().getEditorsProvider(),
myDebugSession.getCurrentPosition(), XDebuggerActions.VALUE_HINT_TREE_POPUP_GROUP);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHintTreeComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHintTreeComponent.java
index d31414f..eb476c9 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHintTreeComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHintTreeComponent.java
@@ -35,11 +35,13 @@
updateTree(initialItem);
}
+ @Override
protected void updateTree(final Pair<XValue, String> selectedItem) {
myTree.setRoot(new XValueNodeImpl(myTree, null, selectedItem.getSecond(), selectedItem.getFirst()), true);
myValueHint.showTreePopup(this, myTree, selectedItem.getSecond());
}
+ @Override
protected void setNodeAsRoot(final Object node) {
if (node instanceof XValueNodeImpl) {
final XValueNodeImpl valueNode = (XValueNodeImpl)node;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
index d7a5468..b407be6 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
@@ -197,11 +197,12 @@
if (commonSettings.length > 0) {
settings.addSeparator();
}
- settings.add(new ToggleSortValuesAction(commonSettings.length == 0));
+ if (!debugProcess.isValuesCustomSorted()) {
+ settings.add(new ToggleSortValuesAction(commonSettings.length == 0));
+ }
leftToolbar.add(settings);
-
leftToolbar.addSeparator();
leftToolbar.add(PinToolwindowTabAction.getPinAction());
@@ -247,4 +248,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java
index 010e452..8bd8c99 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java
@@ -20,8 +20,8 @@
import com.intellij.openapi.ui.Messages;
import com.intellij.ui.AppUIUtil;
import com.intellij.ui.SimpleColoredComponent;
-import com.intellij.ui.SimpleTextAttributes;
import com.intellij.xdebugger.frame.XValueModifier;
+import com.intellij.xdebugger.frame.XValuePresenter;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
@@ -47,11 +47,9 @@
SimpleColoredComponent nameLabel = new SimpleColoredComponent();
nameLabel.setIcon(getNode().getIcon());
nameLabel.append(nodeName, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
- final String separator = node.getSeparator();
- if (separator != null) {
- nameLabel.append(separator, SimpleTextAttributes.REGULAR_ATTRIBUTES);
- }
-
+ XValuePresenter presenter = node.getValuePresenter();
+ assert presenter != null;
+ presenter.appendSeparator(nameLabel);
myEditorPanel.add(nameLabel, BorderLayout.WEST);
myEditorPanel.add(myExpressionEditor.getComponent(), BorderLayout.CENTER);
@@ -60,10 +58,12 @@
myExpressionEditor.selectAll();
}
+ @Override
protected JComponent createInplaceEditorComponent() {
return myEditorPanel;
}
+ @Override
public void doOKAction() {
if (myModifier == null) return;
@@ -71,16 +71,20 @@
final XDebuggerTreeState treeState = XDebuggerTreeState.saveState(myTree);
myValueNode.setValueModificationStarted();
myModifier.setValue(myExpressionEditor.getText(), new XValueModifier.XModificationCallback() {
+ @Override
public void valueModified() {
AppUIUtil.invokeOnEdt(new Runnable() {
+ @Override
public void run() {
myTree.rebuildAndRestore(treeState);
}
});
}
+ @Override
public void errorOccurred(@NotNull final String errorMessage) {
AppUIUtil.invokeOnEdt(new Runnable() {
+ @Override
public void run() {
myTree.rebuildAndRestore(treeState);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XInspectDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XInspectDialog.java
index 25205fa..4480049 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XInspectDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XInspectDialog.java
@@ -45,16 +45,19 @@
init();
}
+ @Override
@Nullable
protected JComponent createCenterPanel() {
return myTreePanel.getMainPanel();
}
+ @Override
@Nullable
protected JComponent createSouthPanel() {
return null;
}
+ @Override
@NonNls
protected String getDimensionServiceKey() {
return "#xdebugger.XInspectDialog";
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNodeImpl.java
index 00d3bfb..2c06c20 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNodeImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNodeImpl.java
@@ -15,8 +15,8 @@
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
-import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.frame.XValue;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import org.jetbrains.annotations.NotNull;
/**
@@ -31,8 +31,9 @@
myExpression = expression;
}
+ @Override
@NotNull
public String getExpression() {
return myExpression;
}
-}
+}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
index 472b356a..2b6ab6f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
@@ -46,32 +46,39 @@
myTree = tree;
}
+ @Override
public TreeNode getChildAt(final int childIndex) {
if (isLeaf()) return null;
return getChildren().get(childIndex);
}
+ @Override
public int getChildCount() {
return isLeaf() ? 0 : getChildren().size();
}
+ @Override
public TreeNode getParent() {
return myParent;
}
+ @Override
public int getIndex(final TreeNode node) {
if (isLeaf()) return -1;
return getChildren().indexOf(node);
}
+ @Override
public boolean getAllowsChildren() {
return true;
}
+ @Override
public boolean isLeaf() {
return myLeaf;
}
+ @Override
public Enumeration children() {
if (isLeaf()) {
return EmptyEnumeration.INSTANCE;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
index afc718b..f77daf1 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
@@ -16,7 +16,6 @@
package com.intellij.xdebugger.impl.ui.tree.nodes;
import com.intellij.ui.SimpleTextAttributes;
-import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.SortedList;
import com.intellij.xdebugger.frame.XCompositeNode;
@@ -92,7 +91,7 @@
myValueChildren = new ArrayList<XValueNodeImpl>();
}
}
- List<XValueContainerNode<?>> newChildren = new SmartList<XValueContainerNode<?>>();
+ List<XValueContainerNode<?>> newChildren = new ArrayList<XValueContainerNode<?>>(children.size());
for (int i = 0; i < children.size(); i++) {
XValueNodeImpl node = new XValueNodeImpl(myTree, XValueContainerNode.this, children.getName(i), children.getValue(i));
myValueChildren.add(node);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
index a435bc5..285ea3e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
@@ -18,9 +18,10 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AppUIUtil;
-import com.intellij.ui.SimpleColoredText;
+import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.NotNullFunction;
+import com.intellij.util.ObjectUtils;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
@@ -39,27 +40,20 @@
/**
* @author nik
*/
-public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValueNode, XCompositeNode {
+public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValueNode, XCompositeNode, XValueNodePresentationConfigurator.ConfigurableXValueNode {
public static final Comparator<XValueNodeImpl> COMPARATOR = new Comparator<XValueNodeImpl>() {
@Override
public int compare(XValueNodeImpl o1, XValueNodeImpl o2) {
+ //noinspection ConstantConditions
return StringUtil.naturalCompare(o1.getName(), o2.getName());
}
};
- public static final XValuePresenter DEFAULT_VALUE_PRESENTER = new StringValuePresenter(-1, null) {
- @Override
- public void append(String value, SimpleColoredText text, boolean changed) {
- doAppend(value, text, changed ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES);
- }
- };
-
- private String myName;
+ private final String myName;
private String myType;
@Nullable
private String myValue;
private XFullValueEvaluator myFullValueEvaluator;
- private String mySeparator;
private boolean myChanged;
private XValuePresenter myValuePresenter;
@@ -76,13 +70,13 @@
@Override
public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @Nullable String value, boolean hasChildren) {
- setPresentation(icon, type, XDebuggerUIConstants.EQ_TEXT, value, hasChildren);
+ XValueNodePresentationConfigurator.setPresentation(icon, type, value, hasChildren, this);
}
@Override
public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String separator,
@NonNls @Nullable String value, boolean hasChildren) {
- setPresentation(null, icon, type, separator, value, hasChildren);
+ XValueNodePresentationConfigurator.setPresentation(icon, type, separator, value, hasChildren, this);
}
@Override
@@ -91,13 +85,16 @@
@NonNls @NotNull String value,
@Nullable NotNullFunction<String, String> valuePresenter,
boolean hasChildren) {
- setPresentation(icon, type, XDebuggerUIConstants.EQ_TEXT, value, valuePresenter, hasChildren);
+ XValueNodePresentationConfigurator.setPresentation(icon, type, value, valuePresenter, hasChildren, this);
}
-
- public void setPresentation(final String name, @Nullable final Icon icon, @Nullable final String type, @NotNull final String value,
- final boolean hasChildren) {
- setPresentation(name, icon, type, XDebuggerUIConstants.EQ_TEXT, value, hasChildren);
+ @Override
+ public void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String type,
+ @NonNls @NotNull String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean hasChildren) {
+ XValueNodePresentationConfigurator.setPresentation(icon, type, value, valuePresenter, hasChildren, this);
}
@Override
@@ -105,59 +102,59 @@
@NonNls @Nullable String type,
@NonNls @NotNull String separator,
@NonNls @NotNull String value,
- final @Nullable NotNullFunction<String, String> valuePresenter,
+ final @Nullable NotNullFunction<String, String> valuePresenter,
boolean hasChildren) {
- setPresentation(null, icon, type, separator, value, valuePresenter == null ? null : new XValuePresenterAdapter(valuePresenter), hasChildren, false);
- }
-
- public void setPresentation(@NonNls final String name, @Nullable final Icon icon, @NonNls @Nullable final String type, @NonNls @NotNull final String separator,
- @NonNls @Nullable final String value, final boolean hasChildren) {
- setPresentation(name, icon, type, separator, value, null, hasChildren, false);
+ XValueNodePresentationConfigurator.setPresentation(icon, type, separator, valuePresenter, hasChildren, this);
}
@Override
- public void setGroupingPresentation(@Nullable Icon icon, @NonNls @Nullable String value, @Nullable XValuePresenter valuePresenter, boolean expand) {
- setPresentation(null, icon, null, value == null ? "" : XDebuggerUIConstants.EQ_TEXT, value, valuePresenter, true, expand);
+ public void setGroupingPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean expand) {
+ XValueNodePresentationConfigurator.setGroupingPresentation(icon, value, valuePresenter, expand, this);
}
@Override
- public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String value, @Nullable XValuePresenter valuePresenter, boolean hasChildren) {
- setPresentation(null, icon, null, XDebuggerUIConstants.EQ_TEXT, value, valuePresenter, hasChildren, false);
+ public void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean hasChildren) {
+ XValueNodePresentationConfigurator.setPresentation(icon, value, valuePresenter, hasChildren, this);
}
- private void setPresentation(@NonNls final String name, @Nullable final Icon icon, @NonNls @Nullable final String type, @NonNls @NotNull final String separator,
- @NonNls @Nullable final String value, @Nullable final XValuePresenter valuePresenter, final boolean hasChildren, final boolean expand) {
- AppUIUtil.invokeOnEdt(new Runnable() {
- public void run() {
- setIcon(icon);
- if (name != null) {
- myName = name;
- }
- myValue = value;
- mySeparator = separator;
- myType = type;
- myValuePresenter = valuePresenter != null ? valuePresenter : DEFAULT_VALUE_PRESENTER;
+ @Override
+ public void applyPresentation(@Nullable Icon icon,
+ @Nullable String type,
+ @Nullable String value,
+ @NotNull XValuePresenter valuePresenter,
+ boolean hasChildren,
+ boolean expand) {
+ setIcon(icon);
+ myValue = value;
+ myType = type;
+ myValuePresenter = valuePresenter;
- updateText();
- setLeaf(!hasChildren);
- fireNodeChanged();
- myTree.nodeLoaded(XValueNodeImpl.this, myName, value);
- if (expand) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- if (!isObsolete()) {
- myTree.expandPath(getPath());
- }
- }
- });
+ updateText();
+ setLeaf(!hasChildren);
+ fireNodeChanged();
+ myTree.nodeLoaded(this, myName, value);
+ if (expand) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ if (!isObsolete()) {
+ myTree.expandPath(getPath());
+ }
}
- }
- });
+ });
+ }
}
+ @Override
public void setFullValueEvaluator(@NotNull final XFullValueEvaluator fullValueEvaluator) {
AppUIUtil.invokeOnEdt(new Runnable() {
+ @Override
public void run() {
myFullValueEvaluator = fullValueEvaluator;
fireNodeChanged();
@@ -174,15 +171,28 @@
myText.append("[" + markup.getText() + "] ", new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, markup.getColor()));
}
}
- myText.append(myName, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
- if (!StringUtil.isEmpty(mySeparator)) {
- myText.append(mySeparator, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ if (!StringUtil.isEmpty(myName)) {
+ StringValuePresenter.append(myName, myText,
+ ObjectUtils.notNull(myValuePresenter.getNameAttributes(), XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES),
+ MAX_VALUE_LENGTH, null);
}
- if (myType != null) {
- myText.append("{" + myType + "} ", XDebuggerUIConstants.TYPE_ATTRIBUTES);
+
+ buildText(myType, myValue, myValuePresenter, myText, myChanged);
+ }
+
+ public static void buildText(@Nullable String type,
+ @Nullable String value,
+ @NotNull XValuePresenter valuePresenter,
+ @NotNull ColoredTextContainer text,
+ boolean changed) {
+ if (value != null) {
+ valuePresenter.appendSeparator(text);
}
- if (myValue != null) {
- myValuePresenter.append(myValue, myText, myChanged);
+ if (type != null) {
+ text.append("{" + type + "} ", XDebuggerUIConstants.TYPE_ATTRIBUTES);
+ }
+ if (value != null) {
+ valuePresenter.append(value, text, changed);
}
}
@@ -222,8 +232,8 @@
}
@Nullable
- public String getSeparator() {
- return mySeparator;
+ public XValuePresenter getValuePresenter() {
+ return myValuePresenter;
}
@Nullable
@@ -237,7 +247,7 @@
}
public boolean isComputed() {
- return myName != null && myValuePresenter != null;
+ return myValuePresenter != null;
}
public void setValueModificationStarted() {
@@ -245,7 +255,7 @@
myValue = null;
myText.clear();
myText.append(myName, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
- myText.append(mySeparator, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ myValuePresenter.appendSeparator(myText);
myText.append(XDebuggerUIConstants.MODIFYING_VALUE_MESSAGE, XDebuggerUIConstants.MODIFYING_VALUE_HIGHLIGHT_ATTRIBUTES);
setLeaf(true);
fireNodeStructureChanged();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java
new file mode 100644
index 0000000..555efa6
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java
@@ -0,0 +1,182 @@
+package com.intellij.xdebugger.impl.ui.tree.nodes;
+
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.ui.ColoredTextContainer;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.NotNullFunction;
+import com.intellij.util.ObjectUtils;
+import com.intellij.xdebugger.frame.XValueNode;
+import com.intellij.xdebugger.frame.XValuePresenter;
+import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public final class XValueNodePresentationConfigurator {
+ private static final XValuePresenter DEFAULT_VALUE_PRESENTER = new XVariableValuePresenter(XDebuggerUIConstants.EQ_TEXT);
+
+ public interface ConfigurableXValueNode {
+ void applyPresentation(@Nullable Icon icon,
+ @Nullable String type,
+ @Nullable String value,
+ @NotNull XValuePresenter valuePresenter,
+ boolean hasChildren,
+ boolean expand);
+ }
+
+ public static abstract class ConfigurableXValueNodeImpl implements ConfigurableXValueNode, XValueNode {
+ @Override
+ public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @Nullable String value, boolean hasChildren) {
+ XValueNodePresentationConfigurator.setPresentation(icon, type, value, hasChildren, this);
+ }
+
+ @Override
+ public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String separator,
+ @NonNls @Nullable String value, boolean hasChildren) {
+ XValueNodePresentationConfigurator.setPresentation(icon, type, separator, value, hasChildren, this);
+ }
+
+ @Override
+ public void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String type,
+ @NonNls @NotNull String value,
+ @Nullable NotNullFunction<String, String> valuePresenter,
+ boolean hasChildren) {
+ XValueNodePresentationConfigurator.setPresentation(icon, type, value, valuePresenter, hasChildren, this);
+ }
+
+ @Override
+ public void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String type,
+ @NonNls @NotNull String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean hasChildren) {
+ XValueNodePresentationConfigurator.setPresentation(icon, type, value, valuePresenter, hasChildren, this);
+ }
+
+ @Override
+ public void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String type,
+ @NonNls @NotNull String separator,
+ @NonNls @NotNull String value,
+ final @Nullable NotNullFunction<String, String> valuePresenter,
+ boolean hasChildren) {
+ XValueNodePresentationConfigurator.setPresentation(icon, type, separator, valuePresenter, hasChildren, this);
+ }
+
+ @Override
+ public void setGroupingPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean expand) {
+ XValueNodePresentationConfigurator.setGroupingPresentation(icon, value, valuePresenter, expand, this);
+ }
+
+ @Override
+ public void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean hasChildren) {
+ XValueNodePresentationConfigurator.setPresentation(icon, value, valuePresenter, hasChildren, this);
+ }
+ }
+
+ public static void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String type,
+ @NonNls @Nullable String value,
+ boolean hasChildren,
+ ConfigurableXValueNode node) {
+ doSetPresentation(icon, type, value, DEFAULT_VALUE_PRESENTER, hasChildren, false, node);
+ }
+
+ public static void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String separator,
+ @NonNls @Nullable String value, boolean hasChildren, ConfigurableXValueNode node) {
+ doSetPresentation(icon, type, value, createPresenter(separator), hasChildren, false, node);
+ }
+
+ private static XValuePresenter createPresenter(@NotNull String separator) {
+ return separator.equals(XDebuggerUIConstants.EQ_TEXT) ? DEFAULT_VALUE_PRESENTER : new XVariableValuePresenter(separator);
+ }
+
+ public static void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String type,
+ @NonNls @NotNull String value,
+ @Nullable NotNullFunction<String, String> valuePresenter,
+ boolean hasChildren, ConfigurableXValueNode node) {
+ doSetPresentation(icon, type, value,
+ valuePresenter == null ? DEFAULT_VALUE_PRESENTER : new XValuePresenterAdapter(valuePresenter),
+ hasChildren, false, node);
+ }
+
+ public static void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String type,
+ @NonNls @NotNull String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean hasChildren, ConfigurableXValueNode node) {
+ doSetPresentation(icon, type, value, valuePresenter, hasChildren, false, node);
+ }
+
+ public static void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String type,
+ @SuppressWarnings("UnusedParameters") @NonNls @NotNull String separator,
+ @NonNls @NotNull String value,
+ final @Nullable NotNullFunction<String, String> valuePresenter,
+ boolean hasChildren, ConfigurableXValueNode node) {
+ // yes, we ignore separator, it is deprecated method
+ doSetPresentation(icon, type, value, valuePresenter == null ? DEFAULT_VALUE_PRESENTER : new XValuePresenterAdapter(valuePresenter), hasChildren, false, node);
+ }
+
+ public static void setGroupingPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean expand,
+ ConfigurableXValueNode node) {
+ doSetPresentation(icon, null, value, valuePresenter, true, expand, node);
+ }
+
+ public static void setPresentation(@Nullable Icon icon,
+ @NonNls @Nullable String value,
+ @Nullable XValuePresenter valuePresenter,
+ boolean hasChildren,
+ ConfigurableXValueNode node) {
+ doSetPresentation(icon, null, value, valuePresenter, hasChildren, false, node);
+ }
+
+ private static void doSetPresentation(@Nullable final Icon icon,
+ @NonNls @Nullable final String type,
+ @NonNls @Nullable final String value,
+ @Nullable XValuePresenter valuePresenter,
+ final boolean hasChildren,
+ final boolean expand,
+ final ConfigurableXValueNode node) {
+ Application application = ApplicationManager.getApplication();
+ final XValuePresenter finalValuePresenter = ObjectUtils.notNull(valuePresenter, DEFAULT_VALUE_PRESENTER);
+ if (application.isDispatchThread()) {
+ node.applyPresentation(icon, type, value, finalValuePresenter, hasChildren, expand);
+ }
+ else {
+ application.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ node.applyPresentation(icon, type, value, finalValuePresenter, hasChildren, expand);
+ }
+ });
+ }
+ }
+
+ private static final class XValuePresenterAdapter extends XValuePresenter {
+ private final NotNullFunction<String, String> valuePresenter;
+
+ public XValuePresenterAdapter(NotNullFunction<String, String> valuePresenter) {
+ this.valuePresenter = valuePresenter;
+ }
+
+ @Override
+ public void append(@NotNull String value, @NotNull ColoredTextContainer text, boolean changed) {
+ text.append(valuePresenter.fun(value), changed ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+ }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValuePresenterAdapter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValuePresenterAdapter.java
deleted file mode 100644
index fa7df03..0000000
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValuePresenterAdapter.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2000-2013 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.xdebugger.impl.ui.tree.nodes;
-
-import com.intellij.ui.SimpleColoredText;
-import com.intellij.ui.SimpleTextAttributes;
-import com.intellij.util.NotNullFunction;
-import com.intellij.xdebugger.frame.XValuePresenter;
-import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
-
-public class XValuePresenterAdapter implements XValuePresenter {
- private final NotNullFunction<String, String> valuePresenter;
-
- public XValuePresenterAdapter(NotNullFunction<String, String> valuePresenter) {
- this.valuePresenter = valuePresenter;
- }
-
- @Override
- public void append(String value, SimpleColoredText text, boolean changed) {
- text.append(valuePresenter.fun(value), changed ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES);
- }
-}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XVariableValuePresenter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XVariableValuePresenter.java
new file mode 100644
index 0000000..4411dc0
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XVariableValuePresenter.java
@@ -0,0 +1,27 @@
+package com.intellij.xdebugger.impl.ui.tree.nodes;
+
+import com.intellij.ui.ColoredTextContainer;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.xdebugger.frame.StringValuePresenter;
+import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
+import org.jetbrains.annotations.NotNull;
+
+public final class XVariableValuePresenter extends StringValuePresenter {
+ private final String separator;
+
+ public XVariableValuePresenter(@NotNull String separator) {
+ super(-1, null);
+
+ this.separator = separator;
+ }
+
+ @Override
+ public void appendSeparator(@NotNull ColoredTextContainer text) {
+ text.append(separator, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+
+ @Override
+ public void append(@NotNull String value, @NotNull ColoredTextContainer text, boolean changed) {
+ doAppend(value, text, changed ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+}
\ No newline at end of file
diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XTestValueNode.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XTestValueNode.java
index 6c4ba46..7ce4891 100644
--- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XTestValueNode.java
+++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XTestValueNode.java
@@ -1,17 +1,15 @@
package com.intellij.xdebugger;
-import com.intellij.util.NotNullFunction;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
-import com.intellij.xdebugger.frame.XValueNode;
import com.intellij.xdebugger.frame.XValuePresenter;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.concurrent.Semaphore;
-public class XTestValueNode implements XValueNode {
+public class XTestValueNode extends XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl {
public String myName;
public String myType;
public String myValue;
@@ -21,9 +19,13 @@
private final Semaphore myFinished = new Semaphore(0);
-
@Override
- public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String value, boolean hasChildren) {
+ public void applyPresentation(@Nullable Icon icon,
+ @Nullable String type,
+ @Nullable String value,
+ @NotNull XValuePresenter valuePresenter,
+ boolean hasChildren,
+ boolean expand) {
myType = type;
myValue = value;
myHasChildren = hasChildren;
@@ -32,64 +34,11 @@
}
@Override
- public void setGroupingPresentation(@Nullable Icon icon, @NonNls @Nullable String value, @Nullable XValuePresenter valuePresenter, boolean expand) {
- setPresentation(icon, value, valuePresenter, true);
- }
-
- @Override
- public void setPresentation(@Nullable Icon icon, @NonNls @Nullable String value, @Nullable XValuePresenter valuePresenter, boolean hasChildren) {
- setPresentation(icon, null, value, hasChildren);
- }
-
- @Override
- public void setPresentation(@Nullable Icon icon,
- @NonNls @Nullable String type,
- @NonNls @NotNull String separator,
- @NonNls @NotNull String value,
- @Nullable NotNullFunction<String, String> valuePresenter,
- boolean hasChildren) {
- setPresentation(icon, type, value, hasChildren);
- }
-
- @Override
- public void setPresentation(@Nullable Icon icon,
- @NonNls @Nullable String type,
- @NonNls @NotNull String separator,
- @NonNls @NotNull String value,
- boolean hasChildren) {
- setPresentation(icon, type, value, hasChildren);
- }
-
- @Override
- public void setPresentation(@Nullable Icon icon,
- @NonNls @Nullable String type,
- @NonNls @NotNull String value,
- @Nullable NotNullFunction<String, String> valuePresenter,
- boolean hasChildren) {
- setPresentation(icon, type, value, hasChildren);
- }
-
- public void setPresentation(@NonNls @NotNull String name,
- @Nullable Icon icon,
- @NonNls @Nullable String type,
- @NonNls @NotNull String value,
- boolean hasChildren) {
- setPresentation(icon, type, value, hasChildren);
- }
-
- public void setPresentation(@NonNls @NotNull String name,
- @Nullable Icon icon,
- @NonNls @Nullable String type,
- @NonNls @NotNull String separator,
- @NonNls @NotNull String value,
- boolean hasChildren) {
- setPresentation(icon, type, value, hasChildren);
- }
-
public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
myFullValueEvaluator = fullValueEvaluator;
}
+ @Override
public boolean isObsolete() {
return false;
}
diff --git a/plugins/ByteCodeViewer/src/META-INF/plugin.xml b/plugins/ByteCodeViewer/src/META-INF/plugin.xml
index 9a0135a..e9c6e32 100644
--- a/plugins/ByteCodeViewer/src/META-INF/plugin.xml
+++ b/plugins/ByteCodeViewer/src/META-INF/plugin.xml
@@ -5,6 +5,9 @@
<description>Viewing java bytecode inside IntelliJ IDEA.</description>
<vendor>JetBrains</vendor>
+ <extensionPoints>
+ <extensionPoint name="classSearcher" interface="com.intellij.byteCodeViewer.ClassSearcher"/>
+ </extensionPoints>
<extensions defaultExtensionNs="com.intellij">
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<projectService serviceInterface="com.intellij.byteCodeViewer.ByteCodeViewerManager"
diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java
index a5fc96c..7d958bb6 100644
--- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java
+++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java
@@ -5,6 +5,7 @@
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
@@ -35,6 +36,8 @@
* Date: 5/7/12
*/
public class ByteCodeViewerManager extends DockablePopupManager<ByteCodeViewerComponent> {
+ private static final ExtensionPointName<ClassSearcher> CLASS_SEARCHER_EP = ExtensionPointName.create("ByteCodeViewer.classSearcher");
+
private static final Logger LOG = Logger.getInstance("#" + ByteCodeViewerManager.class.getName());
public static final String TOOLWINDOW_ID = "Byte Code Viewer";
@@ -232,10 +235,20 @@
return ClassUtil.getJVMClassName(containingClass);
}
- private static PsiClass getContainingClass(PsiElement psiElement) {
+ public static PsiClass getContainingClass(PsiElement psiElement) {
+ for (ClassSearcher searcher : CLASS_SEARCHER_EP.getExtensions()) {
+ PsiClass aClass = searcher.findClass(psiElement);
+ if (aClass != null) {
+ return aClass;
+ }
+ }
+ return findClass(psiElement);
+ }
+
+ public static PsiClass findClass(@NotNull PsiElement psiElement) {
PsiClass containingClass = PsiTreeUtil.getParentOfType(psiElement, PsiClass.class, false);
while (containingClass instanceof PsiTypeParameter) {
- containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
+ containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
}
if (containingClass == null) return null;
diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java
new file mode 100644
index 0000000..9a778d1
--- /dev/null
+++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java
@@ -0,0 +1,14 @@
+package com.intellij.byteCodeViewer;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Created by Max Medvedev on 8/23/13
+ */
+public interface ClassSearcher {
+ @Nullable
+ PsiClass findClass(@NotNull PsiElement place);
+}
diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
index 34b5d44..76cf133 100644
--- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
+++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
@@ -20,7 +20,6 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
-import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.popup.NotLookupOrSearchCondition;
@@ -43,7 +42,7 @@
final PsiElement psiElement = getPsiElement(e.getDataContext(), project, e.getData(PlatformDataKeys.EDITOR));
if (psiElement != null) {
if (psiElement.getContainingFile() instanceof PsiClassOwner &&
- PsiTreeUtil.getParentOfType(psiElement, PsiClass.class, false) != null) {
+ ByteCodeViewerManager.getContainingClass(psiElement) != null) {
e.getPresentation().setEnabled(true);
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index f62b033..8bb0e68 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -1228,6 +1228,9 @@
synchronized.method.move.quickfix=Move synchronization into method
thread.run.replace.quickfix=Replace with 'start()'
volatile.field.problem.descriptor=Volatile field <code>#ref</code> of type ''{0}'' #loc
+string.format.choose.class=Choose Formatter class
+string.format.class.column.name=Additional formatter classes
+string.format.class.method.name=Additional formatter methods
exception.class.column.name=Exception class
bad.exception.thrown.problem.descriptor=Prohibited exception ''{0}'' thrown #loc
empty.catch.block.comments.option=Comments count as content
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java
index 7cd60f3b..d0feec6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java
@@ -29,7 +29,7 @@
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.IncorrectOperationException;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java
index 5e3b4c4..afea6ec 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java
@@ -21,7 +21,7 @@
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java
similarity index 76%
rename from plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java
rename to plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java
index 1cf1973..052e742 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java
@@ -15,6 +15,8 @@
*/
package com.siyeh.ig.bugs;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.*;
import com.intellij.psi.util.ConstantExpressionUtil;
import com.intellij.psi.util.PsiUtil;
@@ -23,9 +25,47 @@
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.FormatUtils;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-public class MalformedFormatStringInspection extends BaseInspection {
+import java.util.ArrayList;
+import java.util.List;
+
+public class MalformedFormatStringInspectionBase extends BaseInspection {
+ /**
+ * @noinspection PublicField
+ */
+ @NonNls public String additionalClasses = "";
+
+ /**
+ * @noinspection PublicField
+ */
+ @NonNls public String additionalMethods = "";
+
+ final List<String> classNames;
+ final List<String> methodNames;
+
+ public MalformedFormatStringInspectionBase() {
+ classNames = new ArrayList<String>();
+ methodNames = new ArrayList<String>();
+ parseString(additionalClasses, classNames);
+ parseString(additionalMethods, methodNames);
+ }
+
+ @Override
+ public void readSettings(@NotNull Element node) throws InvalidDataException {
+ super.readSettings(node);
+ parseString(additionalClasses, classNames);
+ parseString(additionalMethods, methodNames);
+ }
+
+ @Override
+ public void writeSettings(@NotNull Element node) throws WriteExternalException {
+ additionalClasses = formatString(classNames);
+ additionalMethods = formatString(methodNames);
+ super.writeSettings(node);
+ }
@Override
@NotNull
@@ -61,12 +101,12 @@
return new MalformedFormatStringVisitor();
}
- private static class MalformedFormatStringVisitor extends BaseInspectionVisitor {
+ private class MalformedFormatStringVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
- if (!FormatUtils.isFormatCall(expression)) {
+ if (!FormatUtils.isFormatCall(expression, methodNames, classNames)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java
index 36a0dc90..77a3ab3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java
@@ -24,7 +24,7 @@
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteUnnecessaryStatementFix;
import com.siyeh.ig.psiutils.ControlFlowUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java
index 5c8f1df..48c1018 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java
@@ -24,7 +24,7 @@
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteUnnecessaryStatementFix;
import com.siyeh.ig.psiutils.ControlFlowUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
index 07b7786..435dd24 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
@@ -27,7 +27,7 @@
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java
index 4a9b58b..fa50fb4 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java
@@ -24,7 +24,7 @@
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.psiutils.TestUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java
index 8e3fbeb..741d7cf 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java
@@ -25,7 +25,7 @@
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class EmptyFinallyBlockInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java
index 57003f5..04f50af 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java
@@ -20,7 +20,7 @@
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class EmptyTryBlockInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java
index 36c31ac..f0d521d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java
@@ -22,7 +22,7 @@
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteImportFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.psiutils.ImportUtils;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java
index d9d9dd9..f9d5aea 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java
@@ -19,7 +19,7 @@
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class OnDemandImportInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java
index 579a20b..3d9ee11 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java
@@ -21,7 +21,7 @@
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteImportFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class SamePackageImportInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java
index 91692ab..9bcad8f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java
@@ -22,7 +22,7 @@
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class SingleClassImportInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java
index 49c58d1..7b6b72a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java
@@ -21,7 +21,7 @@
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteImportFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java
index bc1fbe0..a1952f0 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java
@@ -25,7 +25,7 @@
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ClassUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java
index 2aa3c07..d1bd35e 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java
@@ -24,7 +24,7 @@
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class ClassWithoutConstructorInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FormatUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FormatUtils.java
index 68e431e..9be61bc 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FormatUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FormatUtils.java
@@ -20,7 +20,9 @@
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
public class FormatUtils {
@@ -48,9 +50,13 @@
private FormatUtils() {}
public static boolean isFormatCall(PsiMethodCallExpression expression) {
+ return isFormatCall(expression, Collections.<String>emptyList(), Collections.<String>emptyList());
+ }
+
+ public static boolean isFormatCall(PsiMethodCallExpression expression, List<String> optionalMethods, List<String> optionalClasses) {
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final String name = methodExpression.getReferenceName();
- if (!formatMethodNames.contains(name)) {
+ if (!formatMethodNames.contains(name) && !optionalMethods.contains(name)) {
return false;
}
final PsiMethod method = expression.resolveMethod();
@@ -62,7 +68,7 @@
return false;
}
final String className = containingClass.getQualifiedName();
- return formatClassNames.contains(className);
+ return formatClassNames.contains(className) || optionalClasses.contains(className);
}
public static boolean isFormatCallArgument(PsiElement element) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InitializationUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InitializationUtils.java
index 29c8b46..67c6a32 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InitializationUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InitializationUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,58 +21,43 @@
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
public class InitializationUtils {
private InitializationUtils() {}
- public static boolean methodAssignsVariableOrFails(
- @Nullable PsiMethod method, @NotNull PsiVariable variable) {
+ public static boolean methodAssignsVariableOrFails(@Nullable PsiMethod method, @NotNull PsiVariable variable) {
return methodAssignsVariableOrFails(method, variable, false);
}
- public static boolean expressionAssignsVariableOrFails(
- @Nullable PsiExpression expression, @NotNull PsiVariable variable) {
- return expressionAssignsVariableOrFails(expression, variable,
- new HashSet(), true);
+ public static boolean expressionAssignsVariableOrFails(@Nullable PsiExpression expression, @NotNull PsiVariable variable) {
+ return expressionAssignsVariableOrFails(expression, variable, new HashSet(), true);
}
- public static boolean methodAssignsVariableOrFails(
- @Nullable PsiMethod method, @NotNull PsiVariable variable,
- boolean strict) {
+ public static boolean methodAssignsVariableOrFails(@Nullable PsiMethod method, @NotNull PsiVariable variable, boolean strict) {
if (method == null) {
return false;
}
- final PsiCodeBlock body = method.getBody();
- return body != null && blockAssignsVariableOrFails(body, variable,
- strict);
+ return blockAssignsVariableOrFails(method.getBody(), variable, strict);
}
- public static boolean blockAssignsVariableOrFails(
- @Nullable PsiCodeBlock block, @NotNull PsiVariable variable) {
+ public static boolean blockAssignsVariableOrFails(@Nullable PsiCodeBlock block, @NotNull PsiVariable variable) {
return blockAssignsVariableOrFails(block, variable, false);
}
- public static boolean blockAssignsVariableOrFails(
- @Nullable PsiCodeBlock block, @NotNull PsiVariable variable,
- boolean strict) {
- return blockAssignsVariableOrFails(block, variable,
- new HashSet<MethodSignature>(), strict);
+ public static boolean blockAssignsVariableOrFails(@Nullable PsiCodeBlock block, @NotNull PsiVariable variable, boolean strict) {
+ return blockAssignsVariableOrFails(block, variable, new HashSet<MethodSignature>(), strict);
}
- private static boolean blockAssignsVariableOrFails(
- @Nullable PsiCodeBlock block, @NotNull PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ private static boolean blockAssignsVariableOrFails(@Nullable PsiCodeBlock block, @NotNull PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
if (block == null) {
return false;
}
- final PsiStatement[] statements = block.getStatements();
int assignmentCount = 0;
- for (final PsiStatement statement : statements) {
- if (statementAssignsVariableOrFails(statement, variable,
- checkedMethods, strict)) {
+ for (final PsiStatement statement : block.getStatements()) {
+ if (statementAssignsVariableOrFails(statement, variable, checkedMethods, strict)) {
if (strict) {
assignmentCount++;
}
@@ -84,9 +69,8 @@
return assignmentCount == 1;
}
- private static boolean statementAssignsVariableOrFails(
- @Nullable PsiStatement statement, PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ private static boolean statementAssignsVariableOrFails(@Nullable PsiStatement statement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
if (statement == null) {
return false;
}
@@ -101,107 +85,70 @@
return false;
}
else if (statement instanceof PsiReturnStatement) {
- final PsiReturnStatement returnStatement =
- (PsiReturnStatement)statement;
- final PsiExpression returnValue = returnStatement.getReturnValue();
- return expressionAssignsVariableOrFails(returnValue, variable,
- checkedMethods, strict);
+ final PsiReturnStatement returnStatement = (PsiReturnStatement)statement;
+ return expressionAssignsVariableOrFails(returnStatement.getReturnValue(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiThrowStatement) {
- final PsiThrowStatement throwStatement =
- (PsiThrowStatement)statement;
- final PsiExpression exception = throwStatement.getException();
- return expressionAssignsVariableOrFails(exception, variable,
- checkedMethods, strict);
+ final PsiThrowStatement throwStatement = (PsiThrowStatement)statement;
+ return expressionAssignsVariableOrFails(throwStatement.getException(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiExpressionListStatement) {
- final PsiExpressionListStatement list =
- (PsiExpressionListStatement)statement;
+ final PsiExpressionListStatement list = (PsiExpressionListStatement)statement;
final PsiExpressionList expressionList = list.getExpressionList();
- final PsiExpression[] expressions = expressionList.getExpressions();
- for (final PsiExpression expression : expressions) {
- if (expressionAssignsVariableOrFails(expression, variable,
- checkedMethods, strict)) {
+ for (final PsiExpression expression : expressionList.getExpressions()) {
+ if (expressionAssignsVariableOrFails(expression, variable, checkedMethods, strict)) {
return true;
}
}
return false;
}
else if (statement instanceof PsiExpressionStatement) {
- final PsiExpressionStatement expressionStatement =
- (PsiExpressionStatement)statement;
- final PsiExpression expression =
- expressionStatement.getExpression();
- return expressionAssignsVariableOrFails(expression, variable,
- checkedMethods, strict);
+ final PsiExpressionStatement expressionStatement = (PsiExpressionStatement)statement;
+ return expressionAssignsVariableOrFails(expressionStatement.getExpression(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiDeclarationStatement) {
- final PsiDeclarationStatement declarationStatement =
- (PsiDeclarationStatement)statement;
- return declarationStatementAssignsVariableOrFails(
- declarationStatement, variable, checkedMethods, strict);
+ final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)statement;
+ return declarationStatementAssignsVariableOrFails(declarationStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiForStatement) {
final PsiForStatement forStatement = (PsiForStatement)statement;
- return forStatementAssignsVariableOrFails(forStatement,
- variable,
- checkedMethods, strict);
+ return forStatementAssignsVariableOrFails(forStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiForeachStatement) {
- final PsiForeachStatement foreachStatement =
- (PsiForeachStatement)statement;
- return foreachStatementAssignsVariableOrFails(variable,
- foreachStatement);
+ final PsiForeachStatement foreachStatement = (PsiForeachStatement)statement;
+ return foreachStatementAssignsVariableOrFails(foreachStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiWhileStatement) {
- final PsiWhileStatement whileStatement =
- (PsiWhileStatement)statement;
- return whileStatementAssignsVariableOrFails(whileStatement,
- variable, checkedMethods, strict);
+ final PsiWhileStatement whileStatement = (PsiWhileStatement)statement;
+ return whileStatementAssignsVariableOrFails(whileStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiDoWhileStatement) {
- final PsiDoWhileStatement doWhileStatement =
- (PsiDoWhileStatement)statement;
- return doWhileAssignsVariableOrFails(doWhileStatement, variable,
- checkedMethods, strict);
+ final PsiDoWhileStatement doWhileStatement = (PsiDoWhileStatement)statement;
+ return doWhileAssignsVariableOrFails(doWhileStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiSynchronizedStatement) {
- final PsiSynchronizedStatement synchronizedStatement =
- (PsiSynchronizedStatement)statement;
- final PsiCodeBlock body = synchronizedStatement.getBody();
- return blockAssignsVariableOrFails(body, variable,
- checkedMethods, strict);
+ final PsiSynchronizedStatement synchronizedStatement = (PsiSynchronizedStatement)statement;
+ return blockAssignsVariableOrFails(synchronizedStatement.getBody(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiBlockStatement) {
- final PsiBlockStatement blockStatement =
- (PsiBlockStatement)statement;
- final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
- return blockAssignsVariableOrFails(codeBlock, variable,
- checkedMethods, strict);
+ final PsiBlockStatement blockStatement = (PsiBlockStatement)statement;
+ return blockAssignsVariableOrFails(blockStatement.getCodeBlock(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiLabeledStatement) {
- final PsiLabeledStatement labeledStatement =
- (PsiLabeledStatement)statement;
- final PsiStatement statementLabeled =
- labeledStatement.getStatement();
- return statementAssignsVariableOrFails(statementLabeled, variable,
- checkedMethods, strict);
+ final PsiLabeledStatement labeledStatement = (PsiLabeledStatement)statement;
+ return statementAssignsVariableOrFails(labeledStatement.getStatement(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiIfStatement) {
final PsiIfStatement ifStatement = (PsiIfStatement)statement;
- return ifStatementAssignsVariableOrFails(ifStatement, variable,
- checkedMethods, strict);
+ return ifStatementAssignsVariableOrFails(ifStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiTryStatement) {
final PsiTryStatement tryStatement = (PsiTryStatement)statement;
- return tryStatementAssignsVariableOrFails(tryStatement, variable,
- checkedMethods, strict);
+ return tryStatementAssignsVariableOrFails(tryStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiSwitchStatement) {
- final PsiSwitchStatement switchStatement =
- (PsiSwitchStatement)statement;
- return switchStatementAssignsVariableOrFails(switchStatement,
- variable, checkedMethods, strict);
+ final PsiSwitchStatement switchStatement = (PsiSwitchStatement)statement;
+ return switchStatementAssignsVariableOrFails(switchStatement, variable, checkedMethods, strict);
}
else {
// unknown statement type
@@ -209,21 +156,15 @@
}
}
- public static boolean switchStatementAssignsVariableOrFails(
- @NotNull PsiSwitchStatement switchStatement,
- @NotNull PsiVariable variable,
- boolean strict) {
- return switchStatementAssignsVariableOrFails(switchStatement, variable,
- new HashSet(), strict);
+ public static boolean switchStatementAssignsVariableOrFails(@NotNull PsiSwitchStatement switchStatement, @NotNull PsiVariable variable,
+ boolean strict) {
+ return switchStatementAssignsVariableOrFails(switchStatement, variable, new HashSet(), strict);
}
- private static boolean switchStatementAssignsVariableOrFails(
- @NotNull PsiSwitchStatement switchStatement,
- @NotNull PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ private static boolean switchStatementAssignsVariableOrFails(@NotNull PsiSwitchStatement switchStatement, @NotNull PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiExpression expression = switchStatement.getExpression();
- if (expressionAssignsVariableOrFails(expression, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(expression, variable, checkedMethods, strict)) {
return true;
}
final PsiCodeBlock body = switchStatement.getBody();
@@ -236,8 +177,7 @@
for (int i = 0; i < statements.length; i++) {
final PsiStatement statement = statements[i];
if (statement instanceof PsiSwitchLabelStatement) {
- final PsiSwitchLabelStatement labelStatement
- = (PsiSwitchLabelStatement)statement;
+ final PsiSwitchLabelStatement labelStatement = (PsiSwitchLabelStatement)statement;
if (i == statements.length - 1) {
return false;
}
@@ -247,8 +187,7 @@
assigns = false;
}
else if (statement instanceof PsiBreakStatement) {
- final PsiBreakStatement breakStatement
- = (PsiBreakStatement)statement;
+ final PsiBreakStatement breakStatement = (PsiBreakStatement)statement;
if (breakStatement.getLabelIdentifier() != null) {
return false;
}
@@ -258,8 +197,7 @@
assigns = false;
}
else {
- assigns |= statementAssignsVariableOrFails(statement, variable,
- checkedMethods, strict);
+ assigns |= statementAssignsVariableOrFails(statement, variable, checkedMethods, strict);
if (i == statements.length - 1 && !assigns) {
return false;
}
@@ -268,18 +206,13 @@
return containsDefault;
}
- private static boolean declarationStatementAssignsVariableOrFails(
- PsiDeclarationStatement declarationStatement, PsiVariable variable,
- Set<MethodSignature> checkedMethods, boolean strict) {
- final PsiElement[] elements =
- declarationStatement.getDeclaredElements();
+ private static boolean declarationStatementAssignsVariableOrFails(PsiDeclarationStatement declarationStatement, PsiVariable variable,
+ Set<MethodSignature> checkedMethods, boolean strict) {
+ final PsiElement[] elements = declarationStatement.getDeclaredElements();
for (PsiElement element : elements) {
if (element instanceof PsiVariable) {
final PsiVariable declaredVariable = (PsiVariable)element;
- final PsiExpression initializer =
- declaredVariable.getInitializer();
- if (expressionAssignsVariableOrFails(initializer, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(declaredVariable.getInitializer(), variable, checkedMethods, strict)) {
return true;
}
}
@@ -291,16 +224,14 @@
@NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiResourceList resourceList = tryStatement.getResourceList();
if (resourceList != null) {
- final List<PsiResourceVariable> resourceVariables = resourceList.getResourceVariables();
- for (PsiResourceVariable resourceVariable : resourceVariables) {
+ for (PsiResourceVariable resourceVariable : resourceList.getResourceVariables()) {
final PsiExpression initializer = resourceVariable.getInitializer();
if (expressionAssignsVariableOrFails(initializer, variable, checkedMethods, strict)) {
return true;
}
}
}
- final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
- boolean initializedInTryAndCatch = blockAssignsVariableOrFails(tryBlock, variable, checkedMethods, strict);
+ boolean initializedInTryAndCatch = blockAssignsVariableOrFails(tryStatement.getTryBlock(), variable, checkedMethods, strict);
final PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks();
for (final PsiCodeBlock catchBlock : catchBlocks) {
if (strict) {
@@ -310,101 +241,71 @@
initializedInTryAndCatch &= blockAssignsVariableOrFails(catchBlock, variable, checkedMethods, strict);
}
}
- if (initializedInTryAndCatch) {
- return true;
- }
- final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
- return blockAssignsVariableOrFails(finallyBlock, variable, checkedMethods, strict);
+ return initializedInTryAndCatch || blockAssignsVariableOrFails(tryStatement.getFinallyBlock(), variable, checkedMethods, strict);
}
- private static boolean ifStatementAssignsVariableOrFails(
- @NotNull PsiIfStatement ifStatement,
- PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods,
- boolean strict) {
+ private static boolean ifStatementAssignsVariableOrFails(@NotNull PsiIfStatement ifStatement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiExpression condition = ifStatement.getCondition();
- if (expressionAssignsVariableOrFails(condition, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(condition, variable, checkedMethods, strict)) {
return true;
}
final PsiStatement thenBranch = ifStatement.getThenBranch();
- final PsiStatement elseBranch = ifStatement.getElseBranch();
if (BoolUtils.isTrue(condition)) {
- return statementAssignsVariableOrFails(thenBranch, variable,
- checkedMethods, strict);
+ return statementAssignsVariableOrFails(thenBranch, variable, checkedMethods, strict);
}
- else if (BoolUtils.isFalse(condition)) {
- return statementAssignsVariableOrFails(elseBranch, variable,
- checkedMethods, strict);
+ final PsiStatement elseBranch = ifStatement.getElseBranch();
+ if (BoolUtils.isFalse(condition)) {
+ return statementAssignsVariableOrFails(elseBranch, variable, checkedMethods, strict);
}
- return statementAssignsVariableOrFails(thenBranch, variable,
- checkedMethods, strict) &&
- statementAssignsVariableOrFails(elseBranch, variable,
- checkedMethods, strict);
+ return statementAssignsVariableOrFails(thenBranch, variable, checkedMethods, strict) &&
+ statementAssignsVariableOrFails(elseBranch, variable, checkedMethods, strict);
}
- private static boolean doWhileAssignsVariableOrFails(
- @NotNull PsiDoWhileStatement doWhileStatement,
- PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods,
- boolean strict) {
- final PsiExpression condition = doWhileStatement.getCondition();
- final PsiStatement body = doWhileStatement.getBody();
- return expressionAssignsVariableOrFails(condition, variable,
- checkedMethods, strict) ||
- statementAssignsVariableOrFails(body, variable, checkedMethods,
- strict);
+ private static boolean doWhileAssignsVariableOrFails(@NotNull PsiDoWhileStatement doWhileStatement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ return statementAssignsVariableOrFails(doWhileStatement.getBody(), variable, checkedMethods, strict) ||
+ expressionAssignsVariableOrFails(doWhileStatement.getCondition(), variable, checkedMethods, strict);
}
- private static boolean whileStatementAssignsVariableOrFails(
- @NotNull PsiWhileStatement whileStatement, PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods,
- boolean strict) {
+ private static boolean whileStatementAssignsVariableOrFails(@NotNull PsiWhileStatement whileStatement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiExpression condition = whileStatement.getCondition();
- if (expressionAssignsVariableOrFails(condition, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(condition, variable, checkedMethods, strict)) {
return true;
}
if (BoolUtils.isTrue(condition)) {
final PsiStatement body = whileStatement.getBody();
- if (statementAssignsVariableOrFails(body, variable, checkedMethods,
- strict)) {
+ if (statementAssignsVariableOrFails(body, variable, checkedMethods, strict)) {
return true;
}
}
return false;
}
- private static boolean forStatementAssignsVariableOrFails(
- @NotNull PsiForStatement forStatement, PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
- final PsiStatement initialization = forStatement.getInitialization();
- if (statementAssignsVariableOrFails(initialization, variable,
- checkedMethods, strict)) {
+ private static boolean forStatementAssignsVariableOrFails(@NotNull PsiForStatement forStatement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ if (statementAssignsVariableOrFails(forStatement.getInitialization(), variable, checkedMethods, strict)) {
return true;
}
- final PsiExpression test = forStatement.getCondition();
- if (expressionAssignsVariableOrFails(test, variable, checkedMethods,
- strict)) {
+ final PsiExpression condition = forStatement.getCondition();
+ if (expressionAssignsVariableOrFails(condition, variable, checkedMethods, strict)) {
return true;
}
- if (BoolUtils.isTrue(test)) {
- final PsiStatement body = forStatement.getBody();
- if (statementAssignsVariableOrFails(body, variable, checkedMethods,
- strict)) {
+ if (BoolUtils.isTrue(condition)) {
+ if (statementAssignsVariableOrFails(forStatement.getBody(), variable, checkedMethods, strict)) {
return true;
}
- final PsiStatement update = forStatement.getUpdate();
- if (statementAssignsVariableOrFails(update, variable,
- checkedMethods, strict)) {
+ if (statementAssignsVariableOrFails(forStatement.getUpdate(), variable, checkedMethods, strict)) {
return true;
}
}
return false;
}
- private static boolean foreachStatementAssignsVariableOrFails(PsiVariable field, PsiForeachStatement forStatement) {
- return false;
+ private static boolean foreachStatementAssignsVariableOrFails(@NotNull PsiForeachStatement foreachStatement, PsiVariable field,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ return expressionAssignsVariableOrFails(foreachStatement.getIteratedValue(), field, checkedMethods, strict);
}
private static boolean expressionAssignsVariableOrFails(@Nullable PsiExpression expression, PsiVariable variable,
@@ -421,8 +322,7 @@
}
else if (expression instanceof PsiParenthesizedExpression) {
final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression;
- final PsiExpression unparenthesizedExpression = parenthesizedExpression.getExpression();
- return expressionAssignsVariableOrFails(unparenthesizedExpression, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(parenthesizedExpression.getExpression(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
@@ -434,8 +334,7 @@
}
else if (expression instanceof PsiArrayInitializerExpression) {
final PsiArrayInitializerExpression array = (PsiArrayInitializerExpression)expression;
- final PsiExpression[] initializers = array.getInitializers();
- for (final PsiExpression initializer : initializers) {
+ for (final PsiExpression initializer : array.getInitializers()) {
if (expressionAssignsVariableOrFails(initializer, variable, checkedMethods, strict)) {
return true;
}
@@ -444,30 +343,24 @@
}
else if (expression instanceof PsiTypeCastExpression) {
final PsiTypeCastExpression typeCast = (PsiTypeCastExpression)expression;
- final PsiExpression operand = typeCast.getOperand();
- return expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(typeCast.getOperand(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiArrayAccessExpression) {
final PsiArrayAccessExpression accessExpression = (PsiArrayAccessExpression)expression;
- final PsiExpression arrayExpression = accessExpression.getArrayExpression();
- final PsiExpression indexExpression = accessExpression.getIndexExpression();
- return expressionAssignsVariableOrFails(arrayExpression, variable, checkedMethods, strict) ||
- expressionAssignsVariableOrFails(indexExpression, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(accessExpression.getArrayExpression(), variable, checkedMethods, strict) ||
+ expressionAssignsVariableOrFails(accessExpression.getIndexExpression(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiPrefixExpression) {
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)expression;
- final PsiExpression operand = prefixExpression.getOperand();
- return expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(prefixExpression.getOperand(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiPostfixExpression) {
final PsiPostfixExpression postfixExpression = (PsiPostfixExpression)expression;
- final PsiExpression operand = postfixExpression.getOperand();
- return expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(postfixExpression.getOperand(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
- final PsiExpression[] operands = polyadicExpression.getOperands();
- for (PsiExpression operand : operands) {
+ for (PsiExpression operand : polyadicExpression.getOperands()) {
if (expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict)) {
return true;
}
@@ -476,14 +369,11 @@
}
else if (expression instanceof PsiConditionalExpression) {
final PsiConditionalExpression conditional = (PsiConditionalExpression)expression;
- final PsiExpression condition = conditional.getCondition();
- if (expressionAssignsVariableOrFails(condition, variable, checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(conditional.getCondition(), variable, checkedMethods, strict)) {
return true;
}
- final PsiExpression thenExpression = conditional.getThenExpression();
- final PsiExpression elseExpression = conditional.getElseExpression();
- return expressionAssignsVariableOrFails(thenExpression, variable, checkedMethods, strict) &&
- expressionAssignsVariableOrFails(elseExpression, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(conditional.getThenExpression(), variable, checkedMethods, strict) &&
+ expressionAssignsVariableOrFails(conditional.getElseExpression(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiAssignmentExpression) {
final PsiAssignmentExpression assignment = (PsiAssignmentExpression)expression;
@@ -491,13 +381,12 @@
if (expressionAssignsVariableOrFails(lhs, variable, checkedMethods, strict)) {
return true;
}
- final PsiExpression rhs = assignment.getRExpression();
- if (expressionAssignsVariableOrFails(rhs, variable, checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(assignment.getRExpression(), variable, checkedMethods, strict)) {
return true;
}
if (lhs instanceof PsiReferenceExpression) {
final PsiElement element = ((PsiReference)lhs).resolve();
- if (element != null && element.equals(variable)) {
+ if (variable.equals(element)) {
return true;
}
}
@@ -505,85 +394,64 @@
}
else if (expression instanceof PsiInstanceOfExpression) {
final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression)expression;
- final PsiExpression operand = instanceOfExpression.getOperand();
- return expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(instanceOfExpression.getOperand(), variable, checkedMethods, strict);
}
else {
return false;
}
}
- private static boolean newExpressionAssignsVariableOrFails(
- @NotNull PsiNewExpression newExpression, PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ private static boolean newExpressionAssignsVariableOrFails(@NotNull PsiNewExpression newExpression, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiExpressionList argumentList = newExpression.getArgumentList();
if (argumentList != null) {
- final PsiExpression[] args = argumentList.getExpressions();
- for (final PsiExpression arg : args) {
- if (expressionAssignsVariableOrFails(arg, variable,
- checkedMethods, strict)) {
+ for (final PsiExpression argument : argumentList.getExpressions()) {
+ if (expressionAssignsVariableOrFails(argument, variable, checkedMethods, strict)) {
return true;
}
}
}
- final PsiArrayInitializerExpression arrayInitializer =
- newExpression.getArrayInitializer();
- if (expressionAssignsVariableOrFails(arrayInitializer, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(newExpression.getArrayInitializer(), variable, checkedMethods, strict)) {
return true;
}
- final PsiExpression[] arrayDimensions =
- newExpression.getArrayDimensions();
- for (final PsiExpression dim : arrayDimensions) {
- if (expressionAssignsVariableOrFails(dim, variable,
- checkedMethods, strict)) {
+ for (final PsiExpression dimension : newExpression.getArrayDimensions()) {
+ if (expressionAssignsVariableOrFails(dimension, variable, checkedMethods, strict)) {
return true;
}
}
return false;
}
- private static boolean methodCallAssignsVariableOrFails(
- @NotNull PsiMethodCallExpression callExpression,
- PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
- final PsiExpressionList argList = callExpression.getArgumentList();
- final PsiExpression[] args = argList.getExpressions();
- for (final PsiExpression arg : args) {
- if (expressionAssignsVariableOrFails(arg, variable, checkedMethods,
- strict)) {
+ private static boolean methodCallAssignsVariableOrFails(@NotNull PsiMethodCallExpression callExpression, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ final PsiExpressionList argumentList = callExpression.getArgumentList();
+ for (final PsiExpression argument : argumentList.getExpressions()) {
+ if (expressionAssignsVariableOrFails(argument, variable, checkedMethods, strict)) {
return true;
}
}
- final PsiReferenceExpression methodExpression =
- callExpression.getMethodExpression();
- if (expressionAssignsVariableOrFails(methodExpression, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(callExpression.getMethodExpression(), variable, checkedMethods, strict)) {
return true;
}
final PsiMethod method = callExpression.resolveMethod();
if (method == null) {
return false;
}
- final MethodSignature methodSignature =
- method.getSignature(PsiSubstitutor.EMPTY);
+ final MethodSignature methodSignature = method.getSignature(PsiSubstitutor.EMPTY);
if (!checkedMethods.add(methodSignature)) {
return false;
}
- final PsiClass containingClass =
- ClassUtils.getContainingClass(callExpression);
+ final PsiClass containingClass = ClassUtils.getContainingClass(callExpression);
final PsiClass calledClass = method.getContainingClass();
if (calledClass == null || !calledClass.equals(containingClass)) {
return false;
}
if (method.hasModifierProperty(PsiModifier.STATIC)
- || method.isConstructor()
|| method.hasModifierProperty(PsiModifier.PRIVATE)
|| method.hasModifierProperty(PsiModifier.FINAL)
+ || method.isConstructor()
|| calledClass.hasModifierProperty(PsiModifier.FINAL)) {
- final PsiCodeBlock body = method.getBody();
- return blockAssignsVariableOrFails(body, variable,
- checkedMethods, strict);
+ return blockAssignsVariableOrFails(method.getBody(), variable, checkedMethods, strict);
}
return false;
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java
index 7df6ad2..5a90d4b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java
@@ -20,7 +20,7 @@
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class DesignForExtensionInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java
index 43060f7..4a9e0f1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java
@@ -21,7 +21,7 @@
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class EmptySynchronizedStatementInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java
new file mode 100644
index 0000000..4f657fd
--- /dev/null
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2013 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.bugs;
+
+import com.intellij.codeInspection.ui.ListTable;
+import com.intellij.codeInspection.ui.ListWrappingTableModel;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.ui.UiUtils;
+
+import javax.swing.*;
+
+public class MalformedFormatStringInspection extends MalformedFormatStringInspectionBase {
+ @Override
+ public JComponent createOptionsPanel() {
+ ListWrappingTableModel classTableModel =
+ new ListWrappingTableModel(classNames, InspectionGadgetsBundle.message("string.format.class.column.name"));
+ JPanel classChooserPanel = UiUtils
+ .createAddRemoveTreeClassChooserPanel(new ListTable(classTableModel), InspectionGadgetsBundle.message("string.format.choose.class"));
+
+ ListWrappingTableModel methodTableModel =
+ new ListWrappingTableModel(methodNames, InspectionGadgetsBundle.message("string.format.class.method.name"));
+ JPanel methodPanel = UiUtils.createAddRemovePanel(new ListTable(methodTableModel));
+
+ final JPanel panel = new JPanel();
+ BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.Y_AXIS);
+ panel.setLayout(boxLayout);
+
+ panel.add(classChooserPanel);
+ panel.add(methodPanel);
+ return panel;
+ }
+}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassInTopLevelPackageInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassInTopLevelPackageInspection.java
index 9b5861c..9b52019 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassInTopLevelPackageInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassInTopLevelPackageInspection.java
@@ -24,7 +24,7 @@
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.MoveClassFix;
import com.siyeh.ig.psiutils.ClassUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class ClassInTopLevelPackageInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspection.java
index cd7c3c0..9866dc6 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspection.java
@@ -23,7 +23,7 @@
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.RenameFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/EmptyClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/EmptyClassInspection.java
index 85b42f1e..85a6dff 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/EmptyClassInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/EmptyClassInspection.java
@@ -25,7 +25,7 @@
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.AddToIgnoreIfAnnotatedByListQuickFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.ui.ExternalizableStringSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/BadExceptionDeclaredInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/BadExceptionDeclaredInspection.java
index 98357a2..5ce1f40 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/BadExceptionDeclaredInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/BadExceptionDeclaredInspection.java
@@ -133,10 +133,8 @@
super.visitMethod(method);
if (ignoreTestCases) {
final PsiClass containingClass = method.getContainingClass();
- if (containingClass != null && TestFrameworks.getInstance().isTestClass(containingClass)) {
- return;
- }
- if (TestUtils.isJUnitTestMethod(method)) {
+ final TestFrameworks testFrameworks = TestFrameworks.getInstance();
+ if (containingClass != null && testFrameworks.isTestOrConfig(containingClass)) {
return;
}
}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java
index 5defb34..e2a88f3 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java
@@ -28,7 +28,7 @@
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.psiutils.StringUtils;
import com.siyeh.ig.psiutils.TestUtils;
import com.siyeh.ig.ui.UiUtils;
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java
index 4835464..dc58029 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java
@@ -27,4 +27,15 @@
public void outOfMemory() {
String.format("%2147483640$s", "s");
}
+
+ public void optionalSettings() {
+ SomeOtherLogger logger = new SomeOtherLogger();
+ logger.d("%s %s", 1); // this is invalid according to the inspector (correct)
+ }
+
+ public class SomeOtherLogger {
+ public void d(String message, Object...args) {
+ // Do some logging.
+ }
+ }
}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml
index 7d528e9..494e160 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml
@@ -56,10 +56,17 @@
<description>Too few arguments for format string "%s %s" + "hmm" #loc</description>
</problem>
- <problem>
- <file>MalformedFormatString.java</file>
- <line>28</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Malformed format string</problem_class>
- <description>Too few arguments for format string "%2147483640$s" #loc</description>
- </problem>
+ <problem>
+ <file>MalformedFormatString.java</file>
+ <line>28</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Malformed format string</problem_class>
+ <description>Too few arguments for format string "%2147483640$s" #loc</description>
+ </problem>
+
+ <problem>
+ <file>MalformedFormatString.java</file>
+ <line>33</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Malformed format string</problem_class>
+ <description>Too few arguments for format string "%s %s" #loc</description>
+ </problem>
</problems>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/field/InstanceVariableInitialization.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/field/InstanceVariableInitialization.java
index 7973f52..e5ce636 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/field/InstanceVariableInitialization.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/field/InstanceVariableInitialization.java
@@ -93,4 +93,10 @@
C() {
boolean b = (o = "") instanceof String;
}
+}
+class D {
+ private java.util.List l;
+ D() {
+ for (Object o : l = new java.util.ArrayList()) {}
+ }
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java
index 769a5fd..6d0149c 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java
@@ -5,7 +5,10 @@
public class MalformedFormatStringInspectionTest extends IGInspectionTestCase {
public void test() throws Exception {
- doTest("com/siyeh/igtest/bugs/malformed_format_string",
- new MalformedFormatStringInspection());
+ MalformedFormatStringInspection inspection = new MalformedFormatStringInspection();
+ inspection.classNames.add("com.siyeh.igtest.bugs.malformed_format_string.MalformedFormatString.SomeOtherLogger");
+ inspection.methodNames.add("d");
+
+ doTest("com/siyeh/igtest/bugs/malformed_format_string", inspection);
}
}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/RemoveBracesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/RemoveBracesIntention.java
index b977e1c..e07e0df 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/RemoveBracesIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/RemoveBracesIntention.java
@@ -17,7 +17,7 @@
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java
index 5fe305e..597d95c4 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java
@@ -17,7 +17,7 @@
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ipp.base.PsiElementPredicate;
class ReplaceConditionalWithIfPredicate implements PsiElementPredicate {
diff --git a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java
index eec055f..a76c166 100644
--- a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java
+++ b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java
@@ -41,6 +41,7 @@
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.dom.*;
+import java.lang.annotation.Annotation;
import java.util.*;
/**
@@ -48,16 +49,70 @@
*/
public class ExtensionDomExtender extends DomExtender<Extensions> {
private static final PsiClassConverter CLASS_CONVERTER = new PluginPsiClassConverter();
+
+ private static class MyRequired implements Required {
+ @Override
+ public boolean value() {
+ return true;
+ }
+
+ @Override
+ public boolean nonEmpty() {
+ return true;
+ }
+
+ @Override
+ public boolean identifier() {
+ return false;
+ }
+
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return Required.class;
+ }
+ }
+
+ private static class MyExtendClass extends ExtendClassImpl {
+ private final String myInterfaceName;
+
+ private MyExtendClass(String interfaceName) {
+ myInterfaceName = interfaceName;
+ }
+
+ @Override
+ public boolean allowAbstract() {
+ return false;
+ }
+
+ @Override
+ public boolean allowInterface() {
+ return false;
+ }
+
+ @Override
+ public boolean allowEnum() {
+ return false;
+ }
+
+ @Override
+ public String value() {
+ return myInterfaceName;
+ }
+ }
+
private static final DomExtender EXTENSION_EXTENDER = new DomExtender() {
public void registerExtensions(@NotNull final DomElement domElement, @NotNull final DomExtensionsRegistrar registrar) {
final ExtensionPoint extensionPoint = (ExtensionPoint)domElement.getChildDescription().getDomDeclaration();
assert extensionPoint != null;
- String interfaceName = extensionPoint.getInterface().getStringValue();
+ final String interfaceName = extensionPoint.getInterface().getStringValue();
final Project project = extensionPoint.getManager().getProject();
if (interfaceName != null) {
- registrar.registerGenericAttributeValueChildExtension(new XmlName("implementation"), PsiClass.class).setConverter(CLASS_CONVERTER);
+ registrar.registerGenericAttributeValueChildExtension(new XmlName("implementation"), PsiClass.class)
+ .setConverter(CLASS_CONVERTER)
+ .addCustomAnnotation(new MyExtendClass(interfaceName))
+ .addCustomAnnotation(new MyRequired());
registerXmlb(registrar, JavaPsiFacade.getInstance(project).findClass(interfaceName, GlobalSearchScope.allScope(project)),
Collections.<With>emptyList());
}
diff --git a/plugins/devkit/src/projectRoots/IdeaJdk.java b/plugins/devkit/src/projectRoots/IdeaJdk.java
index 6b40ced..a958af1 100644
--- a/plugins/devkit/src/projectRoots/IdeaJdk.java
+++ b/plugins/devkit/src/projectRoots/IdeaJdk.java
@@ -121,7 +121,7 @@
}
@Nullable
- public final String getVersionString(final Sdk sdk) {
+ public final String getVersionString(@NotNull final Sdk sdk) {
final Sdk internalJavaSdk = getInternalJavaSdk(sdk);
return internalJavaSdk != null ? internalJavaSdk.getVersionString() : null;
}
@@ -401,13 +401,13 @@
}
@Nullable
- public String getBinPath(Sdk sdk) {
+ public String getBinPath(@NotNull Sdk sdk) {
final Sdk internalJavaSdk = getInternalJavaSdk(sdk);
return internalJavaSdk == null ? null : JavaSdk.getInstance().getBinPath(internalJavaSdk);
}
@Nullable
- public String getToolsPath(Sdk sdk) {
+ public String getToolsPath(@NotNull Sdk sdk) {
final Sdk jdk = getInternalJavaSdk(sdk);
if (jdk != null && jdk.getVersionString() != null){
return JavaSdk.getInstance().getToolsPath(jdk);
@@ -416,12 +416,12 @@
}
@Nullable
- public String getVMExecutablePath(Sdk sdk) {
+ public String getVMExecutablePath(@NotNull Sdk sdk) {
final Sdk internalJavaSdk = getInternalJavaSdk(sdk);
return internalJavaSdk == null ? null : JavaSdk.getInstance().getVMExecutablePath(internalJavaSdk);
}
- public void saveAdditionalData(SdkAdditionalData additionalData, Element additional) {
+ public void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional) {
if (additionalData instanceof Sandbox) {
try {
((Sandbox)additionalData).writeExternal(additional);
@@ -432,7 +432,7 @@
}
}
- public SdkAdditionalData loadAdditionalData(Sdk sdk, Element additional) {
+ public SdkAdditionalData loadAdditionalData(@NotNull Sdk sdk, Element additional) {
Sandbox sandbox = new Sandbox(sdk);
try {
sandbox.readExternal(additional);
diff --git a/plugins/devkit/testData/codeInsight/ExtensionQualifiedName.xml b/plugins/devkit/testData/codeInsight/ExtensionQualifiedName.xml
index e74bde4..d5b03f8 100644
--- a/plugins/devkit/testData/codeInsight/ExtensionQualifiedName.xml
+++ b/plugins/devkit/testData/codeInsight/ExtensionQualifiedName.xml
@@ -6,7 +6,12 @@
</extensionPoints>
<extensions defaultExtensionNs="com.intellij.myPlugin">
- <ext implementation="java.lang.Runnable"/>
+ <<error descr="'implementation' attribute should be defined">ext</error>/>
+ <ext implementation="<error descr="Interface not allowed">java.lang.Runnable</error>"/>
+ <ext implementation="<error descr="'java.util.concurrent.TimeUnit' is not assignable to 'java.lang.Runnable'"><error descr="Enum not allowed">java.util.concurrent.TimeUnit</error></error>"/>
+ <ext implementation="<error descr="'java.lang.String' is not assignable to 'java.lang.Runnable'">java.lang.String</error>"/>
+
+ <ext implementation="foo.MyRunnable"/>
</extensions>
</idea-plugin>
\ No newline at end of file
diff --git a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy
index 52c7857..1ba75d4 100644
--- a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy
+++ b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy
@@ -117,6 +117,7 @@
}
public void testExtensionQualifiedName() throws Throwable {
+ myFixture.addClass("package foo; public class MyRunnable implements java.lang.Runnable {}");
configureByFile();
myFixture.checkHighlighting(false, false, false);
}
diff --git a/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java b/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java
index 6cef328..873b395 100644
--- a/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java
+++ b/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java
@@ -133,8 +133,7 @@
return;
}
entire.append(text);
- if (suppressed || myVcs == null) {
- LOG.debug(text);
+ if (myVcs == null || (suppressed && !LOG.isDebugEnabled())) {
return;
}
int last = lineRest.length() > 0 ? lineRest.charAt(lineRest.length() - 1) : -1;
@@ -158,13 +157,19 @@
else {
line = text.substring(start, savedPos);
}
- if (ProcessOutputTypes.STDOUT == outputType && !StringUtil.isEmptyOrSpaces(line)) {
- myVcs.showMessages(line);
- LOG.info(line.trim());
- }
- else if (ProcessOutputTypes.STDERR == outputType && !StringUtil.isEmptyOrSpaces(line)) {
- myVcs.showErrorMessages(line);
- LOG.info(line.trim());
+ if (!StringUtil.isEmptyOrSpaces(line)) {
+ if (!suppressed) {
+ LOG.info(line.trim());
+ if (ProcessOutputTypes.STDOUT == outputType) {
+ myVcs.showMessages(line);
+ }
+ else if (ProcessOutputTypes.STDERR == outputType) {
+ myVcs.showErrorMessages(line);
+ }
+ }
+ else {
+ LOG.debug(line.trim());
+ }
}
}
start = savedPos;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
index 2f634d0..9854047 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
@@ -28,6 +28,7 @@
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException;
import org.jetbrains.plugins.github.exceptions.GithubJsonException;
+import org.jetbrains.plugins.github.exceptions.GithubRateLimitExceededException;
import org.jetbrains.plugins.github.exceptions.GithubStatusCodeException;
import org.jetbrains.plugins.github.util.GithubAuthData;
import org.jetbrains.plugins.github.util.GithubSslSupport;
@@ -209,7 +210,11 @@
case HttpStatus.SC_UNAUTHORIZED:
case HttpStatus.SC_PAYMENT_REQUIRED:
case HttpStatus.SC_FORBIDDEN:
- throw new GithubAuthenticationException("Request response: " + getErrorMessage(method));
+ String message = getErrorMessage(method);
+ if (message.contains("API rate limit exceeded")) {
+ throw new GithubRateLimitExceededException(message);
+ }
+ throw new GithubAuthenticationException("Request response: " + message);
default:
throw new GithubStatusCodeException(code + ": " + getErrorMessage(method), code);
}
@@ -535,11 +540,15 @@
return createDataFromRaw(fromJson(postRequest(auth, path, gson.toJson(request)), GithubRepoRaw.class), GithubRepo.class);
}
+ /*
+ * Open issues only
+ */
@NotNull
public static List<GithubIssue> getIssuesAssigned(@NotNull GithubAuthData auth,
@NotNull String user,
@NotNull String repo,
- @Nullable String assigned) throws IOException {
+ @Nullable String assigned,
+ int max) throws IOException {
String path;
if (StringUtil.isEmptyOrSpaces(assigned)) {
path = "/repos/" + user + "/" + repo + "/issues?" + PER_PAGE;
@@ -550,10 +559,17 @@
PagedRequest<GithubIssue> request = new PagedRequest<GithubIssue>(path, GithubIssue.class, GithubIssueRaw[].class);
- return request.getAll(auth);
+ List<GithubIssue> result = new ArrayList<GithubIssue>();
+ while (request.hasNext() && max > result.size()) {
+ result.addAll(request.next(auth));
+ }
+ return result;
}
@NotNull
+ /*
+ * All issues - open and closed
+ */
public static List<GithubIssue> getIssuesQueried(@NotNull GithubAuthData auth,
@NotNull String user,
@NotNull String repo,
@@ -601,6 +617,32 @@
}
@NotNull
+ public static List<GithubCommitComment> getCommitComments(@NotNull GithubAuthData auth,
+ @NotNull String user,
+ @NotNull String repo,
+ @NotNull String sha) throws IOException {
+ String path = "/repos/" + user + "/" + repo + "/commits/" + sha + "/comments";
+
+ PagedRequest<GithubCommitComment> request =
+ new PagedRequest<GithubCommitComment>(path, GithubCommitComment.class, GithubCommitCommentRaw[].class, ACCEPT_HTML_BODY_MARKUP);
+
+ return request.getAll(auth);
+ }
+
+ @NotNull
+ public static List<GithubCommitComment> getPullRequestComments(@NotNull GithubAuthData auth,
+ @NotNull String user,
+ @NotNull String repo,
+ long id) throws IOException {
+ String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/comments";
+
+ PagedRequest<GithubCommitComment> request =
+ new PagedRequest<GithubCommitComment>(path, GithubCommitComment.class, GithubCommitCommentRaw[].class, ACCEPT_HTML_BODY_MARKUP);
+
+ return request.getAll(auth);
+ }
+
+ @NotNull
public static GithubPullRequest getPullRequest(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, int id)
throws IOException {
String path = "/repos/" + user + "/" + repo + "/pulls/" + id;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitComment.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitComment.java
new file mode 100644
index 0000000..1f13de7
--- /dev/null
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitComment.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.github.api;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Date;
+
+/**
+ * @author Aleksey Pivovarov
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class GithubCommitComment {
+ @NotNull private final String myHtmlUrl;
+
+ private final long myId;
+ @NotNull private final String mySha;
+ @NotNull private final String myPath;
+ private final long myPosition; // line number in diff
+ @NotNull private final String myBodyHtml;
+
+ @NotNull private final GithubUser myUser;
+
+ @NotNull private final Date myCreatedAt;
+ @NotNull private final Date myUpdatedAt;
+
+ public GithubCommitComment(@NotNull String htmlUrl,
+ long id,
+ @NotNull String sha,
+ @NotNull String path,
+ long position,
+ @NotNull String bodyHtml,
+ @NotNull GithubUser user,
+ @NotNull Date createdAt,
+ @NotNull Date updatedAt) {
+ myHtmlUrl = htmlUrl;
+ myId = id;
+ mySha = sha;
+ myPath = path;
+ myPosition = position;
+ myBodyHtml = bodyHtml;
+ myUser = user;
+ myCreatedAt = createdAt;
+ myUpdatedAt = updatedAt;
+ }
+
+ @NotNull
+ public String getHtmlUrl() {
+ return myHtmlUrl;
+ }
+
+ public long getId() {
+ return myId;
+ }
+
+ @NotNull
+ public String getSha() {
+ return mySha;
+ }
+
+ @NotNull
+ public String getPath() {
+ return myPath;
+ }
+
+ public long getPosition() {
+ return myPosition;
+ }
+
+ @NotNull
+ public String getBodyHtml() {
+ return myBodyHtml;
+ }
+
+ @NotNull
+ public GithubUser getUser() {
+ return myUser;
+ }
+
+ @NotNull
+ public Date getCreatedAt() {
+ return myCreatedAt;
+ }
+
+ @NotNull
+ public Date getUpdatedAt() {
+ return myUpdatedAt;
+ }
+}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitCommentRaw.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitCommentRaw.java
new file mode 100644
index 0000000..229b31a
--- /dev/null
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitCommentRaw.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.github.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Date;
+
+/**
+ * @author Aleksey Pivovarov
+ */
+class GithubCommitCommentRaw implements DataConstructor {
+ @Nullable public String htmlUrl;
+ @Nullable public String url;
+
+ @Nullable public Long id;
+ @Nullable public String commitId;
+ @Nullable public String path;
+ @Nullable public Long position;
+ @Nullable public Long line;
+ @Nullable public String body;
+ @Nullable public String bodyHtml;
+
+ @Nullable public GithubUserRaw user;
+
+ @Nullable public Date createdAt;
+ @Nullable public Date updatedAt;
+
+ @SuppressWarnings("ConstantConditions")
+ @NotNull
+ public GithubCommitComment createCommitComment() {
+ return new GithubCommitComment(htmlUrl, id, commitId, path, position, bodyHtml, user.createUser(), createdAt, updatedAt);
+ }
+
+ @SuppressWarnings("unchecked")
+ @NotNull
+ @Override
+ public <T> T create(@NotNull Class<T> resultClass) {
+ if (resultClass.isAssignableFrom(GithubCommitComment.class)) {
+ return (T)createCommitComment();
+ }
+
+ throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java b/plugins/github/src/org/jetbrains/plugins/github/exceptions/GithubRateLimitExceededException.java
similarity index 65%
copy from plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java
copy to plugins/github/src/org/jetbrains/plugins/github/exceptions/GithubRateLimitExceededException.java
index 6830246..66272f4 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/exceptions/GithubRateLimitExceededException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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,13 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn.properties;
+package org.jetbrains.plugins.github.exceptions;
+
+import java.io.IOException;
/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/12/12
- * Time: 8:40 PM
+ * @author Aleksey Pivovarov
*/
-public class SvnPropDetailsProvider {
+public class GithubRateLimitExceededException extends IOException {
+ public GithubRateLimitExceededException(String message) {
+ super(message);
+ }
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java
index f4e4554..b975956 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java
@@ -20,6 +20,7 @@
import org.jetbrains.plugins.github.api.GithubApiUtil;
import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException;
import org.jetbrains.plugins.github.exceptions.GithubJsonException;
+import org.jetbrains.plugins.github.exceptions.GithubRateLimitExceededException;
import org.jetbrains.plugins.github.exceptions.GithubStatusCodeException;
import org.jetbrains.plugins.github.util.GithubAuthData;
import org.jetbrains.plugins.github.util.GithubUtil;
@@ -85,7 +86,10 @@
@Override
public Task[] getIssues(@Nullable String query, int max, long since) throws Exception {
try {
- return getIssues(query);
+ return getIssues(query, max);
+ }
+ catch (GithubRateLimitExceededException e) {
+ return new Task[0];
}
catch (GithubAuthenticationException e) {
throw new Exception(e.getMessage(), e);
@@ -99,13 +103,13 @@
}
@NotNull
- private Task[] getIssues(@Nullable String query) throws Exception {
+ private Task[] getIssues(@Nullable String query, int max) throws Exception {
List<GithubIssue> issues;
if (StringUtil.isEmptyOrSpaces(query)) {
if (StringUtil.isEmptyOrSpaces(myUser)) {
myUser = GithubApiUtil.getCurrentUser(getAuthData()).getLogin();
}
- issues = GithubApiUtil.getIssuesAssigned(getAuthData(), getRepoAuthor(), getRepoName(), myUser);
+ issues = GithubApiUtil.getIssuesAssigned(getAuthData(), getRepoAuthor(), getRepoName(), myUser, max);
}
else {
issues = GithubApiUtil.getIssuesQueried(getAuthData(), getRepoAuthor(), getRepoName(), query);
@@ -266,6 +270,7 @@
public void setToken(@NotNull String token) {
myToken = token;
+ setUser("");
}
@Tag("token")
diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
index 2a83c85..c926943 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
@@ -65,7 +65,6 @@
myHost.getDocument().addDocumentListener(buttonUpdater);
myRepoAuthor.getDocument().addDocumentListener(buttonUpdater);
myRepoName.getDocument().addDocumentListener(buttonUpdater);
- myURLText.getDocument().addDocumentListener(buttonUpdater);
}
@Nullable
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form
index b540bd9..b166fce 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form
+++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form
@@ -47,7 +47,9 @@
</component>
<component id="5a680" class="com.intellij.openapi.ui.ComboBox" binding="myAuthTypeComboBox">
<constraints>
- <grid row="0" column="3" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="3" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="120" height="-1"/>
+ </grid>
</constraints>
<properties/>
</component>
@@ -143,7 +145,7 @@
<text value="Test"/>
</properties>
</component>
- <component id="b276a" class="com.intellij.ui.components.JBLabel">
+ <component id="b276a" class="com.intellij.ui.components.JBLabel" binding="myAuthTypeLabel">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
index 365fa2f..26cbbf6 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
@@ -33,6 +33,7 @@
import org.jetbrains.plugins.github.api.GithubUser;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.HyperlinkEvent;
@@ -64,6 +65,7 @@
private JTextField myHostTextField;
private ComboBox myAuthTypeComboBox;
private JPanel myCardPanel;
+ private JBLabel myAuthTypeLabel;
private boolean myCredentialsModified;
@@ -75,10 +77,10 @@
BrowserUtil.browse(e.getURL());
}
});
- mySignupTextField.setText(
- "<html>Do not have an account at github.com? <a href=\"https://github.com\">" + "Sign up" + "</a></html>");
+ mySignupTextField.setText("<html>Do not have an account at github.com? <a href=\"https://github.com\">" + "Sign up" + "</a></html>");
mySignupTextField.setBackground(myPane.getBackground());
mySignupTextField.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ myAuthTypeLabel.setBorder(new EmptyBorder(0, 10, 0, 0));
myAuthTypeComboBox.addItem(AUTH_PASSWORD);
myAuthTypeComboBox.addItem(AUTH_TOKEN);
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistContentTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistContentTest.java
index e5bc04b..f5cae2a 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistContentTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistContentTest.java
@@ -30,9 +30,9 @@
* @author Aleksey Pivovarov
*/
public class GithubCreateGistContentTest extends GithubCreateGistTestBase {
+
@Override
- public void setUp() throws Exception {
- super.setUp();
+ protected void beforeTest() throws Exception {
createProjectFiles();
}
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java
index b564267..150e7e8 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java
@@ -38,20 +38,14 @@
protected String GIST_DESCRIPTION;
@Override
- public void setUp() throws Exception {
- super.setUp();
+ protected void beforeTest() throws Exception {
long time = Clock.getTime();
GIST_DESCRIPTION = getTestName(false) + "_" + DateFormatUtil.formatDate(time);
}
@Override
- public void tearDown() throws Exception {
- try {
- deleteGist();
- }
- finally {
- super.tearDown();
- }
+ protected void afterTest() throws Exception {
+ deleteGist();
}
protected void deleteGist() throws IOException {
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java
index 24bb780..9db5ba8 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java
@@ -41,9 +41,7 @@
protected String BRANCH_NAME;
@Override
- public void setUp() throws Exception {
- super.setUp();
-
+ protected void beforeTest() throws Exception {
Random rnd = new Random();
long time = Clock.getTime();
BRANCH_NAME = "branch_" + getTestName(false) + "_" + DateFormatUtil.formatDate(time).replace('/', '-') + "_" + rnd.nextLong();
@@ -58,13 +56,8 @@
}
@Override
- public void tearDown() throws Exception {
- try {
- deleteRemoteBranch();
- }
- finally {
- super.tearDown();
- }
+ protected void afterTest() throws Exception {
+ deleteRemoteBranch();
}
protected void deleteRemoteBranch() {
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java
new file mode 100644
index 0000000..1b47169
--- /dev/null
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.github;
+
+import com.intellij.openapi.util.Comparing;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.plugins.github.api.GithubApiUtil;
+import org.jetbrains.plugins.github.api.GithubIssue;
+import org.jetbrains.plugins.github.test.GithubTest;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Aleksey Pivovarov
+ */
+public class GithubIssuesTest extends GithubTest {
+ private static final String REPO_NAME = "IssuesTest";
+
+ public void testAssigneeIssues1() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesAssigned(myAuth, myLogin2, REPO_NAME, myLogin1, 100);
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(6L, 7L, 8L);
+
+ assertTrue(Comparing.haveEqualElements(issues, expected));
+ }
+
+ public void testAssigneeIssues2() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesAssigned(myAuth, myLogin2, REPO_NAME, myLogin2, 100);
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(1L, 2L);
+
+ assertTrue(Comparing.haveEqualElements(issues, expected));
+ }
+
+ public void testAssigneeIssues3() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesAssigned(myAuth, myLogin2, REPO_NAME, "", 100);
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(1L, 2L, 5L, 6L, 7L, 8L, 9L, 10L, 11L);
+
+ assertTrue(Comparing.haveEqualElements(issues, expected));
+ }
+
+ public void testQueriedIssues1() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesQueried(myAuth, myLogin2, REPO_NAME, "abracadabra");
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(10L, 12L);
+
+ assertContainsElements(issues, expected);
+ }
+
+ public void testQueriedIssues2() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesQueried(myAuth, myLogin2, REPO_NAME, "commentary");
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(11L);
+
+ assertContainsElements(issues, expected);
+ }
+}
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubRequestPagingTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubRequestPagingTest.java
index c72cbc3..4fec0d1c 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubRequestPagingTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubRequestPagingTest.java
@@ -28,9 +28,9 @@
* @author Aleksey Pivovarov
*/
public class GithubRequestPagingTest extends GithubTest {
+
@Override
- protected void setUp() throws Exception {
- super.setUp();
+ protected void beforeTest() throws Exception {
assumeNotNull(myLogin2);
}
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java b/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java
index 4eee8e1..5dd9b21 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java
@@ -35,9 +35,7 @@
protected String PROJECT_NAME;
@Override
- public void setUp() throws Exception {
- super.setUp();
-
+ protected void beforeTest() throws Exception {
Random rnd = new Random();
long time = Clock.getTime();
PROJECT_NAME = "new_project_from_" + getTestName(false) + "_" + DateFormatUtil.formatDate(time).replace('/', '-') + "_" + rnd.nextLong();
@@ -45,13 +43,8 @@
}
@Override
- public void tearDown() throws Exception {
- try {
- deleteGithubRepo();
- }
- finally {
- super.tearDown();
- }
+ protected void afterTest() throws Exception {
+ deleteGithubRepo();
}
protected void deleteGithubRepo() throws IOException {
diff --git a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
index 0f2da38..2c9496e 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
@@ -56,9 +56,11 @@
* <li>Project base directory is the root of everything. </li>
* </ul></p>
* <p>All tests inherited from this class are required to have a login and a password to access the Github server.
- * They are set up in System properties: <br/>
- * <code>-Dtest.github.login=mylogin<br/>
- * -Dtest.github.password=mypassword</code>
+ * They are set up in Environment variables: <br/>
+ * <code>idea.test.github.host=myHost<br/>
+ * idea.test.github.login1=mylogin1<br/> // test user
+ * idea.test.github.login2=mylogin2<br/> // user with configured test repositories
+ * idea.test.github.password=mypassword</code> // password for test user
* </p>
*
* @author Kirill Likhodedov
@@ -173,7 +175,7 @@
}
@Override
- protected void setUp() throws Exception {
+ protected final void setUp() throws Exception {
final String host = System.getenv("idea.test.github.host");
final String login1 = System.getenv("idea.test.github.login1");
final String login2 = System.getenv("idea.test.github.login2");
@@ -186,8 +188,14 @@
super.setUp();
- myProjectFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getTestName(true)).getFixture();
- myProjectFixture.setUp();
+ try {
+ myProjectFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getTestName(true)).getFixture();
+ myProjectFixture.setUp();
+ }
+ catch (Exception e) {
+ super.tearDown();
+ throw e;
+ }
myProject = myProjectFixture.getProject();
myProjectRoot = myProject.getBaseDir();
@@ -209,17 +217,39 @@
myHttpAuthService = (GitHttpAuthTestService)ServiceManager.getService(GitHttpAuthService.class);
myGitRepositoryManager = GitUtil.getRepositoryManager(myProject);
+
+ try {
+ beforeTest();
+ }
+ catch (Exception e) {
+ try {
+ tearDown();
+ }
+ catch (Exception e2) {
+ e2.printStackTrace();
+ }
+ throw e;
+ }
}
@Override
- protected void tearDown() throws Exception {
- myHttpAuthService.cleanup();
- myDialogManager.cleanup();
- myNotificator.cleanup();
+ protected final void tearDown() throws Exception {
+ try {
+ afterTest();
+ }
+ finally {
+ myHttpAuthService.cleanup();
+ myDialogManager.cleanup();
+ myNotificator.cleanup();
- myProjectFixture.tearDown();
- super.tearDown();
+ myProjectFixture.tearDown();
+ super.tearDown();
+ }
}
+ protected void beforeTest() throws Exception {
+ }
+ protected void afterTest() throws Exception {
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
index 669bc3a..5367556 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
@@ -111,8 +111,8 @@
initControls();
content.add(myUseWrapperButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
- content.add(myUseLocalDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
content.add(myUseBundledDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
+ content.add(myUseLocalDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
content.add(myGradleHomeLabel, ExternalSystemUiUtil.getLabelConstraints(indentLevel));
content.add(myGradleHomePathField, ExternalSystemUiUtil.getFillLineConstraints(0));
diff --git a/plugins/groovy/jetgroovy.iml b/plugins/groovy/jetgroovy.iml
index d8531ae..bd8506c 100644
--- a/plugins/groovy/jetgroovy.iml
+++ b/plugins/groovy/jetgroovy.iml
@@ -34,6 +34,7 @@
<orderEntry type="module" module-name="junit" scope="TEST" />
<orderEntry type="module" module-name="java-indexing-api" />
<orderEntry type="module" module-name="groovy-jps-plugin" />
+ <orderEntry type="module" module-name="ByteCodeViewer" />
</component>
</module>
diff --git a/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/after.groovy.template
new file mode 100644
index 0000000..1862911
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/after.groovy.template
@@ -0,0 +1 @@
+<spot>def</spot> list = ['a', 'b', 'c']
\ No newline at end of file
diff --git a/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/before.groovy.template
new file mode 100644
index 0000000..9cc469c
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/before.groovy.template
@@ -0,0 +1 @@
+<spot>ArrayList<String></spot> list = ['a', 'b', 'c']
\ No newline at end of file
diff --git a/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/description.html b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/description.html
new file mode 100644
index 0000000..f3c976c
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/description.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+This intention removes explicit type elements from variables and methods
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 926402f..1a086861 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -26,6 +26,7 @@
<depends optional="true" config-file="intellilang-groovy-support.xml">org.intellij.intelliLang</depends>
<depends optional="true">AntSupport</depends>
<depends optional="true">cucumber</depends>
+ <depends optional="true">ByteCodeViewer</depends>
<extensionPoints>
<extensionPoint name="methodComparator" interface="org.jetbrains.plugins.groovy.lang.resolve.GrMethodComparator"/>
@@ -1393,6 +1394,11 @@
<categoryKey>intention.category.groovy/intention.category.groovy.other</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.other.GrCopyStringConcatenationContentIntention</className>
</intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy/intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrRemoveExplicitTypeDeclarationIntention</className>
+ </intentionAction>
<projectService serviceInterface="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicToolWindowWrapper"
serviceImplementation="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicToolWindowWrapper"/>
@@ -1431,6 +1437,10 @@
<codeFragmentFactory implementation="org.jetbrains.plugins.groovy.debugger.GroovyCodeFragmentFactory"/>
</extensions>
+ <extensions defaultExtensionNs="ByteCodeViewer">
+ <classSearcher implementation="org.jetbrains.plugins.groovy.byteCodeViewer.GroovyScriptClassSearcher"/>
+ </extensions>
+
<actions>
<action id="Groovy.Shell.Execute" class="com.intellij.openapi.actionSystem.EmptyAction" text="Execute Groovy Code"
description="Execute Groovy code in console">
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/byteCodeViewer/GroovyScriptClassSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/byteCodeViewer/GroovyScriptClassSearcher.java
new file mode 100644
index 0000000..3365dc5
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/byteCodeViewer/GroovyScriptClassSearcher.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.byteCodeViewer;
+
+import com.intellij.byteCodeViewer.ClassSearcher;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiTypeParameter;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
+
+/**
+ * Created by Max Medvedev on 8/23/13
+ */
+public class GroovyScriptClassSearcher implements ClassSearcher {
+ @Nullable
+ @Override
+ public PsiClass findClass(@NotNull PsiElement place) {
+ if (place.getLanguage() == GroovyFileType.GROOVY_LANGUAGE) {
+ PsiClass containingClass = PsiTreeUtil.getParentOfType(place, PsiClass.class, false);
+ while (containingClass instanceof PsiTypeParameter) {
+ containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
+ }
+ if (containingClass != null) return containingClass;
+
+ PsiFile file = place.getContainingFile();
+ if (file instanceof GroovyFile && ((GroovyFile)file).isScript()) {
+ return ((GroovyFile)file).getScriptClass();
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingGettersInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingGettersInspection.java
index 9570fb6..c66b967 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingGettersInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingGettersInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -57,6 +57,7 @@
return GroovyInspectionBundle.message("getter.0.clashes.with.getter.1", args);
}
+ @NotNull
@Override
protected BaseInspectionVisitor buildVisitor() {
return new BaseInspectionVisitor() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyAnnotationNamingConventionInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyAnnotationNamingConventionInspection.java
index 62b21ed..dfaca8f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyAnnotationNamingConventionInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyAnnotationNamingConventionInspection.java
@@ -20,7 +20,6 @@
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnnotationTypeDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
public class GroovyAnnotationNamingConventionInspection extends ConventionInspection {
@@ -32,7 +31,7 @@
return "Annotation naming convention";
}
- protected GroovyFix buildFix(PsiElement location) {
+ protected GroovyFix buildFix(@NotNull PsiElement location) {
return new RenameFix();
}
@@ -63,18 +62,15 @@
return DEFAULT_MAX_LENGTH;
}
+ @NotNull
public BaseInspectionVisitor buildVisitor() {
return new NamingConventionsVisitor();
}
private class NamingConventionsVisitor extends BaseInspectionVisitor {
-
- public void visitTypeDefinition(GrTypeDefinition grTypeDefinition) {
- super.visitTypeDefinition(grTypeDefinition);
- if (!(grTypeDefinition instanceof GrAnnotationTypeDefinition)) {
- return;
- }
- final GrAnnotationTypeDefinition aClass = (GrAnnotationTypeDefinition) grTypeDefinition;
+ @Override
+ public void visitAnnotationTypeDefinition(GrAnnotationTypeDefinition aClass) {
+ super.visitAnnotationTypeDefinition(aClass);
final String name = aClass.getName();
if (name == null) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyClassNamingConventionInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyClassNamingConventionInspection.java
index 66937b0..cc48722 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyClassNamingConventionInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyClassNamingConventionInspection.java
@@ -20,7 +20,6 @@
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrClassDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
public class GroovyClassNamingConventionInspection extends ConventionInspection {
@@ -32,7 +31,7 @@
return "Class naming convention";
}
- protected GroovyFix buildFix(PsiElement location) {
+ protected GroovyFix buildFix(@NotNull PsiElement location) {
return new RenameFix();
}
@@ -63,26 +62,23 @@
return DEFAULT_MAX_LENGTH;
}
+ @NotNull
public BaseInspectionVisitor buildVisitor() {
return new NamingConventionsVisitor();
}
private class NamingConventionsVisitor extends BaseInspectionVisitor {
-
- public void visitTypeDefinition(GrTypeDefinition grTypeDefinition) {
- super.visitTypeDefinition(grTypeDefinition);
- if (!(grTypeDefinition instanceof GrClassDefinition)) {
- return;
- }
- GrClassDefinition aClass = (GrClassDefinition) grTypeDefinition;
- final String name = aClass.getName();
+ @Override
+ public void visitClassDefinition(GrClassDefinition classDefinition) {
+ super.visitClassDefinition(classDefinition);
+ final String name = classDefinition.getName();
if (name == null) {
return;
}
if (isValid(name)) {
return;
}
- registerClassError(aClass, name);
+ registerClassError(classDefinition, name);
}
}
}
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyEnumerationNamingConventionInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyEnumerationNamingConventionInspection.java
index a53d2ed..15aa51b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyEnumerationNamingConventionInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyEnumerationNamingConventionInspection.java
@@ -20,7 +20,6 @@
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumTypeDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
public class GroovyEnumerationNamingConventionInspection extends ConventionInspection {
@@ -32,7 +31,7 @@
return "Enumeration naming convention";
}
- protected GroovyFix buildFix(PsiElement location) {
+ protected GroovyFix buildFix(@NotNull PsiElement location) {
return new RenameFix();
}
@@ -63,27 +62,24 @@
return DEFAULT_MAX_LENGTH;
}
+ @NotNull
public BaseInspectionVisitor buildVisitor() {
return new NamingConventionsVisitor();
}
private class NamingConventionsVisitor extends BaseInspectionVisitor {
+ @Override
+ public void visitEnumDefinition(GrEnumTypeDefinition aClass) {
+ super.visitEnumDefinition(aClass);
- public void visitTypeDefinition(GrTypeDefinition grTypeDefinition) {
- super.visitTypeDefinition(grTypeDefinition);
- if (!(grTypeDefinition instanceof GrEnumTypeDefinition)) {
- return;
- }
- final GrEnumTypeDefinition aClass = (GrEnumTypeDefinition) grTypeDefinition;
-
- final String name = aClass.getName();
- if (name == null) {
- return;
- }
- if (isValid(name)) {
- return;
- }
- registerClassError(aClass, name);
+ final String name = aClass.getName();
+ if (name == null) {
+ return;
}
+ if (isValid(name)) {
+ return;
+ }
+ registerClassError(aClass, name);
+ }
}
}
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyInterfaceNamingConventionInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyInterfaceNamingConventionInspection.java
index 832a888..188995a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyInterfaceNamingConventionInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyInterfaceNamingConventionInspection.java
@@ -20,7 +20,6 @@
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrInterfaceDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
public class GroovyInterfaceNamingConventionInspection extends ConventionInspection {
@@ -32,7 +31,7 @@
return "Interface naming convention";
}
- protected GroovyFix buildFix(PsiElement location) {
+ protected GroovyFix buildFix(@NotNull PsiElement location) {
return new RenameFix();
}
@@ -63,18 +62,15 @@
return DEFAULT_MAX_LENGTH;
}
+ @NotNull
public BaseInspectionVisitor buildVisitor() {
return new NamingConventionsVisitor();
}
private class NamingConventionsVisitor extends BaseInspectionVisitor {
-
- public void visitTypeDefinition(GrTypeDefinition grTypeDefinition) {
- super.visitTypeDefinition(grTypeDefinition);
- if (!(grTypeDefinition instanceof GrInterfaceDefinition)) {
- return;
- }
- final GrInterfaceDefinition aClass = (GrInterfaceDefinition) grTypeDefinition;
+ @Override
+ public void visitInterfaceDefinition(GrInterfaceDefinition aClass) {
+ super.visitInterfaceDefinition(aClass);
final String name = aClass.getName();
if (name == null) {
@@ -85,5 +81,6 @@
}
registerClassError(aClass, name);
}
+
}
}
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java
index 985632a..3bc8412 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java
@@ -695,7 +695,7 @@
@Override
public void unregister(@NotNull Condition<IntentionAction> condition) {
if (myInfo != null) {
- QuickFixAction.unregisterQuickFixAction(myInfo, condition);
+ myInfo.unregisterQuickFix(condition);
}
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java
index fa4aaf3..f499eb1 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java
@@ -691,17 +691,15 @@
@Nullable
public static GrControlFlowOwner findControlFlowOwner(PsiElement place) {
- if (place instanceof GrCodeBlock) {
- place = place.getContext();
- }
- while (true) {
- assert place != null;
- place = place.getContext();
- if (place == null) return null;
+ place = place.getContext();
+ while (place != null) {
if (place instanceof GrControlFlowOwner && ((GrControlFlowOwner)place).isTopControlFlowOwner()) return (GrControlFlowOwner)place;
if (place instanceof GrMethod) return ((GrMethod)place).getBlock();
if (place instanceof GrClassInitializer) return ((GrClassInitializer)place).getBlock();
+
+ place = place.getContext();
}
+ return null;
}
/**
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java
index ae2972e..3d3f6e4 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java
@@ -4,6 +4,7 @@
import com.intellij.psi.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.PairFunction;
+import com.intellij.util.SingletonInstancesCache;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -11,7 +12,6 @@
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil;
-import org.jetbrains.plugins.groovy.util.ClassInstanceCache;
import org.jetbrains.plugins.groovy.util.FixedValuesReferenceProvider;
import java.lang.reflect.Modifier;
@@ -253,7 +253,7 @@
@NotNull
public PairFunction<GrMethodCall, PsiMethod, PsiType> getReturnTypeCalculator() {
if (myReturnTypeCalculatorInstance == null) {
- myReturnTypeCalculatorInstance = ClassInstanceCache.getInstance(myReturnTypeCalculatorClassName, myClassLoader);
+ myReturnTypeCalculatorInstance = SingletonInstancesCache.getInstance(myReturnTypeCalculatorClassName, myClassLoader);
}
return myReturnTypeCalculatorInstance;
}
@@ -286,7 +286,7 @@
public GroovyNamedArgumentProvider getNamedArgProvider() {
if (myNamedArgProviderInstance == null) {
- myNamedArgProviderInstance = ClassInstanceCache.getInstance(myNamedArgProviderClassName, myClassLoader);
+ myNamedArgProviderInstance = SingletonInstancesCache.getInstance(myNamedArgProviderClassName, myClassLoader);
}
return myNamedArgProviderInstance;
}
@@ -328,7 +328,7 @@
private Object doGetProvider(ClassLoader classLoader) {
if (myProviderClassName != null) {
- return ClassInstanceCache.getInstance(myProviderClassName, classLoader);
+ return SingletonInstancesCache.getInstance(myProviderClassName, classLoader);
}
return new FixedValuesReferenceProvider(myValues);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
index 49f772d..fc19f64 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
@@ -202,4 +202,6 @@
replace.if.with.ternary.intention.name=Replace with ?:
replace.if.with.ternary.intention.family.name=Replace if-statement with ternary operator
gr.redundant.else.intention.name=Remove redundant 'else' keyword
-gr.redundant.else.intention.family.name=Remove redundant 'else' keyword
\ No newline at end of file
+gr.redundant.else.intention.family.name=Remove redundant 'else' keyword
+gr.remove.explicit.type.declaration.intention.name=Remove explicit type
+gr.remove.explicit.type.declaration.intention.family.name=Remove explicit type declaration
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrRemoveExplicitTypeDeclarationIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrRemoveExplicitTypeDeclarationIntention.java
new file mode 100644
index 0000000..5f530705
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrRemoveExplicitTypeDeclarationIntention.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.intentions.declaration;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.intentions.base.Intention;
+import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
+import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
+
+/**
+ * Created by Max Medvedev on 8/24/13
+ */
+public class GrRemoveExplicitTypeDeclarationIntention extends Intention {
+ @Override
+ protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
+ PsiElement parent = element.getParent();
+
+ if (parent instanceof GrVariable) {
+ ((GrVariable)parent).setType(null);
+ }
+ else if (parent instanceof GrVariableDeclaration) {
+ ((GrVariableDeclaration)parent).setType(null);
+ }
+ else if (parent instanceof GrMethod) {
+ ((GrMethod)parent).setReturnType(null);
+ }
+ }
+
+ @NotNull
+ @Override
+ protected PsiElementPredicate getElementPredicate() {
+ return new PsiElementPredicate() {
+ @Override
+ public boolean satisfiedBy(PsiElement element) {
+ PsiElement parent = element.getParent();
+ if (element instanceof GrTypeElement || element instanceof GrModifierList) {
+ return parent instanceof GrVariableDeclaration && ((GrVariableDeclaration)parent).getTypeElementGroovy() != null ||
+ parent instanceof GrMethod && ((GrMethod)parent).getReturnTypeElementGroovy() != null;
+ }
+
+ if (parent instanceof GrNamedElement && ((GrNamedElement)parent).getNameIdentifierGroovy().equals(element)) {
+ if (parent instanceof GrVariable) {
+ return ((GrVariable)parent).getTypeElementGroovy() != null;
+ }
+
+ if (parent instanceof GrMethod) {
+ return ((GrMethod)parent).getReturnTypeElementGroovy() != null;
+ }
+ }
+
+ return false;
+ }
+ };
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java
index a145b17..642b646 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java
@@ -26,6 +26,7 @@
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
import org.jetbrains.plugins.groovy.intentions.base.Intention;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
@@ -81,6 +82,9 @@
if (methods.size() == 1) {
final Pair<PsiMethod, GrOpenBlock> pair = methods.get(0);
appendClosureTextByMethod(pair.getFirst(), buffer, pair.getSecond(), newExpr);
+ if (!GroovyConfigUtils.getInstance().isVersionAtLeast(psiElement, GroovyConfigUtils.GROOVY2_2)) {
+ buffer.append(" as ").append(iface.getQualifiedName());
+ }
}
else {
buffer.append("[");
@@ -97,8 +101,9 @@
buffer.append('\n');
}
buffer.append("]");
+ buffer.append(" as ").append(iface.getQualifiedName());
}
- buffer.append(" as ").append(iface.getQualifiedName());
+
createAndAdjustNewExpression(project, newExpr, buffer);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java
index e362cba..06b53a4 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java
@@ -255,6 +255,26 @@
visitElement(typeDefinition);
}
+ public void visitClassDefinition(GrClassDefinition classDefinition) {
+ visitTypeDefinition(classDefinition);
+ }
+
+ public void visitEnumDefinition(GrEnumTypeDefinition enumDefinition) {
+ visitTypeDefinition(enumDefinition);
+ }
+
+ public void visitInterfaceDefinition(GrInterfaceDefinition interfaceDefinition) {
+ visitTypeDefinition(interfaceDefinition);
+ }
+
+ public void visitAnonymousClassDefinition(GrAnonymousClassDefinition anonymousClassDefinition) {
+ visitTypeDefinition(anonymousClassDefinition);
+ }
+
+ public void visitAnnotationTypeDefinition(GrAnnotationTypeDefinition annotationTypeDefinition) {
+ visitTypeDefinition(annotationTypeDefinition);
+ }
+
public void visitExtendsClause(GrExtendsClause extendsClause) {
visitElement(extendsClause);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
index 28dfd6d..b9a3a27 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
@@ -96,7 +96,9 @@
final GrTypeElement typeElement = getTypeElementGroovy();
if (type == null) {
if (typeElement == null) return;
- getModifierList().setModifierProperty(GrModifier.DEF, true);
+ if (getModifierList().getModifiers().length == 0) {
+ getModifierList().setModifierProperty(GrModifier.DEF, true);
+ }
typeElement.delete();
return;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java
index 74df206..4331046b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java
@@ -16,10 +16,12 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks;
+import com.intellij.extapi.psi.ASTDelegatePsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.intellij.psi.ResolveState;
+import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.LazyParseablePsiElement;
import com.intellij.psi.impl.source.tree.LeafElement;
@@ -60,6 +62,17 @@
}
@Override
+ public void delete() throws IncorrectOperationException {
+ if (getParent() instanceof ASTDelegatePsiElement) {
+ CheckUtil.checkWritable(this);
+ ((ASTDelegatePsiElement)getParent()).deleteChildInternal(getNode());
+ }
+ else {
+ getParent().deleteChildRange(this, this);
+ }
+ }
+
+ @Override
public void removeElements(PsiElement[] elements) throws IncorrectOperationException {
GroovyPsiElementImpl.removeElements(this, elements);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnnotationTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnnotationTypeDefinitionImpl.java
index 47d849f..16d52d0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnnotationTypeDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnnotationTypeDefinitionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -19,10 +19,11 @@
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiClassType;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnnotationTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub;
-import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
/**
* @author Dmitry.Krasilschikov
@@ -61,4 +62,9 @@
private PsiClassType createAnnotationType() {
return TypesUtil.createTypeByFQClassName("java.lang.annotation.Annotation", this);
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitAnnotationTypeDefinition(this);
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java
index 495603b..aa7876a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -26,6 +26,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
@@ -250,4 +251,10 @@
public PsiIdentifier getNameIdentifier() {
return null;
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitAnonymousClassDefinition(this);
+ }
+
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrClassDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrClassDefinitionImpl.java
index cafc779..2e0b3d9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrClassDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrClassDefinitionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -19,6 +19,7 @@
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrClassDefinition;
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub;
@@ -39,4 +40,9 @@
public String toString() {
return "Class definition";
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitClassDefinition(this);
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrEnumTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrEnumTypeDefinitionImpl.java
index 42308ec..56f4ffd 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrEnumTypeDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrEnumTypeDefinitionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -31,6 +31,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumDefinitionBody;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumTypeDefinition;
@@ -175,4 +176,9 @@
if (enumDefinitionBody != null) return enumDefinitionBody.getEnumConstantList();
return null;
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitEnumDefinition(this);
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrInterfaceDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrInterfaceDefinitionImpl.java
index d4fa5a8..d093bab 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrInterfaceDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrInterfaceDefinitionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -17,11 +17,11 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef;
import com.intellij.lang.ASTNode;
-import com.intellij.psi.stubs.IStubElementType;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrInterfaceDefinition;
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub;
-import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
/**
* @author Dmitry.Krasilschikov
@@ -44,4 +44,9 @@
public boolean isInterface() {
return true;
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitInterfaceDefinition(this);
+ }
}
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java
index 74443e4..2f757a8 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java
@@ -55,6 +55,7 @@
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
+import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.noncode.MixinMemberContributor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
@@ -226,7 +227,7 @@
final DelegatingScopeProcessor delegate = new MixinMemberContributor.MixinProcessor(processor, subjectType, qualifier);
for (GrMethod method : methods) {
- delegate.execute(method, ResolveState.initial());
+ ResolveUtil.processElement(delegate, method, state);
}
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/LocalVarAnalyzer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/LocalVarAnalyzer.java
index c130ec2..edb9c90 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/LocalVarAnalyzer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/LocalVarAnalyzer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java
index bed8605..83713e9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java
@@ -77,7 +77,7 @@
/**
* @author Maxim.Medvedev
*/
-public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSettings> implements RefactoringActionHandler {
+public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSettings, Scope extends PsiElement> implements RefactoringActionHandler {
public static final Function<GrExpression, String> GR_EXPRESSION_RENDERER = new Function<GrExpression, String>() {
@Override
public String fun(@NotNull GrExpression expr) {
@@ -124,7 +124,7 @@
protected abstract String getHelpID();
@NotNull
- protected abstract PsiElement findScope(GrExpression expression, GrVariable variable, StringPartInfo stringPart);
+ protected abstract Scope[] findPossibleScopes(GrExpression expression, GrVariable variable, StringPartInfo stringPart, Editor editor);
protected abstract void checkExpression(@NotNull GrExpression selectedExpr) throws GrRefactoringError;
@@ -276,14 +276,41 @@
// Does nothing
}
- @NotNull
- public GrIntroduceContext getContext(@NotNull Project project,
- @NotNull Editor editor,
- @Nullable GrExpression expression,
- @Nullable GrVariable variable,
- @Nullable StringPartInfo stringPart) {
- final PsiElement scope = findScope(expression, variable, stringPart);
+ public void getContextAndInvoke(@NotNull final Project project,
+ @NotNull final Editor editor,
+ @Nullable final GrExpression expression,
+ @Nullable final GrVariable variable,
+ @Nullable final StringPartInfo stringPart) {
+ final Scope[] scopes = findPossibleScopes(expression, variable, stringPart, editor);
+ Pass<Scope> callback = new Pass<Scope>() {
+ @Override
+ public void pass(Scope scope) {
+ GrIntroduceContext context = getContext(project, editor, expression, variable, stringPart, scope);
+ invokeImpl(project, context, editor);
+ }
+ };
+
+ if (scopes.length == 0) {
+ CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage( getRefactoringName() + "is not available in current scope"),
+ getRefactoringName(), getHelpID());
+ }
+ else if (scopes.length == 1) {
+ callback.pass(scopes[0]);
+ }
+ else {
+ showScopeChooser(scopes, callback, editor);
+ }
+ }
+
+ protected abstract void showScopeChooser(Scope[] scopes, Pass<Scope> callback, Editor editor);
+
+ public GrIntroduceContext getContext(@NotNull Project project,
+ @NotNull Editor editor,
+ @Nullable GrExpression expression,
+ @Nullable GrVariable variable,
+ @Nullable StringPartInfo stringPart,
+ @NotNull PsiElement scope) {
if (variable != null) {
final List<PsiElement> list = Collections.synchronizedList(new ArrayList<PsiElement>());
ReferencesSearch.search(variable, new LocalSearchScope(scope)).forEach(new Processor<PsiReference>() {
@@ -309,42 +336,8 @@
}
}
- @NotNull
- protected PsiElement[] findOccurrences(@NotNull GrExpression expression, @NotNull PsiElement scope) {
- final PsiElement[] occurrences = GroovyRefactoringUtil.getExpressionOccurrences(PsiUtil.skipParentheses(expression, false), scope);
- if (occurrences == null || occurrences.length == 0) {
- throw new GrRefactoringError(GroovyRefactoringBundle.message("no.occurrences.found"));
- }
- return occurrences;
- }
-
- private boolean invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file, int startOffset, int endOffset) {
+ private boolean invokeImpl(final Project project, final GrIntroduceContext context, final Editor editor) {
try {
- PsiDocumentManager.getInstance(project).commitAllDocuments();
- if (!(file instanceof GroovyFileBase)) {
- throw new GrRefactoringError(GroovyRefactoringBundle.message("only.in.groovy.files"));
- }
- if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) {
- throw new GrRefactoringError(RefactoringBundle.message("readonly.occurences.found"));
- }
-
- GrExpression selectedExpr = findExpression(file, startOffset, endOffset);
- final GrVariable variable = findVariable(file, startOffset, endOffset);
- final StringPartInfo stringPart = StringPartInfo.findStringPart(file, startOffset, endOffset);
- if (variable != null) {
- checkVariable(variable);
- }
- else if (selectedExpr != null) {
- checkExpression(selectedExpr);
- }
- else if (stringPart != null) {
- checkStringLiteral(stringPart);
- }
- else {
- throw new GrRefactoringError(null);
- }
-
- final GrIntroduceContext context = getContext(project, editor, selectedExpr, variable, stringPart);
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, context.getOccurrences())) {
return false;
}
@@ -370,15 +363,21 @@
RangeMarker stringPartRangeMarker = createRange(document, context.getStringPart());
RangeMarker varRangeMarker = createRange(document, context.getVar());
- GrVariable var = ApplicationManager.getApplication().runWriteAction(new Computable<GrVariable>() {
- @Override
- public GrVariable compute() {
- return runRefactoring(context, settings);
- }
- });
+ SmartPsiElementPointer<GrVariable> pointer =
+ ApplicationManager.getApplication().runWriteAction(new Computable<SmartPsiElementPointer<GrVariable>>() {
+ @Override
+ public SmartPsiElementPointer<GrVariable> compute() {
+ GrVariable var = runRefactoring(context, settings);
+ return var != null
+ ? SmartPointerManager.getInstance(context.getProject()).createSmartPsiElementPointer(var)
+ : null;
+ }
+ });
+ GrVariable var = pointer != null ? pointer.getElement() : null;
if (isInplace && var != null) {
- GrInplaceIntroducer introducer = getIntroducer(var, context, settings, occurrences, varRangeMarker, expressionRangeMarker, stringPartRangeMarker);
+ GrInplaceIntroducer introducer =
+ getIntroducer(var, context, settings, occurrences, varRangeMarker, expressionRangeMarker, stringPartRangeMarker);
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
introducer.performInplaceRefactoring(introducer.suggestNames(context));
}
@@ -411,11 +410,53 @@
return true;
}
catch (GrRefactoringError e) {
- CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage(e.getMessage()), getRefactoringName(), getHelpID());
+ CommonRefactoringUtil
+ .showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage(e.getMessage()), getRefactoringName(), getHelpID());
return false;
}
}
+ @NotNull
+ protected PsiElement[] findOccurrences(@NotNull GrExpression expression, @NotNull PsiElement scope) {
+ final PsiElement[] occurrences = GroovyRefactoringUtil.getExpressionOccurrences(skipParentheses(expression, false), scope);
+ if (occurrences == null || occurrences.length == 0) {
+ throw new GrRefactoringError(GroovyRefactoringBundle.message("no.occurrences.found"));
+ }
+ return occurrences;
+ }
+
+ private void invoke(@NotNull final Project project,
+ @NotNull final Editor editor,
+ @NotNull PsiFile file,
+ int startOffset,
+ int endOffset) {
+ PsiDocumentManager.getInstance(project).commitAllDocuments();
+ if (!(file instanceof GroovyFileBase)) {
+ throw new GrRefactoringError(GroovyRefactoringBundle.message("only.in.groovy.files"));
+ }
+ if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) {
+ throw new GrRefactoringError(RefactoringBundle.message("readonly.occurences.found"));
+ }
+
+ GrExpression selectedExpr = findExpression(file, startOffset, endOffset);
+ final GrVariable variable = findVariable(file, startOffset, endOffset);
+ final StringPartInfo stringPart = StringPartInfo.findStringPart(file, startOffset, endOffset);
+ if (variable != null) {
+ checkVariable(variable);
+ }
+ else if (selectedExpr != null) {
+ checkExpression(selectedExpr);
+ }
+ else if (stringPart != null) {
+ checkStringLiteral(stringPart);
+ }
+ else {
+ throw new GrRefactoringError(null);
+ }
+
+ getContextAndInvoke(project, editor, selectedExpr, variable, stringPart);
+ }
+
private static RangeMarker createRange(Document document, StringPartInfo part) {
if (part == null) {
return null;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java
index 357fa87..05bd556 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java
@@ -15,7 +15,9 @@
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.constant;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.util.Pass;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.HelpID;
@@ -41,7 +43,7 @@
/**
* @author Maxim.Medvedev
*/
-public class GrIntroduceConstantHandler extends GrIntroduceHandlerBase<GrIntroduceConstantSettings> {
+public class GrIntroduceConstantHandler extends GrIntroduceHandlerBase<GrIntroduceConstantSettings, PsiElement> {
public static final String REFACTORING_NAME = "Introduce Constant";
@NotNull
@@ -58,9 +60,9 @@
@NotNull
@Override
- protected PsiElement findScope(GrExpression expression, GrVariable variable, StringPartInfo stringPart) {
+ public PsiElement[] findPossibleScopes(GrExpression expression, GrVariable variable, StringPartInfo stringPart, Editor editor) {
final PsiElement place = getCurrentPlace(expression, variable, stringPart);
- return place.getContainingFile();
+ return new PsiFile[]{place.getContainingFile()};
}
@Override
@@ -135,6 +137,11 @@
}
@Override
+ protected void showScopeChooser(PsiElement[] scopes, Pass<PsiElement> callback, Editor editor) {
+ //todo do nothing right now
+ }
+
+ @Override
protected boolean isInplace(GrIntroduceContext context) {
return false;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form
index 3ad6c01..96f32e5 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form
@@ -21,6 +21,7 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
+ <labelFor value="58f26"/>
<text value="&Initialize in:"/>
</properties>
</component>
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java
index 1081b61..27878e9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java
@@ -16,17 +16,21 @@
package org.jetbrains.plugins.groovy.refactoring.introduce.field;
import com.intellij.codeInsight.TestFrameworks;
+import com.intellij.codeInsight.navigation.NavigationUtil;
+import com.intellij.ide.util.PsiClassListCellRenderer;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.util.Pass;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
+import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
import com.intellij.refactoring.introduceField.IntroduceFieldHandler;
-import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,7 +55,7 @@
/**
* @author Maxim.Medvedev
*/
-public class GrIntroduceFieldHandler extends GrIntroduceHandlerBase<GrIntroduceFieldSettings> {
+public class GrIntroduceFieldHandler extends GrIntroduceHandlerBase<GrIntroduceFieldSettings, PsiClass> {
@NotNull
@Override
@@ -67,9 +71,23 @@
@NotNull
@Override
- protected PsiClass findScope(GrExpression expression, GrVariable variable, StringPartInfo partInfo) {
+ protected PsiClass[] findPossibleScopes(GrExpression expression,
+ GrVariable variable,
+ StringPartInfo partInfo,
+ Editor editor) {
PsiElement place = getCurrentPlace(expression, variable, partInfo);
- return ObjectUtils.assertNotNull(PsiUtil.getContextClass(place));
+ PsiClass aClass = PsiUtil.getContextClass(place);
+ if (aClass instanceof GroovyScriptClass) {
+ return new PsiClass[]{aClass};
+ }
+ else {
+ List<PsiClass> result = ContainerUtil.newArrayList(aClass);
+ while (aClass != null) {
+ aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class);
+ ContainerUtil.addIfNotNull(result, aClass);
+ }
+ return result.toArray(new PsiClass[result.size()]);
+ }
}
@Override
@@ -233,6 +251,19 @@
};
}
+ @Override
+ protected void showScopeChooser(PsiClass[] scopes, final Pass<PsiClass> callback, Editor editor) {
+ PsiElementProcessor<PsiClass> processor = new PsiElementProcessor<PsiClass>() {
+ @Override
+ public boolean execute(@NotNull PsiClass element) {
+ callback.pass(element);
+ return false;
+ }
+ };
+
+ NavigationUtil.getPsiElementPopup(scopes, new PsiClassListCellRenderer(), "Choose class to introduce field", processor).showInBestPositionFor(editor);
+ }
+
@NotNull
@Override
protected PsiElement[] findOccurrences(@NotNull GrExpression expression, @NotNull PsiElement scope) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java
index ff941be..3e3f688 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java
@@ -75,11 +75,12 @@
int expressionIndex = ArrayUtilRt.find(myOccurrences, myExpression);
final PsiElement[] replaced = processOccurrences();
- GrStatement anchor = getAnchor(replaced);
+ PsiElement replacedExpression = replaced[expressionIndex];
+ GrStatement anchor = getAnchor(replaced, replacedExpression);
RefactoringUtil.highlightAllOccurrences(myContext.getProject(), replaced, myContext.getEditor());
- return insertVariableDefinition(declaration, anchor, replaced[expressionIndex]);
+ return insertVariableDefinition(declaration, anchor, replacedExpression);
}
private void refreshPositionMarker(PsiElement e) {
@@ -206,8 +207,8 @@
}
@NotNull
- private GrStatement getAnchor(PsiElement[] replaced) {
- PsiElement anchor = GrIntroduceHandlerBase.findAnchor(replaced, myContext.getScope());
+ private GrStatement getAnchor(PsiElement[] replaced, PsiElement replacedExpression) {
+ PsiElement anchor = GrIntroduceHandlerBase.findAnchor(replaced, GroovyRefactoringUtil.getEnclosingContainer(replacedExpression));
if (!(anchor instanceof GrStatement)) {
StringBuilder error = new StringBuilder("scope:");
error.append(myContext.getScope());
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java
index 5ce7a09..c27df06 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java
@@ -16,7 +16,9 @@
package org.jetbrains.plugins.groovy.refactoring.introduce.variable;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.util.Pass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
@@ -25,8 +27,9 @@
import com.intellij.refactoring.util.CanonicalTypes;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
+import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
@@ -46,19 +49,20 @@
/**
* @author ilyas
*/
-public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyIntroduceVariableSettings> {
+public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyIntroduceVariableSettings, GrControlFlowOwner> {
public static final String DUMMY_NAME = "________________xxx_________________";
protected static final String REFACTORING_NAME = GroovyRefactoringBundle.message("introduce.variable.title");
private RangeMarker myPosition = null;
@NotNull
@Override
- protected PsiElement findScope(GrExpression selectedExpr, GrVariable variable, StringPartInfo stringPartInfo) {
+ protected GrControlFlowOwner[] findPossibleScopes(GrExpression selectedExpr,
+ GrVariable variable,
+ StringPartInfo stringPartInfo,
+ Editor editor) {
// Get container element
- final PsiElement scope = stringPartInfo != null
- ? GroovyRefactoringUtil.getEnclosingContainer(stringPartInfo.getLiteral())
- : GroovyRefactoringUtil.getEnclosingContainer(selectedExpr);
- if (scope == null || !(scope instanceof GroovyPsiElement)) {
+ final GrControlFlowOwner scope = ControlFlowUtils.findControlFlowOwner(stringPartInfo != null ? stringPartInfo.getLiteral() : selectedExpr);
+ if (scope == null) {
throw new GrRefactoringError(
GroovyRefactoringBundle.message("refactoring.is.not.supported.in.the.current.context", REFACTORING_NAME));
}
@@ -66,7 +70,7 @@
throw new GrRefactoringError(
GroovyRefactoringBundle.message("refactoring.is.not.supported.in.the.current.context", REFACTORING_NAME));
}
- return scope;
+ return new GrControlFlowOwner[]{scope};
}
protected void checkExpression(@NotNull GrExpression selectedExpr) {
@@ -187,6 +191,11 @@
};
}
+ @Override
+ protected void showScopeChooser(GrControlFlowOwner[] scopes, Pass<GrControlFlowOwner> callback, Editor editor) {
+ //todo do nothing right now
+ }
+
@NotNull
private static GrVariableDeclaration generateDeclaration(@NotNull GrIntroduceContext context,
@NotNull GroovyIntroduceVariableSettings settings) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
index 3cdabe3..acac929 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
@@ -51,12 +51,14 @@
@Override
protected boolean isTestClass(PsiClass clazz, boolean canBePotential) {
return clazz.getLanguage() == GroovyFileType.GROOVY_LANGUAGE &&
- JUnitUtil.isTestClass(clazz) &&
+ //JUnitUtil.isTestClass(clazz) &&
InheritanceUtil.isInheritor(clazz, GroovyCommonClassNames.GROOVY_UTIL_TEST_CASE);
}
@Override
protected PsiMethod findSetUpMethod(@NotNull PsiClass clazz) {
+ if (!isTestClass(clazz, false)) return null;
+
for (PsiMethod method : clazz.getMethods()) {
if (method.getName().equals("setUp")) return method;
}
@@ -65,6 +67,8 @@
@Override
protected PsiMethod findTearDownMethod(@NotNull PsiClass clazz) {
+ if (!isTestClass(clazz, false)) return null;
+
for (PsiMethod method : clazz.getMethods()) {
if (method.getName().equals("tearDown")) return method;
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyUnwrapTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyUnwrapTest.groovy
index 867c343..a699922 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyUnwrapTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyUnwrapTest.groovy
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.jetbrains.plugins.groovy.lang
import com.intellij.codeInsight.unwrap.UnwrapHandler
@@ -51,13 +66,11 @@
}
public void testBraces() throws Exception {
- assertUnwrapped("""
+ assertUnwrapped("""\
<caret>{
def x = 1
}
-""", """
-def x = 1
-""");
+""", "def x = 1");
}
public void testUnwrapParameterUnderArgumentList() throws Exception {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy
index 6407c31..c481df1 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy
@@ -95,7 +95,7 @@
final ref = configureByText(text)
assertNotNull(ref)
final resolved = ref.resolve()
- assertInstanceOf(resolved, type)
+ if (type != null) assertInstanceOf(resolved, type)
return resolved
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy
index 8dc6697..f6ee5f0 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy
@@ -1431,6 +1431,30 @@
''', PsiMethod)
}
+ void testRuntimeMixin22() {
+ assertNull resolveByText('''\
+class ReentrantLock {}
+
+ReentrantLock.metaClass.withLock = { nestedCode -> }
+
+new ReentrantLock().withLock {
+ fo<caret>o(3)
+}
+''')
+ }
+
+ void testRuntimeMixin23() {
+ assertNotNull resolveByText('''\
+class ReentrantLock {}
+
+ReentrantLock.metaClass.withLock = { nestedCode -> }
+
+new ReentrantLock().withLock {
+ withL<caret>ock(2)
+}
+''')
+ }
+
void testRunnableVsCallable() {
final PsiMethod method = resolveByText('''\
import java.util.concurrent.Callable
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/IntroduceConstantTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/IntroduceConstantTest.java
index f51e02a..77bc4a1 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/IntroduceConstantTest.java
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/IntroduceConstantTest.java
@@ -18,6 +18,7 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
@@ -86,7 +87,8 @@
final GrExpression expression = findExpression();
final GrVariable variable = findVariable();
final StringPartInfo stringPart = findStringPart();
- final GrIntroduceContext context = handler.getContext(getProject(), editor, expression, variable, stringPart);
+ PsiElement[] scopes = handler.findPossibleScopes(expression, variable, stringPart, editor);
+ final GrIntroduceContext context = handler.getContext(getProject(), editor, expression, variable, stringPart, scopes[0]);
PsiClass targetClass;
if (targetClassName == null) {
diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/f2.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/f2.test
index 7e89dbf..f1a15b4 100644
--- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/f2.test
+++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/f2.test
@@ -4,5 +4,5 @@
-----
def preved = boo
for (i in 1..preved<caret>){
- def foo = boo
+ def foo = preved
}
\ No newline at end of file
diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop7.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop7.test
index ca3771e..e8869c6 100644
--- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop7.test
+++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop7.test
@@ -4,5 +4,5 @@
-----
def preved = true
while (preved<caret>) {
- true
+ preved
}
\ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
index 371fc70..9c68605 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
@@ -221,10 +221,11 @@
// The original file exists so this is a duplication of the file.
// Don't create the before ContentRevision or IDEA will think
// this was a rename.
+ //todo: fix this unexpected status behavior (sometimes added status instead of copied, and copied instead of renamed )
processChange(
null,
HgCurrentContentRevision.create(afterFile, currentNumber),
- HgChangeProvider.COPIED,
+ FileStatus.ADDED,
builder,
vcsKey
);
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
index 60d7a43..37488f3 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
@@ -8,6 +8,7 @@
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
@@ -209,9 +210,8 @@
}
@Override
- public PsiReference[] getValueReferences(XmlAttributeValue value) {
- String s = value.getValue();
- return s != null && !s.startsWith("${") ? super.getValueReferences(value) : PsiReference.EMPTY_ARRAY;
+ public PsiReference[] getValueReferences(XmlElement element, @NotNull String text) {
+ return !text.startsWith("${") ? super.getValueReferences(element, text) : PsiReference.EMPTY_ARRAY;
}
@Override
diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java b/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
index 2bebb05..21828ec 100644
--- a/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
+++ b/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -63,6 +63,8 @@
@Override
@Nullable
protected PsiMethod findSetUpMethod(@NotNull PsiClass clazz) {
+ if (!JUnitUtil.isJUnit3TestClass(clazz)) return null;
+
for (PsiMethod each : clazz.getMethods()) {
if (each.getName().equals("setUp")) return each;
}
@@ -72,6 +74,8 @@
@Override
@Nullable
protected PsiMethod findTearDownMethod(@NotNull PsiClass clazz) {
+ if (!JUnitUtil.isJUnit3TestClass(clazz)) return null;
+
for (PsiMethod each : clazz.getMethods()) {
if (each.getName().equals("tearDown")) return each;
}
diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java
index 569d4b1..422e567 100644
--- a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java
+++ b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -492,7 +492,7 @@
final String fqName = myPattern.iterator().next();
return (fqName.contains("*") ? fqName : StringUtil.getShortName(fqName)) + (size > 1 ? " and " + (size - 1) + " more" : "");
}
- final String className = JavaExecutionUtil.getPresentableClassName(getMainClassName(), configurationModule);
+ final String className = JavaExecutionUtil.getPresentableClassName(getMainClassName());
if (TEST_METHOD.equals(TEST_OBJECT)) {
return className + '.' + getMethodName();
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencySystemPathConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencySystemPathConverter.java
index ae91be9..2641d41 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencySystemPathConverter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencySystemPathConverter.java
@@ -15,20 +15,18 @@
*/
package org.jetbrains.idea.maven.dom.converters;
-import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
-import com.intellij.psi.xml.XmlElement;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.CustomReferenceConverter;
import com.intellij.util.xml.GenericDomValue;
import com.intellij.util.xml.ResolvingConverter;
-import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.dom.references.MavenPathReferenceConverter;
import java.util.Collection;
import java.util.Collections;
@@ -54,63 +52,12 @@
@NotNull
public PsiReference[] createReferences(final GenericDomValue genericDomValue, final PsiElement element, final ConvertContext context) {
- XmlElement xmlElement = genericDomValue.getXmlElement();
-
- if (xmlElement != null && xmlElement.getText().contains("${")) return PsiReference.EMPTY_ARRAY;
-
- return createReferences(element, true);
- }
-
- @NotNull
- public static PsiReference[] createReferences(@NotNull final PsiElement psiElement, final boolean soft) {
- FileReferenceSet set = new MyFileReferenceSet(psiElement, soft);
-
- return set.getAllReferences();
- }
-
- private static class MyFileReferenceSet extends FileReferenceSet {
- private final boolean mySoft;
-
- public MyFileReferenceSet(PsiElement psiElement, boolean soft) {
- super(psiElement);
- mySoft = soft;
- }
-
- @Override
- public boolean isAbsolutePathReference() {
- return true;
- }
-
- @Override
- protected boolean isSoft() {
- return mySoft;
- }
-
- @NotNull
- @Override
- public Collection<PsiFileSystemItem> getDefaultContexts() {
- Collection<PsiFileSystemItem> systemItemCollection = super.getDefaultContexts();
- if (isAbsolutePathReference()) {
- VirtualFile vFile = LocalFileSystem.getInstance().getRoot();
-
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- assert vFile != null : ""; //
- }
-
- if (vFile != null) {
- final PsiDirectory directory = getElement().getManager().findDirectory(vFile);
-
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- assert directory != null : "for element: " + getElement().getText(); //
- }
-
- if (directory != null) {
- systemItemCollection = new THashSet<PsiFileSystemItem>(systemItemCollection);
- systemItemCollection.add(directory);
- }
- }
+ return MavenPathReferenceConverter.createReferences(genericDomValue, element, new Condition<PsiFileSystemItem>() {
+ @Override
+ public boolean value(PsiFileSystemItem item) {
+ return (item instanceof PsiDirectory) || item.getName().endsWith(".jar");
}
- return systemItemCollection;
- }
+ }, true);
}
}
+
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenUrlConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenUrlConverter.java
index c4f864a..d7a4ca4 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenUrlConverter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenUrlConverter.java
@@ -18,10 +18,10 @@
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.UrlPsiReference;
import com.intellij.util.xml.ConvertContext;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.maven.dom.references.MavenUrlPsiReference;
public class MavenUrlConverter extends MavenReferenceConverter<String> {
@Override
@@ -35,6 +35,6 @@
}
protected PsiReference createReference(PsiElement element, String text, TextRange range) {
- return new MavenUrlPsiReference(element, text, range);
+ return new UrlPsiReference(element);
}
}
\ No newline at end of file
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/repositories/MavenRepositoryConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/repositories/MavenRepositoryConverter.java
index 4b08baf..46fa023 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/repositories/MavenRepositoryConverter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/repositories/MavenRepositoryConverter.java
@@ -18,11 +18,10 @@
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.UrlPsiReference;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.GenericDomValue;
import com.intellij.util.xml.ResolvingConverter;
@@ -31,7 +30,6 @@
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.dom.converters.MavenUrlConverter;
import org.jetbrains.idea.maven.dom.model.MavenDomRepositoryBase;
-import org.jetbrains.idea.maven.dom.references.MavenUrlPsiReference;
import java.util.Collection;
import java.util.Collections;
@@ -77,9 +75,7 @@
@NotNull
@Override
public PsiReference[] createReferences(GenericDomValue value, final PsiElement element, final ConvertContext context) {
- String text = value.getStringValue();
- TextRange range = ElementManipulators.getValueTextRange(element);
- return new PsiReference[]{new MavenUrlPsiReference(element, text, range) {
+ return new PsiReference[]{new UrlPsiReference(element) {
@NotNull
@Override
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 56672d7..b136cf4 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
@@ -23,6 +23,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.Function;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomUtil;
@@ -33,6 +34,7 @@
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
import java.util.Collection;
+import java.util.Collections;
/**
* @author Sergey Evdokimov
@@ -52,6 +54,12 @@
public static PsiReference[] createReferences(final DomElement genericDomValue,
PsiElement element,
@NotNull final Condition<PsiFileSystemItem> fileFilter) {
+ return createReferences(genericDomValue, element, fileFilter, false);
+ }
+
+ public static PsiReference[] createReferences(final DomElement genericDomValue,
+ PsiElement element,
+ @NotNull final Condition<PsiFileSystemItem> fileFilter, boolean isAbsolutePath) {
ElementManipulator<PsiElement> manipulator = ElementManipulators.getManipulator(element);
TextRange range = manipulator.getRangeInElement(element);
String text = range.substring(element.getText());
@@ -88,7 +96,19 @@
String resolvedText = model == null ? text : MavenPropertyResolver.resolve(text, model);
if (resolvedText.equals(text)) {
- super.innerResolveInContext(resolvedText, context, result, caseSensitive);
+ if (getIndex() == 0 && resolvedText.length() == 2 && resolvedText.charAt(1) == ':') {
+ // it's root on windows, e.g. "C:"
+ VirtualFile file = LocalFileSystem.getInstance().findFileByPath(resolvedText + '/');
+ if (file != null) {
+ PsiDirectory psiDirectory = context.getManager().findDirectory(file);
+ if (psiDirectory != null) {
+ result.add(new PsiElementResolveResult(psiDirectory));
+ }
+ }
+ }
+ else {
+ super.innerResolveInContext(resolvedText, context, result, caseSensitive);
+ }
}
else {
VirtualFile contextFile = context.getVirtualFile();
@@ -117,6 +137,33 @@
}
};
+ if (isAbsolutePath) {
+ set.addCustomization(FileReferenceSet.DEFAULT_PATH_EVALUATOR_OPTION, new Function<PsiFile, Collection<PsiFileSystemItem>>() {
+ @Override
+ public Collection<PsiFileSystemItem> fun(PsiFile file) {
+ VirtualFile virtualFile = file.getVirtualFile();
+
+ if (virtualFile == null) {
+ return FileReferenceSet.ABSOLUTE_TOP_LEVEL.fun(file);
+ }
+
+ while (true) {
+ VirtualFile parent = virtualFile.getParent();
+ if (parent == null) break;
+ virtualFile = parent;
+ }
+
+ PsiDirectory root = file.getManager().findDirectory(virtualFile);
+
+ if (root == null) {
+ return FileReferenceSet.ABSOLUTE_TOP_LEVEL.fun(file);
+ }
+
+ return Collections.<PsiFileSystemItem>singletonList(root);
+ }
+ });
+ }
+
return set.getAllReferences();
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java
index 31380d2..69cd93e 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java
@@ -298,7 +298,7 @@
return false;
}
- manager.addManagedFiles(pomFiles);
+ manager.addManagedFilesOrUnignore(pomFiles);
return true;
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java
index defe2bf..047fc82 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java
@@ -1,10 +1,10 @@
package org.jetbrains.idea.maven.plugins.api;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.SingletonInstancesCache;
import org.jdom.Element;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.model.MavenPlugin;
-import org.jetbrains.plugins.groovy.util.ClassInstanceCache;
import java.util.Collection;
import java.util.List;
@@ -54,7 +54,8 @@
}
if (descriptor.propertyGenerator != null) {
- MavenPropertiesGenerator generator = ClassInstanceCache.getInstance(descriptor.propertyGenerator, descriptor.getLoaderForClass());
+ MavenPropertiesGenerator generator = SingletonInstancesCache
+ .getInstance(descriptor.propertyGenerator, descriptor.getLoaderForClass());
generator.generate(modelProperties, goal, plugin, cfgElement);
}
}
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 5564984..678f811 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
@@ -484,6 +484,11 @@
addManagedFilesWithProfiles(files, Collections.<String>emptyList());
}
+ public void addManagedFilesOrUnignore(@NotNull List<VirtualFile> files) {
+ removeIgnoredFilesPaths(MavenUtil.collectPaths(files));
+ addManagedFiles(files);
+ }
+
public void removeManagedFiles(@NotNull List<VirtualFile> files) {
myWatcher.removeManagedFiles(files);
}
@@ -629,6 +634,11 @@
myProjectsTree.setIgnoredFilesPaths(paths);
}
+ public void removeIgnoredFilesPaths(final Collection<String> paths) {
+ if (!isInitialized()) return;
+ myProjectsTree.removeIgnoredFilesPaths(paths);
+ }
+
public boolean getIgnoredState(@NotNull MavenProject project) {
if (!isInitialized()) return false;
return myProjectsTree.getIgnoredState(project);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java
index 721908c..81eb778 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java
@@ -112,7 +112,16 @@
@Override
public void moduleRemoved(Project project, Module module) {
MavenProject mavenProject = myManager.findProject(module);
- if (mavenProject != null) myManager.setIgnoredState(Collections.singletonList(mavenProject), true);
+ if (mavenProject != null && !myManager.isIgnored(mavenProject)) {
+ VirtualFile file = mavenProject.getFile();
+
+ if (myManager.isManagedFile(file) && myManager.getModules(mavenProject).isEmpty()) {
+ myManager.removeManagedFiles(Collections.singletonList(file));
+ }
+ else {
+ myManager.setIgnoredState(Collections.singletonList(mavenProject), true);
+ }
+ }
}
@Override
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
index 3a39929..a11d9cb 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
@@ -57,7 +57,7 @@
private final Lock myStructureWriteLock = myStructureLock.writeLock();
// TODO replace with sets
- private volatile List<String> myManagedFilesPaths = new ArrayList<String>();
+ private volatile Set<String> myManagedFilesPaths = new LinkedHashSet<String>();
private volatile List<String> myIgnoredFilesPaths = new ArrayList<String>();
private volatile List<String> myIgnoredFilesPatterns = new ArrayList<String>();
private volatile Pattern myIgnoredFilesPatternsCache;
@@ -91,7 +91,7 @@
try {
try {
if (!STORAGE_VERSION.equals(in.readUTF())) return null;
- result.myManagedFilesPaths = readCollection(in, new ArrayList<String>());
+ result.myManagedFilesPaths = readCollection(in, new LinkedHashSet<String>());
result.myIgnoredFilesPaths = readCollection(in, new ArrayList<String>());
result.myIgnoredFilesPatterns = readCollection(in, new ArrayList<String>());
result.myExplicitProfiles = readCollection(in, new THashSet<String>());
@@ -190,7 +190,7 @@
public void resetManagedFilesPathsAndProfiles(List<String> paths, Collection<String> profiles) {
synchronized (myStateLock) {
- myManagedFilesPaths = new ArrayList<String>(paths);
+ myManagedFilesPaths = new LinkedHashSet<String>(paths);
}
setExplicitProfiles(profiles);
}
@@ -243,6 +243,14 @@
});
}
+ public void removeIgnoredFilesPaths(final Collection<String> paths) {
+ doChangeIgnoreStatus(new Runnable() {
+ public void run() {
+ myIgnoredFilesPaths.removeAll(paths);
+ }
+ });
+ }
+
public boolean getIgnoredState(MavenProject project) {
synchronized (myStateLock) {
return myIgnoredFilesPaths.contains(project.getPath());
@@ -672,10 +680,12 @@
}
public boolean isManagedFile(String path) {
- for (String each : getManagedFilesPaths()) {
- if (FileUtil.pathsEqual(each, path)) return true;
+ synchronized (myStateLock) {
+ for (String each : myManagedFilesPaths) {
+ if (FileUtil.pathsEqual(each, path)) return true;
+ }
+ return false;
}
- return false;
}
public boolean isPotentialProject(String path) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java
index a7d6863..c2980a0 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java
@@ -31,7 +31,7 @@
public void actionPerformed(AnActionEvent e) {
final DataContext context = e.getDataContext();
MavenProjectsManager manager = MavenActionUtil.getProjectsManager(context);
- manager.addManagedFiles(Collections.singletonList(getSelectedFile(context)));
+ manager.addManagedFilesOrUnignore(Collections.singletonList(getSelectedFile(context)));
}
@Override
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java
index f4b12b8..4ebf81b1 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java
@@ -50,6 +50,6 @@
VirtualFile[] files = FileChooser.chooseFiles(singlePomSelection, project, fileToSelect);
if (files.length == 0) return;
- manager.addManagedFiles(Arrays.asList(files));
+ manager.addManagedFilesOrUnignore(Arrays.asList(files));
}
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenFrameworkSupportProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenFrameworkSupportProvider.java
index 01ea1fe..ec8b82c 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenFrameworkSupportProvider.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenFrameworkSupportProvider.java
@@ -66,7 +66,7 @@
VirtualFile existingPom = root.findChild(MavenConstants.POM_XML);
if (existingPom != null) {
- MavenProjectsManager.getInstance(module.getProject()).addManagedFiles(Collections.singletonList(existingPom));
+ MavenProjectsManager.getInstance(module.getProject()).addManagedFilesOrUnignore(Collections.singletonList(existingPom));
}
else {
prepareProjectStructure(model, root);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java
index f951597..7494bab 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java
@@ -117,7 +117,7 @@
if (myAggregatorProject == null) {
MavenProjectsManager manager = MavenProjectsManager.getInstance(project);
- manager.addManagedFiles(Collections.singletonList(pom));
+ manager.addManagedFilesOrUnignore(Collections.singletonList(pom));
}
if (myArchetype == null) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java
index a516632..53a486f 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java
@@ -126,6 +126,9 @@
}
MavenProjectsManager manager = MavenProjectsManager.getInstance(project);
+
+ manager.setIgnoredState(getParameters().mySelectedProjects, false);
+
manager.addManagedFilesWithProfiles(MavenUtil.collectFiles(getParameters().mySelectedProjects), selectedProfiles);
manager.waitForReadingCompletion();
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java
index 6185881..2b257d9 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java
@@ -31,6 +31,7 @@
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
+import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -661,6 +662,30 @@
checkHighlighting();
}
+ public void testCompletionSystemScopeDependenciesWithProperties() throws Throwable {
+ String libPath = myIndicesFixture.getRepositoryHelper().getTestDataPath("local1/junit/junit/4.0/junit-4.0.jar");
+
+ createProjectPom("<groupId>test</groupId>" +
+ "<artifactId>project</artifactId>" +
+ "<version>1</version>" +
+
+ "<properties>" +
+ " <depDir>" + new File(libPath).getParent() + "</depDir>" +
+ "</properties>" +
+
+ "<dependencies>" +
+ " <dependency>" +
+ " <groupId>xxx</groupId>" +
+ " <artifactId>xxx</artifactId>" +
+ " <version>xxx</version>" +
+ " <scope>system</scope>" +
+ " <systemPath>${depDir}/<caret></systemPath>" +
+ " </dependency>" +
+ "</dependencies>");
+
+ assertCompletionVariants(myProjectPom, "junit-4.0.jar");
+ }
+
public void testResolvingSystemScopeDependenciesFromSystemPath() throws Throwable {
String libPath = myIndicesFixture.getRepositoryHelper().getTestDataPath("local1/junit/junit/4.0/junit-4.0.jar");
diff --git a/plugins/svn4idea/bindSvn/bindSvn.iml b/plugins/svn4idea/bindSvn/bindSvn.iml
deleted file mode 100644
index 846587c..0000000
--- a/plugins/svn4idea/bindSvn/bindSvn.iml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="platform-api" />
- <orderEntry type="module" module-name="vcs-api" />
- <orderEntry type="module-library">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/lib/javahl.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/lib/javahlsrc.zip!/src" />
- </SOURCES>
- </library>
- </orderEntry>
- </component>
-</module>
-
diff --git a/plugins/svn4idea/bindSvn/lib/javahl.jar b/plugins/svn4idea/bindSvn/lib/javahl.jar
deleted file mode 100644
index a0c5370..0000000
--- a/plugins/svn4idea/bindSvn/lib/javahl.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/svn4idea/bindSvn/lib/javahlsrc.zip b/plugins/svn4idea/bindSvn/lib/javahlsrc.zip
deleted file mode 100644
index 9c50118..0000000
--- a/plugins/svn4idea/bindSvn/lib/javahlsrc.zip
+++ /dev/null
Binary files differ
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindClient.java b/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindClient.java
deleted file mode 100644
index c155b78..0000000
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindClient.java
+++ /dev/null
@@ -1,925 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.idea.svn;
-
-import org.tigris.subversion.javahl.*;
-
-import java.io.OutputStream;
-import java.util.Map;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/5/13
- * Time: 3:08 PM
- */
-public class SvnBindClient implements SVNClientInterface {
- private final String myExecutablePath;
- private CommitEventHandler myHandler;
- private AuthenticationCallback myAuthenticationCallback;
-
- public SvnBindClient(String path) {
- myExecutablePath = path;
- }
-
- @Override
- public void dispose() {
- }
-
- @Override
- public Version getVersion() {
- // todo real version
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getAdminDirectoryName() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isAdminDirectory(String name) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getLastPath() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Status singleStatus(String path, boolean onServer) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Status[] status(String path, boolean descend, boolean onServer, boolean getAll) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Status[] status(String path, boolean descend, boolean onServer, boolean getAll, boolean noIgnore) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Status[] status(String path, boolean descend, boolean onServer, boolean getAll, boolean noIgnore, boolean ignoreExternals)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void status(String path,
- int depth,
- boolean onServer,
- boolean getAll,
- boolean noIgnore,
- boolean ignoreExternals,
- String[] changelists,
- StatusCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public DirEntry[] list(String url, Revision revision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public DirEntry[] list(String url, Revision revision, Revision pegRevision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void list(String url,
- Revision revision,
- Revision pegRevision,
- int depth,
- int direntFields,
- boolean fetchLocks,
- ListCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void username(String username) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void password(String password) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setPrompt(PromptUserPassword prompt) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LogMessage[] logMessages(String path, Revision revisionStart, Revision revisionEnd) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LogMessage[] logMessages(String path, Revision revisionStart, Revision revisionEnd, boolean stopOnCopy) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LogMessage[] logMessages(String path, Revision revisionStart, Revision revisionEnd, boolean stopOnCopy, boolean discoverPath)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LogMessage[] logMessages(String path,
- Revision revisionStart,
- Revision revisionEnd,
- boolean stopOnCopy,
- boolean discoverPath,
- long limit) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void logMessages(String path,
- Revision pegRevision,
- Revision revisionStart,
- Revision revisionEnd,
- boolean stopOnCopy,
- boolean discoverPath,
- boolean includeMergedRevisions,
- String[] revProps,
- long limit,
- LogMessageCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void logMessages(String path,
- Revision pegRevision,
- RevisionRange[] ranges,
- boolean stopOnCopy,
- boolean discoverPath,
- boolean includeMergedRevisions,
- String[] revProps,
- long limit,
- LogMessageCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long checkout(String moduleName, String destPath, Revision revision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long checkout(String moduleName,
- String destPath,
- Revision revision,
- Revision pegRevision,
- boolean recurse,
- boolean ignoreExternals) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long checkout(String moduleName,
- String destPath,
- Revision revision,
- Revision pegRevision,
- int depth,
- boolean ignoreExternals,
- boolean allowUnverObstructions) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void notification(Notify notify) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void notification2(Notify2 notify) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setConflictResolver(ConflictResolverCallback listener) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setProgressListener(ProgressListener listener) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void commitMessageHandler(CommitMessage messageHandler) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void remove(String[] path, String message, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void remove(String[] path, String message, boolean force, boolean keepLocal, Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void revert(String path, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void revert(String path, int depth, String[] changelists) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void add(String path, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void add(String path, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void add(String path, int depth, boolean force, boolean noIgnores, boolean addParents) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long update(String path, Revision revision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long[] update(String[] path, Revision revision, boolean recurse, boolean ignoreExternals) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long update(String path,
- Revision revision,
- int depth,
- boolean depthIsSticky,
- boolean ignoreExternals,
- boolean allowUnverObstructions) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long[] update(String[] path,
- Revision revision,
- int depth,
- boolean depthIsSticky,
- boolean ignoreExternals,
- boolean allowUnverObstructions) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long commit(String[] path, String message, boolean recurse) throws ClientException {
- return commit(path, message, recurse? 3 : 0, false, false, null, null);
- }
-
- @Override
- public long commit(String[] path, String message, boolean recurse, boolean noUnlock) throws ClientException {
- return commit(path, message, recurse? 3 : 0, noUnlock, false, null, null);
- }
-
- @Override
- public long commit(String[] path,
- String message,
- int depth,
- boolean noUnlock,
- boolean keepChangelist,
- String[] changelists,
- Map revpropTable) throws ClientException {
- final long commit = new SvnCommitRunner(myExecutablePath, myHandler, myAuthenticationCallback).
- commit(path, message, depth, noUnlock, keepChangelist, changelists, revpropTable);
- if (commit < 0) {
- throw new BindClientException("Wrong committed revision number: " + commit, null, -1);
- }
- return commit;
- }
-
- @Override
- public void copy(CopySource[] sources,
- String destPath,
- String message,
- boolean copyAsChild,
- boolean makeParents,
- boolean ignoreExternals,
- Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void copy(CopySource[] sources, String destPath, String message, boolean copyAsChild, boolean makeParents, Map revpropTable)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void copy(String srcPath, String destPath, String message, Revision revision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void move(String[] srcPaths,
- String destPath,
- String message,
- boolean force,
- boolean moveAsChild,
- boolean makeParents,
- Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void move(String srcPath, String destPath, String message, Revision ignored, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void move(String srcPath, String destPath, String message, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void mkdir(String[] path, String message, boolean makeParents, Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void mkdir(String[] path, String message) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void cleanup(String path) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void resolve(String path, int depth, int conflictResult) throws SubversionException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void resolved(String path, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doExport(String srcPath, String destPath, Revision revision, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doExport(String srcPath,
- String destPath,
- Revision revision,
- Revision pegRevision,
- boolean force,
- boolean ignoreExternals,
- boolean recurse,
- String nativeEOL) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doExport(String srcPath,
- String destPath,
- Revision revision,
- Revision pegRevision,
- boolean force,
- boolean ignoreExternals,
- int depth,
- String nativeEOL) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doSwitch(String path, String url, Revision revision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doSwitch(String path,
- String url,
- Revision revision,
- Revision pegRevision,
- int depth,
- boolean depthIsSticky,
- boolean ignoreExternals,
- boolean allowUnverObstructions) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void doImport(String path, String url, String message, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void doImport(String path,
- String url,
- String message,
- int depth,
- boolean noIgnore,
- boolean ignoreUnknownNodeTypes,
- Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String[] suggestMergeSources(String path, Revision pegRevision) throws SubversionException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path1, Revision revision1, String path2, Revision revision2, String localPath, boolean force, boolean recurse)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path1,
- Revision revision1,
- String path2,
- Revision revision2,
- String localPath,
- boolean force,
- boolean recurse,
- boolean ignoreAncestry,
- boolean dryRun) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path1,
- Revision revision1,
- String path2,
- Revision revision2,
- String localPath,
- boolean force,
- int depth,
- boolean ignoreAncestry,
- boolean dryRun,
- boolean recordOnly) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path,
- Revision pegRevision,
- Revision revision1,
- Revision revision2,
- String localPath,
- boolean force,
- boolean recurse,
- boolean ignoreAncestry,
- boolean dryRun) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path,
- Revision pegRevision,
- RevisionRange[] revisions,
- String localPath,
- boolean force,
- int depth,
- boolean ignoreAncestry,
- boolean dryRun,
- boolean recordOnly) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void mergeReintegrate(String path, Revision pegRevision, String localPath, boolean dryRun) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Mergeinfo getMergeinfo(String path, Revision pegRevision) throws SubversionException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void getMergeinfoLog(int kind,
- String pathOrUrl,
- Revision pegRevision,
- String mergeSourceUrl,
- Revision srcPegRevision,
- boolean discoverChangedPaths,
- int depth,
- String[] revProps,
- LogMessageCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void getMergeinfoLog(int kind,
- String pathOrUrl,
- Revision pegRevision,
- String mergeSourceUrl,
- Revision srcPegRevision,
- boolean discoverChangedPaths,
- String[] revProps,
- LogMessageCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target1, Revision revision1, String target2, Revision revision2, String outFileName, boolean recurse)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target1,
- Revision revision1,
- String target2,
- Revision revision2,
- String outFileName,
- boolean recurse,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target1,
- Revision revision1,
- String target2,
- Revision revision2,
- String relativeToDir,
- String outFileName,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force,
- boolean copiesAsAdds) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target1,
- Revision revision1,
- String target2,
- Revision revision2,
- String relativeToDir,
- String outFileName,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target,
- Revision pegRevision,
- Revision startRevision,
- Revision endRevision,
- String outFileName,
- boolean recurse,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target,
- Revision pegRevision,
- Revision startRevision,
- Revision endRevision,
- String relativeToDir,
- String outFileName,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force,
- boolean copiesAsAdds) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target,
- Revision pegRevision,
- Revision startRevision,
- Revision endRevision,
- String relativeToDir,
- String outFileName,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diffSummarize(String target1,
- Revision revision1,
- String target2,
- Revision revision2,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- DiffSummaryReceiver receiver) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diffSummarize(String target,
- Revision pegRevision,
- Revision startRevision,
- Revision endRevision,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- DiffSummaryReceiver receiver) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData[] properties(String path) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData[] properties(String path, Revision revision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData[] properties(String path, Revision revision, Revision pegRevision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void properties(String path, Revision revision, Revision pegRevision, int depth, String[] changelists, ProplistCallback callback)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, String value, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, String value, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, byte[] value, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, byte[] value, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, String value, int depth, String[] changelists, boolean force, Map revpropTable)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyRemove(String path, String name, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyRemove(String path, String name, int depth, String[] changelists) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, String value, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, String value, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, byte[] value, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, byte[] value, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, String value, int depth, String[] changelists, boolean force)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData revProperty(String path, String name, Revision rev) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData[] revProperties(String path, Revision rev) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setRevProperty(String path, String name, Revision rev, String value, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setRevProperty(String path, String name, Revision rev, String value, String originalValue, boolean force)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData propertyGet(String path, String name) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData propertyGet(String path, String name, Revision revision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData propertyGet(String path, String name, Revision revision, Revision pegRevision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public byte[] fileContent(String path, Revision revision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public byte[] fileContent(String path, Revision revision, Revision pegRevision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void streamFileContent(String path, Revision revision, Revision pegRevision, int bufferSize, OutputStream stream)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void relocate(String from, String to, String path, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public byte[] blame(String path, Revision revisionStart, Revision revisionEnd) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void blame(String path, Revision revisionStart, Revision revisionEnd, BlameCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void blame(String path, Revision pegRevision, Revision revisionStart, Revision revisionEnd, BlameCallback callback)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void blame(String path,
- Revision pegRevision,
- Revision revisionStart,
- Revision revisionEnd,
- boolean ignoreMimeType,
- boolean includeMergedRevisions,
- BlameCallback2 callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void blame(String path,
- Revision pegRevision,
- Revision revisionStart,
- Revision revisionEnd,
- boolean ignoreMimeType,
- boolean includeMergedRevisions,
- BlameCallback3 callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setConfigDirectory(String configDir) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getConfigDirectory() throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void cancelOperation() throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Info info(String path) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addToChangelist(String[] paths, String changelist, int depth, String[] changelists) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void removeFromChangelists(String[] paths, int depth, String[] changelists) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void getChangelists(String rootPath, String[] changelists, int depth, ChangelistCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void lock(String[] path, String comment, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void unlock(String[] path, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Info2[] info2(String pathOrUrl, Revision revision, Revision pegRevision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void info2(String pathOrUrl, Revision revision, Revision pegRevision, int depth, String[] changelists, InfoCallback callback)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getVersionInfo(String path, String trailUrl, boolean lastChanged) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void upgrade(String path) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- public void setHandler(CommitEventHandler handler) {
- myHandler = handler;
- }
-
- public void setAuthenticationCallback(AuthenticationCallback authenticationCallback) {
- myAuthenticationCallback = authenticationCallback;
- }
-}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/status/LockWrapper.java b/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/status/LockWrapper.java
deleted file mode 100644
index f4e0f4c..0000000
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/status/LockWrapper.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.idea.svn.status;
-
-import org.apache.subversion.javahl.types.Lock;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Date;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/21/12
- * Time: 2:33 PM
- */
-public class LockWrapper {
- private String myPath;
- private String myID;
- private String myOwner;
- private String myComment;
- private Date myCreationDate;
- private Date myExpirationDate;
-
- public LockWrapper(String path, String ID, String owner, String comment, Date creationDate, Date expirationDate) {
- myPath = path;
- myID = ID;
- myOwner = owner;
- myComment = comment;
- myCreationDate = creationDate;
- myExpirationDate = expirationDate;
- }
-
- public LockWrapper() {
- }
-
- public String getPath() {
- return myPath;
- }
-
- public void setPath(String path) {
- myPath = path;
- }
-
- public String getID() {
- return myID;
- }
-
- public void setID(String ID) {
- myID = ID;
- }
-
- public String getOwner() {
- return myOwner;
- }
-
- public void setOwner(String owner) {
- myOwner = owner;
- }
-
- public String getComment() {
- return myComment;
- }
-
- public void setComment(String comment) {
- myComment = comment;
- }
-
- public Date getCreationDate() {
- return myCreationDate;
- }
-
- public void setCreationDate(Date creationDate) {
- myCreationDate = creationDate;
- }
-
- public Date getExpirationDate() {
- return myExpirationDate;
- }
-
- public void setExpirationDate(Date expirationDate) {
- myExpirationDate = expirationDate;
- }
-
- public org.tigris.subversion.javahl.Lock create() {
- final Date creation = getCreationDate();
- final Date expiration = getExpirationDate();
- final Lock newLock = new Lock(getOwner(), getPath(), getID(), getComment(), creation == null ? 0 : creation.getTime(),
- expiration == null ? 0 : expiration.getTime());
- try {
- final Constructor<org.tigris.subversion.javahl.Lock> constructor = org.tigris.subversion.javahl.Lock.class.getConstructor(Lock.class);
- constructor.setAccessible(true);
- return constructor.newInstance(newLock);
- }
- catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- }
- catch (InvocationTargetException e) {
- throw new RuntimeException(e);
- }
- catch (InstantiationException e) {
- throw new RuntimeException(e);
- }
- catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/plugins/svn4idea/bindSvn/src/org/tigris/subversion/javahl/BindClientException.java b/plugins/svn4idea/bindSvn/src/org/tigris/subversion/javahl/BindClientException.java
deleted file mode 100644
index f8acc17..0000000
--- a/plugins/svn4idea/bindSvn/src/org/tigris/subversion/javahl/BindClientException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.tigris.subversion.javahl;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/25/13
- * Time: 6:29 PM
- */
-public class BindClientException extends ClientException {
- private Throwable myCause;
-
- public BindClientException(String message, String source, int aprError) {
- super(message, source, aprError);
- }
-
- public BindClientException(org.apache.subversion.javahl.ClientException ex) {
- super(ex);
- }
-
- public static BindClientException create(@NotNull final Throwable t, final int code) {
- final BindClientException exception = new BindClientException(t.getMessage(), null, code);
- exception.myCause = t;
- return exception;
- }
-
- @Override
- public Throwable getCause() {
- return myCause;
- }
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/ForNestedRootChecker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/ForNestedRootChecker.java
index 4559a3e..6a62276 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/ForNestedRootChecker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/ForNestedRootChecker.java
@@ -49,11 +49,9 @@
private static class UrlConstructor {
final SvnVcs myVcs;
- final SVNWCClient myClient;
private UrlConstructor(final SvnVcs vcs) {
myVcs = vcs;
- myClient = myVcs.createWCClient();
}
@Nullable
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java
index 6cd0df2..5ca7f9e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java
@@ -123,52 +123,31 @@
@Nullable
private WorkingCopy calculateRoot(final VirtualFile root) {
+ File workingCopyRoot = SvnUtil.getWorkingCopyRootNew(new File(root.getPath()));
WorkingCopy workingCopy = null;
- final File ioFile = new File(root.getPath());
- File workingCopyRoot = null;
- try {
- workingCopyRoot = SVNWCUtil.getWorkingCopyRoot(ioFile, true);
- if (workingCopyRoot != null) {
- // ok to use low-level 1.6 API, 1.7 is checked below
- SVNWCAccess wcAccess = SVNWCAccess.newInstance(null);
- try {
- wcAccess.probeOpen(workingCopyRoot, false, 0);
- SVNEntry entry = wcAccess.getVersionedEntry(workingCopyRoot, false);
- final SVNURL url = entry.getSVNURL();
- if (url != null) {
- workingCopy = new WorkingCopy(workingCopyRoot, url, false);
- }
- } finally {
- wcAccess.close();
- }
+
+ if (workingCopyRoot != null) {
+ final SVNInfo svnInfo = myVcs.getInfo(workingCopyRoot);
+
+ if (svnInfo != null && svnInfo.getURL() != null) {
+ workingCopy = new WorkingCopy(workingCopyRoot, svnInfo.getURL(), true);
}
}
- catch (SVNException e) {
- //
- }
- if (workingCopy == null) {
- workingCopyRoot = SvnUtil.getWcCopyRootIf17(ioFile, null);
- if (workingCopyRoot != null) {
- final SVNInfo svnInfo;
- try {
- svnInfo = SvnVcs.getInstance(myProject).createWCClient().doInfo(workingCopyRoot, SVNRevision.UNDEFINED);
- workingCopy = new WorkingCopy(workingCopyRoot, svnInfo.getURL(), true);
- }
- catch (SVNException e) {
- //
- }
- }
- }
+
+ return registerWorkingCopy(root, workingCopy);
+ }
+
+ private WorkingCopy registerWorkingCopy(@NotNull VirtualFile root, @Nullable WorkingCopy resolvedWorkingCopy) {
synchronized (myLock) {
- if (workingCopy == null) {
+ if (resolvedWorkingCopy == null) {
myRootMapping.remove(root);
myUnversioned.add(root);
} else {
myUnversioned.remove(root);
- myRootMapping.put(root, workingCopy);
+ myRootMapping.put(root, resolvedWorkingCopy);
}
}
- return workingCopy;
+ return resolvedWorkingCopy;
}
public void clear() {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAbstractWriteOperationLocks.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAbstractWriteOperationLocks.java
index b4fd104..29e8742 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAbstractWriteOperationLocks.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAbstractWriteOperationLocks.java
@@ -36,6 +36,7 @@
* Date: 10/19/12
* Time: 12:09 PM
*/
+// TODO: Such locking functionality is not required anymore. Likely to be removed (together with SvnProxies).
public abstract class SvnAbstractWriteOperationLocks {
private final long myTimeout;
private final static Map<String, Lock> myLockMap = new HashMap<String, Lock>();
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java
index 8a94f00..4efcce6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java
@@ -350,7 +350,9 @@
}
SvnInteractiveAuthenticationProvider.clearCallState();
try {
+ // start svnkit authentication cycle
SvnVcs.getInstance(project).createWCClient(manager).doInfo(url, SVNRevision.UNDEFINED, SVNRevision.HEAD);
+ //SvnVcs.getInstance(project).getInfo(url, SVNRevision.HEAD, manager);
} catch (SVNAuthenticationException e) {
log(e);
return false;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
index c306386..61a5bb2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
@@ -537,6 +537,7 @@
dialog.show.svn.map.table.version15.text=1.5
dialog.show.svn.map.table.version16.text=1.6
dialog.show.svn.map.table.version17.text=1.7
+dialog.show.svn.map.table.version18.text=1.8
action.change.wcopy.format.task.title=Convert working copy format
action.change.wcopy.format.task.progress.text=Converting working copy at {0} format from {1} to {2}
action.change.wcopy.format.after.change.settings=Selected working copy format ({0}) is older than upgrade mode selected in Project Settings ({1}).\
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java
index dc8cbb1..b28ebd5 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java
@@ -85,7 +85,7 @@
statusReceiver.addListener(context);
statusReceiver.addListener(nestedCopiesBuilder);
- final SvnRecursiveStatusWalker walker = new SvnRecursiveStatusWalker(myVcs.getProject(), statusReceiver.getMulticaster(), partner);
+ final SvnRecursiveStatusWalker walker = new SvnRecursiveStatusWalker(myVcs, statusReceiver.getMulticaster(), partner);
for (FilePath path : zipper.getRecursiveDirs()) {
walker.go(path, SVNDepth.INFINITY);
@@ -180,7 +180,7 @@
public void getChanges(final FilePath path, final boolean recursive, final ChangelistBuilder builder) throws SVNException {
final SvnChangeProviderContext context = new SvnChangeProviderContext(myVcs, builder, null);
final StatusWalkerPartnerImpl partner = new StatusWalkerPartnerImpl(myVcs, ProgressManager.getInstance().getProgressIndicator());
- final SvnRecursiveStatusWalker walker = new SvnRecursiveStatusWalker(myVcs.getProject(), context, partner);
+ final SvnRecursiveStatusWalker walker = new SvnRecursiveStatusWalker(myVcs, context, partner);
walker.go(path, recursive ? SVNDepth.INFINITY : SVNDepth.IMMEDIATES);
processCopiedAndDeleted(context, null);
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
index 40c34d3..9689dce 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
@@ -259,23 +259,15 @@
public void addModifiedNotSavedChange(final VirtualFile file) throws SVNException {
final FilePath filePath = new FilePathImpl(file);
- final SVNInfo svnInfo;
- try {
- svnInfo = myVcs.createWCClient().doInfo(new File(file.getPath()), SVNRevision.UNDEFINED);
+ final SVNInfo svnInfo = myVcs.getInfo(file);
+
+ if (svnInfo != null) {
+ final SVNStatus svnStatus = new SVNStatus();
+ svnStatus.setRevision(svnInfo.getRevision());
+ myChangelistBuilder.processChangeInList(
+ createChange(SvnContentRevision.createBaseRevision(myVcs, filePath, svnInfo.getRevision()), CurrentContentRevision.create(filePath),
+ FileStatus.MODIFIED, svnStatus), (String)null, SvnVcs.getKey());
}
- catch (SVNException e) {
- final SVNErrorCode errorCode = e.getErrorMessage().getErrorCode();
- if (SVNErrorCode.WC_PATH_NOT_FOUND.equals(errorCode) ||
- SVNErrorCode.UNVERSIONED_RESOURCE.equals(errorCode) || SVNErrorCode.WC_NOT_WORKING_COPY.equals(errorCode)) {
- return;
- }
- throw e;
- }
- final SVNStatus svnStatus = new SVNStatus();
- svnStatus.setRevision(svnInfo.getRevision());
- myChangelistBuilder.processChangeInList(createChange(SvnContentRevision.createBaseRevision(myVcs, filePath, svnInfo.getRevision()),
- CurrentContentRevision.create(filePath), FileStatus.MODIFIED, svnStatus), (String) null,
- SvnVcs.getKey());
}
private void checkSwitched(final FilePath filePath, final ChangelistBuilder builder, final SVNStatus status,
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangelistListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangelistListener.java
index ee326a4..51d5dc4 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangelistListener.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangelistListener.java
@@ -176,11 +176,9 @@
}
@Nullable
- public static String getCurrentMapping(final Project project, final File file) {
- final SvnVcs vcs = SvnVcs.getInstance(project);
- final SVNStatusClient statusClient = vcs.createStatusClient();
+ public static String getCurrentMapping(final SvnVcs vcs, final File file) {
try {
- final SVNStatus status = statusClient.doStatus(file, false);
+ final SVNStatus status = vcs.getFactory(file).createStatusClient().doStatus(file, false);
return status == null ? null : status.getChangelistName();
}
catch (SVNException e) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form
index e4f0e7c..55f7512 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form
@@ -18,7 +18,7 @@
<properties/>
<border type="none"/>
<children>
- <grid id="2ae3a" layout-manager="GridLayoutManager" row-count="6" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="2ae3a" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<tabbedpane title="General"/>
@@ -29,7 +29,7 @@
<grid id="a4729" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="3" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -87,7 +87,7 @@
</grid>
<component id="df054" class="javax.swing.JCheckBox" binding="myUseDefaultCheckBox">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="org/jetbrains/idea/svn/SvnBundle" key="checkbox.configure.use.system.default.configuration.directory"/>
@@ -96,7 +96,7 @@
<grid id="137aa" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="5" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -123,36 +123,29 @@
</grid>
<hspacer id="e8f24">
<constraints>
- <grid row="5" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<vspacer id="aa6b2">
<constraints>
- <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
- <component id="300b5" class="javax.swing.JLabel">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="Subversion 1.7 Acceleration"/>
- </properties>
- </component>
<grid id="12735" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="3ecd1" class="com.intellij.ui.components.JBCheckBox" binding="myWithCommandLineClient">
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <text value="with command line client:"/>
+ <margin top="2" left="3" bottom="2" right="3"/>
+ <text value="Use command line client:"/>
</properties>
</component>
<component id="44a8" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myCommandLineClient">
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnContentRevision.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnContentRevision.java
index 38c099b..cff64be 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnContentRevision.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnContentRevision.java
@@ -31,6 +31,7 @@
import org.jetbrains.annotations.Nullable;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNStatus;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
import java.io.IOException;
@@ -113,7 +114,8 @@
if (lock.exists()) {
throw new VcsException("Can not access file base revision contents: administrative area is locked");
}
- return SvnUtil.getFileContents(myVcs, file.getPath(), false, myUseBaseRevision ? SVNRevision.BASE : myRevision, SVNRevision.UNDEFINED);
+ return SvnUtil.getFileContents(myVcs, SvnTarget.fromFile(file), myUseBaseRevision ? SVNRevision.BASE : myRevision,
+ SVNRevision.UNDEFINED);
}
@NotNull
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java
index 2a8a00a..813d41c 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java
@@ -17,6 +17,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.actions.VcsContextFactory;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.diff.DiffMixin;
@@ -26,8 +27,10 @@
import com.intellij.openapi.vcs.history.VcsRevisionDescriptionImpl;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
import org.jetbrains.idea.svn.history.LatestExistentSearcher;
import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.*;
@@ -43,19 +46,12 @@
}
public VcsRevisionNumber getCurrentRevision(VirtualFile file) {
- final SVNWCClient client = myVcs.createWCClient();
- try {
- final SVNInfo svnInfo = client.doInfo(new File(file.getPresentableUrl()), SVNRevision.UNDEFINED);
- if (svnInfo == null) return null;
- if (SVNRevision.UNDEFINED.equals(svnInfo.getCommittedRevision()) && svnInfo.getCopyFromRevision() != null) {
- return new SvnRevisionNumber(svnInfo.getCopyFromRevision());
- }
- return new SvnRevisionNumber(svnInfo.getRevision());
+ final SVNInfo svnInfo = myVcs.getInfo(new File(file.getPresentableUrl()));
+ if (svnInfo == null) return null;
+ if (SVNRevision.UNDEFINED.equals(svnInfo.getCommittedRevision()) && svnInfo.getCopyFromRevision() != null) {
+ return new SvnRevisionNumber(svnInfo.getCopyFromRevision());
}
- catch (SVNException e) {
- LOG.debug(e); // most likely the file is unversioned
- return null;
- }
+ return new SvnRevisionNumber(svnInfo.getRevision());
}
@Override
@@ -65,53 +61,36 @@
}
private VcsRevisionDescription getCurrentRevisionDescription(File path) {
- final SVNWCClient client = myVcs.createWCClient();
- try {
- final SVNInfo svnInfo = client.doInfo(path, SVNRevision.UNDEFINED);
-
- if (svnInfo.getCommittedRevision().equals(SVNRevision.UNDEFINED) && ! svnInfo.getCopyFromRevision().equals(SVNRevision.UNDEFINED) &&
+ final SVNInfo svnInfo = myVcs.getInfo(path);
+ if (svnInfo == null) {
+ return null;
+ }
+
+ if (svnInfo.getCommittedRevision().equals(SVNRevision.UNDEFINED) && !svnInfo.getCopyFromRevision().equals(SVNRevision.UNDEFINED) &&
svnInfo.getCopyFromURL() != null) {
- SVNURL copyUrl = svnInfo.getCopyFromURL();
- String localPath = myVcs.getSvnFileUrlMapping().getLocalPath(copyUrl.toString());
- if (localPath != null) {
- return getCurrentRevisionDescription(new File(localPath));
- }
+ SVNURL copyUrl = svnInfo.getCopyFromURL();
+ String localPath = myVcs.getSvnFileUrlMapping().getLocalPath(copyUrl.toString());
+ if (localPath != null) {
+ return getCurrentRevisionDescription(new File(localPath));
}
- final String message = getProperties(client, path);
+ }
+
+ try {
+ final String message = getCommitMessage(path);
return new VcsRevisionDescriptionImpl(new SvnRevisionNumber(svnInfo.getCommittedRevision()), svnInfo.getCommittedDate(),
svnInfo.getAuthor(), message);
}
- catch (SVNException e) {
+ catch (VcsException e) {
LOG.debug(e); // most likely the file is unversioned
return null;
}
}
- private String getProperties(SVNWCClient client, File path) throws SVNException {
- final String[] message = new String[1];
- client.doGetRevisionProperty(path, null, SVNRevision.BASE, new ISVNPropertyHandler() {
- @Override
- public void handleProperty(File path, SVNPropertyData property) throws SVNException {
- handle(property);
- }
+ private String getCommitMessage(File path) throws VcsException {
+ SVNPropertyData property =
+ myVcs.getFactory(path).createPropertyClient().getProperty(path, COMMIT_MESSAGE, true, null, SVNRevision.BASE);
- @Override
- public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
- handle(property);
- }
-
- @Override
- public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
- handle(property);
- }
-
- private void handle(SVNPropertyData data) {
- if (COMMIT_MESSAGE.equals(data.getName())) {
- message[0] = data.getValue().getString();
- }
- }
- });
- return message[0];
+ return property != null ? SVNPropertyValue.getPropertyAsString(property.getValue()) : null;
}
private static ItemLatestState defaultResult() {
@@ -135,18 +114,45 @@
return SvnContentRevision.createBaseRevision(myVcs, filePath, svnRevision);
}
}
+
// not clear why we need it, with remote check..
- final SVNStatusClient client = myVcs.createStatusClient();
- try {
- final SVNStatus svnStatus = client.doStatus(new File(selectedFile.getPresentableUrl()), false, false);
- if (svnRevision.equals(svnStatus.getRevision())) {
+ SVNStatus svnStatus = getFileStatus(new File(selectedFile.getPresentableUrl()), false);
+ if (svnStatus != null && svnRevision.equals(svnStatus.getRevision())) {
return SvnContentRevision.createBaseRevision(myVcs, filePath, svnRevision);
- }
+ }
+ return SvnContentRevision.createRemote(myVcs, filePath, svnRevision);
+ }
+
+ private SVNStatus getFileStatus(File file, boolean remote) {
+ WorkingCopyFormat format = myVcs.getWorkingCopyFormat(file);
+
+ return WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ? getStatusCommandLine(file, remote) : getStatusWithSvnKit(file, remote);
+ }
+
+ private SVNStatus getStatusWithSvnKit(File file, boolean remote) {
+ SVNStatus result = null;
+
+ try {
+ result = myVcs.createStatusClient().doStatus(file, remote, false);
}
catch (SVNException e) {
LOG.debug(e); // most likely the file is unversioned
}
- return SvnContentRevision.createRemote(myVcs, filePath, svnRevision);
+
+ return result;
+ }
+
+ private SVNStatus getStatusCommandLine(File file, boolean remote) {
+ SVNStatus result = null;
+
+ try {
+ result = new SvnCommandLineStatusClient(myVcs.getProject()).doStatus(file, remote, false);
+ }
+ catch (SVNException e) {
+ LOG.debug(e);
+ }
+
+ return result;
}
public ItemLatestState getLastRevision(FilePath filePath) {
@@ -159,36 +165,29 @@
}
private ItemLatestState getLastRevision(final File file) {
- final SVNStatusClient client = myVcs.createStatusClient();
- try {
- final SVNStatus svnStatus = client.doStatus(file, true);
- if (svnStatus == null || itemExists(svnStatus) && SVNRevision.UNDEFINED.equals(svnStatus.getRemoteRevision())) {
- // IDEADEV-21785 (no idea why this can happen)
- final SVNInfo info = myVcs.createWCClient().doInfo(file, SVNRevision.HEAD);
- if (info == null || info.getURL() == null) {
- LOG.info("No SVN status returned for " + file.getPath());
- return defaultResult();
- }
- return createResult(info.getCommittedRevision(), true, false);
+ final SVNStatus svnStatus = getFileStatus(file, true);
+ if (svnStatus == null || itemExists(svnStatus) && SVNRevision.UNDEFINED.equals(svnStatus.getRemoteRevision())) {
+ // IDEADEV-21785 (no idea why this can happen)
+ final SVNInfo info = myVcs.getInfo(file, SVNRevision.HEAD);
+ if (info == null || info.getURL() == null) {
+ LOG.info("No SVN status returned for " + file.getPath());
+ return defaultResult();
}
- final boolean exists = itemExists(svnStatus);
- if (! exists) {
- // get really latest revision
- final LatestExistentSearcher searcher = new LatestExistentSearcher(myVcs, svnStatus.getURL());
- final long revision = searcher.getDeletionRevision();
+ return createResult(info.getCommittedRevision(), true, false);
+ }
+ final boolean exists = itemExists(svnStatus);
+ if (! exists) {
+ // get really latest revision
+ final LatestExistentSearcher searcher = new LatestExistentSearcher(myVcs, svnStatus.getURL());
+ final long revision = searcher.getDeletionRevision();
- return createResult(SVNRevision.create(revision), exists, false);
- }
- final SVNRevision remoteRevision = svnStatus.getRemoteRevision();
- if (remoteRevision != null) {
- return createResult(remoteRevision, exists, false);
- }
- return createResult(svnStatus.getRevision(), exists, false);
+ return createResult(SVNRevision.create(revision), exists, false);
}
- catch (SVNException e) {
- LOG.debug(e); // most likely the file is unversioned
- return defaultResult();
+ final SVNRevision remoteRevision = svnStatus.getRemoteRevision();
+ if (remoteRevision != null) {
+ return createResult(remoteRevision, exists, false);
}
+ return createResult(svnStatus.getRevision(), exists, false);
}
private boolean itemExists(SVNStatus svnStatus) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java
index 062c412..da1adc6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java
@@ -44,10 +44,7 @@
import com.intellij.vcsUtil.ActionWithTempFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.tmatesoft.svn.core.SVNErrorCode;
-import org.tmatesoft.svn.core.SVNErrorMessage;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNNodeKind;
+import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import org.tmatesoft.svn.core.wc.*;
@@ -160,10 +157,10 @@
}
private class UUIDHelper {
- private final SVNWCClient myWcClient;
+ private final SvnVcs myVcs;
private UUIDHelper(final SvnVcs vcs) {
- myWcClient = vcs.createWCClient();
+ myVcs = vcs;
}
/**
@@ -175,7 +172,7 @@
final SVNInfo info1 = new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- myT = myWcClient.doInfo(new File(dir.getPath()), SVNRevision.UNDEFINED);
+ myT = myVcs.getInfo(new File(dir.getPath()));
}
}.compute();
if (info1 == null || info1.getRepositoryUUID() == null) {
@@ -244,10 +241,11 @@
long srcTime = src.lastModified();
try {
final boolean isUndo = isUndo(vcs);
- final String list = isUndo ? null : SvnChangelistListener.getCurrentMapping(vcs.getProject(), src);
+ final String list = isUndo ? null : SvnChangelistListener.getCurrentMapping(vcs, src);
- final boolean is17 = SvnUtil.is17CopyPart(src);
- if (is17) {
+ WorkingCopyFormat format = vcs.getWorkingCopyFormat(src);
+ final boolean is17OrLater = WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format);
+ if (is17OrLater) {
SVNStatus srcStatus = getFileStatus(vcs, src);
final File toDir = dst.getParentFile();
SVNStatus dstStatus = getFileStatus(vcs, toDir);
@@ -283,29 +281,18 @@
ourStatusesForUndoMove.add(SVNStatusType.STATUS_ADDED);
}
- private boolean for17move(SvnVcs vcs, final File src, final File dst, boolean undo, SVNStatus srcStatus) throws SVNException {
+ private boolean for17move(final SvnVcs vcs, final File src, final File dst, boolean undo, SVNStatus srcStatus) throws SVNException {
if (srcStatus != null && srcStatus.getCopyFromURL() == null) {
undo = false;
}
if (undo) {
myUndoingMove = true;
- final SVNWCClient wcClient = vcs.createWCClient();
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doRevert(dst, true);
- }
- }.execute();
+ createRevertAction(vcs, dst, true).execute();
copyUnversionedMembersOfDirectory(src, dst);
if (srcStatus == null || SvnVcs.svnStatusIsUnversioned(srcStatus)) {
FileUtil.delete(src);
} else {
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doRevert(src, true);
- }
- }.execute();
+ createRevertAction(vcs, src, true).execute();
}
restoreFromUndoStorage(dst);
} else {
@@ -317,15 +304,9 @@
copyFileOrDir(src, dst);
}
catch (IOException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
- final SVNWCClient wcClient = vcs.createWCClient();
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doDelete(src, true, false);
- }
- }.execute();
+ createDeleteAction(vcs, src, true).execute();
return false;
}
moveFileWithSvn(vcs, src, dst);
@@ -333,13 +314,16 @@
return false;
}
- public static void moveFileWithSvn(SvnVcs vcs, File src, final File dst) throws SVNException {
- final SVNCopyClient copyClient = vcs.createCopyClient();
- final SVNCopySource svnCopySource = new SVNCopySource(SVNRevision.UNDEFINED, SVNRevision.WORKING, src);
+ public static void moveFileWithSvn(final SvnVcs vcs, final File src, final File dst) throws SVNException {
new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- copyClient.doCopy(new SVNCopySource[]{svnCopySource}, dst, true, false, true);
+ try {
+ vcs.getFactory(src).createCopyMoveClient().copy(src, dst, false, true);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
}
}.execute();
}
@@ -357,7 +341,7 @@
copyFileOrDir(src, dst);
}
catch (IOException e) {
- exc[0] = new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ exc[0] = new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
return false;
}
}
@@ -464,7 +448,7 @@
* deleted: do nothing, return true (strange)
*/
public boolean delete(VirtualFile file) throws IOException {
- SvnVcs vcs = getVCS(file);
+ final SvnVcs vcs = getVCS(file);
if (vcs != null && SvnUtil.isAdminDirectory(file)) {
return true;
}
@@ -476,12 +460,8 @@
if (! SvnUtil.isSvnVersioned(vcs.getProject(), ioFile.getParentFile())) {
return false;
}
- try {
- if (SVNWCUtil.isWorkingCopyRoot(ioFile)) {
- return false;
- }
- } catch (SVNException e) {
- //
+ if (SvnUtil.isWorkingCopyRoot(ioFile)) {
+ return false;
}
SVNStatus status = getFileStatus(vcs, ioFile);
@@ -507,13 +487,7 @@
}
if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_ADDED)) {
try {
- final SVNWCClient wcClient = vcs.createWCClient();
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doRevert(ioFile, false);
- }
- }.execute();
+ createRevertAction(vcs, ioFile, false).execute();
}
catch (SVNException e) {
// ignore
@@ -529,6 +503,41 @@
}
}
+ @NotNull
+ private RepeatSvnActionThroughBusy createRevertAction(@NotNull final SvnVcs vcs, @NotNull final File file, final boolean recursive) {
+ return new RepeatSvnActionThroughBusy() {
+ @Override
+ protected void executeImpl() throws SVNException {
+ try {
+ vcs.getFactory(file).createRevertClient().revert(new File[]{file}, SVNDepth.fromRecurse(recursive), null);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
+ }
+ };
+ }
+
+ @NotNull
+ private RepeatSvnActionThroughBusy createDeleteAction(@NotNull final SvnVcs vcs, @NotNull final File file, final boolean force) {
+ return new RepeatSvnActionThroughBusy() {
+ @Override
+ protected void executeImpl() throws SVNException {
+ try {
+ vcs.getFactory(file).createDeleteClient().delete(file, force);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
+ }
+ };
+ }
+
+ private static void wrapAndThrow(VcsException e) throws SVNException {
+ // TODO: probably we should wrap into new exception only if e.getCause is not SVNException
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.FS_GENERAL, e), e);
+ }
+
private boolean isAboveSourceOfCopyOrMove(final Project p, File ioFile) {
for (MovedFileInfo file : myMovedFiles) {
if (FileUtil.isAncestor(ioFile, file.mySrc, false)) return true;
@@ -583,7 +592,6 @@
if (! SvnUtil.isSvnVersioned(vcs.getProject(), ioDir) && ! pendingAdd) {
return false;
}
- final SVNWCClient wcClient = vcs.createWCClient();
final File targetFile = new File(ioDir, name);
SVNStatus status = getFileStatus(vcs, targetFile);
@@ -603,12 +611,7 @@
}
try {
if (isUndo(vcs)) {
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doRevert(targetFile, false);
- }
- }.execute();
+ createRevertAction(vcs, targetFile, false).execute();
return true;
}
myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(dir, name, null, recursive));
@@ -759,8 +762,6 @@
return new Runnable() {
@Override
public void run() {
- final SVNWCClient wcClient = vcs.createWCClient();
- final SVNCopyClient copyClient = vcs.createCopyClient();
for(VirtualFile file: filesToProcess) {
final File ioFile = new File(file.getPath());
try {
@@ -771,11 +772,15 @@
protected void executeInternal() throws VcsException {
try {
// not recursive
- final SVNCopySource[] copySource = {new SVNCopySource(SVNRevision.WORKING, SVNRevision.WORKING, copyFrom)};
new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- copyClient.doCopy(copySource, ioFile, false, true, true);
+ try {
+ vcs.getFactory(copyFrom).createCopyMoveClient().copy(copyFrom, ioFile, true, false);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
}
}.execute();
}
@@ -793,7 +798,12 @@
new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- wcClient.doAdd(ioFile, true, false, false, true);
+ try {
+ vcs.getFactory(ioFile).createAddClient().add(ioFile, null, false, false, true, null);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
}
}.execute();
}
@@ -915,17 +925,11 @@
final List<VcsException> exceptions) {
return new Runnable() {
public void run() {
- final SVNWCClient wcClient = vcs.createWCClient();
for(FilePath file: filesToProcess) {
VirtualFile vFile = file.getVirtualFile(); // for deleted directories
final File ioFile = new File(file.getPath());
try {
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doDelete(ioFile, true, false);
- }
- }.execute();
+ createDeleteAction(vcs, ioFile, true).execute();
if (vFile != null && vFile.isValid() && vFile.isDirectory()) {
vFile.refresh(true, true);
VcsDirtyScopeManager.getInstance(project).dirDirtyRecursively(vFile);
@@ -978,18 +982,15 @@
private void fillDeletedFiles(Project project, List<Pair<FilePath, WorkingCopyFormat>> deletedFiles, Collection<FilePath> deleteAnyway)
throws SVNException {
final SvnVcs vcs = SvnVcs.getInstance(project);
- final SVNStatusClient sc = vcs.createStatusClient();
final Collection<File> files = myDeletedFiles.remove(project);
for (final File file : files) {
- boolean isAdded = false;
- final SVNStatus status;
- status = new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- myT = sc.doStatus(file, false);
- }
- }.compute();
- isAdded = SVNStatusType.STATUS_ADDED.equals(status.getNodeStatus());
+ final SVNStatus status = new RepeatSvnActionThroughBusy() {
+ @Override
+ protected void executeImpl() throws SVNException {
+ myT = vcs.getFactory(file).createStatusClient().doStatus(file, false);
+ }
+ }.compute();
+ boolean isAdded = SVNStatusType.STATUS_ADDED.equals(status.getNodeStatus());
final FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file);
if (isAdded) {
deleteAnyway.add(filePath);
@@ -1034,18 +1035,12 @@
}
@Nullable
- private static SVNStatus getFileStatus(SvnVcs vcs, File file) {
- SVNStatusClient stClient = vcs.createStatusClient();
- return getFileStatus(file, stClient);
- }
-
- @Nullable
- private static SVNStatus getFileStatus(final File file, final SVNStatusClient stClient) {
+ private static SVNStatus getFileStatus(@NotNull final SvnVcs vcs, @NotNull final File file) {
try {
return new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- myT = stClient.doStatus(file, false);
+ myT = vcs.getFactory(file).createStatusClient().doStatus(file, false);
}
}.compute();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java
index 46545c4..68e7c07 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java
@@ -312,8 +312,8 @@
LOG.info("Error: cannot find repository URL for versioned folder: " + foundRoot.getFile().getPath());
} else {
myRepositoryRoots.register(repoRoot);
- myTopRoots.add(new RootUrlInfo(repoRoot, foundRoot.getInfo().getURL(),
- SvnFormatSelector.getWorkingCopyFormat(new File(foundRoot.getFile().getPath())), foundRoot.getFile(), vcsRoot));
+ myTopRoots.add(new RootUrlInfo(repoRoot, foundRoot.getInfo().getURL(), SvnFormatSelector.findRootAndGetFormat(
+ new File(foundRoot.getFile().getPath())), foundRoot.getFile(), vcsRoot));
}
}
}
@@ -541,8 +541,9 @@
final SVNInfo svnInfo = vcs.getInfo(copyRoot);
if ((svnInfo == null) || (svnInfo.getRepositoryRootURL() == null)) continue;
- final RootUrlInfo info = new RootUrlInfo(svnInfo.getRepositoryRootURL(), svnInfo.getURL(),
- SvnFormatSelector.getWorkingCopyFormat(svnInfo.getFile()), copyRoot, vcsRoot);
+ final RootUrlInfo info =
+ new RootUrlInfo(svnInfo.getRepositoryRootURL(), svnInfo.getURL(), SvnFormatSelector.findRootAndGetFormat(svnInfo.getFile()),
+ copyRoot, vcsRoot);
mapping.add(info);
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
index 94d21db..77783bad 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
@@ -16,6 +16,7 @@
package org.jetbrains.idea.svn;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.util.WaitForProgressToShow;
@@ -37,6 +38,9 @@
import java.util.Iterator;
public class SvnFormatSelector implements ISVNAdminAreaFactorySelector {
+
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnFormatSelector");
+
public Collection getEnabledFactories(File path, Collection factories, boolean writeAccess) throws SVNException {
if (ApplicationManager.getApplication().isUnitTestMode()) {
return factories;
@@ -145,7 +149,19 @@
return newMode[0];
}
+ public static WorkingCopyFormat findRootAndGetFormat(final File path) {
+ File root = SvnUtil.getWorkingCopyRootNew(path);
+
+ return root != null ? getWorkingCopyFormat(root) : WorkingCopyFormat.UNKNOWN;
+ }
+
public static WorkingCopyFormat getWorkingCopyFormat(final File path) {
+ WorkingCopyFormat format = SvnUtil.getFormat(path);
+
+ return WorkingCopyFormat.UNKNOWN.equals(format) ? detectWithSvnKit(path) : format;
+ }
+
+ private static WorkingCopyFormat detectWithSvnKit(File path) {
try {
final SvnWcGeneration svnWcGeneration = SvnOperationFactory.detectWcGeneration(path, true);
if (SvnWcGeneration.V17.equals(svnWcGeneration)) return WorkingCopyFormat.ONE_DOT_SEVEN;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
index 97b87ef..fcac396 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
@@ -29,6 +29,7 @@
* Date: 10/19/12
* Time: 4:22 PM
*/
+// TODO: Likely to be removed (together with SvnAbstractWriteOperationLocks).
public class SvnProxies {
private final SvnAbstractWriteOperationLocks myLocks;
private final AtomicReference<LearningProxy<SVNChangelistClientI, SVNException>> myChangelist;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
index 4a49dc1..8b51819 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
@@ -47,13 +47,15 @@
public class SvnRecursiveStatusWalker {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnRecursiveStatusWalker");
private final StatusWalkerPartner myPartner;
+ private final SvnVcs myVcs;
private final Project myProject;
private final StatusReceiver myReceiver;
private final LinkedList<MyItem> myQueue;
private final MyHandler myHandler;
- public SvnRecursiveStatusWalker(final Project project, final StatusReceiver receiver, final StatusWalkerPartner partner) {
- myProject = project;
+ public SvnRecursiveStatusWalker(final SvnVcs vcs, final StatusReceiver receiver, final StatusWalkerPartner partner) {
+ myVcs = vcs;
+ myProject = vcs.getProject();
myReceiver = receiver;
myPartner = partner;
myQueue = new LinkedList<MyItem>();
@@ -61,7 +63,7 @@
}
public void go(final FilePath rootPath, final SVNDepth depth) throws SVNException {
- final MyItem root = new MyItem(myProject, rootPath, depth, myPartner.createStatusClient(), false);
+ final MyItem root = new MyItem(myVcs, rootPath, depth, myPartner.createStatusClient(), false);
myQueue.add(root);
while (! myQueue.isEmpty()) {
@@ -83,7 +85,7 @@
}
} else {
try {
- final SVNStatus status = item.getClient().doStatus(ioFile, false, false);
+ final SVNStatus status = item.getClient(ioFile).doStatus(ioFile, false, false);
myReceiver.process(path, status);
} catch (SVNException e) {
handleStatusException(item, path, e);
@@ -115,18 +117,20 @@
private final Project myProject;
private final FilePath myPath;
private final SVNDepth myDepth;
- private final SVNStatusClient myClient;
private final SvnStatusClientI mySvnClient;
+ private final SvnStatusClientI myCommandLineClient;
private final boolean myIsInnerCopyRoot;
private final SvnConfiguration myConfiguration17;
+ private final SvnVcs myVcs;
- private MyItem(Project project, FilePath path, SVNDepth depth, SVNStatusClient client, boolean isInnerCopyRoot) {
- myProject = project;
+ private MyItem(SvnVcs vcs, FilePath path, SVNDepth depth, SVNStatusClient client, boolean isInnerCopyRoot) {
+ myVcs = vcs;
+ myProject = vcs.getProject();
myConfiguration17 = SvnConfiguration.getInstance(myProject);
myPath = path;
myDepth = depth;
- myClient = client;
mySvnClient = new SvnkitSvnStatusClient(client);
+ myCommandLineClient = new SvnCommandLineStatusClient(myProject);
myIsInnerCopyRoot = isInnerCopyRoot;
}
@@ -138,20 +142,20 @@
return myDepth;
}
- public SvnStatusClientI getClient() {
- return mySvnClient;
- }
-
public SvnStatusClientI getClient(final File file) {
- if (! SVNDepth.INFINITY.equals(myDepth)) {
- return mySvnClient;
+ WorkingCopyFormat format = myVcs.getWorkingCopyFormat(file);
+
+ if (format == WorkingCopyFormat.ONE_DOT_EIGHT) {
+ return myCommandLineClient;
}
+
// check format
if (CheckJavaHL.isPresent() && SvnConfiguration.UseAcceleration.javaHL.equals(myConfiguration17.myUseAcceleration) &&
Svn17Detector.is17(myProject, file)) {
return new JavaHLSvnStatusClient(myProject);
- } else if (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration17.myUseAcceleration) && Svn17Detector.is17(myProject, file)) {
- return new SvnCommandLineStatusClient(myProject);
+ } else if (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration17.myUseAcceleration)) {
+ // apply command line disregarding working copy format
+ return myCommandLineClient;
}
return mySvnClient;
}
@@ -186,7 +190,7 @@
return true;
}
if (file.isDirectory() && new File(file, SVNFileUtil.getAdminDirectoryName()).exists()) {
- final MyItem childItem = new MyItem(myProject, path, newDepth, myPartner.createStatusClient(), true);
+ final MyItem childItem = new MyItem(myVcs, path, newDepth, myPartner.createStatusClient(), true);
myQueue.add(childItem);
} else if (vf != null) {
myReceiver.processUnversioned(vf);
@@ -228,12 +232,13 @@
}
public void checkIfCopyRootWasReported(@Nullable final SVNStatus ioFileStatus, final File ioFile) {
- if (! myMetCurrentItem && FileUtil.filesEqual(ioFile, myCurrentItem.getPath().getIOFile())) {
+ File itemFile = myCurrentItem.getPath().getIOFile();
+ if (! myMetCurrentItem && FileUtil.filesEqual(ioFile, itemFile)) {
myMetCurrentItem = true;
SVNStatus statusInner;
try {
statusInner = ioFileStatus != null ? ioFileStatus :
- myCurrentItem.getClient().doStatus(myCurrentItem.getPath().getIOFile(), false);
+ myCurrentItem.getClient(itemFile).doStatus(itemFile, false);
}
catch (SVNException e) {
LOG.info(e);
@@ -294,7 +299,7 @@
//myReceiver.processUnversioned(vFile);
//processRecursively(vFile, myCurrentItem.getDepth());
} else {
- final MyItem childItem = new MyItem(myProject, new FilePathImpl(vFile), SVNDepth.INFINITY,
+ final MyItem childItem = new MyItem(myVcs, new FilePathImpl(vFile), SVNDepth.INFINITY,
myPartner.createStatusClient(), true);
myQueue.add(childItem);
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnTestWriteOperationLocks.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnTestWriteOperationLocks.java
index 853e995..efea2f9 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnTestWriteOperationLocks.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnTestWriteOperationLocks.java
@@ -25,6 +25,7 @@
* Date: 10/23/12
* Time: 2:31 PM
*/
+// TODO: Used only in SvnLockingTest which is not required anymore. Likely to be removed.
public class SvnTestWriteOperationLocks extends SvnAbstractWriteOperationLocks {
private final WorkingCopy myWorkingCopy;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
index 0c049ac..7cd6bdd9 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
@@ -30,21 +30,19 @@
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangesUtil;
-import com.intellij.openapi.vcs.impl.ContentRevisionCache;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.openapi.vfs.*;
import com.intellij.openapi.wm.impl.status.StatusBarUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.MultiMap;
-import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.ClientFactory;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.dialogs.LockDialog;
+import org.tmatesoft.sqljet.core.SqlJetException;
+import org.tmatesoft.sqljet.core.table.SqlJetDb;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
@@ -53,14 +51,14 @@
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.*;
import org.tmatesoft.svn.core.wc2.SvnOperationFactory;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
import java.util.*;
public class SvnUtil {
+ // TODO: ASP.NET hack behavior should be supported - http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt
+ // TODO: Remember this when moving out SVNKit classes.
@NonNls public static final String SVN_ADMIN_DIR_NAME = SVNFileUtil.getAdminDirectoryName();
@NonNls public static final String ENTRIES_FILE_NAME = "entries";
@NonNls public static final String WC_DB_FILE_NAME = "wc.db";
@@ -71,13 +69,9 @@
private SvnUtil() { }
public static boolean isSvnVersioned(final Project project, File parent) {
- try {
- final SVNInfo info = SvnVcs.getInstance(project).createWCClient().doInfo(parent, SVNRevision.UNDEFINED);
- return info != null;
- }
- catch (SVNException e) {
- return false;
- }
+ final SVNInfo info = SvnVcs.getInstance(project).getInfo(parent);
+
+ return info != null;
}
public static Collection<VirtualFile> crawlWCRoots(final Project project, File path, SvnWCRootCrawler callback, ProgressIndicator progress) {
@@ -123,15 +117,8 @@
@Nullable
public static String getExactLocation(final SvnVcs vcs, File path) {
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- SVNInfo info = wcClient.doInfo(path, SVNRevision.UNDEFINED);
- if (info != null && info.getURL() != null) {
- return info.getURL().toString();
- }
- }
- catch (SVNException ignored) { }
- return null;
+ SVNInfo info = vcs.getInfo(path);
+ return info != null && info.getURL() != null ? info.getURL().toString() : null;
}
public static Map<String, File> getLocationInfoForModule(final SvnVcs vcs, File path, ProgressIndicator progress) {
@@ -288,7 +275,9 @@
}
public static String formatRepresentation(final WorkingCopyFormat format) {
- if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) {
+ if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format)) {
+ return SvnBundle.message("dialog.show.svn.map.table.version18.text");
+ } else if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) {
return SvnBundle.message("dialog.show.svn.map.table.version17.text");
} else if (WorkingCopyFormat.ONE_DOT_SIX.equals(format)) {
return SvnBundle.message("dialog.show.svn.map.table.version16.text");
@@ -352,6 +341,54 @@
return result;
}
+ /**
+ * Gets working copy internal format. Works for 1.7 and 1.8.
+ *
+ * @param path
+ * @return
+ */
+ public static WorkingCopyFormat getFormat(final File path) {
+ int format = 0;
+ File dbFile = resolveDatabase(path);
+
+ if (dbFile != null) {
+ SqlJetDb db = null;
+ try {
+ db = SqlJetDb.open(dbFile, false);
+ format = db.getOptions().getUserVersion();
+ }
+ catch (SqlJetException e) {
+ LOG.error(e);
+ } finally {
+ if (db != null) {
+ try {
+ db.close();
+ }
+ catch (SqlJetException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ }
+
+ return WorkingCopyFormat.getInstance(format);
+ }
+
+ private static File resolveDatabase(final File path) {
+ File dbFile = getWcDb(path);
+ File result = null;
+
+ try {
+ if (dbFile.exists() && dbFile.isFile()) {
+ result = dbFile;
+ }
+ } catch (SecurityException e) {
+ LOG.error("Failed to access working copy database", e);
+ }
+
+ return result;
+ }
+
private static class LocationsCrawler implements SvnWCRootCrawler {
private final SvnVcs myVcs;
private final Map<String, File> myLocations;
@@ -371,15 +408,9 @@
oldText = progress.getText();
progress.setText(SvnBundle.message("progress.text.discovering.location", root.getAbsolutePath()));
}
- try {
- SVNWCClient wcClient = myVcs.createWCClient();
- SVNInfo info = wcClient.doInfo(root, SVNRevision.UNDEFINED);
- if (info != null && info.getURL() != null) {
- myLocations.put(info.getURL().toString(), info.getFile());
- }
- }
- catch (SVNException e) {
- //
+ SVNInfo info = myVcs.getInfo(root);
+ if (info != null && info.getURL() != null) {
+ myLocations.put(info.getURL().toString(), info.getFile());
}
if (progress != null) {
progress.setText(oldText);
@@ -389,20 +420,15 @@
@Nullable
public static String getRepositoryUUID(final SvnVcs vcs, final File file) {
- final SVNWCClient client = vcs.createWCClient();
- try {
- final SVNInfo info = client.doInfo(file, SVNRevision.UNDEFINED);
- return (info == null) ? null : info.getRepositoryUUID();
- } catch (SVNException e) {
- return null;
- }
+ final SVNInfo info = vcs.getInfo(file);
+ return info != null ? info.getRepositoryUUID() : null;
}
@Nullable
public static String getRepositoryUUID(final SvnVcs vcs, final SVNURL url) {
- final SVNWCClient client = vcs.createWCClient();
try {
- final SVNInfo info = client.doInfo(url, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
+ final SVNInfo info = vcs.getInfo(url, SVNRevision.UNDEFINED);
+
return (info == null) ? null : info.getRepositoryUUID();
} catch (SVNException e) {
return null;
@@ -411,19 +437,14 @@
@Nullable
public static SVNURL getRepositoryRoot(final SvnVcs vcs, final File file) {
- final SVNWCClient client = vcs.createWCClient();
- try {
- final SVNInfo info = client.doInfo(file, SVNRevision.UNDEFINED);
- return (info == null) ? null : info.getRepositoryRootURL();
- } catch (SVNException e) {
- return null;
- }
+ final SVNInfo info = vcs.getInfo(file);
+ return info != null ? info.getRepositoryRootURL() : null;
}
@Nullable
public static SVNURL getRepositoryRoot(final SvnVcs vcs, final String url) {
try {
- return getRepositoryRoot(vcs, SVNURL.parseURIEncoded(url), true);
+ return getRepositoryRoot(vcs, SVNURL.parseURIEncoded(url));
}
catch (SVNException e) {
return null;
@@ -431,18 +452,14 @@
}
@Nullable
- public static SVNURL getRepositoryRoot(final SvnVcs vcs, final SVNURL url, boolean allowRemote) throws SVNException {
- final SVNWCClient client = vcs.createWCClient();
- SVNInfo info = client.doInfo(url, SVNRevision.UNDEFINED, SVNRevision.HEAD);
+ public static SVNURL getRepositoryRoot(final SvnVcs vcs, final SVNURL url) throws SVNException {
+ SVNInfo info = vcs.getInfo(url, SVNRevision.HEAD);
+
return (info == null) ? null : info.getRepositoryRootURL();
}
public static boolean isWorkingCopyRoot(final File file) {
- try {
- return SVNWCUtil.isWorkingCopyRoot(file);
- } catch (SVNException e) {
- return false;
- }
+ return FileUtil.filesEqual(file, getWorkingCopyRootNew(file));
}
@Nullable
@@ -548,17 +565,9 @@
}
public static SVNDepth getDepth(final SvnVcs vcs, final File file) {
- final SVNWCClient client = vcs.createWCClient();
- try {
- final SVNInfo svnInfo = client.doInfo(file, SVNRevision.UNDEFINED);
- if (svnInfo != null) {
- return svnInfo.getDepth();
- }
- }
- catch (SVNException e) {
- //
- }
- return SVNDepth.UNKNOWN;
+ SVNInfo info = vcs.getInfo(file);
+
+ return info != null && info.getDepth() != null ? info.getDepth() : SVNDepth.UNKNOWN;
}
public static boolean seemsLikeVersionedDir(final VirtualFile file) {
@@ -590,21 +599,17 @@
}
public static SVNURL getCommittedURL(final SvnVcs vcs, final File file) {
- final File root = getWorkingCopyRoot(file);
- if (root == null) return null;
- return getUrl(vcs, root);
+ final File root = getWorkingCopyRootNew(file);
+
+ return root == null ? null : getUrl(vcs, root);
}
@Nullable
public static SVNURL getUrl(final SvnVcs vcs, final File file) {
- try {
- final SVNInfo info = vcs.createWCClient().doInfo(file, SVNRevision.UNDEFINED);
- return info == null ? null : info.getURL(); // todo for moved items?
- }
- catch (SVNException e) {
- LOG.debug(e);
- return null;
- }
+ // todo for moved items?
+ final SVNInfo info = vcs.getInfo(file);
+
+ return info == null ? null : info.getURL();
}
public static boolean doesRepositorySupportMergeInfo(final SvnVcs vcs, final SVNURL url) {
@@ -648,17 +653,9 @@
@Nullable
public static File getWcCopyRootIf17(final File file, @Nullable final File upperBound) {
- File current = file;
- boolean wcDbFound = false;
- while (current != null) {
- File wcDb;
- if ((wcDb = getWcDb(current)).exists() && ! wcDb.isDirectory()) {
- wcDbFound = true;
- break;
- }
- current = current.getParentFile();
- }
- if (! wcDbFound) return null;
+ File current = getParentWithDb(file);
+ if (current == null) return null;
+
while (current != null) {
try {
final SvnWcGeneration svnWcGeneration = SvnOperationFactory.detectWcGeneration(current, false);
@@ -674,6 +671,40 @@
return null;
}
+ /**
+ * Utility method that deals also with 1.8 working copies.
+ * TODO: Should be renamed when all parts updated for 1.8.
+ *
+ * @param file
+ * @return
+ */
+ @Nullable
+ public static File getWorkingCopyRootNew(final File file) {
+ File current = getParentWithDb(file);
+ if (current == null) return getWorkingCopyRoot(file);
+
+ WorkingCopyFormat format = getFormat(current);
+
+ return WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)
+ ? current
+ : getWorkingCopyRoot(file);
+ }
+
+ private static File getParentWithDb(File file) {
+ File current = file;
+ boolean wcDbFound = false;
+ while (current != null) {
+ File wcDb;
+ if ((wcDb = getWcDb(current)).exists() && ! wcDb.isDirectory()) {
+ wcDbFound = true;
+ break;
+ }
+ current = current.getParentFile();
+ }
+ if (! wcDbFound) return null;
+ return current;
+ }
+
public static boolean is17CopyPart(final File file) {
try {
return SvnWcGeneration.V17.equals(SvnOperationFactory.detectWcGeneration(file, true));
@@ -703,44 +734,24 @@
return result;
}
- public static byte[] getFileContents(final SvnVcs vcs, final String path, final boolean isUrl, final SVNRevision revision,
- final SVNRevision pegRevision)
+ public static byte[] getFileContents(@NotNull final SvnVcs vcs,
+ @NotNull final SvnTarget target,
+ @Nullable final SVNRevision revision,
+ @Nullable final SVNRevision pegRevision)
throws VcsException {
- final int maxSize = VcsUtil.getMaxVcsLoadedFileSize();
- ByteArrayOutputStream buffer = new ByteArrayOutputStream() {
- @Override
- public synchronized void write(int b) {
- if (size() > maxSize) throw new FileTooBigRuntimeException();
- super.write(b);
- }
+ ClientFactory factory = target.isFile() ? vcs.getFactory(target.getFile()) : vcs.getFactory();
- @Override
- public synchronized void write(byte[] b, int off, int len) {
- if (size() > maxSize) throw new FileTooBigRuntimeException();
- super.write(b, off, len);
- }
-
- @Override
- public synchronized void writeTo(OutputStream out) throws IOException {
- if (size() > maxSize) throw new FileTooBigRuntimeException();
- super.writeTo(out);
- }
- };
- SVNWCClient wcClient = vcs.createWCClient();
- try {
- if (isUrl) {
- wcClient.doGetFileContents(SVNURL.parseURIEncoded(path), pegRevision, revision, true, buffer);
- } else {
- wcClient.doGetFileContents(new File(path), pegRevision, revision, true, buffer);
- }
- ContentRevisionCache.checkContentsSize(path, buffer.size());
- } catch (FileTooBigRuntimeException e) {
- ContentRevisionCache.checkContentsSize(path, buffer.size());
- } catch (SVNException e) {
- throw new VcsException(e);
- }
- return buffer.toByteArray();
+ return factory.createContentClient().getContent(target, revision, pegRevision);
}
- private static class FileTooBigRuntimeException extends RuntimeException {}
+ public static SVNURL parseUrl(@NotNull String url) {
+ try {
+ return SVNURL.parseURIEncoded(url);
+ }
+ catch (SVNException e) {
+ IllegalArgumentException runtimeException = new IllegalArgumentException();
+ runtimeException.initCause(e);
+ throw runtimeException;
+ }
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
index 748fc86..1a5a0f8 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
@@ -13,8 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-
package org.jetbrains.idea.svn;
import com.intellij.ide.FrameStateListener;
@@ -68,8 +66,12 @@
import org.jetbrains.idea.svn.actions.ShowPropertiesDiffWithLocalAction;
import org.jetbrains.idea.svn.actions.SvnMergeProvider;
import org.jetbrains.idea.svn.annotate.SvnAnnotationProvider;
+import org.jetbrains.idea.svn.api.ClientFactory;
+import org.jetbrains.idea.svn.api.CmdClientFactory;
+import org.jetbrains.idea.svn.api.SvnKitClientFactory;
import org.jetbrains.idea.svn.checkin.SvnCheckinEnvironment;
import org.jetbrains.idea.svn.checkout.SvnCheckoutProvider;
+import org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient;
import org.jetbrains.idea.svn.commandLine.SvnExecutableChecker;
import org.jetbrains.idea.svn.dialogs.SvnBranchPointsCalculator;
import org.jetbrains.idea.svn.dialogs.WCInfo;
@@ -79,6 +81,7 @@
import org.jetbrains.idea.svn.history.SvnHistoryProvider;
import org.jetbrains.idea.svn.lowLevel.PrimitivePool;
import org.jetbrains.idea.svn.networking.SSLProtocolExceptionParser;
+import org.jetbrains.idea.svn.portable.SvnWcClientI;
import org.jetbrains.idea.svn.rollback.SvnRollbackEnvironment;
import org.jetbrains.idea.svn.update.SvnIntegrateEnvironment;
import org.jetbrains.idea.svn.update.SvnUpdateEnvironment;
@@ -195,9 +198,10 @@
};
private SvnCheckoutProvider myCheckoutProvider;
- public void checkCommandLineVersion() {
- myChecker.checkExecutableAndNotifyIfNeeded();
- }
+ private ClientFactory cmdClientFactory;
+ private ClientFactory svnKitClientFactory;
+
+ private final boolean myLogExceptions;
static {
System.setProperty("svnkit.log.native.calls", "true");
@@ -235,8 +239,8 @@
public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBrachesStorage storage) {
super(project, VCS_NAME);
+
myLoadedBranchesStorage = storage;
- LOG.debug("ct");
myRootsToWorkingCopies = new RootsToWorkingCopies(this);
myConfiguration = svnConfiguration;
myAuthNotifier = new SvnAuthenticationNotifier(this);
@@ -284,6 +288,9 @@
// remove used some time before old notification group ids
correctNotificationIds();
myChecker = new SvnExecutableChecker(myProject);
+
+ Application app = ApplicationManager.getApplication();
+ myLogExceptions = app != null && (app.isInternal() || app.isUnitTestMode());
}
private void correctNotificationIds() {
@@ -348,6 +355,10 @@
});
}
+ public void checkCommandLineVersion() {
+ myChecker.checkExecutableAndNotifyIfNeeded();
+ }
+
public void invokeRefreshSvnRoots() {
if (REFRESH_LOG.isDebugEnabled()) {
REFRESH_LOG.debug("refresh: ", new Throwable());
@@ -481,6 +492,9 @@
myChecker.checkExecutableAndNotifyIfNeeded();
}
+ cmdClientFactory = new CmdClientFactory(this);
+ svnKitClientFactory = new SvnKitClientFactory(this);
+
// do one time after project loaded
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
@Override
@@ -911,24 +925,127 @@
return new File(file, pathToDirProps);
}
+ /**
+ * Provides info either with command line or SvnKit based on project settings.
+ * Call this method only if failed to detect working copy format by any other means.
+ *
+ * @param file
+ * @return
+ */
+ private SVNInfo runInfoCommand(@NotNull final File file) {
+ SVNInfo result = null;
+
+ try {
+ result = SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration.myUseAcceleration)
+ ? getInfoCommandLine(file, SVNRevision.UNDEFINED)
+ : getInfoSvnKit(file);
+ }
+ catch (SVNException e) {
+ handleInfoException(e);
+ }
+
+ return result;
+ }
+
+ public SVNInfo getInfo(@NotNull SVNURL url,
+ SVNRevision pegRevision,
+ SVNRevision revision,
+ ISVNAuthenticationManager manager) throws SVNException {
+ if (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration.myUseAcceleration)) {
+ return createInfoClient().doInfo(url, pegRevision, revision);
+ } else {
+ return (manager != null ? createWCClient(manager) : createWCClient()).doInfo(url, pegRevision, revision);
+ }
+ }
+
+ public SVNInfo getInfo(@NotNull SVNURL url, SVNRevision revision) throws SVNException {
+ return getInfo(url, SVNRevision.UNDEFINED, revision, null);
+ }
+
@Nullable
- public SVNInfo getInfo(final VirtualFile file) {
+ public SVNInfo getInfo(@NotNull final VirtualFile file) {
final File ioFile = new File(file.getPath());
return getInfo(ioFile);
}
- public SVNInfo getInfo(File ioFile) {
+ @Nullable
+ public SVNInfo getInfo(@NotNull String path) {
+ return getInfo(new File(path));
+ }
+
+ @Nullable
+ public SVNInfo getInfo(@NotNull File ioFile) {
+ WorkingCopyFormat format = getWorkingCopyFormat(ioFile);
+ SVNInfo result = null;
+
try {
- SVNWCClient wcClient = createWCClient();
- SVNInfo info = wcClient.doInfo(ioFile, SVNRevision.UNDEFINED);
- if (info == null || info.getRepositoryRootURL() == null) {
- info = wcClient.doInfo(ioFile, SVNRevision.HEAD);
- }
- return info;
+ result = format == WorkingCopyFormat.ONE_DOT_EIGHT ? getInfoCommandLine(ioFile, SVNRevision.UNDEFINED) : runInfoCommand(ioFile);
}
catch (SVNException e) {
- return null;
+ handleInfoException(e);
}
+
+ return result;
+ }
+
+ @Nullable
+ public SVNInfo getInfo(@NotNull File ioFile, @NotNull SVNRevision revision) {
+ WorkingCopyFormat format = getWorkingCopyFormat(ioFile);
+ SVNInfo result = null;
+
+ try {
+ result = format == WorkingCopyFormat.ONE_DOT_EIGHT ? getInfoCommandLine(ioFile, revision) : getInfoSvnKit(ioFile, revision);
+ }
+ catch (SVNException e) {
+ handleInfoException(e);
+ }
+
+ return result;
+ }
+
+ private void handleInfoException(SVNException e) {
+ final SVNErrorCode errorCode = e.getErrorMessage().getErrorCode();
+ if (!myLogExceptions ||
+ SVNErrorCode.WC_PATH_NOT_FOUND.equals(errorCode) ||
+ SVNErrorCode.UNVERSIONED_RESOURCE.equals(errorCode) ||
+ SVNErrorCode.WC_NOT_WORKING_COPY.equals(errorCode)) {
+ LOG.debug(e);
+ }
+ else {
+ LOG.error(e);
+ }
+ }
+
+ private SVNInfo getInfoSvnKit(@NotNull File ioFile) throws SVNException {
+ SVNInfo info = getInfoSvnKit(ioFile, SVNRevision.UNDEFINED);
+ if (info == null || info.getRepositoryRootURL() == null) {
+ info = getInfoSvnKit(ioFile, SVNRevision.HEAD);
+ }
+ return info;
+ }
+
+ private SVNInfo getInfoSvnKit(@NotNull File ioFile, SVNRevision revision) throws SVNException {
+ return createWCClient().doInfo(ioFile, revision);
+ }
+
+ private SVNInfo getInfoCommandLine(@NotNull File ioFile, SVNRevision revision) throws SVNException {
+ SvnCommandLineInfoClient client = new SvnCommandLineInfoClient(myProject);
+ return client.doInfo(ioFile, revision);
+ }
+
+ private SvnWcClientI createInfoClient() {
+ return new SvnCommandLineInfoClient(myProject);
+ }
+
+ public WorkingCopyFormat getWorkingCopyFormat(@NotNull File ioFile) {
+ RootUrlInfo rootInfo = getSvnFileUrlMapping().getWcRootForFilePath(ioFile);
+ WorkingCopyFormat format = rootInfo != null ? rootInfo.getFormat() : WorkingCopyFormat.UNKNOWN;
+
+ if (WorkingCopyFormat.UNKNOWN.equals(format)) {
+ format = SvnFormatSelector.findRootAndGetFormat(ioFile);
+ }
+
+ return format;
}
public void refreshSSLProperty() {
@@ -1245,4 +1362,27 @@
}
return myCheckoutProvider;
}
+
+ /**
+ * Try to avoid usages of this method (for now) as it could not correctly for all cases
+ * detect svn 1.8 working copy format to guarantee command line client.
+ *
+ * For instance, when working copies of several formats are presented in project
+ * (though it seems to be rather unlikely case).
+ *
+ * @return
+ */
+ public ClientFactory getFactory() {
+ // check working copy format of project directory
+ WorkingCopyFormat format = getWorkingCopyFormat(new File(getProject().getBaseDir().getPath()));
+
+ return WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ||
+ myConfiguration.myUseAcceleration.equals(SvnConfiguration.UseAcceleration.commandLine) ? cmdClientFactory : svnKitClientFactory;
+ }
+
+ public ClientFactory getFactory(@NotNull File file) {
+ WorkingCopyFormat format = getWorkingCopyFormat(file);
+
+ return WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ? cmdClientFactory : getFactory();
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnWriteOperationLocks.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnWriteOperationLocks.java
index 36e0b08..ca97edb 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnWriteOperationLocks.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnWriteOperationLocks.java
@@ -30,6 +30,7 @@
* Date: 10/23/12
* Time: 2:29 PM
*/
+// TODO: Such locking functionality is not required anymore. Likely to be removed.
public class SvnWriteOperationLocks extends SvnAbstractWriteOperationLocks {
private final RootsToWorkingCopies myRootsToWorkingCopies;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
index d40f947..c007541 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
@@ -15,19 +15,22 @@
*/
package org.jetbrains.idea.svn;
-import org.tmatesoft.svn.core.internal.wc17.db.ISVNWCDb;
-
/**
* since not all constants are available from svnkit & constants are fixed
*/
public enum WorkingCopyFormat {
+
ONE_DOT_THREE(4, false, false, false, SvnBundle.message("dialog.show.svn.map.table.version13.text")),
ONE_DOT_FOUR(8, false, false, false, SvnBundle.message("dialog.show.svn.map.table.version14.text")),
ONE_DOT_FIVE(9, true, true, false, SvnBundle.message("dialog.show.svn.map.table.version15.text")),
ONE_DOT_SIX(10, true, true, true, SvnBundle.message("dialog.show.svn.map.table.version16.text")),
ONE_DOT_SEVEN(12, true, true, true, SvnBundle.message("dialog.show.svn.map.table.version17.text")),
+ ONE_DOT_EIGHT(12, true, true, true, SvnBundle.message("dialog.show.svn.map.table.version18.text")),
UNKNOWN(0, false, false, false, "unknown");
+ public static final int INTERNAL_FORMAT_17 = 29;
+ public static final int INTERNAL_FORMAT_18 = 31;
+
private final int myFormat;
private final boolean myChangelistSupport;
private final boolean myMergeInfoSupport;
@@ -60,10 +63,11 @@
public static WorkingCopyFormat getInstance(final int value) {
// somewhy 1.7 wc format can also be 29
- if (ISVNWCDb.WC_FORMAT_17 == value) {
+ if (INTERNAL_FORMAT_17 == value) {
return ONE_DOT_SEVEN;
- }
- if (ONE_DOT_FIVE.getFormat() == value) {
+ } else if (INTERNAL_FORMAT_18 == value) {
+ return ONE_DOT_EIGHT;
+ } else if (ONE_DOT_FIVE.getFormat() == value) {
return ONE_DOT_FIVE;
} else if (ONE_DOT_FOUR.getFormat() == value) {
return ONE_DOT_FOUR;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AddAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AddAction.java
index 06c255b..7558a48 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AddAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AddAction.java
@@ -30,8 +30,6 @@
import org.jetbrains.idea.svn.SvnStatusUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.checkin.SvnCheckinEnvironment;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
import java.util.*;
@@ -68,8 +66,6 @@
ProjectLevelVcsManager manager = ProjectLevelVcsManager.getInstance(project);
manager.startBackgroundVcsOperation();
try {
-
- SVNWCClient wcClient = activeVcs.createWCClient();
final Set<VirtualFile> additionallyDirty = new HashSet<VirtualFile>();
final FileStatusManager fileStatusManager = FileStatusManager.getInstance(project);
for (VirtualFile item : items) {
@@ -84,13 +80,13 @@
}
}
}
- Collection<SVNException> exceptions =
- SvnCheckinEnvironment.scheduleUnversionedFilesForAddition(wcClient, Arrays.asList(items), true);
+ Collection<VcsException> exceptions =
+ SvnCheckinEnvironment.scheduleUnversionedFilesForAddition(activeVcs, Arrays.asList(items), true);
additionallyDirty.addAll(Arrays.asList(items));
markDirty(project, additionallyDirty);
if (!exceptions.isEmpty()) {
final Collection<String> messages = new ArrayList<String>(exceptions.size());
- for (SVNException exception : exceptions) {
+ for (VcsException exception : exceptions) {
messages.add(exception.getMessage());
}
throw new VcsException(messages);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkResolvedAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkResolvedAction.java
index 87b3697..d65c6d3 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkResolvedAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkResolvedAction.java
@@ -19,6 +19,7 @@
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vcs.AbstractVcs;
@@ -32,8 +33,9 @@
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnStatusUtil;
import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.conflict.ConflictClient;
import org.jetbrains.idea.svn.dialogs.SelectFilesDialog;
-import org.tmatesoft.svn.core.SVNDepth;
+import org.jetbrains.idea.svn.portable.SvnStatusClientI;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.*;
@@ -42,6 +44,8 @@
import java.util.TreeSet;
public class MarkResolvedAction extends BasicAction {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.actions.MarkResolvedAction");
+
protected String getActionName(AbstractVcs vcs) {
return SvnBundle.message("action.name.mark.resolved");
}
@@ -88,15 +92,13 @@
}
pathsArray = dialog.getSelectedPaths();
try {
- SVNWCClient wcClient = vcs.createWCClient();
for (String path : pathsArray) {
File ioFile = new File(path);
- wcClient.doResolve(ioFile, SVNDepth.EMPTY, SVNConflictChoice.MERGED);
+ ConflictClient client = vcs.getFactory(ioFile).createConflictClient();
+
+ client.resolve(ioFile, true);
}
}
- catch (SVNException e) {
- throw new VcsException(e);
- }
finally {
for (VirtualFile file : files) {
VcsDirtyScopeManager.getInstance(project).fileDirty(file);
@@ -115,10 +117,12 @@
private static Collection<String> collectResolvablePaths(final SvnVcs vcs, VirtualFile[] files) {
final Collection<String> target = new TreeSet<String>();
- SVNStatusClient stClient = vcs.createStatusClient();
for (VirtualFile file : files) {
try {
- stClient.doStatus(new File(file.getPath()), true, false, false, false, new ISVNStatusHandler() {
+ File path = new File(file.getPath());
+ SvnStatusClientI client = vcs.getFactory(path).createStatusClient();
+
+ client.doStatus(path, true, false, false, false, new ISVNStatusHandler() {
public void handleStatus(SVNStatus status) {
if (status.getContentsStatus() == SVNStatusType.STATUS_CONFLICTED ||
status.getPropertiesStatus() == SVNStatusType.STATUS_CONFLICTED) {
@@ -128,7 +132,7 @@
});
}
catch (SVNException e) {
- //
+ LOG.warn(e);
}
}
return target;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java
index 4c582d0..3130dc9 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java
@@ -27,12 +27,13 @@
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnRevisionNumber;
+import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
-import org.tmatesoft.svn.core.SVNDepth;
-import org.tmatesoft.svn.core.SVNException;
+import org.jetbrains.idea.svn.properties.PropertyClient;
import org.tmatesoft.svn.core.SVNProperty;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -57,38 +58,34 @@
final MergeData data = new MergeData();
VcsRunnable runnable = new VcsRunnable() {
public void run() throws VcsException {
- SvnVcs vcs = SvnVcs.getInstance(myProject);
File oldFile = null;
File newFile = null;
File workingFile = null;
- SVNWCClient client;
boolean mergeCase = false;
- try {
- client = vcs.createWCClient();
- SVNInfo info = client.doInfo(new File(file.getPath()), SVNRevision.UNDEFINED);
- if (info != null) {
- oldFile = info.getConflictOldFile();
- newFile = info.getConflictNewFile();
- workingFile = info.getConflictWrkFile();
- mergeCase = workingFile == null || workingFile.getName().contains("working");
- // for debug
- if (workingFile == null) {
- LOG.info("Null working file when merging text conflict for " + file.getPath() + " old file: " + oldFile + " new file: " + newFile);
- }
- if (mergeCase) {
- // this is merge case
- oldFile = info.getConflictNewFile();
- newFile = info.getConflictOldFile();
- workingFile = info.getConflictWrkFile();
- }
- data.LAST_REVISION_NUMBER = new SvnRevisionNumber(info.getRevision());
+ SvnVcs vcs = SvnVcs.getInstance(myProject);
+ SVNInfo info = vcs.getInfo(file);
+
+ if (info != null) {
+ oldFile = info.getConflictOldFile();
+ newFile = info.getConflictNewFile();
+ workingFile = info.getConflictWrkFile();
+ mergeCase = workingFile == null || workingFile.getName().contains("working");
+ // for debug
+ if (workingFile == null) {
+ LOG.info("Null working file when merging text conflict for " + file.getPath() + " old file: " + oldFile + " new file: " + newFile);
}
- }
- catch (SVNException e) {
- throw new VcsException(e);
+ if (mergeCase) {
+ // this is merge case
+ oldFile = info.getConflictNewFile();
+ newFile = info.getConflictOldFile();
+ workingFile = info.getConflictWrkFile();
+ }
+ data.LAST_REVISION_NUMBER = new SvnRevisionNumber(info.getRevision());
+ } else {
+ throw new VcsException("Could not get info for " + file.getPath());
}
if (oldFile == null || newFile == null || workingFile == null) {
- ByteArrayOutputStream bos = getBaseRevisionContents(client, file);
+ ByteArrayOutputStream bos = getBaseRevisionContents(vcs, file);
data.ORIGINAL = bos.toByteArray();
data.LAST = bos.toByteArray();
data.CURRENT = readFile(new File(file.getPath()));
@@ -99,7 +96,7 @@
data.CURRENT = readFile(workingFile);
}
if (mergeCase) {
- final ByteArrayOutputStream contents = getBaseRevisionContents(vcs.createWCClient(), file);
+ final ByteArrayOutputStream contents = getBaseRevisionContents(vcs, file);
if (! Arrays.equals(contents.toByteArray(), data.ORIGINAL)) {
// swap base and server: another order of merge arguments
byte[] original = data.ORIGINAL;
@@ -114,13 +111,17 @@
return data;
}
- private ByteArrayOutputStream getBaseRevisionContents(SVNWCClient client, VirtualFile file) {
+ private ByteArrayOutputStream getBaseRevisionContents(@NotNull SvnVcs vcs, @NotNull VirtualFile file) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
- client.doGetFileContents(new File(file.getPath()), SVNRevision.UNDEFINED, SVNRevision.BASE, true, bos);
+ byte[] contents = SvnUtil.getFileContents(vcs, SvnTarget.fromFile(new File(file.getPath())), SVNRevision.BASE, SVNRevision.UNDEFINED);
+ bos.write(contents);
}
- catch (SVNException e) {
- //
+ catch (VcsException e) {
+ LOG.warn(e);
+ }
+ catch (IOException e) {
+ LOG.warn(e);
}
return bos;
}
@@ -135,13 +136,14 @@
}
public void conflictResolvedForFile(VirtualFile file) {
+ // TODO: Add possibility to resolve content conflicts separately from property conflicts.
SvnVcs vcs = SvnVcs.getInstance(myProject);
+ File path = new File(file.getPath());
try {
- SVNWCClient client = vcs.createWCClient();
- client.doResolve(new File(file.getPath()), SVNDepth.EMPTY, true, false, SVNConflictChoice.MERGED);
+ vcs.getFactory(path).createConflictClient().resolve(path, false);
}
- catch (SVNException e) {
- //
+ catch (VcsException e) {
+ LOG.warn(e);
}
// the .mine/.r## files have been deleted
final VirtualFile parent = file.getParent();
@@ -152,17 +154,20 @@
public boolean isBinary(@NotNull final VirtualFile file) {
SvnVcs vcs = SvnVcs.getInstance(myProject);
+
try {
- SVNWCClient client = vcs.createWCClient();
File ioFile = new File(file.getPath());
- SVNPropertyData svnPropertyData = client.doGetProperty(ioFile, SVNProperty.MIME_TYPE, SVNRevision.UNDEFINED, SVNRevision.WORKING);
+ PropertyClient client = vcs.getFactory(ioFile).createPropertyClient();
+
+ SVNPropertyData svnPropertyData = client.getProperty(ioFile, SVNProperty.MIME_TYPE, false, SVNRevision.UNDEFINED, SVNRevision.WORKING);
if (svnPropertyData != null && SVNProperty.isBinaryMimeType(SVNPropertyValue.getPropertyAsString(svnPropertyData.getValue()))) {
return true;
}
}
- catch (SVNException e) {
- //
+ catch (VcsException e) {
+ LOG.warn(e);
}
+
return false;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/add/AddClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/AddClient.java
new file mode 100644
index 0000000..718a56d
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/AddClient.java
@@ -0,0 +1,23 @@
+package org.jetbrains.idea.svn.add;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface AddClient extends SvnClient {
+
+ void add(@NotNull File file,
+ @Nullable SVNDepth depth,
+ boolean makeParents,
+ boolean includeIgnored,
+ boolean force,
+ @Nullable ISVNEventHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/add/CmdAddClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/CmdAddClient.java
new file mode 100644
index 0000000..c786671
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/CmdAddClient.java
@@ -0,0 +1,69 @@
+package org.jetbrains.idea.svn.add;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.containers.Convertor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.api.FileStatusResultParser;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+import org.tmatesoft.svn.core.wc.SVNStatusType;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdAddClient extends BaseSvnClient implements AddClient {
+
+ private static final String STATUS = "\\s*(\\w)\\s*";
+ private static final String OPTIONAL_FILE_TYPE = "(\\(.*\\))?";
+ private static final String PATH = "\\s*(.*?)\\s*";
+ private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + OPTIONAL_FILE_TYPE + PATH);
+
+ @Override
+ public void add(@NotNull File file,
+ @Nullable SVNDepth depth,
+ boolean makeParents,
+ boolean includeIgnored,
+ boolean force,
+ @Nullable ISVNEventHandler handler) throws VcsException {
+ List<String> parameters = prepareParameters(file, depth, makeParents, includeIgnored, force);
+
+ // TODO: handler should be called in parallel with command execution, but this will be in other thread
+ // TODO: check if that is ok for current handler implementation
+ // TODO: add possibility to invoke "handler.checkCancelled" - process should be killed
+ CommandUtil.execute(myVcs, SvnCommandName.add, parameters, new FileStatusResultParser(CHANGED_PATH, handler, new AddStatusConvertor()));
+ }
+
+ private static List<String> prepareParameters(File file, SVNDepth depth, boolean makeParents, boolean includeIgnored, boolean force) {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, file);
+ CommandUtil.put(parameters, depth);
+ CommandUtil.put(parameters, makeParents, "--parents");
+ CommandUtil.put(parameters, includeIgnored, "--no-ignore");
+ CommandUtil.put(parameters, force, "--force");
+
+ return parameters;
+ }
+
+ private static class AddStatusConvertor implements Convertor<Matcher, SVNEvent> {
+ @Override
+ public SVNEvent convert(Matcher o) {
+ SVNStatusType contentStatus = CommandUtil.getStatusType(o.group(1));
+ String path = o.group(3);
+
+ return new SVNEvent(new File(path), null, null, 0, contentStatus, null, null, null, null, null, null, null,
+ null, null, null);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/add/SvnKitAddClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/SvnKitAddClient.java
new file mode 100644
index 0000000..d6250c7
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/SvnKitAddClient.java
@@ -0,0 +1,39 @@
+package org.jetbrains.idea.svn.add;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNWCClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitAddClient extends BaseSvnClient implements AddClient {
+
+ @Override
+ public void add(@NotNull File file,
+ @Nullable SVNDepth depth,
+ boolean makeParents,
+ boolean includeIgnored,
+ boolean force,
+ @Nullable ISVNEventHandler handler) throws VcsException {
+ try {
+ SVNWCClient client = myVcs.createWCClient();
+
+ client.setEventHandler(handler);
+ client.doAdd(file, force,
+ false, // directory should already be created
+ makeParents, // not used but will be passed as makeParents value
+ SVNDepth.recurseFromDepth(depth));
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java
new file mode 100644
index 0000000..df30cfd
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java
@@ -0,0 +1,24 @@
+package org.jetbrains.idea.svn.annotate;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler;
+import org.tmatesoft.svn.core.wc.SVNDiffOptions;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface AnnotateClient extends SvnClient {
+
+ void annotate(@NotNull SvnTarget target,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean includeMergedRevisions,
+ @Nullable SVNDiffOptions diffOptions,
+ @Nullable ISVNAnnotateHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
new file mode 100644
index 0000000..d29d40ec
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
@@ -0,0 +1,126 @@
+package org.jetbrains.idea.svn.annotate;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommand;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler;
+import org.tmatesoft.svn.core.wc.SVNDiffOptions;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient {
+
+ @Override
+ public void annotate(@NotNull SvnTarget target,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean includeMergedRevisions,
+ @Nullable SVNDiffOptions diffOptions,
+ @Nullable final ISVNAnnotateHandler handler) throws VcsException {
+ // TODO: after merge remove setting includeMergedRevisions to false and update parsing
+ includeMergedRevisions = false;
+
+ List<String> parameters = new ArrayList<String>();
+ CommandUtil.put(parameters, target.getPathOrUrlString(), pegRevision);
+ parameters.add("--revision");
+ parameters.add(startRevision + ":" + endRevision);
+ CommandUtil.put(parameters, includeMergedRevisions, "--use-merge-history");
+ CommandUtil.put(parameters, diffOptions);
+ parameters.add("--xml");
+
+ SvnCommand command = CommandUtil.execute(myVcs, SvnCommandName.blame, parameters, null);
+
+ parseOutput(command.getOutput(), handler);
+ }
+
+ public void parseOutput(@NotNull String output, @Nullable ISVNAnnotateHandler handler) throws VcsException {
+ try {
+ JAXBContext context = JAXBContext.newInstance(BlameInfo.class);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ BlameInfo info = (BlameInfo)unmarshaller.unmarshal(new StringReader(output));
+
+ if (handler != null && info != null && info.target != null && info.target.lineEntries != null) {
+ for (LineEntry entry : info.target.lineEntries) {
+ invokeHandler(handler, entry);
+ }
+ }
+ }
+ catch (JAXBException e) {
+ throw new VcsException(e);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+
+ private static void invokeHandler(ISVNAnnotateHandler handler, LineEntry entry) throws SVNException {
+ // line numbers in our api start from 0 - not from 1 like in svn output
+ handler.handleLine(entry.date(), entry.revision(), entry.author(), null, null, 0, null, null, entry.lineNumber - 1);
+ }
+
+ @XmlRootElement(name = "blame")
+ public static class BlameInfo {
+
+ @XmlElement(name = "target")
+ public TargetEntry target;
+ }
+
+ public static class TargetEntry {
+
+ @XmlElement(name = "entry")
+ List<LineEntry> lineEntries;
+ }
+
+ public static class LineEntry {
+
+ @XmlAttribute(name = "line-number")
+ public int lineNumber;
+
+ @XmlElement(name = "commit")
+ public CommitEntry commit;
+
+ public long revision() {
+ return commit != null ? commit.revision : 0;
+ }
+
+ public String author() {
+ return commit != null ? commit.author : null;
+ }
+
+ public Date date() {
+ return commit != null ? commit.date : null;
+ }
+ }
+
+ public static class CommitEntry {
+
+ @XmlAttribute(name = "revision")
+ public long revision;
+
+ @XmlElement(name = "author")
+ public String author;
+
+ @XmlElement(name = "date")
+ public Date date;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java
index d0885c8..88adf25 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java
@@ -32,14 +32,16 @@
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.history.HistoryClient;
import org.jetbrains.idea.svn.history.SvnChangeList;
import org.jetbrains.idea.svn.history.SvnFileRevision;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
-import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -89,9 +91,8 @@
final String contents;
if (loadExternally) {
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- myVcs.createWCClient().doGetFileContents(ioFile, SVNRevision.UNDEFINED, SVNRevision.BASE, true, buffer);
- contents = LoadTextUtil.getTextByBinaryPresentation(buffer.toByteArray(), file, false, false).toString();
+ byte[] data = SvnUtil.getFileContents(myVcs, SvnTarget.fromFile(ioFile), SVNRevision.BASE, SVNRevision.UNDEFINED);
+ contents = LoadTextUtil.getTextByBinaryPresentation(data, file, false, false).toString();
} else {
final byte[] bytes = VcsHistoryUtil.loadRevisionContent(revision);
contents = LoadTextUtil.getTextByBinaryPresentation(bytes, file, false, false).toString();
@@ -99,16 +100,13 @@
final SvnFileAnnotation result = new SvnFileAnnotation(myVcs, file, contents, lastChangedRevision);
- SVNWCClient wcClient = myVcs.createWCClient();
- info = wcClient.doInfo(ioFile, SVNRevision.UNDEFINED);
+ info = myVcs.getInfo(ioFile);
if (info == null) {
exception[0] = new VcsException(new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, "File ''{0}'' is not under version control", ioFile)));
return;
}
final String url = info.getURL() == null ? null : info.getURL().toString();
- SVNLogClient client = myVcs.createLogClient();
- setLogClientOptions(client);
SVNRevision endRevision = ((SvnFileRevision) revision).getRevision();
if (SVNRevision.WORKING.equals(endRevision)) {
endRevision = info.getRevision();
@@ -122,14 +120,20 @@
final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).SHOW_MERGE_SOURCES_IN_ANNOTATE &&
SvnUtil.checkRepositoryVersion15(myVcs, url);
- final SVNRevision svnRevision = ((SvnRevisionNumber)revision.getRevisionNumber()).getRevision();
+ final MySteppedLogGetter logGetter = new MySteppedLogGetter(
+ myVcs, ioFile, progress,
+ myVcs.getFactory(ioFile).createHistoryClient(), endRevision, result,
+ url, calculateMergeinfo, file.getCharset());
- final MySteppedLogGetter logGetter = new MySteppedLogGetter(myVcs, ioFile, progress, client, endRevision, result, url, calculateMergeinfo, file.getCharset());
logGetter.go();
final LinkedList<SVNRevision> rp = logGetter.getRevisionPoints();
+ // TODO: only 2 elements will be in rp and for loop will be executed only once - probably rewrite with Pair
+ AnnotateClient annotateClient = myVcs.getFactory(ioFile).createAnnotateClient();
for (int i = 0; i < rp.size() - 1; i++) {
- client.doAnnotate(ioFile, svnRevision, rp.get(i + 1), rp.get(i), true, calculateMergeinfo, annotateHandler, null);
+ annotateClient.annotate(SvnTarget.fromFile(ioFile), rp.get(i + 1), rp.get(i), ((SvnFileRevision)revision).getPegRevision(),
+ calculateMergeinfo,
+ getLogClientOptions(myVcs), annotateHandler);
}
if (rp.get(1).getNumber() > 0) {
@@ -137,31 +141,15 @@
}
annotation[0] = result;
}
- catch (SVNException e) {
- if (SVNErrorCode.FS_NOT_FOUND.equals(e.getErrorMessage().getErrorCode())) {
- final CommittedChangesProvider<SvnChangeList,ChangeBrowserSettings> provider = myVcs.getCommittedChangesProvider();
- try {
- final Pair<SvnChangeList, FilePath> pair = provider.getOneList(file, revision.getRevisionNumber());
- if (pair != null && info != null && pair.getSecond() != null && ! Comparing.equal(pair.getSecond().getIOFile(), ioFile)) {
- annotation[0] = annotateNonExisting(pair, revision, info, file.getCharset(), file);
- return;
- }
- }
- catch (VcsException e1) {
- exception[0] = e1;
- }
- catch (SVNException e1) {
- exception[0] = new VcsException(e);
- }
- catch (IOException e1) {
- exception[0] = new VcsException(e);
- }
- }
- exception[0] = new VcsException(e);
- } catch (IOException e) {
+ catch (IOException e) {
exception[0] = new VcsException(e);
} catch (VcsException e) {
- exception[0] = e;
+ if (e.getCause() instanceof SVNException) {
+ handleSvnException(ioFile, info, (SVNException)e.getCause(), file, revision, annotation, exception);
+ }
+ else {
+ exception[0] = e;
+ }
}
}
};
@@ -177,6 +165,35 @@
return annotation[0];
}
+ private void handleSvnException(File ioFile,
+ SVNInfo info,
+ SVNException e,
+ VirtualFile file,
+ VcsFileRevision revision,
+ FileAnnotation[] annotation, VcsException[] exception) {
+ // TODO: Check how this scenario could be reproduced by user and what changes needs to be done for command line client
+ if (SVNErrorCode.FS_NOT_FOUND.equals(e.getErrorMessage().getErrorCode())) {
+ final CommittedChangesProvider<SvnChangeList,ChangeBrowserSettings> provider = myVcs.getCommittedChangesProvider();
+ try {
+ final Pair<SvnChangeList, FilePath> pair = provider.getOneList(file, revision.getRevisionNumber());
+ if (pair != null && info != null && pair.getSecond() != null && ! Comparing.equal(pair.getSecond().getIOFile(), ioFile)) {
+ annotation[0] = annotateNonExisting(pair, revision, info, file.getCharset(), file);
+ return;
+ }
+ }
+ catch (VcsException e1) {
+ exception[0] = e1;
+ }
+ catch (SVNException e1) {
+ exception[0] = new VcsException(e);
+ }
+ catch (IOException e1) {
+ exception[0] = new VcsException(e);
+ }
+ }
+ exception[0] = new VcsException(e);
+ }
+
public static File getCommonAncestor(final File file1, final File file2) throws IOException {
if (FileUtil.filesEqual(file1, file2)) return file1;
final File can1 = file1.getCanonicalFile();
@@ -214,8 +231,7 @@
final String relativePath = FileUtil.getRelativePath(root.getPath(), wasFile.getPath(), File.separatorChar);
if (relativePath == null) throw new VcsException("Can not find relative path for " + wasFile.getPath() + "@" + revision.getRevisionNumber().asString());
- SVNWCClient wcClient = myVcs.createWCClient();
- SVNInfo wcRootInfo = wcClient.doInfo(root, SVNRevision.UNDEFINED);
+ SVNInfo wcRootInfo = myVcs.getInfo(root);
if (wcRootInfo == null || wcRootInfo.getURL() == null) {
throw new VcsException("Can not find relative path for " + wasFile.getPath() + "@" + revision.getRevisionNumber().asString());
}
@@ -225,21 +241,18 @@
wasUrl = wasUrl.appendPath(string, true);
}
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
final SVNRevision svnRevision = ((SvnRevisionNumber)revision.getRevisionNumber()).getRevision();
- myVcs.createWCClient().doGetFileContents(wasUrl, svnRevision, svnRevision, true, buffer);
- final String contents = LoadTextUtil.getTextByBinaryPresentation(buffer.toByteArray(),
- charset == null ? CharsetToolkit.UTF8_CHARSET : charset).toString();
- SVNLogClient client = myVcs.createLogClient();
- setLogClientOptions(client);
+ byte[] data = SvnUtil.getFileContents(myVcs, SvnTarget.fromURL(wasUrl), svnRevision, svnRevision);
+ final String contents = LoadTextUtil.getTextByBinaryPresentation(data, charset == null ? CharsetToolkit.UTF8_CHARSET : charset).toString();
final SvnRemoteFileAnnotation result = new SvnRemoteFileAnnotation(myVcs, contents, revision.getRevisionNumber(), pair.getFirst(),
pair.getSecond().getPath(), current);
final ISVNAnnotateHandler annotateHandler = createAnnotationHandler(ProgressManager.getInstance().getProgressIndicator(), result);
final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).SHOW_MERGE_SOURCES_IN_ANNOTATE &&
SvnUtil.checkRepositoryVersion15(myVcs, wasUrl.toString());
- client.doAnnotate(wasUrl, svnRevision, SVNRevision.create(1), svnRevision, true, calculateMergeinfo, annotateHandler, null);
-
+ AnnotateClient client = myVcs.getFactory().createAnnotateClient();
+ client.annotate(SvnTarget.fromURL(wasUrl), SVNRevision.create(1), svnRevision, svnRevision, calculateMergeinfo,
+ getLogClientOptions(myVcs), annotateHandler);
return result;
}
@@ -370,14 +383,14 @@
private final SvnVcs myVcs;
private final File myIoFile;
private final ProgressIndicator myProgress;
- private final SVNLogClient myClient;
+ private final HistoryClient myClient;
private final SVNRevision myEndRevision;
private final boolean myCalculateMergeinfo;
private final SvnFileAnnotation myResult;
private final String myUrl;
private final Charset myCharset;
- private MySteppedLogGetter(final SvnVcs vcs, final File ioFile, final ProgressIndicator progress, final SVNLogClient client,
+ private MySteppedLogGetter(final SvnVcs vcs, final File ioFile, final ProgressIndicator progress, final HistoryClient client,
final SVNRevision endRevision,
final SvnFileAnnotation result,
final String url,
@@ -395,7 +408,7 @@
myRevisionPoints = new LinkedList<SVNRevision>();
}
- public void go() throws SVNException {
+ public void go() throws VcsException {
final int maxAnnotateRevisions = SvnConfiguration.getInstance(myVcs.getProject()).getMaxAnnotateRevisions();
boolean longHistory = true;
if (maxAnnotateRevisions == -1) {
@@ -437,8 +450,8 @@
myRevisionPoints.add(SVNRevision.create(0));
}
- private void doLog(final boolean includeMerged, final SVNRevision truncateTo, final int max) throws SVNException {
- myClient.doLog(new File[]{myIoFile}, myEndRevision, truncateTo == null ? SVNRevision.create(1L) : truncateTo,
+ private void doLog(final boolean includeMerged, final SVNRevision truncateTo, final int max) throws VcsException {
+ myClient.doLog(myIoFile, myEndRevision, truncateTo == null ? SVNRevision.create(1L) : truncateTo,
SVNRevision.UNDEFINED, false, false, includeMerged, max, null,
new ISVNLogEntryHandler() {
public void handleLogEntry(SVNLogEntry logEntry) {
@@ -464,9 +477,7 @@
return true;
}
- private void setLogClientOptions(final SVNLogClient client) {
- if (SvnConfiguration.getInstance(myVcs.getProject()).IGNORE_SPACES_IN_ANNOTATE) {
- client.setDiffOptions(new SVNDiffOptions(true, true, true));
- }
+ private static SVNDiffOptions getLogClientOptions(@NotNull SvnVcs vcs) {
+ return SvnConfiguration.getInstance(vcs.getProject()).IGNORE_SPACES_IN_ANNOTATE ? new SVNDiffOptions(true, true, true) : null;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java
new file mode 100644
index 0000000..315178c
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java
@@ -0,0 +1,42 @@
+package org.jetbrains.idea.svn.annotate;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler;
+import org.tmatesoft.svn.core.wc.SVNDiffOptions;
+import org.tmatesoft.svn.core.wc.SVNLogClient;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitAnnotateClient extends BaseSvnClient implements AnnotateClient {
+
+ @Override
+ public void annotate(@NotNull SvnTarget target,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean includeMergedRevisions,
+ @Nullable SVNDiffOptions diffOptions,
+ @Nullable ISVNAnnotateHandler handler) throws VcsException {
+ try {
+ SVNLogClient client = myVcs.createLogClient();
+
+ client.setDiffOptions(diffOptions);
+ if (target.isFile()) {
+ client.doAnnotate(target.getFile(), pegRevision, startRevision, endRevision, true, includeMergedRevisions, handler, null);
+ }
+ else {
+ client.doAnnotate(target.getURL(), pegRevision, startRevision, endRevision, true, includeMergedRevisions, handler, null);
+ }
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java
new file mode 100644
index 0000000..54401cf
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java
@@ -0,0 +1,22 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public abstract class BaseSvnClient implements SvnClient {
+ protected SvnVcs myVcs;
+
+ @NotNull
+ @Override
+ public SvnVcs getVcs() {
+ return myVcs;
+ }
+
+ @Override
+ public void setVcs(@NotNull SvnVcs vcs) {
+ myVcs = vcs;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
new file mode 100644
index 0000000..b851216
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
@@ -0,0 +1,99 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.add.AddClient;
+import org.jetbrains.idea.svn.annotate.AnnotateClient;
+import org.jetbrains.idea.svn.conflict.ConflictClient;
+import org.jetbrains.idea.svn.content.ContentClient;
+import org.jetbrains.idea.svn.copy.CopyMoveClient;
+import org.jetbrains.idea.svn.delete.DeleteClient;
+import org.jetbrains.idea.svn.history.HistoryClient;
+import org.jetbrains.idea.svn.portable.SvnStatusClientI;
+import org.jetbrains.idea.svn.properties.PropertyClient;
+import org.jetbrains.idea.svn.revert.RevertClient;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public abstract class ClientFactory {
+
+ @NotNull
+ protected SvnVcs myVcs;
+
+ protected AddClient addClient;
+ protected AnnotateClient annotateClient;
+ protected ContentClient contentClient;
+ protected HistoryClient historyClient;
+ protected RevertClient revertClient;
+ protected DeleteClient deleteClient;
+ protected SvnStatusClientI statusClient;
+ protected CopyMoveClient copyMoveClient;
+ protected ConflictClient conflictClient;
+ protected PropertyClient propertyClient;
+
+ protected ClientFactory(@NotNull SvnVcs vcs) {
+ myVcs = vcs;
+ setup();
+ }
+
+ protected abstract void setup();
+
+ @NotNull
+ public AddClient createAddClient() {
+ return prepare(addClient);
+ }
+
+ @NotNull
+ public AnnotateClient createAnnotateClient() {
+ return prepare(annotateClient);
+ }
+
+ @NotNull
+ public ContentClient createContentClient() {
+ return prepare(contentClient);
+ }
+
+ @NotNull
+ public HistoryClient createHistoryClient() {
+ return prepare(historyClient);
+ }
+
+ @NotNull
+ public RevertClient createRevertClient() {
+ return prepare(revertClient);
+ }
+
+ @NotNull
+ public SvnStatusClientI createStatusClient() {
+ // TODO: Update this in same like other clients - move to corresponding package, rename clients
+ return statusClient;
+ }
+
+ @NotNull
+ public DeleteClient createDeleteClient() {
+ return prepare(deleteClient);
+ }
+
+ @NotNull
+ public CopyMoveClient createCopyMoveClient() {
+ return prepare(copyMoveClient);
+ }
+
+ @NotNull
+ public ConflictClient createConflictClient() {
+ return prepare(conflictClient);
+ }
+
+ @NotNull
+ public PropertyClient createPropertyClient() {
+ return prepare(propertyClient);
+ }
+
+ @NotNull
+ protected <T extends SvnClient> T prepare(@NotNull T client) {
+ client.setVcs(myVcs);
+
+ return client;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
new file mode 100644
index 0000000..ca4088b
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
@@ -0,0 +1,38 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.add.CmdAddClient;
+import org.jetbrains.idea.svn.annotate.CmdAnnotateClient;
+import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
+import org.jetbrains.idea.svn.conflict.CmdConflictClient;
+import org.jetbrains.idea.svn.content.CmdContentClient;
+import org.jetbrains.idea.svn.copy.CmdCopyMoveClient;
+import org.jetbrains.idea.svn.delete.CmdDeleteClient;
+import org.jetbrains.idea.svn.history.CmdHistoryClient;
+import org.jetbrains.idea.svn.properties.CmdPropertyClient;
+import org.jetbrains.idea.svn.revert.CmdRevertClient;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdClientFactory extends ClientFactory {
+
+ public CmdClientFactory(@NotNull SvnVcs vcs) {
+ super(vcs);
+ }
+
+ @Override
+ protected void setup() {
+ addClient = new CmdAddClient();
+ annotateClient = new CmdAnnotateClient();
+ contentClient = new CmdContentClient();
+ historyClient = new CmdHistoryClient();
+ revertClient = new CmdRevertClient();
+ deleteClient = new CmdDeleteClient();
+ copyMoveClient = new CmdCopyMoveClient();
+ conflictClient = new CmdConflictClient();
+ propertyClient = new CmdPropertyClient();
+ statusClient = new SvnCommandLineStatusClient(myVcs.getProject());
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/FileStatusResultParser.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/FileStatusResultParser.java
new file mode 100644
index 0000000..fc202c2
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/FileStatusResultParser.java
@@ -0,0 +1,68 @@
+package org.jetbrains.idea.svn.api;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.containers.Convertor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class FileStatusResultParser {
+
+ private static final double DEFAULT_PROGRESS = 0.0;
+
+ @NotNull
+ private Pattern myLinePattern;
+
+ @Nullable
+ private ISVNEventHandler handler;
+
+ @NotNull
+ private Convertor<Matcher, SVNEvent> myConvertor;
+
+ public FileStatusResultParser(@NotNull Pattern linePattern,
+ @Nullable ISVNEventHandler handler,
+ @NotNull Convertor<Matcher, SVNEvent> convertor) {
+ myLinePattern = linePattern;
+ this.handler = handler;
+ myConvertor = convertor;
+ }
+
+ public void parse(@NotNull String output) throws VcsException {
+ if (StringUtil.isEmpty(output)) {
+ return;
+ }
+
+ for (String line : StringUtil.splitByLines(output)) {
+ onLine(line);
+ }
+ }
+
+ public void onLine(@NotNull String line) throws VcsException {
+ Matcher matcher = myLinePattern.matcher(line);
+ if (matcher.matches()) {
+ process(matcher);
+ }
+ else {
+ throw new VcsException("unknown state on line " + line);
+ }
+ }
+
+ public void process(@NotNull Matcher matcher) throws VcsException {
+ if (handler != null) {
+ try {
+ handler.handleEvent(myConvertor.convert(matcher), DEFAULT_PROGRESS);
+ } catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java
new file mode 100644
index 0000000..90124f1
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java
@@ -0,0 +1,15 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface SvnClient {
+
+ @NotNull
+ SvnVcs getVcs();
+
+ void setVcs(@NotNull SvnVcs vcs);
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
new file mode 100644
index 0000000..7e19518
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
@@ -0,0 +1,38 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.add.SvnKitAddClient;
+import org.jetbrains.idea.svn.annotate.SvnKitAnnotateClient;
+import org.jetbrains.idea.svn.conflict.SvnKitConflictClient;
+import org.jetbrains.idea.svn.content.SvnKitContentClient;
+import org.jetbrains.idea.svn.copy.SvnKitCopyMoveClient;
+import org.jetbrains.idea.svn.delete.SvnKitDeleteClient;
+import org.jetbrains.idea.svn.history.SvnKitHistoryClient;
+import org.jetbrains.idea.svn.portable.SvnkitSvnStatusClient;
+import org.jetbrains.idea.svn.properties.SvnKitPropertyClient;
+import org.jetbrains.idea.svn.revert.SvnKitRevertClient;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitClientFactory extends ClientFactory {
+
+ public SvnKitClientFactory(@NotNull SvnVcs vcs) {
+ super(vcs);
+ }
+
+ @Override
+ protected void setup() {
+ addClient = new SvnKitAddClient();
+ annotateClient = new SvnKitAnnotateClient();
+ contentClient = new SvnKitContentClient();
+ historyClient = new SvnKitHistoryClient();
+ revertClient = new SvnKitRevertClient();
+ deleteClient = new SvnKitDeleteClient();
+ copyMoveClient = new SvnKitCopyMoveClient();
+ conflictClient = new SvnKitConflictClient();
+ propertyClient = new SvnKitPropertyClient();
+ statusClient = new SvnkitSvnStatusClient(myVcs.createStatusClient());
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java
index 021568a..2b779fd 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java
@@ -49,7 +49,7 @@
final SvnVcs vcs = SvnVcs.getInstance(project);
File rootFile = new File(vcsRoot.getPath());
- final SVNInfo info = vcs.createWCClient().doInfo(rootFile, SVNRevision.UNDEFINED);
+ final SVNInfo info = vcs.getInfo(rootFile);
if (info == null || info.getURL() == null) {
LOG.info("Directory is not a working copy: " + vcsRoot.getPresentableUrl());
return null;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java
index 28e74e7..483bfda 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java
@@ -223,9 +223,8 @@
private BranchRootSearcher(final SvnVcs vcs, final VirtualFile root) throws SVNException {
myRoot = root;
myBranchesUnder = new HashMap<String, String>();
- final SVNWCClient client = vcs.createWCClient();
- final SVNInfo info = client.doInfo(new File(myRoot.getPath()), SVNRevision.UNDEFINED);
- myRootUrl = info.getURL();
+ final SVNInfo info = vcs.getInfo(myRoot.getPath());
+ myRootUrl = info != null ? info.getURL() : null;
}
public boolean accept(final String url) throws SVNException {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
index 3bd8256..5ac6b96 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
@@ -16,8 +16,8 @@
package org.jetbrains.idea.svn.checkin;
import com.intellij.openapi.progress.ProgressIndicator;
-import org.jetbrains.idea.svn.CommitEventHandler;
-import org.jetbrains.idea.svn.CommitEventType;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
+import org.jetbrains.idea.svn.commandLine.CommitEventType;
import org.jetbrains.idea.svn.SvnBundle;
import java.io.File;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaSvnkitBasedAuthenticationCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaSvnkitBasedAuthenticationCallback.java
index 995646f..f765595 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaSvnkitBasedAuthenticationCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaSvnkitBasedAuthenticationCallback.java
@@ -28,6 +28,7 @@
import com.intellij.util.proxy.CommonProxy;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.commandLine.AuthenticationCallback;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.*;
import org.tmatesoft.svn.core.internal.util.SVNBase64;
@@ -77,6 +78,20 @@
return new CredentialsAuthenticator(myVcs).tryAuthenticate(realm, url, file, previousFailed, passwordRequest);
}
+ @Nullable
+ @Override
+ public SVNAuthentication requestCredentials(@Nullable SVNURL url, String type) {
+ SVNAuthentication authentication =
+ url != null ? myVcs.getSvnConfiguration().getInteractiveManager(myVcs).getProvider().requestClientAuthentication(
+ type, url, url.toDecodedString(), null, null, true) : null;
+
+ if (authentication == null) {
+ LOG.warn("Could not get authentication. Type - " + type + ", Url - " + url);
+ }
+
+ return authentication;
+ }
+
@Override
public boolean acceptSSLServerCertificate(final File file, final String realm) {
final File base = getExistingParent(file);
@@ -354,7 +369,9 @@
}, new ThrowableRunnable<SVNException>() {
@Override
public void run() throws SVNException {
+ // NOTE: DO NOT replace this call - SSL authentication highly tied to SVNKit
myVcs.createWCClient(active).doInfo(myUrl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
+ //myVcs.getInfo(myUrl, SVNRevision.HEAD, active);
}
}
);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
index 433e406..c7d2d4b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
@@ -48,8 +48,8 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.commandLine.SvnBindClient;
import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
-import org.tigris.subversion.javahl.ClientException;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
@@ -177,7 +177,7 @@
if (committables.isEmpty()) {
return;
}
- if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format) &&
+ if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format) &&
SvnConfiguration.UseAcceleration.commandLine.equals(SvnConfiguration.getInstance(mySvnVcs.getProject()).myUseAcceleration) &&
(SvnAuthenticationManager.HTTP.equals(url.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(url.getProtocol()))) {
doWithCommandLine(committables, comment, exception, feedback);
@@ -256,14 +256,25 @@
});
final IdeaSvnkitBasedAuthenticationCallback authenticationCallback = new IdeaSvnkitBasedAuthenticationCallback(mySvnVcs);
try {
- final SvnBindClient client = new SvnBindClient(SvnApplicationSettings.getInstance().getCommandLinePath());
+ final SvnBindClient client = new SvnBindClient(SvnApplicationSettings.getInstance().getCommandLinePath(), new Convertor<String[], SVNURL>() {
+ @Override
+ public SVNURL convert(String[] o) {
+ SVNInfo info = o.length > 0 ? mySvnVcs.getInfo(o[0]) : null;
+
+ if (info == null || info.getURL() == null) {
+ LOG.warn("Could not resolve repository url for commit. Paths - " + Arrays.toString(o));
+ }
+
+ return info != null ? info.getURL() : null;
+ }
+ });
client.setAuthenticationCallback(authenticationCallback);
client.setHandler(new IdeaCommitHandler(ProgressManager.getInstance().getProgressIndicator()));
final long revision = client.commit(ArrayUtil.toStringArray(paths), comment, false, false);
reportCommittedRevisions(feedback, String.valueOf(revision));
}
- catch (ClientException e) {
- exception.add(new VcsException(e));
+ catch (VcsException e) {
+ exception.add(e);
} finally {
authenticationCallback.reset();
}
@@ -348,25 +359,19 @@
private List<File> getCommitables(List<File> paths) {
final Adder adder = new Adder();
- SVNStatusClient statusClient = mySvnVcs.createStatusClient();
for (File path : paths) {
File file = path.getAbsoluteFile();
adder.add(file);
if (file.getParentFile() != null) {
- addParents(statusClient, file.getParentFile(), adder);
+ addParents(file.getParentFile(), adder);
}
}
return adder.getResult();
}
- private static void addParents(SVNStatusClient statusClient, File file, final Adder adder) {
- SVNStatus status;
- try {
- status = statusClient.doStatus(file, false);
- }
- catch (SVNException e) {
- return;
- }
+ private void addParents(File file, final Adder adder) {
+ SVNStatus status = getStatus(file);
+
if (status != null &&
(SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_ADDED) ||
SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_REPLACED))) {
@@ -374,11 +379,33 @@
adder.add(file);
file = file.getParentFile();
if (file != null) {
- addParents(statusClient, file, adder);
+ addParents(file, adder);
}
}
}
+ private SVNStatus getStatus(File file) {
+ SVNStatus result = null;
+ WorkingCopyFormat format = mySvnVcs.getWorkingCopyFormat(file);
+
+ try {
+ result = WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ? getStatusCommandLine(file) : getStatusSvnKit(file);
+ }
+ catch (SVNException e) {
+ // do nothing
+ }
+
+ return result;
+ }
+
+ private SVNStatus getStatusSvnKit(File file) throws SVNException {
+ return mySvnVcs.createStatusClient().doStatus(file, false);
+ }
+
+ private SVNStatus getStatusCommandLine(File file) throws SVNException {
+ return new SvnCommandLineStatusClient(mySvnVcs.getProject()).doStatus(file, false);
+ }
+
private static List<File> collectPaths(final List<Change> changes) {
// case sensitive..
ArrayList<File> result = new ArrayList<File>();
@@ -418,15 +445,14 @@
public List<VcsException> scheduleMissingFileForDeletion(List<FilePath> filePaths) {
List<VcsException> exceptions = new ArrayList<VcsException>();
- final SVNWCClient wcClient = mySvnVcs.createWCClient();
-
List<File> files = ChangesUtil.filePathsToFiles(filePaths);
+
for (File file : files) {
try {
- wcClient.doDelete(file, true, false);
+ mySvnVcs.getFactory(file).createDeleteClient().delete(file, true);
}
- catch (SVNException e) {
- exceptions.add(new VcsException(e));
+ catch (VcsException e) {
+ exceptions.add(e);
}
}
@@ -434,30 +460,22 @@
}
public List<VcsException> scheduleUnversionedFilesForAddition(List<VirtualFile> files) {
- final List<VcsException> result = new ArrayList<VcsException>();
- final SVNWCClient wcClient = mySvnVcs.createWCClient();
-
- final List<SVNException> exceptionList = scheduleUnversionedFilesForAddition(wcClient, files);
- for (SVNException svnException : exceptionList) {
- result.add(new VcsException(svnException));
- }
- return result;
+ return scheduleUnversionedFilesForAddition(mySvnVcs, files);
}
- public static List<SVNException> scheduleUnversionedFilesForAddition(SVNWCClient wcClient, List<VirtualFile> files) {
- return scheduleUnversionedFilesForAddition(wcClient, files, false);
+ public static List<VcsException> scheduleUnversionedFilesForAddition(@NotNull SvnVcs vcs, List<VirtualFile> files) {
+ return scheduleUnversionedFilesForAddition(vcs, files, false);
}
- public static List<SVNException> scheduleUnversionedFilesForAddition(SVNWCClient wcClient, List<VirtualFile> files, final boolean recursive) {
- List<SVNException> exceptions = new ArrayList<SVNException>();
-
+ public static List<VcsException> scheduleUnversionedFilesForAddition(@NotNull SvnVcs vcs, List<VirtualFile> files, final boolean recursive) {
Collections.sort(files, FilePathComparator.getInstance());
- wcClient.setEventHandler(new ISVNEventHandler() {
+ ISVNEventHandler eventHandler = new ISVNEventHandler() {
@Override
public void handleEvent(SVNEvent event, double progress) throws SVNException {
final ProgressManager pm = ProgressManager.getInstance();
final ProgressIndicator pi = pm.getProgressIndicator();
+ // TODO: pi is null here when invoking "Add" action
if (pi != null && event.getFile() != null) {
File file = event.getFile();
pi.setText(SvnBundle.message("progress.text2.adding", file.getName() + " (" + file.getParent() + ")"));
@@ -472,12 +490,18 @@
if (pi.isCanceled()) throw new SVNCancelException();
}
}
- });
+ };
+
+ List<VcsException> exceptions = new ArrayList<VcsException>();
+
for (VirtualFile file : files) {
try {
- wcClient.doAdd(new File(FileUtil.toSystemDependentName(file.getPath())), true, false, true, recursive);
+ File convertedFile = new File(FileUtil.toSystemDependentName(file.getPath()));
+ SVNDepth depth = recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY;
+
+ vcs.getFactory(convertedFile).createAddClient().add(convertedFile, depth, true, false, true, eventHandler);
}
- catch (SVNException e) {
+ catch (VcsException e) {
exceptions.add(e);
}
}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/AuthenticationCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java
similarity index 87%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/AuthenticationCallback.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java
index bdc9c2d..1944749 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/AuthenticationCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java
@@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
import org.jetbrains.annotations.Nullable;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.auth.SVNAuthentication;
import java.io.File;
import java.io.IOException;
@@ -51,6 +53,17 @@
boolean authenticateFor(@Nullable String realm, File base, boolean previousFailed, boolean passwordRequest);
/**
+ * Provides authentication information to access given url by authentication protocol identified by type.
+ * For instance, username/password for http/svn protocols. SSL client certificate for two way SSL protocol.
+ *
+ * @param url url to item in repository
+ * @param type authentication protocol type with svn specific values, like "svn.simple" for http.
+ * @return
+ */
+ @Nullable
+ SVNAuthentication requestCredentials(@Nullable SVNURL url, String type);
+
+ /**
* @return config directory if TMP was created
*/
@Nullable
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
new file mode 100644
index 0000000..737d8a8
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
@@ -0,0 +1,218 @@
+package org.jetbrains.idea.svn.commandLine;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.SvnApplicationSettings;
+import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.api.FileStatusResultParser;
+import org.jetbrains.idea.svn.checkin.IdeaSvnkitBasedAuthenticationCallback;
+import org.tmatesoft.svn.core.*;
+import org.tmatesoft.svn.core.wc.SVNDiffOptions;
+import org.tmatesoft.svn.core.wc.SVNInfo;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNStatusType;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CommandUtil {
+ public static SvnLineCommand runSimple(@NotNull SvnCommandName name,
+ @NotNull SvnVcs vcs,
+ @Nullable File base,
+ @Nullable SVNURL url,
+ List<String> parameters)
+ throws SVNException {
+ String exe = resolveExePath();
+ base = resolveBaseDirectory(base, exe);
+ url = resolveRepositoryUrl(vcs, url);
+
+ try {
+ return SvnLineCommand
+ .runWithAuthenticationAttempt(exe, base, url, name, new SvnCommitRunner.CommandListener(null),
+ new IdeaSvnkitBasedAuthenticationCallback(vcs), ArrayUtil.toStringArray(parameters));
+ }
+ catch (SvnBindException e) {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
+ }
+ }
+
+ @Nullable
+ private static SVNURL resolveRepositoryUrl(@NotNull SvnVcs vcs, @Nullable SVNURL url) {
+ if (url == null) {
+ // TODO: or take it from RootUrlInfo
+ SVNInfo info = vcs.getInfo(vcs.getProject().getBaseDir());
+
+ url = info != null ? info.getURL() : null;
+ }
+ return url;
+ }
+
+ @NotNull
+ private static File resolveBaseDirectory(@Nullable File base, @NotNull String defaultBase) {
+ return base == null ? new File(defaultBase) : base;
+ }
+
+ @NotNull
+ private static String resolveExePath() {
+ return SvnApplicationSettings.getInstance().getCommandLinePath();
+ }
+
+ public static SvnLineCommand runSimple(@NotNull SvnSimpleCommand command, @NotNull SvnVcs vcs, @Nullable File base, @Nullable SVNURL url)
+ throws SVNException {
+ // empty command name passed, as command name is already in command.getParameters()
+ return runSimple(SvnCommandName.empty, vcs, base, url, new ArrayList<String>(Arrays.asList(command.getParameters())));
+ }
+
+ /**
+ * Puts given value to parameters if condition is satisfied
+ *
+ * @param parameters
+ * @param condition
+ * @param value
+ */
+ public static void put(@NotNull List<String> parameters, boolean condition, @NotNull String value) {
+ if (condition) {
+ parameters.add(value);
+ }
+ }
+
+ public static void put(@NotNull List<String> parameters, @NotNull File path) {
+ parameters.add(path.getAbsolutePath());
+ }
+
+ public static void put(@NotNull List<String> parameters, @NotNull File path, @Nullable SVNRevision pegRevision) {
+ put(parameters, path.getAbsolutePath(), pegRevision);
+ }
+
+ public static void put(@NotNull List<String> parameters, @NotNull String path, @Nullable SVNRevision pegRevision) {
+ StringBuilder builder = new StringBuilder(path);
+
+ if (pegRevision != null && !SVNRevision.UNDEFINED.equals(pegRevision) && !SVNRevision.WORKING.equals(pegRevision) &&
+ pegRevision.getNumber() > 0) {
+ builder.append("@");
+ builder.append(pegRevision);
+ }
+
+ parameters.add(builder.toString());
+ }
+
+ public static void put(@NotNull List<String> parameters, @NotNull File... paths) {
+ for (File path : paths) {
+ put(parameters, path);
+ }
+ }
+
+ public static void put(@NotNull List<String> parameters, @Nullable SVNDepth depth) {
+ if (depth != null && !SVNDepth.UNKNOWN.equals(depth)) {
+ parameters.add("--depth");
+ parameters.add(depth.getName());
+ }
+ }
+
+ public static void put(@NotNull List<String> parameters, @Nullable SVNRevision revision) {
+ if (revision != null && !SVNRevision.UNDEFINED.equals(revision) && !SVNRevision.WORKING.equals(revision) && revision.getNumber() >= 0) {
+ parameters.add("--revision");
+ parameters.add(revision.toString());
+ }
+ }
+
+ public static void put(@NotNull List<String> parameters, @Nullable SVNDiffOptions diffOptions) {
+ if (diffOptions != null) {
+ StringBuilder builder = new StringBuilder();
+
+ if (diffOptions.isIgnoreAllWhitespace()) {
+ builder.append(" --ignore-space-change");
+ }
+ if (diffOptions.isIgnoreAmountOfWhitespace()) {
+ builder.append(" --ignore-all-space");
+ }
+ if (diffOptions.isIgnoreEOLStyle()) {
+ builder.append(" --ignore-eol-style");
+ }
+
+ String value = builder.toString().trim();
+
+ if (!StringUtil.isEmpty(value)) {
+ parameters.add("--extensions");
+ parameters.add(value);
+ }
+ }
+ }
+
+ /**
+ * Utility method for running commands changing certain file status information.
+ * // TODO: Should be replaced with non-static analogue.
+ *
+ * @param vcs
+ * @param name
+ * @param parameters
+ * @param parser
+ * @throws VcsException
+ */
+ public static SvnCommand execute(@NotNull SvnVcs vcs,
+ @NotNull SvnCommandName name,
+ @NotNull List<String> parameters,
+ @Nullable FileStatusResultParser parser)
+ throws VcsException {
+ String exe = resolveExePath();
+ File base = resolveBaseDirectory(null, exe);
+ SVNURL url = resolveRepositoryUrl(vcs, null);
+
+ SvnLineCommand command = SvnLineCommand.runWithAuthenticationAttempt(
+ exe, base, url, name, new SvnCommitRunner.CommandListener(null),
+ new IdeaSvnkitBasedAuthenticationCallback(vcs),
+ ArrayUtil.toStringArray(parameters));
+
+ if (parser != null) {
+ parser.parse(command.getOutput());
+ }
+
+ return command;
+ }
+
+ /**
+ * Gets svn status represented by single character.
+ *
+ * @param type
+ * @return
+ */
+ public static char getStatusChar(@Nullable String type) {
+ return !StringUtil.isEmpty(type) ? type.charAt(0) : ' ';
+ }
+
+ @NotNull
+ public static SVNStatusType getStatusType(@Nullable String type) {
+ return getStatusType(getStatusChar(type));
+ }
+
+ @NotNull
+ public static SVNStatusType getStatusType(char first) {
+ final SVNStatusType contentsStatus;
+ if ('A' == first) {
+ contentsStatus = SVNStatusType.STATUS_ADDED;
+ } else if ('D' == first) {
+ contentsStatus = SVNStatusType.STATUS_DELETED;
+ } else if ('U' == first) {
+ contentsStatus = SVNStatusType.CHANGED;
+ } else if ('C' == first) {
+ contentsStatus = SVNStatusType.CONFLICTED;
+ } else if ('G' == first) {
+ contentsStatus = SVNStatusType.MERGED;
+ } else if ('R' == first) {
+ contentsStatus = SVNStatusType.STATUS_REPLACED;
+ } else if ('E' == first) {
+ contentsStatus = SVNStatusType.STATUS_OBSTRUCTED;
+ } else {
+ contentsStatus = SVNStatusType.STATUS_NORMAL;
+ }
+ return contentsStatus;
+ }
+}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventHandler.java
similarity index 95%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventHandler.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventHandler.java
index 7f3bcf3..d748840 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventHandler.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
import java.io.File;
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventType.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
similarity index 96%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventType.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
index 46609e4..87dc212 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventType.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
/**
* Created with IntelliJ IDEA.
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java
similarity index 100%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindClient.java
new file mode 100644
index 0000000..8f14cb2
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindClient.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.svn.commandLine;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.containers.Convertor;
+import org.tmatesoft.svn.core.SVNURL;
+
+import java.util.Map;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 2/5/13
+ * Time: 3:08 PM
+ */
+public class SvnBindClient {
+ private final String myExecutablePath;
+ private CommitEventHandler myHandler;
+ private AuthenticationCallback myAuthenticationCallback;
+ private Convertor<String[], SVNURL> myUrlProvider;
+
+ public SvnBindClient(String path, Convertor<String[], SVNURL> urlProvider) {
+ myExecutablePath = path;
+ myUrlProvider = urlProvider;
+ }
+
+ public long commit(String[] path, String message, boolean recurse, boolean noUnlock) throws VcsException {
+ return commit(path, message, recurse? 3 : 0, noUnlock, false, null, null);
+ }
+
+ public long commit(String[] path,
+ String message,
+ int depth,
+ boolean noUnlock,
+ boolean keepChangelist,
+ String[] changelists,
+ Map revpropTable) throws VcsException {
+ final long commit = new SvnCommitRunner(myExecutablePath, myHandler, myAuthenticationCallback).
+ commit(path, message, depth, noUnlock, keepChangelist, changelists, revpropTable, myUrlProvider);
+ if (commit < 0) {
+ throw new VcsException("Wrong committed revision number: " + commit);
+ }
+ return commit;
+ }
+
+ public void setHandler(CommitEventHandler handler) {
+ myHandler = handler;
+ }
+
+ public void setAuthenticationCallback(AuthenticationCallback authenticationCallback) {
+ myAuthenticationCallback = authenticationCallback;
+ }
+}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/config/SvnBindException.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java
similarity index 68%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/config/SvnBindException.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java
index 8957843..524b928 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/config/SvnBindException.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java
@@ -13,12 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn.config;
+package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.vcs.VcsException;
-import java.util.Collection;
-
/**
* Created with IntelliJ IDEA.
* User: Irina.Chernushina
@@ -32,23 +30,7 @@
super(message);
}
- public SvnBindException(Throwable throwable, boolean isWarning) {
- super(throwable, isWarning);
- }
-
public SvnBindException(Throwable throwable) {
super(throwable);
}
-
- public SvnBindException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public SvnBindException(String message, boolean isWarning) {
- super(message, isWarning);
- }
-
- public SvnBindException(Collection<String> messages) {
- super(messages);
- }
}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindUtil.java
similarity index 73%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindUtil.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindUtil.java
index 1fec6b3..7d663ba 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindUtil.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
import java.io.File;
import java.text.DateFormat;
@@ -31,16 +31,7 @@
* Time: 4:56 PM
*/
public class SvnBindUtil {
- /**
- * SVN_ASP_DOT_NET_HACK allows use of an alternate name for Subversion working copy
- * administrative directories on Windows (which were formerly always
- * named ".svn"), by setting the SVN_ASP_DOT_NET_HACK environment variable.
- * When the variable is set (to any value), the administrative directory
- * will be "_svn" instead of ".svn".
- *
- * http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt
- */
- public static final String ADM_NAME = System.getenv("SVN_ASP_DOT_NET_HACK") != null ? "_svn" : ".svn";
+
private final static List<DateFormat> ourFormats = new ArrayList<DateFormat>();
static {
@@ -88,17 +79,4 @@
}
return null;
}
-
- public static File getWcRoot(File base) {
- File current = base;
- while (current != null) {
- if (getWcDbUnder(current).exists()) return current;
- current = current.getParentFile();
- }
- return null;
- }
-
- public static File getWcDbUnder(final File file) {
- return new File(file, ADM_NAME + File.separator + "wc.db");
- }
}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java
similarity index 81%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java
index d6df6ba..9e355e5 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java
@@ -16,6 +16,7 @@
package org.jetbrains.idea.svn.commandLine;
import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.process.CapturingProcessAdapter;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessListener;
@@ -38,6 +39,7 @@
*/
public abstract class SvnCommand {
static final Logger LOG = Logger.getInstance(SvnCommand.class.getName());
+ private final File myConfigDir;
private boolean myIsDestroyed;
private int myExitCode;
@@ -45,13 +47,13 @@
private final File myWorkingDirectory;
private Process myProcess;
private OSProcessHandler myHandler;
+ // TODO: Try to implement commands in a way that they manually indicate if they need full output - to prevent situations
+ // TODO: when large amount of data needs to be stored instead of just sequential processing.
+ private CapturingProcessAdapter outputAdapter;
private final Object myLock;
private final EventDispatcher<ProcessEventListener> myListeners = EventDispatcher.create(ProcessEventListener.class);
-
- // todo check version
- /*c:\Program Files (x86)\CollabNet\Subversion Client17>svn --version --quiet
- 1.7.2*/
+ private final SvnCommandName myCommandName;
public SvnCommand(File workingDirectory, @NotNull SvnCommandName commandName, @NotNull @NonNls String exePath) {
this(workingDirectory, commandName, exePath, null);
@@ -59,15 +61,34 @@
public SvnCommand(File workingDirectory, @NotNull SvnCommandName commandName, @NotNull @NonNls String exePath,
@Nullable File configDir) {
+ myCommandName = commandName;
myLock = new Object();
myCommandLine = new GeneralCommandLine();
myWorkingDirectory = workingDirectory;
myCommandLine.setExePath(exePath);
myCommandLine.setWorkDirectory(workingDirectory);
+ myConfigDir = configDir;
if (configDir != null) {
myCommandLine.addParameters("--config-dir", configDir.getPath());
}
- myCommandLine.addParameter(commandName.getName());
+ if (!SvnCommandName.empty.equals(commandName)) {
+ myCommandLine.addParameter(commandName.getName());
+ }
+ }
+
+ public String[] getParameters() {
+ synchronized (myLock) {
+ return myCommandLine.getParametersList().getArray();
+ }
+ }
+
+ /**
+ * Indicates if process was destroyed "manually" by command execution logic.
+ *
+ * @return
+ */
+ public boolean isManuallyDestroyed() {
+ return myIsDestroyed;
}
public void start() {
@@ -112,10 +133,16 @@
}
};
+ outputAdapter = new CapturingProcessAdapter();
+ myHandler.addProcessListener(outputAdapter);
myHandler.addProcessListener(processListener);
myHandler.startNotify();
}
+ public String getOutput() {
+ return outputAdapter.getOutput().getStdout();
+ }
+
/**
* Wait for process termination
* @param timeout
@@ -186,6 +213,18 @@
}
}
+ public String getCommandText() {
+ synchronized (myLock) {
+ return myCommandLine.getCommandLineString();
+ }
+ }
+
+ public String getExePath() {
+ synchronized (myLock) {
+ return myCommandLine.getExePath();
+ }
+ }
+
/**
* check that process is not started yet
*
@@ -226,4 +265,8 @@
protected File getWorkingDirectory() {
return myWorkingDirectory;
}
+
+ public SvnCommandName getCommandName() {
+ return myCommandName;
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
index 0d2f4d0..47b6b523 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
@@ -15,12 +15,13 @@
*/
package org.jetbrains.idea.svn.commandLine;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.Consumer;
-import org.jetbrains.idea.svn.SvnBindUtil;
+import org.jetbrains.idea.svn.SvnApplicationSettings;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.portable.SvnExceptionWrapper;
import org.jetbrains.idea.svn.portable.SvnkitSvnWcClient;
@@ -36,7 +37,9 @@
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
/**
* Created with IntelliJ IDEA.
@@ -45,9 +48,12 @@
* Time: 12:59 PM
*/
public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
+
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient");
private final Project myProject;
public SvnCommandLineInfoClient(final Project project) {
+ // TODO: Remove svn kit client instantiation
super(SvnVcs.getInstance(project).createWCClient());
myProject = project;
}
@@ -74,22 +80,56 @@
base = SvnBindUtil.correctUpToExistingParent(base);
if (base == null) {
// very unrealistic
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), new RuntimeException("Can not find existing parent file"));
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, "Can not find existing parent file"));
}
- final SvnSimpleCommand command = SvnCommandFactory.createSimpleCommand(myProject, base, SvnCommandName.info);
+ issueCommand(path.getAbsolutePath(), pegRevision, revision, depth, changeLists, handler, base);
+ }
- if (depth != null) {
- command.addParameters("--depth", depth.getName());
- }
- if (revision != null && ! SVNRevision.UNDEFINED.equals(revision) && ! SVNRevision.WORKING.equals(revision)) {
- command.addParameters("-r", revision.toString());
- }
- command.addParameters("--xml");
+ private void issueCommand(String path, SVNRevision pegRevision,
+ SVNRevision revision,
+ SVNDepth depth,
+ Collection changeLists,
+ final ISVNInfoHandler handler, File base) throws SVNException {
+ final SvnSimpleCommand command = SvnCommandFactory.createSimpleCommand(myProject, base, SvnCommandName.info);
+ List<String> parameters = new ArrayList<String>();
+
+ fillParameters(path, pegRevision, revision, depth, parameters);
+ command.addParameters(parameters);
SvnCommandLineStatusClient.changelistsToCommand(changeLists, command);
- if (pegRevision != null && ! SVNRevision.UNDEFINED.equals(pegRevision) && ! SVNRevision.WORKING.equals(pegRevision)) {
- command.addParameters(path.getPath() + "@" + pegRevision.toString());
- } else {
- command.addParameters(path.getPath());
+
+ parseResult(handler, base, execute(command));
+ }
+
+ private String execute(SvnSimpleCommand command) throws SVNException {
+ try {
+ return command.run();
+ }
+ catch (VcsException e) {
+ final String text = e.getMessage();
+ final boolean notEmpty = !StringUtil.isEmptyOrSpaces(text);
+ if (notEmpty && text.contains("W155010")) {
+ // just null
+ return null;
+ }
+ // not a working copy exception
+ // "E155007: '' is not a working copy"
+ if (notEmpty && text.contains("is not a working copy")) {
+ if (StringUtil.isNotEmpty(command.getOutput())) {
+ // workaround: as in subversion 1.8 "svn info" on a working copy root outputs such error for parent folder,
+ // if there are files with conflicts.
+ // but the requested info is still in the output except root closing tag
+ return command.getOutput() + "</info>";
+ } else {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, e), e);
+ }
+ }
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
+ }
+ }
+
+ private void parseResult(final ISVNInfoHandler handler, File base, String result) throws SVNException {
+ if (StringUtil.isEmpty(result)) {
+ return;
}
final SvnInfoHandler[] infoHandler = new SvnInfoHandler[1];
@@ -106,36 +146,32 @@
});
try {
- final String result = command.run();
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
- parser.parse(new ByteArrayInputStream(result.getBytes(CharsetToolkit.UTF8_CHARSET)), infoHandler[0]);
+ parser.parse(new ByteArrayInputStream(result.getBytes(CharsetToolkit.UTF8_CHARSET)), infoHandler[0]);
}
catch (SvnExceptionWrapper e) {
+ LOG.info("info output " + result);
throw (SVNException) e.getCause();
} catch (IOException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ LOG.info("info output " + result);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
catch (ParserConfigurationException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ LOG.info("info output " + result);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
catch (SAXException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ LOG.info("info output " + result);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
- catch (VcsException e) {
- final String text = e.getMessage();
- final boolean notEmpty = !StringUtil.isEmptyOrSpaces(text);
- if (notEmpty && text.contains("W155010")) {
- // just null
- return;
- }
- // not a working copy exception
- // "E155007: '' is not a working copy"
- if (notEmpty && text.contains("is not a working copy")) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY), e);
- }
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
- }
+ }
+
+ private void fillParameters(String path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, List<String> parameters) {
+ CommandUtil.put(parameters, depth);
+ CommandUtil.put(parameters, revision);
+ CommandUtil.put(parameters, path, pegRevision);
+ parameters.add("--xml");
}
@Override
@@ -147,7 +183,14 @@
@Override
public void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, ISVNInfoHandler handler)
throws SVNException {
- throw new UnsupportedOperationException();
+ String path = url.toDecodedString();
+ List<String> parameters = new ArrayList<String>();
+
+ fillParameters(path, pegRevision, revision, depth, parameters);
+ File base = new File(SvnApplicationSettings.getInstance().getCommandLinePath());
+ String result = CommandUtil.runSimple(SvnCommandName.info, SvnVcs.getInstance(myProject), base, url, parameters).getOutput();
+
+ parseResult(handler, base, result);
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
index a1a3153..c1429be 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
@@ -15,14 +15,16 @@
*/
package org.jetbrains.idea.svn.commandLine;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.containers.Convertor;
-import org.jetbrains.idea.svn.SvnBindUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnUtil;
+import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.portable.PortableStatus;
import org.jetbrains.idea.svn.portable.SvnExceptionWrapper;
import org.jetbrains.idea.svn.portable.SvnStatusClientI;
@@ -48,6 +50,8 @@
* Time: 5:21 PM
*/
public class SvnCommandLineStatusClient implements SvnStatusClientI {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient");
+
private final Project myProject;
private final SvnCommandLineInfoClient myInfoClient;
@@ -102,47 +106,84 @@
final SVNInfo infoBase = myInfoClient.doInfo(base, revision);
final SvnSimpleCommand command = SvnCommandFactory.createSimpleCommand(myProject, base, SvnCommandName.st);
- putParameters(depth, remote, reportAll, includeIgnored, changeLists, command);
+ putParameters(path, depth, remote, reportAll, includeIgnored, changeLists, command);
- final SvnStatusHandler[] svnHandl = new SvnStatusHandler[1];
- svnHandl[0] = createStatusHandler(revision, handler, base, infoBase, svnHandl);
+ parseResult(path, revision, handler, base, infoBase, command, execute(command, base));
+ return 0;
+ }
+
+ private String execute(SvnSimpleCommand command, File base) throws SVNException {
+ String result = CommandUtil.runSimple(command, SvnVcs.getInstance(myProject), base, null).getOutput();
+
+ if (StringUtil.isEmptyOrSpaces(result)) {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.FS_GENERAL, "Status request returned nothing for command: " +
+ command.myCommandLine.getCommandLineString()));
+ }
+
+ return result;
+ }
+
+ private void parseResult(final File path,
+ SVNRevision revision,
+ ISVNStatusHandler handler,
+ File base,
+ SVNInfo infoBase,
+ SvnSimpleCommand command, String result) throws SVNException {
+
+ if (StringUtil.isEmpty(result)) {
+ return;
+ }
try {
- final String result = command.run();
- if (StringUtil.isEmptyOrSpaces(result)) {
- throw new VcsException("Status request returned nothing for command: " + command.myCommandLine.getCommandLineString());
- }
+ final SvnStatusHandler[] svnHandl = new SvnStatusHandler[1];
+ svnHandl[0] = createStatusHandler(revision, handler, base, infoBase, svnHandl);
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(new ByteArrayInputStream(result.getBytes(CharsetToolkit.UTF8_CHARSET)), svnHandl[0]);
- if (! svnHandl[0].isAnythingReported()) {
- if (! SvnUtil.isSvnVersioned(myProject, path)) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_DIRECTORY));
+ if (!svnHandl[0].isAnythingReported()) {
+ if (!SvnUtil.isSvnVersioned(myProject, path)) {
+ throw new SVNException(
+ SVNErrorMessage.create(SVNErrorCode.WC_NOT_DIRECTORY, "Command - " + command.getCommandText() + ". Result - " + result));
+ } else {
+ // return status indicating "NORMAL" state
+ // typical output would be like
+ // <status>
+ // <target path="1.txt"></target>
+ // </status>
+ // so it does not contain any <entry> element and current parsing logic returns null
+
+ PortableStatus status = new PortableStatus();
+ status.setPath(path.getAbsolutePath());
+ status.setContentsStatus(SVNStatusType.STATUS_NORMAL);
+ status.setInfoGetter(new Getter<SVNInfo>() {
+ @Override
+ public SVNInfo get() {
+ return createInfoGetter(null).convert(path);
+ }
+ });
+ handler.handleStatus(status);
}
}
}
catch (SvnExceptionWrapper e) {
throw (SVNException) e.getCause();
} catch (IOException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
catch (ParserConfigurationException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
catch (SAXException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
- catch (VcsException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
- }
- return 0;
}
- private void putParameters(SVNDepth depth,
+ private void putParameters(@NotNull File path, SVNDepth depth,
boolean remote,
boolean reportAll,
boolean includeIgnored,
Collection changeLists,
SvnSimpleCommand command) {
+ command.addParameters(path.getAbsolutePath());
if (depth != null) {
command.addParameters("--depth", depth.getName());
}
@@ -171,7 +212,11 @@
final SVNInfo infoBase, final SvnStatusHandler[] svnHandl) {
final SvnStatusHandler.ExternalDataCallback callback = createStatusCallback(handler, base, infoBase, svnHandl);
- return new SvnStatusHandler(callback, base, new Convertor<File, SVNInfo>() {
+ return new SvnStatusHandler(callback, base, createInfoGetter(revision));
+ }
+
+ private Convertor<File, SVNInfo> createInfoGetter(final SVNRevision revision) {
+ return new Convertor<File, SVNInfo>() {
@Override
public SVNInfo convert(File o) {
try {
@@ -181,7 +226,7 @@
throw new SvnExceptionWrapper(e);
}
}
- });
+ };
}
public static SvnStatusHandler.ExternalDataCallback createStatusCallback(final ISVNStatusHandler handler,
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
index c0e9c8e..e0834c2f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
@@ -24,7 +24,6 @@
import org.jetbrains.idea.svn.SvnApplicationSettings;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.checkin.IdeaSvnkitBasedAuthenticationCallback;
-import org.jetbrains.idea.svn.config.SvnBindException;
import org.jetbrains.idea.svn.portable.SvnSvnkitUpdateClient;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
@@ -49,9 +48,9 @@
private final VirtualFile myCommonAncestor;
private boolean myIgnoreExternals;
- public SvnCommandLineUpdateClient(final Project project, VirtualFile commonAncestor) {
- super(SvnVcs.getInstance(project).createUpdateClient());
- myProject = project;
+ public SvnCommandLineUpdateClient(final SvnVcs vcs, VirtualFile commonAncestor) {
+ super(vcs.createUpdateClient());
+ myProject = vcs.getProject();
myCommonAncestor = commonAncestor;
}
@@ -88,35 +87,7 @@
File base = myCommonAncestor == null ? paths[0] : new File(myCommonAncestor.getPath());
base = base.isDirectory() ? base : base.getParentFile();
- final List<String> parameters = new ArrayList<String>();
- if (revision != null && ! SVNRevision.UNDEFINED.equals(revision) && ! SVNRevision.WORKING.equals(revision)) {
- parameters.add("-r");
- parameters.add(revision.toString());
- }
- // unknown depth is not used any more for 1.7 -> why?
- if (depth != null && ! SVNDepth.UNKNOWN.equals(depth)) {
- parameters.add("--depth");
- parameters.add(depth.toString());
- }
- if (allowUnversionedObstructions) {
- parameters.add("--force");
- }
- if (depthIsSticky && depth != null) {// !!! not sure, but not used
- parameters.add("--set-depth");
- parameters.add(depth.toString());
- }
- if (makeParents) {
- parameters.add("--parents");
- }
- if (myIgnoreExternals) {
- parameters.add("--ignore-externals");
- }
- parameters.add("--accept");
- parameters.add("postpone");
-
- for (File path : paths) {
- parameters.add(path.getPath());
- }
+ final List<String> parameters = prepareParameters(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
final AtomicReference<SVNException> excRef = new AtomicReference<SVNException>();
final ISVNEventHandler handler = getEventHandler();
@@ -166,7 +137,7 @@
}
};
SvnLineCommand.runWithAuthenticationAttempt(SvnApplicationSettings.getInstance().getCommandLinePath(),
- base, SvnCommandName.up, listener,
+ base, info.getURL(), SvnCommandName.up, listener,
new IdeaSvnkitBasedAuthenticationCallback(SvnVcs.getInstance(myProject)),
ArrayUtil.toStringArray(parameters));
}
@@ -180,6 +151,29 @@
return updatedToRevision.get();
}
+ private List<String> prepareParameters(File[] paths,
+ SVNRevision revision,
+ SVNDepth depth,
+ boolean allowUnversionedObstructions,
+ boolean depthIsSticky, boolean makeParents) {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, revision);
+ CommandUtil.put(parameters, depth);
+ CommandUtil.put(parameters, allowUnversionedObstructions, "--force");
+ if (depthIsSticky && depth != null) {// !!! not sure, but not used
+ parameters.add("--set-depth");
+ parameters.add(depth.toString());
+ }
+ CommandUtil.put(parameters, makeParents, "--parents");
+ CommandUtil.put(parameters, myIgnoreExternals, "--ignore-externals");
+ parameters.add("--accept");
+ parameters.add("postpone");
+ CommandUtil.put(parameters, paths);
+
+ return parameters;
+ }
+
private void checkForException(final StringBuffer sbError) throws SVNException {
if (sbError.length() == 0) return;
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
similarity index 75%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
index 58c2ff2..c19ea283 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
@@ -22,13 +22,25 @@
* Time: 1:49 PM
*/
public enum SvnCommandName {
+ // TODO: temporary command for "more smooth" converting between simple commands and line commands
+ empty("", false),
version("--version", false),
info("info", false),
st("st", false),
up("up", true),
ci("commit", true),
- cleanup("cleanup", true);
-
+ cleanup("cleanup", true),
+ cat("cat", false),
+ add("add", true),
+ log("log", false),
+ revert("revert", true),
+ delete("delete", true),
+ copy("copy", true),
+ move("move", true),
+ resolve("resolve", true),
+ propget("propget", false),
+ blame("blame", false);
+
private final String myName;
private final boolean myWriteable;
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnCommitRunner.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
similarity index 85%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnCommitRunner.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
index 525d675..83f6ec1 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnCommitRunner.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
@@ -13,22 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.Convertor;
import org.apache.subversion.javahl.types.Revision;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.svn.commandLine.LineCommandListener;
-import org.jetbrains.idea.svn.commandLine.SvnCommandName;
-import org.jetbrains.idea.svn.commandLine.SvnLineCommand;
-import org.jetbrains.idea.svn.config.SvnBindException;
-import org.tigris.subversion.javahl.BindClientException;
-import org.tigris.subversion.javahl.ClientException;
+import org.tmatesoft.svn.core.SVNURL;
import java.io.File;
import java.util.*;
@@ -42,7 +39,7 @@
public class SvnCommitRunner {
private final String myExePath;
@Nullable private final AuthenticationCallback myAuthenticationCallback;
- private static final Logger LOG = Logger.getInstance("org.jetbrains.idea.svn.SvnCommitRunner");
+ private static final Logger LOG = Logger.getInstance("org.jetbrains.idea.svn.commandLine.SvnCommitRunner");
private SvnCommitRunner.CommandListener myCommandListener;
public SvnCommitRunner(@NotNull String path, @Nullable CommitEventHandler handler, @Nullable AuthenticationCallback authenticationCallback) {
@@ -57,7 +54,7 @@
boolean noUnlock,
boolean keepChangelist,
String[] changelists,
- Map revpropTable) throws ClientException {
+ Map revpropTable, Convertor<String[], SVNURL> urlProvider) throws VcsException {
if (paths.length == 0) return Revision.SVN_INVALID_REVNUM;
final List<String> parameters = new ArrayList<String>();
@@ -84,19 +81,14 @@
Arrays.sort(paths);
parameters.addAll(Arrays.asList(paths));
- try {
- SvnLineCommand.runWithAuthenticationAttempt(myExePath, new File(paths[0]), SvnCommandName.ci,
- myCommandListener, myAuthenticationCallback, ArrayUtil.toStringArray(parameters));
- }
- catch (SvnBindException e) {
- throw BindClientException.create(e, Revision.SVN_INVALID_REVNUM);
- }
+ SvnLineCommand.runWithAuthenticationAttempt(myExePath, new File(paths[0]), urlProvider.convert(paths), SvnCommandName.ci,
+ myCommandListener, myAuthenticationCallback, ArrayUtil.toStringArray(parameters));
myCommandListener.throwExceptionIfOccurred();
return myCommandListener.getCommittedRevision();
}
- private static class CommandListener extends LineCommandListener {
+ public static class CommandListener extends LineCommandListener {
@Nullable private final CommitEventHandler myHandler;
private SvnBindException myException;
private long myCommittedRevision = Revision.SVN_INVALID_REVNUM;
@@ -106,9 +98,9 @@
myHandler = handler;
}
- public void throwExceptionIfOccurred() throws BindClientException {
+ public void throwExceptionIfOccurred() throws VcsException {
if (myException != null) {
- throw BindClientException.create(myException, Revision.SVN_INVALID_REVNUM);
+ throw myException;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoHandler.java
index 022130e..d8dbb6c1 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoHandler.java
@@ -18,6 +18,7 @@
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
@@ -49,7 +50,7 @@
public SvnInfoHandler(File base, final Consumer<SVNInfo> infoConsumer) {
myBase = base;
myInfoConsumer = infoConsumer;
- myPending = new SvnInfoStructure();
+ myPending = createPending();
myElementsMap = new HashMap<String, Getter<ElementHandlerBase>>();
fillElements();
myParseStack = new ArrayList<ElementHandlerBase>();
@@ -70,7 +71,14 @@
myInfoConsumer.consume(info);
}
myResultsMap.put(info.getFile(), info);
- myPending = new SvnInfoStructure();
+ myPending = createPending();
+ }
+
+ private SvnInfoStructure createPending() {
+ SvnInfoStructure pending = new SvnInfoStructure();
+ pending.myDepth = SVNDepth.INFINITY;
+
+ return pending;
}
@Override
@@ -90,16 +98,13 @@
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
assertSAX(! myParseStack.isEmpty());
ElementHandlerBase current = myParseStack.get(myParseStack.size() - 1);
- if (mySb.length() > 0) {
- current.characters(mySb.toString().trim(), myPending);
- mySb.setLength(0);
- }
while (true) {
final boolean createNewChild = current.startElement(uri, localName, qName, attributes);
if (createNewChild) {
assertSAX(myElementsMap.containsKey(qName));
final ElementHandlerBase newChild = myElementsMap.get(qName).get();
+ newChild.setParent(current);
newChild.updateInfo(attributes, myPending);
myParseStack.add(newChild);
return;
@@ -116,6 +121,18 @@
}
@Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ ElementHandlerBase current = myParseStack.get(myParseStack.size() - 1);
+ String value = mySb.toString().trim();
+
+ if (!StringUtil.isEmpty(value)) {
+ current.characters(value, myPending);
+ }
+
+ mySb.setLength(0);
+ }
+
+ @Override
public void characters(char[] ch, int start, int length) throws SAXException {
assertSAX(! myParseStack.isEmpty());
mySb.append(ch, start, length);
@@ -252,6 +269,24 @@
return new Url();
}
});
+ myElementsMap.put("relative-url", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new RelativeUrl();
+ }
+ });
+ myElementsMap.put("lock", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new Lock();
+ }
+ });
+ myElementsMap.put("created", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new Date();
+ }
+ });
myElementsMap.put("uuid", new Getter<ElementHandlerBase>() {
@Override
public ElementHandlerBase get() {
@@ -270,6 +305,18 @@
return new WcInfo();
}
});
+ myElementsMap.put("moved-to", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new MovedPath();
+ }
+ });
+ myElementsMap.put("moved-from", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new MovedPath();
+ }
+ });
myElementsMap.put("wcroot-abspath", new Getter<ElementHandlerBase>() {
@Override
public ElementHandlerBase get() {
@@ -295,6 +342,12 @@
@Override
protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException {
+ // TODO: Currently information for conflict (not tree-conflict) available in svn 1.8 is not used
+ // TODO: And it also not suite well for SVNKit api
+ if (getParent() instanceof Conflict) {
+ return;
+ }
+
final String side = attributes.getValue("side");
if ("source-left".equals(side)) {
final SvnInfoStructure.ConflictVersion conflictVersion = new SvnInfoStructure.ConflictVersion();
@@ -382,7 +435,7 @@
@Override
public void characters(String s, SvnInfoStructure structure) throws SAXException {
- structure.myConflictWorking = s;
+ structure.myConflictNew = new File(s).getName();
}
}
@@ -397,7 +450,7 @@
@Override
public void characters(String s, SvnInfoStructure structure) throws SAXException {
- structure.myConflictNew = s;
+ structure.myConflictWorking = new File(s).getName();
}
}
@@ -412,14 +465,13 @@
@Override
public void characters(String s, SvnInfoStructure structure) throws SAXException {
- // todo path? or plus base
- structure.myConflictOld = s;
+ structure.myConflictOld = new File(s).getName();
}
}
private static class Conflict extends ElementHandlerBase {
private Conflict() {
- super(new String[]{"prev-base-file","prev-wc-file","cur-base-file","prop-file"}, new String[]{});
+ super(new String[]{"prev-base-file","prev-wc-file","cur-base-file","prop-file"}, new String[]{"version"});
}
@Override
@@ -498,6 +550,25 @@
}
}
+ /**
+ * "moved-from" and "moved-to" elements are represented by this class.
+ */
+ private static class MovedPath extends ElementHandlerBase {
+
+ private MovedPath() {
+ super(new String[]{}, new String[]{});
+ }
+
+ @Override
+ protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException {
+ }
+
+ @Override
+ public void characters(String s, SvnInfoStructure structure) throws SAXException {
+ // TODO: is there some field to initialize from this value?
+ }
+ }
+
private static class TextUpdated extends ElementHandlerBase {
private TextUpdated() {
super(new String[]{}, new String[]{});
@@ -617,7 +688,7 @@
private static class WcInfo extends ElementHandlerBase {
private WcInfo() {
super(new String[]{"wcroot-abspath", "schedule", "depth", "text-updated", "checksum", "changelist", "copy-from-url",
- "copy-from-rev"}, new String[]{});
+ "copy-from-rev", "moved-to", "moved-from"}, new String[]{});
}
@Override
@@ -698,11 +769,34 @@
}
}
+ private static class RelativeUrl extends Url{
+ @Override
+ public void characters(String s, SvnInfoStructure structure) throws SAXException {
+ structure.relativeUrl = s;
+ }
+ }
+
+ private static class Lock extends ElementHandlerBase {
+ private Lock() {
+ super(new String[]{"created"}, new String[]{});
+ }
+
+ @Override
+ protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException {
+ // TODO:
+ }
+
+ @Override
+ public void characters(String s, SvnInfoStructure structure) throws SAXException {
+ // TODO:
+ }
+ }
+
private static class Entry extends ElementHandlerBase {
private final File myBase;
private Entry(final File base) {
- super(new String[]{"url","repository","wc-info","commit","conflict","tree-conflict"}, new String[]{});
+ super(new String[]{"url", "relative-url", "lock", "repository","wc-info","commit","conflict","tree-conflict"}, new String[]{});
myBase = base;
}
@@ -763,12 +857,22 @@
private abstract static class ElementHandlerBase {
private final Set<String> myAwaitedChildren;
private final Set<String> myAwaitedChildrenMultiple;
+ private ElementHandlerBase parent;
ElementHandlerBase(String[] awaitedChildren, String[] awaitedChildrenMultiple) {
myAwaitedChildren = new HashSet<String>(Arrays.asList(awaitedChildren));
myAwaitedChildrenMultiple = new HashSet<String>(Arrays.asList(awaitedChildrenMultiple));
}
+ @NotNull
+ public ElementHandlerBase getParent() {
+ return parent;
+ }
+
+ public void setParent(@NotNull ElementHandlerBase parent) {
+ this.parent = parent;
+ }
+
protected abstract void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException;
public boolean startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoStructure.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoStructure.java
index 0292b7d..1aa5248 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoStructure.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoStructure.java
@@ -34,6 +34,7 @@
*/
public class SvnInfoStructure {
public File myFile;
+ public String relativeUrl;
public SVNURL myUrl;
public SVNURL myRootURL;
public long myRevision;
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java
similarity index 62%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java
index 5821d7a..c5e3b9e 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java
@@ -23,20 +23,30 @@
import com.intellij.openapi.vcs.LineHandlerHelper;
import com.intellij.openapi.vcs.LineProcessEventListener;
import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.svn.AuthenticationCallback;
-import org.jetbrains.idea.svn.SvnBindUtil;
-import org.jetbrains.idea.svn.config.SvnBindException;
+import org.jetbrains.idea.svn.SvnUtil;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
+import org.tmatesoft.svn.core.auth.SVNAuthentication;
+import org.tmatesoft.svn.core.auth.SVNPasswordAuthentication;
+import org.tmatesoft.svn.core.auth.SVNSSLAuthentication;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Created with IntelliJ IDEA.
@@ -47,11 +57,21 @@
* honestly stolen from GitLineHandler
*/
public class SvnLineCommand extends SvnCommand {
+
public static final String AUTHENTICATION_REALM = "Authentication realm:";
public static final String CERTIFICATE_ERROR = "Error validating server certificate for";
public static final String PASSPHRASE_FOR = "Passphrase for";
public static final String UNABLE_TO_CONNECT = "svn: E170001:";
public static final String CANNOT_AUTHENTICATE_TO_PROXY = "Could not authenticate to proxy server";
+ public static final String AUTHENTICATION_FAILED_MESSAGE = "Authentication failed";
+
+ private static final String INVALID_CREDENTIALS_FOR_SVN_PROTOCOL = "svn: E170001: Can't get";
+ private static final String UNTRUSTED_SERVER_CERTIFICATE = "Server SSL certificate untrusted";
+ private static final String ACCESS_TO_PREFIX = "Access to ";
+ private static final String FORBIDDEN_STATUS = "forbidden";
+ private static final String PASSWORD_STRING = "password";
+
+ private static final Pattern UNABLE_TO_CONNECT_TO_URL_PATTERN = Pattern.compile("Unable to connect to a repository at URL '(.*)'");
// kept for exact text
//public static final String CLIENT_CERTIFICATE_FILENAME = "Client certificate filename:";
@@ -66,6 +86,7 @@
private final EventDispatcher<LineProcessEventListener> myLineListeners;
private final AtomicReference<Integer> myExitCode;
private final StringBuffer myErr;
+ private final StringBuffer myStdOut;
public SvnLineCommand(File workingDirectory, @NotNull SvnCommandName commandName, @NotNull @NonNls String exePath) {
this(workingDirectory, commandName, exePath, null);
@@ -76,6 +97,7 @@
myLineListeners = EventDispatcher.create(LineProcessEventListener.class);
myExitCode = new AtomicReference<Integer>();
myErr = new StringBuffer();
+ myStdOut = new StringBuffer();
}
@Override
@@ -89,13 +111,14 @@
}
}
- public static void runWithAuthenticationAttempt(final String exePath,
- final File firstFile,
- SvnCommandName commandName,
- final LineCommandListener listener,
- @Nullable AuthenticationCallback authenticationCallback,
- final String... parameters) throws SvnBindException {
- File base = firstFile.isDirectory() ? firstFile : firstFile.getParentFile();
+ public static SvnLineCommand runWithAuthenticationAttempt(final String exePath,
+ final File firstFile,
+ final SVNURL url,
+ SvnCommandName commandName,
+ final LineCommandListener listener,
+ @Nullable AuthenticationCallback authenticationCallback,
+ String... parameters) throws SvnBindException {
+ File base = firstFile != null ? (firstFile.isDirectory() ? firstFile : firstFile.getParentFile()) : null;
base = SvnBindUtil.correctUpToExistingParent(base);
listener.baseDirectory(base);
@@ -111,27 +134,35 @@
while (true) {
final SvnLineCommand command = runCommand(exePath, commandName, listener, base, configDir, parameters);
- if (command.myErr.length() > 0) {
- final String errText = command.myErr.toString().trim();
- if (authenticationCallback != null) {
- final AuthCallbackCase callback = createCallback(errText, authenticationCallback, base);
- if (callback != null) {
- cleanup(exePath, commandName, base);
- if (callback.getCredentials(errText)) {
- if (authenticationCallback.getSpecialConfigDir() != null) {
- configDir = authenticationCallback.getSpecialConfigDir();
+ final Integer exitCode = command.myExitCode.get();
+
+ // could be situations when exit code = 0, but there is info "warning" in error stream
+ // for instance, for "svn status" on non-working copy folder
+ if (exitCode != 0) {
+ if (command.myErr.length() > 0) {
+ // handle authentication
+ final String errText = command.myErr.toString().trim();
+ if (authenticationCallback != null) {
+ final AuthCallbackCase callback = createCallback(errText, authenticationCallback, base, url);
+ if (callback != null) {
+ cleanup(exePath, command, base);
+ if (callback.getCredentials(errText)) {
+ if (authenticationCallback.getSpecialConfigDir() != null) {
+ configDir = authenticationCallback.getSpecialConfigDir();
+ }
+ parameters = updateParameters(callback, parameters);
+ continue;
}
- continue;
}
}
+ throw new SvnBindException(errText);
+ } else {
+ throw new SvnBindException("Svn process exited with error code: " + exitCode);
}
- throw new SvnBindException(errText);
+ } else if (command.myErr.length() > 0) {
+ LOG.info("Detected warning - " + command.myErr);
}
- final Integer exitCode = command.myExitCode.get();
- if (exitCode != 0) {
- throw new SvnBindException("Svn process exited with error code: " + exitCode);
- }
- return;
+ return command;
}
} finally {
if (authenticationCallback != null) {
@@ -140,6 +171,13 @@
}
}
+ private static String[] updateParameters(AuthCallbackCase callback, String[] parameters) {
+ List<String> p = new ArrayList<String>(Arrays.asList(parameters));
+
+ callback.updateParameters(p);
+ return ArrayUtil.toStringArray(p);
+ }
+
private static void writeIdeaConfig2SubversionConfig(@NotNull AuthenticationCallback authenticationCallback, @NotNull File base) throws SvnBindException {
if (authenticationCallback.haveDataForTmpConfig()) {
try {
@@ -158,7 +196,7 @@
}
}
- private static AuthCallbackCase createCallback(final String errText, final AuthenticationCallback callback, final File base) {
+ private static AuthCallbackCase createCallback(final String errText, final AuthenticationCallback callback, final File base, final SVNURL url) {
if (errText.startsWith(CERTIFICATE_ERROR)) {
return new CertificateCallbackCase(callback, base);
}
@@ -171,9 +209,85 @@
if (errText.startsWith(UNABLE_TO_CONNECT) && errText.contains(CANNOT_AUTHENTICATE_TO_PROXY)) {
return new ProxyCallback(callback, base);
}
+ // http/https protocol invalid credentials
+ if (errText.contains(AUTHENTICATION_FAILED_MESSAGE)) {
+ return new UsernamePasswordCallback(callback, base, url);
+ }
+ // messages could be "Can't get password", "Can't get username or password"
+ if (errText.contains(INVALID_CREDENTIALS_FOR_SVN_PROTOCOL) && errText.contains(PASSWORD_STRING)) {
+ // svn protocol invalid credentials
+ return new UsernamePasswordCallback(callback, base, url);
+ }
+ // https one-way protocol untrusted server certificate
+ if (errText.contains(UNTRUSTED_SERVER_CERTIFICATE)) {
+ return new CertificateCallbackCase(callback, base);
+ }
+ // https two-way protocol invalid client certificate
+ if (errText.contains(ACCESS_TO_PREFIX) && errText.contains(FORBIDDEN_STATUS)) {
+ return new TwoWaySslCallback(callback, base, url);
+ }
return null;
}
+ // Special callback for svn 1.8 credentials request as --non-interactive does not return
+ // authentication realm (just url) - so we could not create temp cache
+ private static class UsernamePasswordCallback extends AuthCallbackCase {
+ protected SVNAuthentication myAuthentication;
+ protected SVNURL myUrl;
+
+ protected UsernamePasswordCallback(AuthenticationCallback callback, File base, SVNURL url) {
+ super(callback, base);
+ myUrl = url;
+ }
+
+ @Override
+ boolean getCredentials(String errText) throws SvnBindException {
+ myAuthentication = myAuthenticationCallback.requestCredentials(myUrl != null ? myUrl : parseUrlFromError(errText),
+ getType());
+
+ return myAuthentication != null;
+ }
+
+ public String getType() {
+ return ISVNAuthenticationManager.PASSWORD;
+ }
+
+ @Override
+ public void updateParameters(List<String> parameters) {
+ if (myAuthentication instanceof SVNPasswordAuthentication) {
+ SVNPasswordAuthentication auth = (SVNPasswordAuthentication)myAuthentication;
+
+ parameters.add("--username");
+ parameters.add(auth.getUserName());
+ parameters.add("--password");
+ parameters.add(auth.getPassword());
+ if (!auth.isStorageAllowed()) {
+ parameters.add("--no-auth-cache");
+ }
+ }
+ }
+
+ private SVNURL parseUrlFromError(String errorText) {
+ Matcher matcher = UNABLE_TO_CONNECT_TO_URL_PATTERN.matcher(errorText);
+ String urlValue = null;
+
+ if (matcher.find()) {
+ urlValue = matcher.group(1);
+ }
+
+ return urlValue != null ? parseUrl(urlValue) : null;
+ }
+
+ private SVNURL parseUrl(String urlValue) {
+ try {
+ return SVNURL.parseURIEncoded(urlValue);
+ }
+ catch (SVNException e) {
+ return null;
+ }
+ }
+ }
+
private static class ProxyCallback extends AuthCallbackCase {
protected ProxyCallback(AuthenticationCallback callback, File base) {
super(callback, base);
@@ -192,7 +306,8 @@
@Override
boolean getCredentials(String errText) throws SvnBindException {
- final String realm = cutFirstLine(errText).substring(AUTHENTICATION_REALM.length()).trim();
+ final String realm =
+ errText.startsWith(AUTHENTICATION_REALM) ? cutFirstLine(errText).substring(AUTHENTICATION_REALM.length()).trim() : null;
final boolean isPassword = StringUtil.containsIgnoreCase(errText, "password");
if (myTried) {
myAuthenticationCallback.clearPassiveCredentials(realm, myBase, isPassword);
@@ -212,13 +327,16 @@
}
private static class CertificateCallbackCase extends AuthCallbackCase {
+ private boolean accepted;
+
private CertificateCallbackCase(AuthenticationCallback callback, File base) {
super(callback, base);
}
@Override
public boolean getCredentials(final String errText) throws SvnBindException {
- String realm = cutFirstLine(errText).substring(CERTIFICATE_ERROR.length());
+ // parse realm from error text
+ String realm = errText;
final int idx1 = realm.indexOf('\'');
if (idx1 == -1) {
throw new SvnBindException("Can not detect authentication realm name: " + errText);
@@ -229,11 +347,48 @@
}
realm = realm.substring(idx1 + 1, idx2);
if (! myTried && myAuthenticationCallback.acceptSSLServerCertificate(myBase, realm)) {
+ accepted = true;
myTried = true;
return true;
}
throw new SvnBindException("Server SSL certificate rejected");
}
+
+ @Override
+ public void updateParameters(List<String> parameters) {
+ if (accepted) {
+ parameters.add("--trust-server-cert");
+ }
+ }
+ }
+
+ private static class TwoWaySslCallback extends UsernamePasswordCallback {
+
+ protected TwoWaySslCallback(AuthenticationCallback callback, File base, SVNURL url) {
+ super(callback, base, url);
+ }
+
+ @Override
+ public String getType() {
+ return ISVNAuthenticationManager.SSL;
+ }
+
+ @Override
+ public void updateParameters(List<String> parameters) {
+ if (myAuthentication instanceof SVNSSLAuthentication) {
+ SVNSSLAuthentication auth = (SVNSSLAuthentication)myAuthentication;
+
+ // TODO: Seems that config option should be specified for concrete server and not for global group.
+ // as in that case it could be overriden by settings in config file
+ parameters.add("--config-option");
+ parameters.add("servers:global:ssl-client-cert-file=" + auth.getCertificatePath());
+ parameters.add("--config-option");
+ parameters.add("servers:global:ssl-client-cert-password=" + auth.getPassword());
+ if (!auth.isStorageAllowed()) {
+ parameters.add("--no-auth-cache");
+ }
+ }
+ }
}
private static abstract class AuthCallbackCase {
@@ -247,17 +402,23 @@
}
abstract boolean getCredentials(final String errText) throws SvnBindException;
+
+ public void updateParameters(List<String> parameters) {
+ }
}
- private static void cleanup(String exePath, SvnCommandName commandName, File base) throws SvnBindException {
- File wcRoot = SvnBindUtil.getWcRoot(base);
- if (wcRoot == null) throw new SvnBindException("Can not find working copy root for: " + base.getPath());
+ private static void cleanup(String exePath, SvnCommand command, File base) throws SvnBindException {
+ // TODO: could be issues with fake "empty" command as it is not writable - but only read commands currently use "empty" command
+ // TODO: and "empty" command will be removed shortly
+ if (command.isManuallyDestroyed() && command.getCommandName().isWriteable()) {
+ File wcRoot = SvnUtil.getWorkingCopyRootNew(base);
+ if (wcRoot == null) {
+ throw new SvnBindException("Can not find working copy root for: " + base.getPath());
+ }
- //cleanup -> check command type
- if (commandName.isWriteable()) {
- final SvnSimpleCommand command = new SvnSimpleCommand(wcRoot, SvnCommandName.cleanup, exePath);
+ final SvnSimpleCommand cleanupCommand = new SvnSimpleCommand(wcRoot, SvnCommandName.cleanup, exePath);
try {
- command.run();
+ cleanupCommand.run();
}
catch (VcsException e) {
throw new SvnBindException(e);
@@ -320,6 +481,10 @@
command.addLineListener(new LineProcessEventListener() {
@Override
public void onLineAvailable(String line, Key outputType) {
+ if (ProcessOutputTypes.STDOUT.equals(outputType)) {
+ command.myStdOut.append(line);
+ }
+
if (SvnCommand.LOG.isDebugEnabled()) {
SvnCommand.LOG.debug("==> " + line);
}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java
similarity index 96%
rename from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java
rename to plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java
index 75c43be..a088da0 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java
@@ -94,7 +94,11 @@
if (myException != null) throw myException;
final int code = getExitCode();
if (code == 0) {
- return myStdout.toString();
+ String result = myStdout.toString();
+
+ LOG.debug(result);
+
+ return result;
} else {
final String msg = new StringBuilder("Svn process exited with error code: ").append(code).append("\n")
.append("stderr: ").append(myStderr.toString()).append("\nstdout: ").append(getStdout().toString())
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
index 6536646..8700c36 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
@@ -62,6 +62,8 @@
}
public SVNEvent convert(final String line) {
+ // TODO: Add direct processing of "Summary of conflicts" lines at the end of "svn update" output (if there are conflicts).
+ // TODO: Now it works ok because parseNormalLine could not determine necessary statuses from that and further lines
if (StringUtil.isEmptyOrSpaces(line)) return null;
if (line.startsWith(UPDATING)) {
@@ -103,9 +105,9 @@
if (line.length() < 5) return null;
final char first = line.charAt(0);
if (' ' != first && ! ourActions.contains(first)) return null;
- final SVNStatusType contentsStatus = getStatusType(first);
+ final SVNStatusType contentsStatus = CommandUtil.getStatusType(first);
final char second = line.charAt(1);
- final SVNStatusType propertiesStatus = getStatusType(second);
+ final SVNStatusType propertiesStatus = CommandUtil.getStatusType(second);
final char lock = line.charAt(2); // dont know what to do with stolen lock info
if (' ' != lock && 'B' != lock) return null;
final char treeConflict = line.charAt(3);
@@ -140,28 +142,6 @@
null, action, expectedAction, null, null, null, null, null);
}
- private SVNStatusType getStatusType(char first) {
- final SVNStatusType contentsStatus;
- if ('A' == first) {
- contentsStatus = SVNStatusType.STATUS_ADDED;
- } else if ('D' == first) {
- contentsStatus = SVNStatusType.STATUS_DELETED;
- } else if ('U' == first) {
- contentsStatus = SVNStatusType.CHANGED;
- } else if ('C' == first) {
- contentsStatus = SVNStatusType.CONFLICTED;
- } else if ('G' == first) {
- contentsStatus = SVNStatusType.MERGED;
- } else if ('R' == first) {
- contentsStatus = SVNStatusType.STATUS_REPLACED;
- } else if ('E' == first) {
- contentsStatus = SVNStatusType.STATUS_OBSTRUCTED;
- } else {
- contentsStatus = SVNStatusType.STATUS_NORMAL;
- }
- return contentsStatus;
- }
-
@Nullable
private long matchAndGetRevision(final Pattern pattern, final String line) {
final Matcher matcher = pattern.matcher(line);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/CmdConflictClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/CmdConflictClient.java
new file mode 100644
index 0000000..79614a2
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/CmdConflictClient.java
@@ -0,0 +1,33 @@
+package org.jetbrains.idea.svn.conflict;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNDepth;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdConflictClient extends BaseSvnClient implements ConflictClient {
+
+ // TODO: Add possibility to resolve content conflicts separately from property conflicts.
+ @Override
+ public void resolve(@NotNull File path, boolean resolvePropertyConflicts) throws VcsException {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, path);
+ CommandUtil.put(parameters, SVNDepth.EMPTY);
+ parameters.add("--accept");
+ parameters.add("working");
+
+ // for now parsing of the output is not required as command is executed only for one file
+ // and will be either successful or exception will be thrown
+ CommandUtil.execute(myVcs, SvnCommandName.resolve, parameters, null);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/ConflictClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/ConflictClient.java
new file mode 100644
index 0000000..812fdef
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/ConflictClient.java
@@ -0,0 +1,15 @@
+package org.jetbrains.idea.svn.conflict;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.SvnClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface ConflictClient extends SvnClient {
+
+ void resolve(@NotNull File path, boolean resolvePropertyConflicts) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/SvnKitConflictClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/SvnKitConflictClient.java
new file mode 100644
index 0000000..33ee0f8
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/SvnKitConflictClient.java
@@ -0,0 +1,25 @@
+package org.jetbrains.idea.svn.conflict;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.SVNConflictChoice;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitConflictClient extends BaseSvnClient implements ConflictClient {
+ @Override
+ public void resolve(@NotNull File path, boolean resolvePropertyConflicts) throws VcsException {
+ try {
+ myVcs.createWCClient().doResolve(path, SVNDepth.EMPTY, true, resolvePropertyConflicts, SVNConflictChoice.MERGED);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/content/CmdContentClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/CmdContentClient.java
new file mode 100644
index 0000000..c822fe0
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/CmdContentClient.java
@@ -0,0 +1,39 @@
+package org.jetbrains.idea.svn.content;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.impl.ContentRevisionCache;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.*;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdContentClient extends BaseSvnClient implements ContentClient {
+
+ @Override
+ public byte[] getContent(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable SVNRevision pegRevision)
+ throws VcsException, FileTooBigRuntimeException {
+ // TODO: rewrite this to provide output as Stream
+ // TODO: rewrite without conversion from String to byte[]
+ // TODO: Also implement max size constraint like in SvnKitContentClient
+ List<String> parameters = new ArrayList<String>();
+ CommandUtil.put(parameters, target.getPathOrUrlString(), pegRevision);
+ CommandUtil.put(parameters, revision);
+
+ SvnCommand command = CommandUtil.execute(myVcs, SvnCommandName.cat, parameters, null);
+
+ byte[] bytes = CharsetToolkit.getUtf8Bytes(command.getOutput());
+
+ ContentRevisionCache.checkContentsSize(target.getPathOrUrlString(), bytes.length);
+
+ return bytes;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/content/ContentClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/ContentClient.java
new file mode 100644
index 0000000..3654d09
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/ContentClient.java
@@ -0,0 +1,17 @@
+package org.jetbrains.idea.svn.content;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface ContentClient extends SvnClient {
+
+ byte[] getContent(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable SVNRevision pegRevision)
+ throws VcsException, FileTooBigRuntimeException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/content/FileTooBigRuntimeException.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/FileTooBigRuntimeException.java
new file mode 100644
index 0000000..0a0e585
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/FileTooBigRuntimeException.java
@@ -0,0 +1,7 @@
+package org.jetbrains.idea.svn.content;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class FileTooBigRuntimeException extends RuntimeException {
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/content/SvnKitContentClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/SvnKitContentClient.java
new file mode 100644
index 0000000..d591697
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/SvnKitContentClient.java
@@ -0,0 +1,61 @@
+package org.jetbrains.idea.svn.content;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.impl.ContentRevisionCache;
+import com.intellij.vcsUtil.VcsUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNWCClient;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitContentClient extends BaseSvnClient implements ContentClient {
+
+ @Override
+ public byte[] getContent(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable SVNRevision pegRevision)
+ throws VcsException, FileTooBigRuntimeException {
+ final int maxSize = VcsUtil.getMaxVcsLoadedFileSize();
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream() {
+ @Override
+ public synchronized void write(int b) {
+ if (size() > maxSize) throw new FileTooBigRuntimeException();
+ super.write(b);
+ }
+
+ @Override
+ public synchronized void write(byte[] b, int off, int len) {
+ if (size() > maxSize) throw new FileTooBigRuntimeException();
+ super.write(b, off, len);
+ }
+
+ @Override
+ public synchronized void writeTo(OutputStream out) throws IOException {
+ if (size() > maxSize) throw new FileTooBigRuntimeException();
+ super.writeTo(out);
+ }
+ };
+ SVNWCClient wcClient = myVcs.createWCClient();
+ try {
+ if (target.isURL()) {
+ wcClient.doGetFileContents(target.getURL(), pegRevision, revision, true, buffer);
+ } else {
+ wcClient.doGetFileContents(target.getFile(), pegRevision, revision, true, buffer);
+ }
+ ContentRevisionCache.checkContentsSize(target.getPathOrUrlString(), buffer.size());
+ } catch (FileTooBigRuntimeException e) {
+ ContentRevisionCache.checkContentsSize(target.getPathOrUrlString(), buffer.size());
+ } catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ return buffer.toByteArray();
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CmdCopyMoveClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CmdCopyMoveClient.java
new file mode 100644
index 0000000..eceef14
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CmdCopyMoveClient.java
@@ -0,0 +1,30 @@
+package org.jetbrains.idea.svn.copy;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdCopyMoveClient extends BaseSvnClient implements CopyMoveClient {
+
+ @Override
+ public void copy(@NotNull File src, @NotNull File dst, boolean makeParents, boolean isMove) throws VcsException {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, src);
+ CommandUtil.put(parameters, dst);
+ CommandUtil.put(parameters, makeParents, "--parents");
+
+ // for now parsing of the output is not required as command is executed only for one file
+ // and will be either successful or exception will be thrown
+ CommandUtil.execute(myVcs, isMove ? SvnCommandName.move : SvnCommandName.copy, parameters, null);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CopyMoveClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CopyMoveClient.java
new file mode 100644
index 0000000..ec48107
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CopyMoveClient.java
@@ -0,0 +1,15 @@
+package org.jetbrains.idea.svn.copy;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.SvnClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface CopyMoveClient extends SvnClient {
+
+ void copy(@NotNull File src, @NotNull File dst, boolean makeParents, boolean isMove) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/SvnKitCopyMoveClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/SvnKitCopyMoveClient.java
new file mode 100644
index 0000000..ea84bc6
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/SvnKitCopyMoveClient.java
@@ -0,0 +1,28 @@
+package org.jetbrains.idea.svn.copy;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.SVNCopySource;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitCopyMoveClient extends BaseSvnClient implements CopyMoveClient {
+
+ @Override
+ public void copy(@NotNull File src, @NotNull File dst, boolean makeParents, boolean isMove) throws VcsException {
+ final SVNCopySource copySource = new SVNCopySource(isMove ? SVNRevision.UNDEFINED : SVNRevision.WORKING, SVNRevision.WORKING, src);
+
+ try {
+ myVcs.createCopyClient().doCopy(new SVNCopySource[]{copySource}, dst, isMove, makeParents, true);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/CmdDeleteClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/CmdDeleteClient.java
new file mode 100644
index 0000000..5fc26ac
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/CmdDeleteClient.java
@@ -0,0 +1,29 @@
+package org.jetbrains.idea.svn.delete;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdDeleteClient extends BaseSvnClient implements DeleteClient {
+
+ @Override
+ public void delete(@NotNull File path, boolean force) throws VcsException {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, path);
+ CommandUtil.put(parameters, force, "--force");
+
+ // for now parsing of the output is not required as command is executed only for one file
+ // and will be either successful or exception will be thrown
+ CommandUtil.execute(myVcs, SvnCommandName.delete, parameters, null);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/DeleteClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/DeleteClient.java
new file mode 100644
index 0000000..23a1cf9
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/DeleteClient.java
@@ -0,0 +1,15 @@
+package org.jetbrains.idea.svn.delete;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.SvnClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface DeleteClient extends SvnClient {
+
+ void delete(@NotNull File path, boolean force) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/SvnKitDeleteClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/SvnKitDeleteClient.java
new file mode 100644
index 0000000..c97cfd2
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/SvnKitDeleteClient.java
@@ -0,0 +1,24 @@
+package org.jetbrains.idea.svn.delete;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitDeleteClient extends BaseSvnClient implements DeleteClient {
+
+ @Override
+ public void delete(@NotNull File path, boolean force) throws VcsException {
+ try {
+ myVcs.createWCClient().doDelete(path, force, false);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java
index 62fc918..e1ad915 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java
@@ -263,17 +263,11 @@
super.init();
SvnVcs vcs = SvnVcs.getInstance(myProject);
String revStr = "";
- try {
- SVNWCClient client = vcs.createWCClient();
- SVNInfo info = client.doInfo(mySrcFile, SVNRevision.UNDEFINED);
- if (info != null) {
- mySrcURL = info.getURL() == null ? null : info.getURL().toString();
- revStr = String.valueOf(info.getRevision());
- myURL = mySrcURL;
- }
- }
- catch (SVNException e) {
- //
+ SVNInfo info = vcs.getInfo(mySrcFile);
+ if (info != null) {
+ mySrcURL = info.getURL() == null ? null : info.getURL().toString();
+ revStr = String.valueOf(info.getRevision());
+ myURL = mySrcURL;
}
if (myURL == null) {
return;
@@ -354,15 +348,8 @@
return true;
}
else if (myWorkingCopyRadioButton.isSelected()) {
- String srcUrl;
- try {
- SVNWCClient client = SvnVcs.getInstance(myProject).createWCClient();
- SVNInfo info = client.doInfo(mySrcFile, SVNRevision.UNDEFINED);
- srcUrl = info != null && info.getURL() != null ? info.getURL().toString() : null;
- }
- catch (SVNException e) {
- srcUrl = null;
- }
+ SVNInfo info = SvnVcs.getInstance(myProject).getInfo(mySrcFile);
+ String srcUrl = info != null && info.getURL() != null ? info.getURL().toString() : null;
if (srcUrl == null) {
myErrorLabel.setText(SvnBundle.message("create.branch.no.working.copy.error", myWorkingCopyField.getText()));
return false;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
new file mode 100644
index 0000000..3948dde
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
@@ -0,0 +1,223 @@
+package org.jetbrains.idea.svn.history;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.LineSeparator;
+import com.intellij.util.containers.hash.HashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.jetbrains.idea.svn.commandLine.SvnLineCommand;
+import org.tmatesoft.svn.core.ISVNLogEntryHandler;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNLogEntry;
+import org.tmatesoft.svn.core.SVNLogEntryPath;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdHistoryClient extends BaseSvnClient implements HistoryClient {
+
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.CmdHistoryClient");
+
+ @Override
+ public void doLog(@NotNull File path,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean stopOnCopy,
+ boolean discoverChangedPaths,
+ boolean includeMergedRevisions,
+ long limit,
+ @Nullable String[] revisionProperties,
+ @Nullable ISVNLogEntryHandler handler) throws VcsException {
+ // TODO: add revision properties parameter if necessary
+ // TODO: svn log command supports --xml option - could update parsing to use xml format
+
+ // TODO: after merge remove setting includeMergedRevisions to false and update parsing
+ includeMergedRevisions = false;
+
+ List<String> parameters =
+ prepareCommand(path, startRevision, endRevision, pegRevision, stopOnCopy, discoverChangedPaths, includeMergedRevisions, limit);
+
+ try {
+ SvnLineCommand command = CommandUtil.runSimple(SvnCommandName.log, myVcs, path, null, parameters);
+ // TODO: handler should be called in parallel with command execution, but this will be in other thread
+ // TODO: check if that is ok for current handler implementation
+ parseOutput(handler, command);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+
+ private static void parseOutput(@Nullable ISVNLogEntryHandler handler, @NotNull SvnLineCommand command)
+ throws VcsException, SVNException {
+ Parser parser = new Parser(handler);
+ for (String line : StringUtil.splitByLines(command.getOutput(), false)) {
+ parser.onLine(line);
+ }
+ }
+
+ private static List<String> prepareCommand(@NotNull File path,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean stopOnCopy, boolean discoverChangedPaths, boolean includeMergedRevisions, long limit) {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, path, pegRevision);
+ parameters.add("--revision");
+ parameters.add(startRevision + ":" + endRevision);
+
+ CommandUtil.put(parameters, stopOnCopy, "--stop-on-copy");
+ CommandUtil.put(parameters, discoverChangedPaths, "--verbose");
+ CommandUtil.put(parameters, includeMergedRevisions, "--use-merge-history");
+ if (limit > 0) {
+ parameters.add("--limit");
+ parameters.add(String.valueOf(limit));
+ }
+
+ return parameters;
+ }
+
+ private static class Parser {
+ private static final String REVISION = "\\s*r(\\d+)\\s*";
+ private static final String AUTHOR = "\\s*([^|]*)\\s*";
+ private static final String DATE = "\\s*([^|]*)\\s*";
+ private static final String MESSAGE_LINES = "\\s*(\\d+).*";
+
+ private static final Pattern ENTRY_START = Pattern.compile("-+");
+ private static final Pattern DETAILS = Pattern.compile(REVISION + "\\|" + AUTHOR + "\\|" + DATE + "\\|" + MESSAGE_LINES);
+
+ private static final String STATUS = "\\s*(\\w)";
+ private static final String PATH = "\\s*(.*?)\\s*";
+ private static final String COPY_FROM_PATH = "(/[^:]*)";
+ private static final String COPY_FROM_REVISION = "(\\d+)\\))\\s*";
+ private static final String COPY_FROM_INFO = "((\\(from " + COPY_FROM_PATH + ":" + COPY_FROM_REVISION + ")?";
+ private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH + COPY_FROM_INFO);
+
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
+
+ ISVNLogEntryHandler handler;
+
+ Entry entry;
+ boolean waitDetails;
+ boolean waitChangedPath;
+ boolean waitMessage;
+
+ public Parser(@Nullable ISVNLogEntryHandler handler) {
+ this.handler = handler;
+ }
+
+ public void onLine(@NotNull String line) throws VcsException, SVNException {
+ if (ENTRY_START.matcher(line).matches()) {
+ processEntryStart();
+ }
+ else if (waitDetails) {
+ processDetails(line);
+ }
+ else if (waitMessage) {
+ processMessage(line);
+ }
+ else if (StringUtil.isEmpty(line.trim())) {
+ processChangedPathsFinished();
+ }
+ else if (line.startsWith("Changed paths:")) {
+ processChangedPathsStarted();
+ }
+ else if (waitChangedPath) {
+ processChangedPath(line);
+ }
+ else {
+ throw new VcsException("unknown state on line " + line);
+ }
+ }
+
+ private void processChangedPath(@NotNull String line) throws VcsException {
+ Matcher matcher = CHANGED_PATH.matcher(line);
+ if (!matcher.matches()) {
+ throw new VcsException("changed path not found in " + line);
+ }
+
+ String path = matcher.group(2);
+ char type = CommandUtil.getStatusChar(matcher.group(1));
+ String copyPath = matcher.group(5);
+ long copyRevision = !StringUtil.isEmpty(matcher.group(6)) ? Long.valueOf(matcher.group(6)) : 0;
+
+ entry.changedPaths.put(path, new SVNLogEntryPath(path, type, copyPath, copyRevision));
+ }
+
+ private void processChangedPathsStarted() {
+ waitChangedPath = true;
+ }
+
+ private void processChangedPathsFinished() {
+ waitChangedPath = false;
+ waitMessage = true;
+ }
+
+ private void processMessage(@NotNull String line) {
+ entry.message.append(line);
+ entry.message.append(LineSeparator.LF.getSeparatorString());
+ }
+
+ private void processDetails(@NotNull String line) throws VcsException {
+ Matcher matcher = DETAILS.matcher(line);
+ if (!matcher.matches()) {
+ throw new VcsException("details not found in " + line);
+ }
+ entry.revision = Long.valueOf(matcher.group(1));
+ entry.author = matcher.group(2).trim();
+ entry.date = tryGetDate(matcher.group(3));
+
+ waitDetails = false;
+ }
+
+ private void processEntryStart() throws SVNException {
+ if (entry != null) {
+ handler.handleLogEntry(entry.toLogEntry());
+ }
+ entry = new Entry();
+ waitDetails = true;
+ waitMessage = false;
+ }
+
+ private static Date tryGetDate(@NotNull String value) {
+ Date result = null;
+ try {
+ result = DATE_FORMAT.parse(value);
+ }
+ catch (ParseException e) {
+ LOG.debug(e);
+ }
+ return result;
+ }
+
+ private static class Entry {
+ Map<String, SVNLogEntryPath> changedPaths = new HashMap<String, SVNLogEntryPath>();
+ long revision;
+ String author;
+ Date date;
+ StringBuilder message = new StringBuilder();
+
+ private SVNLogEntry toLogEntry() {
+ return new SVNLogEntry(changedPaths, revision, author, date, message.toString());
+ }
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/HistoryClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/HistoryClient.java
new file mode 100644
index 0000000..87e5e76
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/HistoryClient.java
@@ -0,0 +1,28 @@
+package org.jetbrains.idea.svn.history;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.ISVNLogEntryHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface HistoryClient extends SvnClient {
+
+ // TODO: Url is also supported as parameter in cmd - use Target class
+ void doLog(@NotNull File path,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean stopOnCopy,
+ boolean discoverChangedPaths,
+ boolean includeMergedRevisions,
+ long limit,
+ @Nullable String[] revisionProperties,
+ @Nullable ISVNLogEntryHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java
index 7ef0b2f..3552853 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java
@@ -518,9 +518,8 @@
revisionBefore = SVNRevision.create(revision);
svnurl = SVNURL.parseURIEncoded(url);
- final SVNWCClient client = myVcs.createWCClient();
- final SVNInfo info = client.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
- targetInfo = client.doInfo(new File(file.getPath()), SVNRevision.UNDEFINED);
+ final SVNInfo info = myVcs.getInfo(svnurl, SVNRevision.HEAD);
+ targetInfo = myVcs.getInfo(new File(file.getPath()));
if (info == null) {
throw new VcsException("Can not get repository URL");
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
index 5ca1150..d67e29b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
@@ -137,7 +137,7 @@
final String url = myLocation.getURL();
final SVNURL root;
try {
- root = SvnUtil.getRepositoryRoot(myVcs, SVNURL.parseURIEncoded(url), true);
+ root = SvnUtil.getRepositoryRoot(myVcs, SVNURL.parseURIEncoded(url));
if (root == null) {
myException = new VcsException("Can not determine repository root for URL: " + url);
return;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java
index bcb40a0..046e16c 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java
@@ -33,6 +33,7 @@
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -211,7 +212,7 @@
}
try {
- myContents = SvnUtil.getFileContents(myVCS, myURL, true, myRevision, myPegRevision);
+ myContents = SvnUtil.getFileContents(myVCS, SvnTarget.fromURL(SvnUtil.parseUrl(myURL)), myRevision, myPegRevision);
}
catch (VcsException e) {
myException = e;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
index 4a2c872..860b646 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
@@ -42,7 +42,6 @@
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
-import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.*;
import org.tmatesoft.svn.util.SVNLogType;
@@ -50,7 +49,6 @@
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.MouseEvent;
-import java.io.File;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Date;
@@ -285,18 +283,9 @@
@Override
protected void preliminary() throws SVNException {
- SVNWCClient wcClient = myVcs.createWCClient();
- myInfo = wcClient.doInfo(new File(myFile.getIOFile().getAbsolutePath()), SVNRevision.UNDEFINED);
- wcClient.setEventHandler(new ISVNEventHandler() {
- public void handleEvent(SVNEvent event, double progress) throws SVNException {
- }
-
- public void checkCancelled() throws SVNCancelException {
- myPI.checkCanceled();
- }
- });
+ myInfo = myVcs.getInfo(myFile.getIOFile());
if (myInfo == null || myInfo.getRepositoryRootURL() == null) {
- myException = new VcsException("File ''{0}'' is not under version control" + myFile.getIOFile());
+ myException = new VcsException("File " + myFile.getPath() + " is not under version control");
return;
}
if (myInfo.getURL() == null) {
@@ -319,14 +308,15 @@
myPI.setText2(SvnBundle.message("progress.text2.changes.establishing.connection", myUrl));
}
final SVNRevision pegRevision = myInfo.getRevision();
- SVNLogClient client = myVcs.createLogClient();
try {
- // a bug noticed when testing: we should pass "limit + 1" to get "limit" rows
- client
- .doLog(new File[]{new File(myFile.getIOFile().getAbsolutePath())},
- myFrom == null ? SVNRevision.HEAD : myFrom, myTo == null ? SVNRevision.create(1) : myTo, myPeg,
- false, true, myShowMergeSources && mySupport15, myLimit + 1, null,
- new MyLogEntryHandler(myVcs, myUrl, pegRevision, relativeUrl, createConsumerAdapter(myConsumer), repoRootURL, myFile.getCharset()));
+ myVcs.getFactory(myFile.getIOFile()).createHistoryClient().doLog(
+ myFile.getIOFile(),
+ myFrom == null ? SVNRevision.HEAD : myFrom,
+ myTo == null ? SVNRevision.create(1) : myTo, myPeg,
+ false, true, myShowMergeSources && mySupport15, myLimit + 1, null,
+ new MyLogEntryHandler(myVcs, myUrl, pegRevision, relativeUrl,
+ createConsumerAdapter(myConsumer),
+ repoRootURL, myFile.getCharset()));
}
catch (SVNCancelException e) {
//
@@ -383,7 +373,6 @@
}
}
- SVNWCClient wcClient = myVcs.createWCClient();
final SVNURL svnurl = SVNURL.parseURIEncoded(myUrl);
SVNRevision operationalFrom = myFrom == null ? SVNRevision.HEAD : myFrom;
final SVNURL rootURL = getRepositoryRoot(svnurl, myFrom);
@@ -395,6 +384,7 @@
if (myUrl.startsWith(root)) {
relativeUrl = myUrl.substring(root.length());
}
+ // TODO: Update this call to myVcs.getFactory.createHistoryClient
SVNLogClient client = myVcs.createLogClient();
// a bug noticed when testing: we should pass "limit + 1" to get "limit" rows
client.doLog(svnurl, new String[]{}, myPeg == null ? myFrom : myPeg,
@@ -420,6 +410,7 @@
relativeUrl = myUrl.substring(root.length());
}
+ // TODO: Update this call to myVcs.getFactory.createHistoryClient
SVNLogClient client = myVcs.createLogClient();
final RepositoryLogEntryHandler repositoryLogEntryHandler =
@@ -437,36 +428,15 @@
}
private SVNURL getRepositoryRoot(SVNURL svnurl, SVNRevision operationalFrom) throws SVNException {
- final SVNRepository repository = myVcs.createRepository(svnurl);
- final SVNURL root = repository.getRepositoryRoot(false);
- if (root == null) {
- return repository.getRepositoryRoot(true);
- }
- return root;
- /*final SVNWCClient wcClient = myVcs.createWCClient();
- try {
- final SVNInfo info;
- info = wcClient.doInfo(svnurl, myPeg, operationalFrom);
- return info.getRepositoryRootURL();
- }
- catch (SVNException e) {
- try {
- final SVNInfo info;
- info = wcClient.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
- return info.getRepositoryRootURL();
- } catch (SVNException e1) {
- final SVNInfo info;
- info = wcClient.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
- return info.getRepositoryRootURL();
- }
- }*/
+ SVNInfo info = myVcs.getInfo(svnurl, SVNRevision.HEAD);
+
+ return info != null ? info.getRepositoryRootURL() : null;
}
private boolean existsNow(SVNURL svnurl) {
- final SVNWCClient wcClient = myVcs.createWCClient();
final SVNInfo info;
try {
- info = wcClient.doInfo(svnurl, SVNRevision.HEAD, SVNRevision.HEAD);
+ info = myVcs.getInfo(svnurl, SVNRevision.HEAD, SVNRevision.HEAD, null);
}
catch (SVNException e) {
return false;
@@ -493,6 +463,7 @@
protected final SvnPathThroughHistoryCorrection myLastPathCorrector;
private final Charset myCharset;
protected final ThrowableConsumer<VcsFileRevision, SVNException> myResult;
+ private final String myLastPath;
private VcsFileRevision myPrevious;
private final SVNRevision myPegRevision;
protected final String myUrl;
@@ -512,6 +483,7 @@
throws SVNException, VcsException {
myVcs = vcs;
myLastPathCorrector = new SvnPathThroughHistoryCorrection(lastPath);
+ myLastPath = lastPath;
myCharset = charset;
myIndicator = ProgressManager.getInstance().getProgressIndicator();
myResult = result;
@@ -610,9 +582,9 @@
String author = logEntry.getAuthor();
String message = logEntry.getMessage();
SVNRevision rev = SVNRevision.create(logEntry.getRevision());
-// final SVNURL url = myRepositoryRoot.appendPath(myLastPath, true);
- final SVNURL url = entryPath != null ? myRepositoryRoot.appendPath(entryPath.getPath(), true) :
- myRepositoryRoot.appendPath(myLastPathCorrector.getBefore(), false);
+ final SVNURL url = myRepositoryRoot.appendPath(myLastPath, true);
+// final SVNURL url = entryPath != null ? myRepositoryRoot.appendPath(entryPath.getPath(), true) :
+// myRepositoryRoot.appendPath(myLastPathCorrector.getBefore(), false);
return new SvnFileRevision(myVcs, myPegRevision, rev, url.toString(), author, date, message, copyPath, myCharset);
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java
index e30f8ca..171b39c 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java
@@ -20,21 +20,19 @@
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnRevisionNumber;
import org.jetbrains.idea.svn.SvnVcs;
-import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNRevision;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
import java.io.File;
import java.util.List;
/**
-* Created with IntelliJ IDEA.
-* User: Irina.Chernushina
-* Date: 4/27/12
-* Time: 12:24 PM
-* To change this template use File | Settings | File Templates.
-*/
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 4/27/12
+ * Time: 12:24 PM
+ * To change this template use File | Settings | File Templates.
+ */
public class SvnHistorySession extends VcsAbstractHistorySession {
private final SvnVcs myVcs;
private final FilePath myCommittedPath;
@@ -71,19 +69,8 @@
}
public static VcsRevisionNumber getCurrentCommittedRevision(final SvnVcs vcs, final File file) {
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- SVNInfo info = wcClient.doInfo(file, SVNRevision.UNDEFINED);
- if (info != null) {
- return new SvnRevisionNumber(info.getCommittedRevision());
- }
- else {
- return null;
- }
- }
- catch (SVNException e) {
- return null;
- }
+ SVNInfo info = vcs.getInfo(file);
+ return info != null ? new SvnRevisionNumber(info.getCommittedRevision()) : null;
}
public FilePath getCommittedPath() {
@@ -101,7 +88,8 @@
@Override
public VcsHistorySession copy() {
- return new SvnHistorySession(myVcs, getRevisionList(), myCommittedPath, myHaveMergeSources, getCurrentRevisionNumber(), true, myHasLocalSource);
+ return new SvnHistorySession(myVcs, getRevisionList(), myCommittedPath, myHaveMergeSources, getCurrentRevisionNumber(), true,
+ myHasLocalSource);
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnKitHistoryClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnKitHistoryClient.java
new file mode 100644
index 0000000..6d41285
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnKitHistoryClient.java
@@ -0,0 +1,40 @@
+package org.jetbrains.idea.svn.history;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.ISVNLogEntryHandler;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.SVNLogClient;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitHistoryClient extends BaseSvnClient implements HistoryClient {
+ @Override
+ public void doLog(@NotNull File path,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean stopOnCopy,
+ boolean discoverChangedPaths,
+ boolean includeMergedRevisions,
+ long limit,
+ @Nullable String[] revisionProperties,
+ @Nullable ISVNLogEntryHandler handler) throws VcsException {
+ try {
+ // TODO: a bug noticed when testing: we should pass "limit + 1" to get "limit" rows
+ SVNLogClient client = myVcs.createLogClient();
+
+ client.doLog(new File[]{path}, startRevision, endRevision, pegRevision, stopOnCopy, discoverChangedPaths, includeMergedRevisions,
+ limit, revisionProperties, handler);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java
index a668a54f9..b01308f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java
@@ -38,13 +38,10 @@
import com.intellij.openapi.vcs.impl.ContentRevisionCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.svn.SvnBundle;
-import org.jetbrains.idea.svn.SvnRevisionNumber;
-import org.jetbrains.idea.svn.SvnUtil;
-import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.*;
import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -108,7 +105,7 @@
else {
loader.run();
}
- final SVNException exception = loader.getException();
+ final Exception exception = loader.getException();
if (exception != null) {
throw new VcsException(exception);
}
@@ -148,7 +145,7 @@
private final String myPath;
private final long myRevision;
private final OutputStream myDst;
- private SVNException myException;
+ private Exception myException;
public ContentLoader(String path, OutputStream dst, long revision) {
myPath = path;
@@ -156,7 +153,7 @@
myRevision = revision;
}
- public SVNException getException() {
+ public Exception getException() {
return myException;
}
@@ -166,16 +163,16 @@
progress.setText(SvnBundle.message("progress.text.loading.contents", myPath));
progress.setText2(SvnBundle.message("progress.text2.revision.information", myRevision));
}
+
try {
- SVNRepository repository = myVcs.createRepository(getFullPath());
- try {
- repository.getFile("", myRevision, null, myDst);
- }
- finally {
- repository.closeSession();
- }
+ byte[] contents = SvnUtil.getFileContents(myVcs, SvnTarget.fromURL(SvnUtil.parseUrl(getFullPath())), SVNRevision.create(myRevision),
+ SVNRevision.UNDEFINED);
+ myDst.write(contents);
}
- catch (SVNException e) {
+ catch (VcsException e) {
+ myException = e;
+ }
+ catch (IOException e) {
myException = e;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java
index 78718a7..bfb9f1f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java
@@ -251,19 +251,10 @@
@Nullable
private static SVNURL realTargetUrl(final SvnVcs vcs, final WorkingCopyInfo info, final String targetBranchUrl) {
- final SVNWCClient client = vcs.createWCClient();
- try {
- final SVNInfo svnInfo = client.doInfo(new File(info.getLocalPath()), SVNRevision.UNDEFINED);
- final SVNURL svnurl = svnInfo.getURL();
+ final SVNInfo svnInfo = vcs.getInfo(info.getLocalPath());
+ final SVNURL svnurl = svnInfo != null ? svnInfo.getURL() : null;
- if ((svnurl != null) && (svnurl.toString().startsWith(targetBranchUrl))) {
- return svnurl;
- }
- }
- catch (SVNException e) {
- // tracked by return value
- }
- return null;
+ return (svnurl != null) && (svnurl.toString().startsWith(targetBranchUrl)) ? svnurl : null;
}
@Nullable
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java
index b6c6a89..bc08fff 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java
@@ -238,12 +238,7 @@
}
private SVNInfo getInfo(final File pathFile) {
- try {
- return myClient.doInfo(pathFile, SVNRevision.UNDEFINED);
- } catch (SVNException e) {
- //
- }
- return null;
+ return myVcs.getInfo(pathFile);
}
private SvnMergeInfoCache.MergeCheckResult checkPathGoingUp(final long revisionAsked, final long targetRevision, final String branchRootPath,
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/PortableStatus.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/PortableStatus.java
index 184d559..9799cf7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/PortableStatus.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/PortableStatus.java
@@ -117,6 +117,7 @@
return null;
}
};
+ // TODO: Update working copy format detection
setWorkingCopyFormat(WorkingCopyFormat.ONE_DOT_SEVEN.getFormat());
}
@@ -242,6 +243,30 @@
}
@Override
+ public SVNURL getURL() {
+ SVNURL url = super.getURL();
+
+ if (url == null) {
+ SVNInfo info = initInfo();
+ url = info != null ? info.getURL() : url;
+ }
+
+ return url;
+ }
+
+ @Override
+ public File getFile() {
+ File file = super.getFile();
+
+ if (file == null) {
+ SVNInfo info = initInfo();
+ file = info != null ? info.getFile() : file;
+ }
+
+ return file;
+ }
+
+ @Override
public SVNRevision getRevision() {
final SVNRevision revision = super.getRevision();
if (revision != null && revision.isValid()) return revision;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
new file mode 100644
index 0000000..4720b33
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
@@ -0,0 +1,65 @@
+package org.jetbrains.idea.svn.properties;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommand;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNPropertyValue;
+import org.tmatesoft.svn.core.wc.SVNInfo;
+import org.tmatesoft.svn.core.wc.SVNPropertyData;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
+
+ @Nullable
+ @Override
+ public SVNPropertyData getProperty(@NotNull File path,
+ @NotNull String property,
+ boolean revisionProperty,
+ @Nullable SVNRevision pegRevision,
+ @Nullable SVNRevision revision)
+ throws VcsException {
+ List<String> parameters = new ArrayList<String>();
+
+ parameters.add(property);
+ CommandUtil.put(parameters, path, pegRevision);
+ if (!revisionProperty) {
+ CommandUtil.put(parameters, revision);
+ } else {
+ parameters.add("--revprop");
+ CommandUtil.put(parameters, resolveRevisionNumber(path, revision));
+ }
+
+ SvnCommand command = CommandUtil.execute(myVcs, SvnCommandName.propget, parameters, null);
+
+ return new SVNPropertyData(property, SVNPropertyValue.create(StringUtil.nullize(command.getOutput())), null);
+ }
+
+ private SVNRevision resolveRevisionNumber(@NotNull File path, @Nullable SVNRevision revision) throws VcsException {
+ long result = revision != null ? revision.getNumber() : -1;
+
+ // base should be resolved manually - could not set revision to BASE to get revision property
+ if (SVNRevision.BASE.equals(revision)) {
+ SVNInfo info = myVcs.getInfo(path, SVNRevision.BASE);
+
+ result = info != null ? info.getRevision().getNumber() : -1;
+ }
+
+ if (result == -1) {
+ throw new VcsException("Could not determine revision number for file " + path + " and revision " + revision);
+ }
+
+ return SVNRevision.create(result);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
new file mode 100644
index 0000000..118a397
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
@@ -0,0 +1,23 @@
+package org.jetbrains.idea.svn.properties;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.wc.SVNPropertyData;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface PropertyClient extends SvnClient {
+
+ @Nullable
+ SVNPropertyData getProperty(@NotNull final File path,
+ @NotNull final String property,
+ boolean revisionProperty,
+ @Nullable SVNRevision pegRevision,
+ @Nullable SVNRevision revision) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
new file mode 100644
index 0000000..1c3c236
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
@@ -0,0 +1,68 @@
+package org.jetbrains.idea.svn.properties;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
+import org.tmatesoft.svn.core.wc.SVNPropertyData;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNWCClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClient {
+
+ @Nullable
+ @Override
+ public SVNPropertyData getProperty(@NotNull File path,
+ @NotNull String property,
+ boolean revisionProperty,
+ @Nullable SVNRevision pegRevision,
+ @Nullable SVNRevision revision) throws VcsException {
+ try {
+ if (!revisionProperty) {
+ return myVcs.createWCClient().doGetProperty(path, property, pegRevision, revision);
+ } else {
+ return getRevisionProperty(path, property, revision);
+ }
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+
+ private SVNPropertyData getRevisionProperty(@NotNull File path, @NotNull final String property, @Nullable SVNRevision revision) throws SVNException{
+ final SVNWCClient client = myVcs.createWCClient();
+ final SVNPropertyData[] result = new SVNPropertyData[1];
+
+ client.doGetRevisionProperty(path, null, revision, new ISVNPropertyHandler() {
+ @Override
+ public void handleProperty(File path, SVNPropertyData property) throws SVNException {
+ handle(property);
+ }
+
+ @Override
+ public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
+ handle(property);
+ }
+
+ @Override
+ public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
+ handle(property);
+ }
+
+ private void handle(@NotNull SVNPropertyData data) {
+ if (property.equals(data.getName())) {
+ result[0] = data;
+ }
+ }
+ });
+ return result[0];
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java
new file mode 100644
index 0000000..53c998f
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java
@@ -0,0 +1,79 @@
+package org.jetbrains.idea.svn.revert;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.containers.Convertor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.api.FileStatusResultParser;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+import org.tmatesoft.svn.core.wc.SVNEventAction;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdRevertClient extends BaseSvnClient implements RevertClient {
+
+ private static final String STATUS = "\\s*(.+?)\\s*";
+ private static final String PATH = "\\s*\'(.*?)\'\\s*";
+ private static final String OPTIONAL_COMMENT = "(.*)";
+ private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH + OPTIONAL_COMMENT);
+
+ @Override
+ public void revert(@NotNull File[] paths, @Nullable SVNDepth depth, @Nullable ISVNEventHandler handler) throws VcsException {
+ List<String> parameters = prepareParameters(paths, depth);
+
+ // TODO: handler should be called in parallel with command execution, but this will be in other thread
+ // TODO: check if that is ok for current handler implementation
+ // TODO: add possibility to invoke "handler.checkCancelled" - process should be killed
+ CommandUtil
+ .execute(myVcs, SvnCommandName.revert, parameters, new FileStatusResultParser(CHANGED_PATH, handler, new RevertStatusConvertor()));
+ }
+
+ private static List<String> prepareParameters(File[] paths, SVNDepth depth) {
+ ArrayList<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, paths);
+ CommandUtil.put(parameters, depth);
+
+ return parameters;
+ }
+
+ private static class RevertStatusConvertor implements Convertor<Matcher, SVNEvent> {
+
+ public SVNEvent convert(@NotNull Matcher matcher) {
+ String statusMessage = matcher.group(1);
+ String path = matcher.group(2);
+
+ return new SVNEvent(new File(path), null, null, 0, null, null, null, null, createAction(statusMessage), null, null, null, null, null,
+ null);
+ }
+
+ @Nullable
+ public static SVNEventAction createAction(@NotNull String code) {
+ SVNEventAction result = null;
+
+ if ("Reverted".equals(code)) {
+ result = SVNEventAction.REVERT;
+ }
+ else if ("Failed to revert".equals(code)) {
+ result = SVNEventAction.FAILED_REVERT;
+ }
+ else if ("Skipped".equals(code)) {
+ result = SVNEventAction.SKIP;
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/RevertClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/RevertClient.java
new file mode 100644
index 0000000..053de37
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/RevertClient.java
@@ -0,0 +1,18 @@
+package org.jetbrains.idea.svn.revert;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface RevertClient extends SvnClient {
+
+ void revert(@NotNull File[] paths, @Nullable SVNDepth depth, @Nullable ISVNEventHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/SvnKitRevertClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/SvnKitRevertClient.java
new file mode 100644
index 0000000..17c725c
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/SvnKitRevertClient.java
@@ -0,0 +1,31 @@
+package org.jetbrains.idea.svn.revert;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNWCClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitRevertClient extends BaseSvnClient implements RevertClient {
+
+ @Override
+ public void revert(@NotNull File[] paths, @Nullable SVNDepth depth, @Nullable ISVNEventHandler handler) throws VcsException {
+ SVNWCClient client = myVcs.createWCClient();
+
+ client.setEventHandler(handler);
+ try {
+ client.doRevert(paths, depth, null);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java
index 265d4ca..4140ca7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java
@@ -28,6 +28,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.revert.RevertClient;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
@@ -74,8 +75,7 @@
checker.gather(changes);
exceptions.addAll(checker.getExceptions());
- final SVNWCClient client = mySvnVcs.createWCClient();
- client.setEventHandler(new ISVNEventHandler() {
+ ISVNEventHandler revertHandler = new ISVNEventHandler() {
public void handleEvent(SVNEvent event, double progress) {
if (event.getAction() == SVNEventAction.REVERT) {
final File file = event.getFile();
@@ -91,7 +91,7 @@
public void checkCancelled() {
listener.checkCanceled();
}
- });
+ };
final List<CopiedAsideInfo> fromToModified = new ArrayList<CopiedAsideInfo>();
final MultiMap<File, SVNPropertyData> properties = new MultiMap<File, SVNPropertyData>();
@@ -99,7 +99,7 @@
// adds (deletes)
// deletes (adds)
// modifications
- final Reverter reverter = new Reverter(client, exceptions);
+ final Reverter reverter = new Reverter(mySvnVcs.getFactory().createRevertClient(), revertHandler, exceptions);
reverter.revert(checker.getForAdds(), true);
reverter.revert(checker.getForDeletes(), true);
final List<File> edits = checker.getForEdits();
@@ -256,24 +256,36 @@
}
private static class Reverter {
- private final SVNWCClient myClient;
+ private final RevertClient myClient;
+ private ISVNEventHandler myHandler;
private final List<VcsException> myExceptions;
- private Reverter(SVNWCClient client, List<VcsException> exceptions) {
+ private Reverter(RevertClient client, ISVNEventHandler handler, List<VcsException> exceptions) {
myClient = client;
+ myHandler = handler;
myExceptions = exceptions;
}
public void revert(final File[] files, final boolean recursive) {
if (files.length == 0) return;
try {
- myClient.doRevert(files, recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY, null);
+ myClient.revert(files, recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY, myHandler);
}
- catch (SVNException e) {
- if (e.getErrorMessage().getErrorCode() != SVNErrorCode.WC_NOT_DIRECTORY) {
- // skip errors on unversioned resources.
- myExceptions.add(new VcsException(e));
+ catch (VcsException e) {
+ processRevertError(e);
+ }
+ }
+
+ private void processRevertError(@NotNull VcsException e) {
+ if (e.getCause() instanceof SVNException) {
+ SVNException cause = (SVNException)e.getCause();
+
+ // skip errors on unversioned resources.
+ if (cause.getErrorMessage().getErrorCode() != SVNErrorCode.WC_NOT_DIRECTORY) {
+ myExceptions.add(e);
}
+ } else {
+ myExceptions.add(e);
}
}
}
@@ -294,18 +306,17 @@
}
private void revertFileOrDir(File file) throws SVNException, VcsException {
- final SVNWCClient wcClient = mySvnVcs.createWCClient();
- SVNInfo info = wcClient.doInfo(file, SVNRevision.UNDEFINED);
+ SVNInfo info = mySvnVcs.getInfo(file);
if (info != null) {
if (info.getKind() == SVNNodeKind.FILE) {
- wcClient.doRevert(file, false);
+ doRevert(file, false);
} else {
if (SVNProperty.SCHEDULE_ADD.equals(info.getSchedule())) {
- wcClient.doRevert(file, true);
+ doRevert(file, true);
} else {
boolean under17Copy = isUnder17Copy(file, info);
if (under17Copy) {
- wcClient.doRevert(file, true);
+ doRevert(file, true);
} else {
// do update to restore missing directory.
mySvnVcs.createUpdateClient().doUpdate(file, SVNRevision.HEAD, true);
@@ -317,10 +328,16 @@
}
}
+ private void doRevert(@NotNull File path, boolean recursive) throws VcsException {
+ mySvnVcs.getFactory(path).createRevertClient().revert(new File[]{path}, SVNDepth.fromRecurse(recursive), null);
+ }
+
private boolean isUnder17Copy(final File file, final SVNInfo info) throws VcsException {
final RootsToWorkingCopies copies = mySvnVcs.getRootsToWorkingCopies();
WorkingCopy copy = copies.getMatchingCopy(info.getURL());
if (copy == null) {
+ // TODO: Why null could be here?
+ // TODO: Think we could just rewrite it with mySvnVcs.getWorkingCopyFormat(file)
SVNStatus status = null;
try {
status = mySvnVcs.createStatusClient().doStatus(file, false);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdatePanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdatePanel.java
index ecc3fa6..d6bdf63 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdatePanel.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdatePanel.java
@@ -109,17 +109,8 @@
@Nullable
private SVNURL getUrlFor(@NotNull final FilePath root) {
- try {
- SVNWCClient wcClient = myVCS.createWCClient();
- final SVNInfo info = wcClient.doInfo(root.getIOFile(), SVNRevision.UNDEFINED);
- if (info != null) {
- return info.getURL();
- }
- return null;
- }
- catch (SVNException e) {
- return null;
- }
+ final SVNInfo info = myVCS.getInfo(root.getIOFile());
+ return info != null ? info.getURL() : null;
}
protected abstract JComponent getPanel();
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java
index e9e7b0b..826f753 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java
@@ -59,7 +59,7 @@
SVNUpdateClient client = myVcs.createUpdateClient();
client.setEventHandler(myHandler);
- long rev = doUpdate(root, client);
+ long rev = doUpdate(root);
if (rev < 0 && !isMerge()) {
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, SvnBundle.message("exception.text.root.was.not.properly.updated", root)));
@@ -73,9 +73,7 @@
protected abstract void showProgressMessage(ProgressIndicator progress, File root);
- protected abstract long doUpdate(
- File root,
- SVNUpdateClient client) throws SVNException;
+ protected abstract long doUpdate(File root) throws SVNException;
protected abstract boolean isMerge();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/MergeRootInfo.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/MergeRootInfo.java
index b8ea052..96701b51 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/MergeRootInfo.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/MergeRootInfo.java
@@ -18,6 +18,7 @@
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNWCClient;
@@ -33,17 +34,9 @@
myRevision1 = SVNRevision.HEAD;
myRevision2 = SVNRevision.HEAD;
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- final SVNURL url = wcClient.doInfo(file, SVNRevision.UNDEFINED).getURL();
- myUrl1 = url.toString();
- myUrl2 = url.toString();
- }
- catch (SVNException e) {
- myUrl1 = "";
- myUrl2 = "";
- }
-
+ SVNInfo info = vcs.getInfo(file);
+ myUrl1 = info != null && info.getURL() != null ? info.getURL().toString() : "";
+ myUrl2 = myUrl1;
}
public SVNURL getUrl1() {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateEnvironment.java
index 9e8a599..9f4a95f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateEnvironment.java
@@ -91,10 +91,7 @@
}
}
- protected long doUpdate(
- final File root,
- final SVNUpdateClient client) throws
- SVNException {
+ protected long doUpdate(final File root) throws SVNException {
final SvnConfiguration svnConfig = SvnConfiguration.getInstance(myVcs.getProject());
MergeRootInfo info = svnConfig.getMergeRootInfo(root, myVcs);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
index 80e43aa..5d2d415 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
@@ -33,7 +33,6 @@
import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
import java.io.File;
import java.util.ArrayList;
@@ -76,10 +75,7 @@
progress.setText(SvnBundle.message("progress.text.updating", root.getAbsolutePath()));
}
- protected long doUpdate(
- final File root,
- final SVNUpdateClient client) throws
- SVNException {
+ protected long doUpdate(final File root) throws SVNException {
final long rev;
final SvnConfiguration configuration = SvnConfiguration.getInstance(myVcs.getProject());
@@ -104,13 +100,15 @@
private SvnUpdateClientI createUpdateClient(SvnConfiguration configuration, File root, boolean isSwitch, SVNURL sourceUrl) {
final SvnUpdateClientI updateClient;
+ boolean is18Format = myVcs.getWorkingCopyFormat(root) == WorkingCopyFormat.ONE_DOT_EIGHT;
+
// do not do from command line for switch now
- if (! isSwitch && SvnConfiguration.UseAcceleration.commandLine.equals(configuration.myUseAcceleration) &&
+ if (! isSwitch && (is18Format || SvnConfiguration.UseAcceleration.commandLine.equals(configuration.myUseAcceleration) &&
Svn17Detector.is17(myVcs.getProject(), root) && (
SvnAuthenticationManager.HTTP.equals(sourceUrl.getProtocol()) ||
SvnAuthenticationManager.HTTPS.equals(sourceUrl.getProtocol())
- )) {
- updateClient = new SvnCommandLineUpdateClient(myVcs.getProject(), null);
+ ))) {
+ updateClient = new SvnCommandLineUpdateClient(myVcs, null);
} else {
updateClient = new SvnSvnkitUpdateClient(myVcs.createUpdateClient());
}
@@ -129,18 +127,8 @@
@Nullable
private static SVNURL getSourceUrl(final SvnVcs vcs, final File root) {
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- final SVNInfo svnInfo = wcClient.doInfo(root, SVNRevision.UNDEFINED);
- if (svnInfo != null) {
- return svnInfo.getURL();
- } else {
- return null;
- }
- }
- catch (SVNException e) {
- return null;
- }
+ final SVNInfo svnInfo = vcs.getInfo(root);
+ return svnInfo != null ? svnInfo.getURL() : null;
}
public boolean validateOptions(final Collection<FilePath> roots) {
@@ -193,9 +181,8 @@
// false - do not do update
private boolean checkAncestry(final File sourceFile, final SVNURL targetUrl, final SVNRevision targetRevision) throws SVNException {
- final SVNWCClient client = myVcs.createWCClient();
- final SVNInfo sourceSvnInfo = client.doInfo(sourceFile, SVNRevision.UNDEFINED);
- final SVNInfo targetSvnInfo = client.doInfo(targetUrl, SVNRevision.UNDEFINED, targetRevision);
+ final SVNInfo sourceSvnInfo = myVcs.getInfo(sourceFile);
+ final SVNInfo targetSvnInfo = myVcs.getInfo(targetUrl, targetRevision);
if (sourceSvnInfo == null || targetSvnInfo == null) {
// cannot check
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateRootInfo.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateRootInfo.java
index 4852e9f..201260e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateRootInfo.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateRootInfo.java
@@ -31,20 +31,9 @@
public UpdateRootInfo(File file, SvnVcs vcs) {
myRevision = SVNRevision.HEAD;
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- SVNInfo info = wcClient.doInfo(file, SVNRevision.UNDEFINED);
- if (info != null) {
- final SVNURL url = info.getURL();
- myUrl = url.toString();
- } else {
- myUrl = "";
- }
- }
- catch (SVNException e) {
- myUrl = "";
- }
+ SVNInfo info = vcs.getInfo(file);
+ myUrl = info != null && info.getURL() != null ? info.getDepth().toString() : "";
}
public SVNURL getUrl() {
diff --git a/plugins/svn4idea/svn4idea-tests.iml b/plugins/svn4idea/svn4idea-tests.iml
index 9a537c2..0b826ed 100644
--- a/plugins/svn4idea/svn4idea-tests.iml
+++ b/plugins/svn4idea/svn4idea-tests.iml
@@ -38,7 +38,6 @@
</SOURCES>
</library>
</orderEntry>
- <orderEntry type="module" module-name="bindSvn" />
</component>
</module>
diff --git a/plugins/svn4idea/svn4idea.iml b/plugins/svn4idea/svn4idea.iml
index 4f0d931..53dd661 100644
--- a/plugins/svn4idea/svn4idea.iml
+++ b/plugins/svn4idea/svn4idea.iml
@@ -76,16 +76,6 @@
</SOURCES>
</library>
</orderEntry>
- <orderEntry type="module" module-name="bindSvn" />
- <orderEntry type="module-library">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/bindSvn/lib/javahl.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </orderEntry>
</component>
</module>
diff --git a/plugins/svn4idea/testData18/svn/bin/windows/svn.exe b/plugins/svn4idea/testData18/svn/bin/windows/svn.exe
new file mode 100644
index 0000000..827753f4
--- /dev/null
+++ b/plugins/svn4idea/testData18/svn/bin/windows/svn.exe
Binary files differ
diff --git a/plugins/svn4idea/testData18/svn/newrepo.zip b/plugins/svn4idea/testData18/svn/newrepo.zip
new file mode 100644
index 0000000..fd9a577
--- /dev/null
+++ b/plugins/svn4idea/testData18/svn/newrepo.zip
Binary files differ
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java b/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java
index 14d1b4c..d5a5552 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java
@@ -78,13 +78,19 @@
* @author yole
*/
public abstract class SvnTestCase extends AbstractJunitVcsTestCase {
+
+ public static String ourGlobalTestDataDir;
+ public static Boolean ourGlobalUseNativeAcceleration;
+
protected TempDirTestFixture myTempDirFixture;
protected String myRepoUrl;
protected TestClientRunner myRunner;
protected String myWcRootName;
- protected boolean myUseNativeAcceleration = new GregorianCalendar().get(Calendar.HOUR_OF_DAY) % 2 == 0;
+ // TODO: Change this to explicitly run either with native acceleration or not.
+ // properties set through run configurations or different runners (like Suite) could be used
+ private boolean myUseNativeAcceleration = new GregorianCalendar().get(Calendar.HOUR_OF_DAY) % 2 == 0;
- protected final String myTestDataDir;
+ private String myTestDataDir;
private File myRepoRoot;
private File myWcRoot;
private ChangeListManagerGate myGate;
@@ -118,7 +124,13 @@
@Before
public void setUp() throws Exception {
- System.out.println("Native client for status: " + myUseNativeAcceleration);
+ System.out.println("Native client for status: " + isUseNativeAcceleration());
+
+ String property = System.getProperty("svn.test.data.directory");
+ if (!StringUtil.isEmpty(property)) {
+ myTestDataDir = property;
+ }
+
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
@@ -138,7 +150,7 @@
myPluginRoot = new File(rootPath).getParentFile().getParentFile().getParentFile();
}
- File svnBinDir = new File(myPluginRoot, myTestDataDir + "/svn/bin");
+ File svnBinDir = new File(myPluginRoot, getTestDataDir() + "/svn/bin");
File svnExecutable = null;
if (SystemInfo.isWindows) {
svnExecutable = new File(svnBinDir, "windows/svn.exe");
@@ -156,7 +168,7 @@
? createClientRunner(Collections.singletonMap("DYLD_LIBRARY_PATH", myClientBinaryPath.getPath()))
: createClientRunner();
- ZipUtil.extract(new File(myPluginRoot, myTestDataDir + "/svn/newrepo.zip"), myRepoRoot, null);
+ ZipUtil.extract(new File(myPluginRoot, getTestDataDir() + "/svn/newrepo.zip"), myRepoRoot, null);
myWcRoot = new File(myTempDirFixture.getTempDirPath(), myWcRootName);
assert myWcRoot.mkdir() || myWcRoot.isDirectory() : myWcRoot;
@@ -205,7 +217,7 @@
@Override
protected void projectCreated() {
- if (myUseNativeAcceleration) {
+ if (isUseNativeAcceleration()) {
SvnConfiguration.getInstance(myProject).myUseAcceleration = SvnConfiguration.UseAcceleration.commandLine;
SvnApplicationSettings.getInstance().setCommandLinePath(myClientBinaryPath + File.separator + "svn");
}
@@ -319,6 +331,22 @@
//clManager.ensureUpToDate(false);
}
+ public String getTestDataDir() {
+ return StringUtil.isEmpty(ourGlobalTestDataDir) ? myTestDataDir : ourGlobalTestDataDir;
+ }
+
+ public void setTestDataDir(String testDataDir) {
+ myTestDataDir = testDataDir;
+ }
+
+ public boolean isUseNativeAcceleration() {
+ return ourGlobalUseNativeAcceleration != null ? ourGlobalUseNativeAcceleration : myUseNativeAcceleration;
+ }
+
+ public void setUseNativeAcceleration(boolean useNativeAcceleration) {
+ myUseNativeAcceleration = useNativeAcceleration;
+ }
+
protected class SubTree {
public VirtualFile myRootDir;
public VirtualFile mySourceDir;
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java
index 270e6d4..bded7af 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java
@@ -54,6 +54,7 @@
@Before
public void setUp() throws Exception {
+ super.setUp();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnChangesCorrectlyRefreshedNativeTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnChangesCorrectlyRefreshedNativeTest.java
index a9c1074..6153d65 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnChangesCorrectlyRefreshedNativeTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnChangesCorrectlyRefreshedNativeTest.java
@@ -34,7 +34,7 @@
@Override
public void setUp() throws Exception {
- myUseNativeAcceleration = true;
+ setUseNativeAcceleration(true);
super.setUp();
clManager = ChangeListManager.getInstance(myProject);
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommitTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommitTest.java
index f4da04e..f18b6a5 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommitTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommitTest.java
@@ -465,7 +465,7 @@
return feedback;
}
- private void checkinFile(VirtualFile file, FileStatus status) {
+ protected void checkinFile(VirtualFile file, FileStatus status) {
final Change change = myChangeListManager.getChange(file);
Assert.assertNotNull(change);
Assert.assertEquals(status, change.getFileStatus());
@@ -478,6 +478,7 @@
}
protected void run2variants(final MyRunner runner) throws Exception {
+ // TODO: Change this to run different variants separately. See SvnTestCase.myUseAcceleration.
setNativeAcceleration(false);
runner.run();
runner.cleanup();
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnExternalTests.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnExternalTests.java
index 500acbd..3e3b2fd 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnExternalTests.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnExternalTests.java
@@ -27,6 +27,7 @@
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ui.UIUtil;
import junit.framework.Assert;
import org.junit.Test;
@@ -171,8 +172,7 @@
private void updatedCreatedExternalFromIDEAImpl() {
final File sourceDir = new File(myWorkingCopyDir.getPath(), "source");
- ProjectLevelVcsManager.getInstance(myProject).setDirectoryMappings(
- Arrays.asList(new VcsDirectoryMapping(FileUtil.toSystemIndependentName(sourceDir.getPath()), myVcs.getName())));
+ setNewDirectoryMappings(sourceDir);
imitUpdate(myProject);
final File externalFile = new File(sourceDir, "external/t11.txt");
@@ -180,6 +180,16 @@
Assert.assertNotNull(externalVf);
}
+ private void setNewDirectoryMappings(final File sourceDir) {
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ ProjectLevelVcsManager.getInstance(myProject).setDirectoryMappings(
+ Arrays.asList(new VcsDirectoryMapping(FileUtil.toSystemIndependentName(sourceDir.getPath()), myVcs.getName())));
+ }
+ });
+ }
+
@Test
public void testUncommittedExternalStatus() throws Exception {
prepareExternal(false, true, false);
@@ -221,8 +231,7 @@
private void uncommittedExternalCopyIsDetectedImpl() {
final File sourceDir = new File(myWorkingCopyDir.getPath(), "source");
- ProjectLevelVcsManager.getInstance(myProject).setDirectoryMappings(
- Arrays.asList(new VcsDirectoryMapping(FileUtil.toSystemIndependentName(sourceDir.getPath()), myVcs.getName())));
+ setNewDirectoryMappings(sourceDir);
imitUpdate(myProject);
refreshSvnMappingsSynchronously();
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnLockingTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnLockingTest.java
index 171bb1c..7c32af9 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnLockingTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnLockingTest.java
@@ -22,6 +22,7 @@
import junit.framework.Assert;
import junit.framework.TestCase;
import org.junit.Before;
+import org.junit.Ignore;
import org.tmatesoft.sqljet.core.SqlJetException;
import org.tmatesoft.sqljet.core.table.ISqlJetBusyHandler;
import org.tmatesoft.sqljet.core.table.ISqlJetTransaction;
@@ -42,6 +43,8 @@
* Date: 10/23/12
* Time: 2:27 PM
*/
+// TODO: Locking functionality which is tested by this test is not required anymore. Likely test needs to be removed.
+@Ignore
public class SvnLockingTest extends TestCase {
private File myWorkingCopyRoot;
private SvnTestWriteOperationLocks myLocks;
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnNativeClientAuthTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnNativeClientAuthTest.java
index 61aca567..b6d6ae1 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnNativeClientAuthTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnNativeClientAuthTest.java
@@ -72,7 +72,7 @@
@Before
public void setUp() throws Exception {
super.setUp();
- final File certFile = new File(myPluginRoot, myTestDataDir + "/svn/____.pfx");
+ final File certFile = new File(myPluginRoot, getTestDataDir() + "/svn/____.pfx");
setNativeAcceleration(true);
myVcs = SvnVcs.getInstance(myProject);
// replace authentication provider so that pass credentials without dialogs
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnChangesCorrectlyRefreshedNativeTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnChangesCorrectlyRefreshedNativeTest.java
index 2057336..8939f1c 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnChangesCorrectlyRefreshedNativeTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnChangesCorrectlyRefreshedNativeTest.java
@@ -49,7 +49,7 @@
@Override
public void setUp() throws Exception {
- myUseNativeAcceleration = true;
+ setUseNativeAcceleration(true);
super.setUp();
clManager = ChangeListManager.getInstance(myProject);
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn18/Svn18TestSuite.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn18/Svn18TestSuite.java
new file mode 100644
index 0000000..a701973
--- /dev/null
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn18/Svn18TestSuite.java
@@ -0,0 +1,33 @@
+package org.jetbrains.idea.svn18;
+
+import org.jetbrains.idea.SvnTestCase;
+import org.jetbrains.idea.svn.*;
+import org.junit.ClassRule;
+import org.junit.rules.ExternalResource;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+// TODO: Add svn clients for mac and linux
+@RunWith(Suite.class)
+@Suite.SuiteClasses({SvnAddTest.class, SvnDeleteTest.class})
+public class Svn18TestSuite {
+
+ @ClassRule
+ public static TestRule configuration = new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ SvnTestCase.ourGlobalTestDataDir = "testData18";
+ SvnTestCase.ourGlobalUseNativeAcceleration = true;
+ }
+
+ @Override
+ protected void after() {
+ SvnTestCase.ourGlobalTestDataDir = null;
+ SvnTestCase.ourGlobalUseNativeAcceleration = null;
+ }
+ };
+}
diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
index 13b8e7d..ffa9118 100644
--- a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
+++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
@@ -46,14 +46,12 @@
public static final int STATE_UPDATING = 0x0008;
/**
* Supporting this feature means that server implements some kind of issues filtering.
- * It may be special query language like the one used in Youtrack or mere plain
+ * It may be special query language like the one used in YouTrack or mere plain
* text search.
- * If server supports this feature it MUST return tasks already
- * filtered according to {@code query} parameter from {@code getIssues} method.
- * Otherwise they will be filtered using {@code TaskSearchSupport#filterTasks}
- *
- * @see com.intellij.tasks.impl.TaskManagerImpl
- * @see com.intellij.tasks.actions.TaskSearchSupport
+ * <p>
+ * If server supports this feature it MUST return tasks already filtered according
+ * to {@code query} parameter from {@link #getIssues}} method, otherwise they will
+ * be filtered internally in {@link TaskManager#getIssues}
*/
public static final int NATIVE_SEARCH = 0x0010;
@@ -106,7 +104,7 @@
/**
* Get issues from the repository. If query is null, return issues should assigned to current user only.
- * If server supports {@code NATIVE_SEARCH} feature, tasks returned MUST be filtered by specified query.
+ * If server supports {@link #NATIVE_SEARCH} feature, tasks returned MUST be filtered by specified query.
*
* @param query repository specific.
* @param max maximum issues number to return
diff --git a/plugins/tasks/tasks-core/src/META-INF/plugin.xml b/plugins/tasks/tasks-core/src/META-INF/plugin.xml
index 3573bb1..dd42d52 100644
--- a/plugins/tasks/tasks-core/src/META-INF/plugin.xml
+++ b/plugins/tasks/tasks-core/src/META-INF/plugin.xml
@@ -8,6 +8,8 @@
<!--fake dependency for Web IDE-->
<depends>com.intellij.modules.xml</depends>
<depends optional="true" config-file="java-contexts.xml">com.intellij.modules.java</depends>
+ <!-- Optional dependency on XPath plugin for syntax highlighting in GenericRepository configuration dialog -->
+ <depends optional="true">XPathView</depends>
<project-components>
<component>
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java
index cdc20c5..756abde 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java
@@ -14,7 +14,6 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.Ref;
-import com.intellij.psi.PsiManager;
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.Task;
import com.intellij.tasks.TaskManager;
@@ -22,7 +21,6 @@
import com.intellij.tasks.impl.TaskManagerImpl;
import com.intellij.tasks.impl.TaskUtil;
import com.intellij.util.ArrayUtil;
-import com.intellij.util.Function;
import com.intellij.util.IconUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
@@ -67,53 +65,25 @@
boolean everywhere,
@NotNull ProgressIndicator cancelled,
@NotNull Processor<Object> consumer) {
- List<Task> cachedAndLocalTasks = TaskSearchSupport.getLocalAndCachedTasks(TaskManager.getManager(project), pattern, everywhere);
- List<TaskPsiElement> taskPsiElements = ContainerUtil.map(cachedAndLocalTasks, new Function<Task, TaskPsiElement>() {
- @Override
- public TaskPsiElement fun(Task task) {
- return new TaskPsiElement(PsiManager.getInstance(project), task);
- }
- });
CREATE_NEW_TASK_ACTION.setTaskName(pattern);
- cancelled.checkCanceled();
if (!consumer.process(CREATE_NEW_TASK_ACTION)) return false;
- boolean cachedTasksFound = taskPsiElements.size() != 0;
- if (cachedTasksFound) {
- cancelled.checkCanceled();
- if (!consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false;
- }
-
- for (Object element : taskPsiElements) {
- cancelled.checkCanceled();
- if (!consumer.process(element)) return false;
- }
+ List<Task> cachedAndLocalTasks = TaskSearchSupport.getLocalAndCachedTasks(TaskManager.getManager(project), pattern, everywhere);
+ boolean cachedTasksFound = !cachedAndLocalTasks.isEmpty();
+ if (!processTasks(cachedAndLocalTasks, consumer, cachedTasksFound, cancelled)) return false;
List<Task> tasks = TaskSearchSupport
.getRepositoriesTasks(TaskManager.getManager(project), pattern, base.getMaximumListSizeLimit(), 0, true, everywhere, cancelled);
tasks.removeAll(cachedAndLocalTasks);
- taskPsiElements = ContainerUtil.map(tasks, new Function<Task, TaskPsiElement>() {
- @Override
- public TaskPsiElement fun(Task task) {
- return new TaskPsiElement(PsiManager.getInstance(project), task);
- }
- });
- if (!cachedTasksFound && taskPsiElements.size() != 0) {
- cancelled.checkCanceled();
- if (!consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false;
- }
-
- for (Object element : taskPsiElements) {
- cancelled.checkCanceled();
- if (!consumer.process(element)) return false;
- }
- return true;
+ return processTasks(tasks, consumer, cachedTasksFound, cancelled);
}
}, null, false, 0);
+
popup.setShowListForEmptyPattern(true);
popup.setSearchInAnyPlace(true);
+ popup.setFixLostTyping(false);
popup.setAdText("<html>Press SHIFT to merge with current context<br/>" +
"Pressing " +
KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_QUICK_JAVADOC)) +
@@ -166,6 +136,16 @@
}, null, popup);
}
+ private static boolean processTasks(List<Task> tasks, Processor<Object> consumer, boolean cachedTasksFound, ProgressIndicator cancelled) {
+ if (!cachedTasksFound && !tasks.isEmpty() && !consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false;
+
+ for (Object element : tasks) {
+ cancelled.checkCanceled();
+ if (!consumer.process(element)) return false;
+ }
+ return true;
+ }
+
private static void showOpenTaskDialog(final Project project, final Task task) {
JBPopup hint = DocumentationManager.getInstance(project).getDocInfoHint();
if (hint != null) hint.cancel();
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java
index 489afb9..3eeea41 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java
@@ -117,6 +117,11 @@
@Override
protected void doOKAction() {
+ createTask();
+ super.doOKAction();
+ }
+
+ public void createTask() {
TaskManagerImpl taskManager = (TaskManagerImpl)TaskManager.getManager(myProject);
taskManager.getState().markAsInProgress = isMarkAsInProgress();
@@ -133,18 +138,17 @@
LOG.warn(ex);
}
}
+ LocalTask activeTask = taskManager.getActiveTask();
LocalTask localTask = taskManager.activateTask(myTask, isClearContext());
if (myCreateChangelist.isSelected()) {
taskManager.createChangeList(localTask, myChangelistName.getText());
}
if (myCreateBranch.isSelected()) {
- LocalTask activeTask = taskManager.getActiveTask();
taskManager.createBranch(localTask, activeTask, myBranchName.getText());
}
if (myTask.getType() == TaskType.EXCEPTION && AnalyzeTaskStacktraceAction.hasTexts(myTask)) {
AnalyzeTaskStacktraceAction.analyzeStacktrace(myTask, myProject);
}
- super.doOKAction();
}
@Nullable
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskCellRenderer.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskCellRenderer.java
index 65a4d45..bb8f458 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskCellRenderer.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskCellRenderer.java
@@ -7,7 +7,6 @@
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.Task;
import com.intellij.tasks.TaskManager;
-import com.intellij.tasks.doc.TaskPsiElement;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
@@ -39,8 +38,8 @@
final JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(UIUtil.getListBackground(sel));
panel.setForeground(UIUtil.getListForeground(sel));
- if (value instanceof TaskPsiElement) {
- final Task task = ((TaskPsiElement)value).getTask();
+ if (value instanceof Task) {
+ final Task task = ((Task)value);
final SimpleColoredComponent c = new SimpleColoredComponent();
final TaskManager taskManager = TaskManager.getManager(myProject);
final boolean isLocalTask = taskManager.findTask(task.getId()) != null;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java
index c2c6306..98704b7 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java
@@ -77,12 +77,7 @@
String pattern,
boolean cached,
boolean autopopup) {
- final Matcher matcher = getMatcher(pattern);
- return ContainerUtil.mapNotNull(getTasks(pattern, cached, autopopup, myManager), new NullableFunction<Task, Task>() {
- public Task fun(Task task) {
- return matcher.matches(task.getId()) || matcher.matches(task.getSummary()) ? task : null;
- }
- });
+ return filterTasks(pattern, getTasks(pattern, cached, autopopup, myManager));
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java
index 5c4733b..f437897 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java
@@ -27,6 +27,7 @@
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.tasks.Task;
import com.intellij.util.NullableFunction;
@@ -170,7 +171,7 @@
//noinspection ResultOfMethodCallIgnored
tasksFolder.mkdir();
}
- String projectName = myProject.getName();
+ String projectName = FileUtil.sanitizeFileName(myProject.getName());
return new File(tasksFolder, projectName + postfix);
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java
index f3ed0f9..c4c5869 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java
@@ -16,6 +16,7 @@
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -31,19 +32,22 @@
public class GenericRepository extends BaseRepositoryImpl {
private static final Logger LOG = Logger.getInstance(GenericRepository.class);
- public final PredefinedFactoryVariable SERVER_URL_TEMPLATE_VARIABLE = new PredefinedFactoryVariable("serverUrl") {
+ public final FactoryVariable SERVER_URL_TEMPLATE_VARIABLE = new FactoryVariable("serverUrl") {
+ @NotNull
@Override
public String getValue() {
return GenericRepository.this.getUrl();
}
};
- public final PredefinedFactoryVariable USERNAME_TEMPLATE_VARIABLE = new PredefinedFactoryVariable("username") {
+ public final FactoryVariable USERNAME_TEMPLATE_VARIABLE = new FactoryVariable("username") {
+ @NotNull
@Override
public String getValue() {
return GenericRepository.this.getUsername();
}
};
- public final PredefinedFactoryVariable PASSWORD_TEMPLATE_VARIABLE = new PredefinedFactoryVariable("password", true) {
+ public final FactoryVariable PASSWORD_TEMPLATE_VARIABLE = new FactoryVariable("password", true) {
+ @NotNull
@Override
public String getValue() {
return GenericRepository.this.getPassword();
@@ -155,7 +159,7 @@
public boolean isConfigured() {
if (!super.isConfigured()) return false;
for (TemplateVariable variable : getTemplateVariables()) {
- if (variable.getIsShownOnFirstTab() && StringUtil.isEmpty(variable.getValue())) {
+ if (variable.isShownOnFirstTab() && StringUtil.isEmpty(variable.getValue())) {
return false;
}
}
@@ -171,8 +175,8 @@
executeMethod(getLoginMethod());
}
List<TemplateVariable> variables = concat(getAllTemplateVariables(),
- new TemplateVariable("max", max),
- new TemplateVariable("since", since));
+ new TemplateVariable("max", String.valueOf(max)),
+ new TemplateVariable("since", String.valueOf(since)));
String requestUrl = GenericRepositoryUtil.substituteTemplateVariables(getTasksListUrl(), variables);
String responseBody = executeMethod(getHttpMethod(requestUrl, myTasksListMethodType));
Task[] tasks = getActiveResponseHandler().parseIssues(responseBody, max);
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java
index 6ddb8da..c677744 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java
@@ -131,7 +131,7 @@
myRepository.setTemplateVariables(ContainerUtil.filter(dialog.getTemplateVariables(), new Condition<TemplateVariable>() {
@Override
public boolean value(TemplateVariable variable) {
- return !variable.getIsPredefined();
+ return !variable.isReadOnly();
}
}));
myCustomPanel.removeAll();
@@ -186,8 +186,8 @@
myField2Variable = new IdentityHashMap<JTextField, TemplateVariable>();
FormBuilder builder = FormBuilder.createFormBuilder();
for (final TemplateVariable variable : myRepository.getTemplateVariables()) {
- if (variable.getIsShownOnFirstTab()) {
- JTextField field = variable.getIsHidden() ? new JPasswordField(variable.getValue()) : new JTextField(variable.getValue());
+ if (variable.isShownOnFirstTab()) {
+ JTextField field = variable.isHidden() ? new JPasswordField(variable.getValue()) : new JTextField(variable.getValue());
myField2Variable.put(field, variable);
installListener(field);
JBLabel label = new JBLabel(prettifyVariableName(variable.getName()) + ":", SwingConstants.RIGHT);
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java
index 1a9bb42..95f865b 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java
@@ -59,7 +59,8 @@
public List<TaskRepositorySubtype> getAvailableSubtypes() {
return Arrays.asList(
this,
- new AsanaRepository()
+ new AsanaRepository(),
+ new AssemblaRepository()
);
}
@@ -111,4 +112,10 @@
super("Asana", TasksIcons.Asana);
}
}
+
+ public class AssemblaRepository extends GenericSubtype {
+ public AssemblaRepository() {
+ super("Assembla", TasksIcons.Assembla);
+ }
+ }
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java
index cc80ed2..c97a77f 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java
@@ -1,7 +1,5 @@
package com.intellij.tasks.generic;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
@@ -17,7 +15,7 @@
import java.util.Map;
/**
- * Author: Mikhail Golubev
+ * @author Mikhail Golubev
*/
@Tag("JsonResponseHandler")
public final class JsonPathResponseHandler extends SelectorBasedResponseHandler {
@@ -44,11 +42,6 @@
super(repository);
}
- @Override
- public FileType getSelectorFileType() {
- return PlainTextFileType.INSTANCE;
- }
-
@Nullable
private Object extractRawValue(@NotNull Selector selector, @NotNull String source) throws Exception {
if (StringUtil.isEmpty(selector.getPath())) {
@@ -140,6 +133,7 @@
return myCompiledCache.get(path);
}
+ @NotNull
@Override
public ResponseType getResponseType() {
return ResponseType.JSON;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java
index e9e6d5e..3c3ed23 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java
@@ -60,7 +60,7 @@
@Override
public boolean isCellEditable(TemplateVariable templateVariable) {
- return !templateVariable.getIsPredefined();
+ return !templateVariable.isReadOnly();
}
@Override
@@ -82,7 +82,7 @@
@Override
public boolean isCellEditable(TemplateVariable templateVariable) {
- return !templateVariable.getIsPredefined();
+ return !templateVariable.isReadOnly();
}
@Override
@@ -93,7 +93,7 @@
@Override
public TableCellRenderer getRenderer(TemplateVariable variable) {
- if (variable.getIsHidden()) {
+ if (variable.isHidden()) {
return new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
@@ -112,7 +112,7 @@
@Nullable
@Override
public TableCellEditor getEditor(final TemplateVariable variable) {
- if (variable.getIsHidden()) {
+ if (variable.isHidden()) {
return new AbstractTableCellEditor() {
private JPasswordField myPasswordField;
@Override
@@ -141,12 +141,12 @@
@Nullable
@Override
public Boolean valueOf(TemplateVariable o) {
- return o.getIsShownOnFirstTab();
+ return o.isShownOnFirstTab();
}
@Override
public void setValue(TemplateVariable variable, Boolean value) {
- variable.setIsShownOnFirstTab(value);
+ variable.setShownOnFirstTab(value);
setModified();
}
@@ -157,7 +157,7 @@
@Override
public boolean isCellEditable(TemplateVariable variable) {
- return !variable.getIsPredefined();
+ return !variable.isReadOnly();
}
@Nullable
@@ -171,12 +171,12 @@
@Nullable
@Override
public Boolean valueOf(TemplateVariable o) {
- return o.getIsHidden();
+ return o.isHidden();
}
@Override
public void setValue(TemplateVariable variable, Boolean value) {
- variable.setIsHidden(value);
+ variable.setHidden(value);
setModified();
// value column editor may be changed
TemplateVariablesTable.this.refreshValues();
@@ -189,7 +189,7 @@
@Override
public boolean isCellEditable(TemplateVariable variable) {
- return !variable.getIsPredefined();
+ return !variable.isReadOnly();
}
@Nullable
@@ -203,7 +203,7 @@
@Override
protected TemplateVariable createElement() {
- return new TemplateVariable("", "", false, null);
+ return new TemplateVariable("", "");
}
@Override
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java
index c080851..4d7f5a5 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java
@@ -68,8 +68,9 @@
return myTaskRegex.hashCode();
}
+ @NotNull
@Override
- public JComponent getConfigurationComponent(Project project) {
+ public JComponent getConfigurationComponent(@NotNull Project project) {
FormBuilder builder = FormBuilder.createFormBuilder();
final EditorTextField taskPatternText;
taskPatternText = new LanguageTextField(RegExpLanguage.INSTANCE, project, myTaskRegex, false);
@@ -86,7 +87,7 @@
@NotNull
@Override
- public Task[] parseIssues(String response, int max) throws Exception {
+ public Task[] parseIssues(@NotNull String response, int max) throws Exception {
final List<String> placeholders = getPlaceholders(myTaskRegex);
if (!placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) {
throw new Exception("Incorrect Task Pattern");
@@ -120,7 +121,7 @@
@Nullable
@Override
- public Task parseIssue(String response) throws Exception {
+ public Task parseIssue(@NotNull String response) throws Exception {
return null;
}
@@ -150,6 +151,7 @@
return !StringUtil.isEmpty(myTaskRegex);
}
+ @NotNull
@Override
public ResponseType getResponseType() {
return ResponseType.TEXT;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java
index d51c38a..cb8830b 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java
@@ -10,7 +10,7 @@
/**
* ResponseHandler subclasses represent different strategies of extracting tasks from
- * task server responses (e.g. using regular expressions, XPath, JSONPath, CSS selector etc.).
+ * task server responses (e.g. using regular expressions, XPath, JSONPath, CSS selector etc.)
*
* @see XPathResponseHandler
* @see JsonPathResponseHandler
@@ -19,36 +19,40 @@
*/
public abstract class ResponseHandler implements Cloneable {
- // XXX: what about serialization of circular dependencies?
protected GenericRepository myRepository;
- // Serialization constructor
+ /**
+ * Serialization constructor
+ */
public ResponseHandler() {
// empty
}
- public ResponseHandler(GenericRepository repository) {
+ public ResponseHandler(@NotNull GenericRepository repository) {
myRepository = repository;
}
- public void setRepository(GenericRepository repository) {
+ public void setRepository(@NotNull GenericRepository repository) {
myRepository = repository;
}
+ @NotNull
@Transient
public GenericRepository getRepository() {
return myRepository;
}
- public abstract JComponent getConfigurationComponent(Project project);
+ @NotNull
+ public abstract JComponent getConfigurationComponent(@NotNull Project project);
+ @NotNull
public abstract ResponseType getResponseType();
@NotNull
- public abstract Task[] parseIssues(String response, int max) throws Exception;
+ public abstract Task[] parseIssues(@NotNull String response, int max) throws Exception;
@Nullable
- public abstract Task parseIssue(String response) throws Exception;
+ public abstract Task parseIssue(@NotNull String response) throws Exception;
public abstract boolean isConfigured();
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java
index aa4bd78..8889e26 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java
@@ -2,40 +2,82 @@
import com.intellij.ide.highlighter.HtmlFileType;
import com.intellij.ide.highlighter.XmlFileType;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import org.intellij.lang.regexp.RegExpFileType;
-import org.intellij.lang.xpath.XPathFileType;
+import org.jetbrains.annotations.NotNull;
+
/**
- * User: evgeny.zakrevsky
- * Date: 10/25/12
+ * ResponseType contains information about what selector types used
+ * to extract information from server responses with specific content-type.
+ *
+ * @author evgeny.zakrevsky
+ * @author Mikhail Golubev
*/
public enum ResponseType {
- XML("application/xml", XmlFileType.INSTANCE, XPathFileType.XPATH2),
- JSON("application/json", PlainTextFileType.INSTANCE, PlainTextFileType.INSTANCE),
+
+ XML("application/xml", XmlFileType.INSTANCE, findXPathFileType()),
+ JSON("application/json", findFileTypePlainDefault("JSON"), PlainTextFileType.INSTANCE),
// TODO: think about possible selector type if it needed at all (e.g. CSS selector)
HTML("text/html", HtmlFileType.INSTANCE, PlainTextFileType.INSTANCE),
TEXT("text/plain", PlainTextFileType.INSTANCE, RegExpFileType.INSTANCE);
- private String myMimeType;
- private FileType myContentFileType;
- private FileType mySelectorFileType;
+ private final String myMimeType;
+ private final FileType myContentFileType;
+ private final FileType mySelectorFileType;
- ResponseType(final String s, final FileType contentFileType, final FileType selectorFileType) {
+ private static Logger LOG = Logger.getInstance(ResponseType.class);
+
+
+ ResponseType(@NotNull String s, @NotNull FileType contentFileType, @NotNull FileType selectorFileType) {
myMimeType = s;
myContentFileType = contentFileType;
mySelectorFileType = selectorFileType;
}
+ /**
+ * Unfortunately XPATH instance can't be received this way, because XPathSupportLoader
+ * registers XPathFileType in FileTypeManager only in unit test and debug modes
+ */
+ @NotNull
+ private static FileType findFileTypePlainDefault(@NotNull final String name) {
+ FileType fileType = FileTypeManager.getInstance().findFileTypeByName(name);
+ return fileType == null ? PlainTextFileType.INSTANCE : fileType;
+ }
+
+ /**
+ * Temporary workaround for IDEA-112605
+ */
+ @NotNull
+ private static FileType findXPathFileType() {
+ if (LOG == null) {
+ LOG = Logger.getInstance(ResponseType.class);
+ }
+ try {
+ Class<?> xPathClass = Class.forName("org.intellij.lang.xpath.XPathFileType");
+ LOG.debug("XPathFileType class loaded successfully");
+ return (FileType)xPathClass.getField("XPATH").get(null);
+ }
+ catch (Exception e) {
+ LOG.debug("XPathFileType class not found. Using PlainText.INSTANCE instead");
+ return PlainTextFileType.INSTANCE;
+ }
+ }
+
+ @NotNull
public String getMimeType() {
return myMimeType;
}
+ @NotNull
public FileType getContentFileType() {
return myContentFileType;
}
+ @NotNull
public FileType getSelectorFileType() {
return mySelectorFileType;
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java
index 865e43d..0394cc5 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java
@@ -1,5 +1,6 @@
package com.intellij.tasks.generic;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -24,6 +25,7 @@
* @author Mikhail Golubev
*/
public abstract class SelectorBasedResponseHandler extends ResponseHandler {
+ private static final Logger LOG = Logger.getInstance(SelectorBasedResponseHandler.class);
// Supported selector names
@NonNls protected static final String TASKS = "tasks";
@@ -81,8 +83,6 @@
));
}
- public abstract FileType getSelectorFileType();
-
@Tag("selectors")
@Property(surroundWithTag = false)
@AbstractCollection(surroundWithTag = false)
@@ -112,11 +112,11 @@
return s.getPath();
}
+ @NotNull
@Override
- public JComponent getConfigurationComponent(Project project) {
- HighlightedSelectorsTable table = new HighlightedSelectorsTable(getSelectorFileType(),
- project,
- getSelectors());
+ public JComponent getConfigurationComponent(@NotNull Project project) {
+ FileType fileType = getResponseType().getSelectorFileType();
+ HighlightedSelectorsTable table = new HighlightedSelectorsTable(fileType, project, getSelectors());
return new JBScrollPane(table);
}
@@ -158,13 +158,14 @@
@NotNull
@Override
- public final Task[] parseIssues(String response, int max) throws Exception {
+ public final Task[] parseIssues(@NotNull String response, int max) throws Exception {
if (StringUtil.isEmpty(getSelectorPath(TASKS)) ||
StringUtil.isEmpty(getSelectorPath(ID)) ||
StringUtil.isEmpty(getSelectorPath(SUMMARY))) {
throw new Exception("Selectors 'tasks', 'id' and 'summary' are mandatory");
}
List<Object> tasks = selectTasksList(response, max);
+ LOG.debug(String.format("Total %d tasks extracted from response", tasks.size()));
List<Task> result = new ArrayList<Task>(tasks.size());
for (Object context : tasks) {
String id = selectString(getSelector(ID), context);
@@ -232,7 +233,7 @@
@Nullable
@Override
- public final Task parseIssue(String response) throws Exception {
+ public final Task parseIssue(@NotNull String response) throws Exception {
if (StringUtil.isEmpty(getSelectorPath(SINGLE_TASK_ID)) ||
StringUtil.isEmpty(getSelectorPath(SINGLE_TASK_SUMMARY))) {
throw new Exception("Selectors 'singleTask-id' and 'singleTask-summary' are mandatory");
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java
index d8377bb..f3b59fe 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java
@@ -3,51 +3,42 @@
import com.intellij.util.xmlb.annotations.Attribute;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
- * User: evgeny.zakrevsky
- * Date: 10/26/12
+ * Editable variable which name can be used as placeholder and auto completed in EditorFields of
+ * {@link GenericRepositoryEditor}. Variables is editable via {@link ManageTemplateVariablesDialog},
+ * but if {@code shownOnFirstTab} property was set, it will also be shown on "General" tab among
+ * standard fields like "Server URL", "Username" and "Password".
+ *
+ * @see GenericRepositoryEditor
+ * @see ManageTemplateVariablesDialog
+ *
+ * @author evgeny.zakrevsky
+ * @author Mikhail Golubev
*/
public class TemplateVariable {
private String myName;
private String myValue = "";
- private String myDescription;
- private boolean myIsPredefined;
- private boolean myIsHidden;
- private boolean myIsShownOnFirstTab;
+ private String myDescription = "";
+ private boolean myReadOnly;
+ private boolean myHidden;
+ private boolean myShownOnFirstTab;
- public static TemplateVariableBuilder builder(String name) {
- return new TemplateVariableBuilder(name);
- }
-
- private TemplateVariable(TemplateVariableBuilder builder) {
- myName = builder.myName;
- myValue = builder.myValue;
- myDescription = builder.myDescription;
- myIsHidden = builder.myIsHidden;
- myIsShownOnFirstTab = builder.myIsShowOnFirstTab;
- myIsPredefined = builder.myIsPredefined;
- }
-
- public TemplateVariable(String name, Object value) {
- this(name, value, false, "");
- }
-
- public TemplateVariable(@NotNull @NonNls String name, @NotNull @NonNls Object value, boolean isPredefined, @Nullable String description) {
+ public TemplateVariable(@NotNull @NonNls String name, @NotNull @NonNls String value) {
myName = name;
myValue = String.valueOf(value);
- myIsPredefined = isPredefined;
- myDescription = description;
+ myReadOnly = false;
+ myDescription = "";
}
/**
* Serialization constructor
*/
+ @SuppressWarnings("unusedDesclaration")
public TemplateVariable() {
+ // empty
}
-
/**
* Cloning constructor
*/
@@ -55,157 +46,119 @@
myName = other.getName();
myValue = other.getValue();
myDescription = other.getDescription();
- myIsHidden = other.getIsHidden();
- myIsPredefined = other.getIsPredefined();
- myIsShownOnFirstTab = other.getIsShownOnFirstTab();
+ myHidden = other.isHidden();
+ myReadOnly = other.isReadOnly();
+ myShownOnFirstTab = other.isShownOnFirstTab();
}
- public void setName(String name) {
+ public void setName(@NotNull @NonNls String name) {
myName = name;
}
- public void setValue(String value) {
+ public void setValue(@NotNull @NonNls String value) {
myValue = value;
}
+ @NotNull
public String getName() {
return myName;
}
+ @NotNull
public String getValue() {
return myValue;
}
- @Nullable
+ // TODO: actually not used in UI
+ @NotNull
public String getDescription() {
return myDescription;
}
- @Attribute("isPredefined")
- public boolean getIsPredefined() {
- return myIsPredefined;
+ public void setDescription(@NotNull @NonNls String description) {
+ myDescription = description;
}
- public void setIsPredefined(boolean isPredefined) {
- myIsPredefined = isPredefined;
+ @Attribute("readOnly")
+ public boolean isReadOnly() {
+ return myReadOnly;
}
- @Attribute("isHidden")
- public boolean getIsHidden() {
- return myIsHidden;
+ public void setReadOnly(boolean readOnly) {
+ myReadOnly = readOnly;
}
- public void setIsHidden(boolean isHidden) {
- myIsHidden = isHidden;
+ @Attribute("hidden")
+ public boolean isHidden() {
+ return myHidden;
+ }
+
+ public void setHidden(boolean hidden) {
+ myHidden = hidden;
}
@Attribute("shownOnFirstTab")
- public boolean getIsShownOnFirstTab() {
- return myIsShownOnFirstTab;
+ public boolean isShownOnFirstTab() {
+ return myShownOnFirstTab;
}
- public void setIsShownOnFirstTab(boolean isShownOnFirstTab) {
- myIsShownOnFirstTab = isShownOnFirstTab;
+ public void setShownOnFirstTab(boolean shownOnFirstTab) {
+ myShownOnFirstTab = shownOnFirstTab;
}
public TemplateVariable clone() {
return new TemplateVariable(this);
}
- public void setDescription(final String description) {
- myDescription = description;
- }
-
@Override
public String toString() {
return String.format("TemplateVariable(name='%s', value='%s')", getName(), getValue());
}
- public static class TemplateVariableBuilder {
- private String myName;
- private String myValue = "";
- private String myDescription;
- private boolean myIsHidden;
- private boolean myIsPredefined;
- private boolean myIsShowOnFirstTab;
-
- private TemplateVariableBuilder(String name) {
- myName = name;
- }
-
- public TemplateVariableBuilder value(Object value) {
- myValue = String.valueOf(value);
- return this;
- }
-
- public TemplateVariableBuilder description(String description) {
- myDescription = description;
- return this;
- }
-
- public TemplateVariableBuilder isHidden(boolean isHidden) {
- myIsHidden = isHidden;
- return this;
- }
-
- public TemplateVariableBuilder isPredefined(boolean isPredefined) {
- myIsPredefined = isPredefined;
- return this;
- }
-
- public TemplateVariableBuilder isShownOnFirstTab(boolean isShowOnFirstTab) {
- myIsShowOnFirstTab = isShowOnFirstTab;
- return this;
- }
-
- public TemplateVariable build() {
- return new TemplateVariable(this);
- }
- }
-
/**
* Represents predefined template variable such as "serverUrl", "login" or "password" which are not
* set explicitly by user but instead taken from repository itself.
+ *
+ * @see GenericRepository
*/
- public abstract static class PredefinedFactoryVariable extends TemplateVariable {
+ public abstract static class FactoryVariable extends TemplateVariable {
- protected PredefinedFactoryVariable(String name) {
+ protected FactoryVariable(@NotNull @NonNls String name) {
this(name, false);
}
- public PredefinedFactoryVariable(String name, boolean isHidden) {
- this(name, name, isHidden);
+ public FactoryVariable(@NotNull @NonNls String name, boolean hidden) {
+ super(name, "");
+ setHidden(hidden);
}
- public PredefinedFactoryVariable(String name, String description, boolean isHidden) {
- super(builder(name).description(description).isHidden(isHidden));
- }
+ @NotNull
@Override
public abstract String getValue();
@Override
- public final void setName(String name) {
+ public final void setName(@NotNull String name) {
throw new UnsupportedOperationException("Name of predefined variable can't be changed");
}
@Override
- public final void setValue(String value) {
+ public final void setValue(@NotNull String value) {
throw new UnsupportedOperationException("Value of predefined variable can't be changed explicitly");
}
@Override
- public final void setIsShownOnFirstTab(boolean isShownOnFirstTab) {
+ public final void setShownOnFirstTab(boolean shownOnFirstTab) {
throw new UnsupportedOperationException("This parameter can't be changed for predefined variable");
}
@Override
- public void setIsPredefined(boolean isPredefined) {
+ public void setReadOnly(boolean readOnly) {
throw new UnsupportedOperationException("This parameter can't be changed for predefined variable");
}
@Override
- public boolean getIsPredefined() {
+ public boolean isReadOnly() {
return true;
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java
index f768258..8d82ac1 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java
@@ -1,10 +1,8 @@
package com.intellij.tasks.generic;
-import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.xmlb.annotations.Tag;
-import org.intellij.lang.xpath.XPathFileType;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
@@ -79,11 +77,7 @@
return myCompiledCache.get(path);
}
- @Override
- public FileType getSelectorFileType() {
- return XPathFileType.XPATH;
- }
-
+ @NotNull
@Override
public ResponseType getResponseType() {
return ResponseType.XML;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml
index 942ca6f..94d69c1 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml
@@ -55,8 +55,8 @@
<option name="tasksListUrl" value="{serverUrl}/projects/{project_ID}/tasks?assignee=me"/>
<option name="templateVariables">
<list>
- <TemplateVariable isHidden="false" isPredefined="false" shownOnFirstTab="true">
- <option name="description"/>
+ <TemplateVariable hidden="false" readOnly="false" shownOnFirstTab="true">
+ <option name="description" value=""/>
<option name="name" value="project_ID"/>
<option name="value" value=""/>
</TemplateVariable>
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/assembla.xml b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/assembla.xml
new file mode 100644
index 0000000..da466a6
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/assembla.xml
@@ -0,0 +1,64 @@
+<Assembla shared="false" url="http://www.assembla.com">
+ <commitMessageFormat>{id} {summary}</commitMessageFormat>
+ <option name="downloadTasksInSeparateRequests" value="false" />
+ <password/>
+ <option name="loginAnonymously" value="false" />
+ <option name="loginMethodType" value="GET" />
+ <option name="loginUrl" value="" />
+ <option name="responseHandlers">
+ <XPathResponseHandler>
+ <selectors>
+ <selector name="tasks" path="/tickets/ticket" />
+ <selector name="id" path="id" />
+ <selector name="summary" path="summary" />
+ <selector name="description" path="description" />
+ <selector name="updated" path="updated-at" />
+ <selector name="created" path="created-on" />
+ <selector name="closed" path="" />
+ <selector name="issueUrl" path="" />
+ <selector name="singleTask-id" path="" />
+ <selector name="singleTask-summary" path="" />
+ <selector name="singleTask-description" path="" />
+ <selector name="singleTask-updated" path="" />
+ <selector name="singleTask-created" path="" />
+ <selector name="singleTask-closed" path="" />
+ <selector name="singleTask-issueUrl" path="" />
+ </selectors>
+ </XPathResponseHandler>
+ <JsonResponseHandler>
+ <selectors>
+ <selector name="tasks" path="" />
+ <selector name="id" path="" />
+ <selector name="summary" path="" />
+ <selector name="description" path="" />
+ <selector name="updated" path="" />
+ <selector name="created" path="" />
+ <selector name="closed" path="" />
+ <selector name="issueUrl" path="" />
+ <selector name="singleTask-id" path="" />
+ <selector name="singleTask-summary" path="" />
+ <selector name="singleTask-description" path="" />
+ <selector name="singleTask-updated" path="" />
+ <selector name="singleTask-created" path="" />
+ <selector name="singleTask-closed" path="" />
+ <selector name="singleTask-issueUrl" path="" />
+ </selectors>
+ </JsonResponseHandler>
+ <RegExResponseHandler>
+ <option name="taskRegex" value=""/>
+ </RegExResponseHandler>
+ </option>
+ <option name="responseType" value="XML" />
+ <option name="shouldFormatCommitMessage" value="false" />
+ <option name="singleTaskMethodType" value="GET" />
+ <option name="singleTaskUrl" value="" />
+ <option name="subtypeName" />
+ <option name="tasksListMethodType" value="GET" />
+ <option name="tasksListUrl" value="http://www.assembla.com/tickets.xml" />
+ <option name="templateVariables">
+ <list />
+ </option>
+ <option name="useHttpAuthentication" value="true" />
+ <option name="useProxy" value="false" />
+ <username/>
+</Assembla>
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementType.java
index fde826e..9d9dc91 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementType.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementType.java
@@ -15,22 +15,49 @@
*/
package com.intellij.tasks.jira.jql;
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import java.lang.reflect.Constructor;
+
/**
* @author Mikhail Golubev
*/
public class JqlElementType extends IElementType {
- private String myName;
+ private static final Class<?>[] PARAMETER_TYPES = {ASTNode.class};
+
+ private final Class<? extends PsiElement> myClass;
+ private Constructor<? extends PsiElement> myConstructor;
+
public JqlElementType(@NotNull @NonNls String debugName) {
+ this(debugName, ASTWrapperPsiElement.class);
+ }
+
+ public JqlElementType(@NotNull @NonNls String debugName, @NotNull Class<? extends PsiElement> cls) {
super(debugName, JqlLanguage.INSTANCE);
- myName = debugName;
+ myClass = cls;
}
@Override
public String toString() {
return "JQL: " + super.toString();
}
+
+ @NotNull
+ public PsiElement createElement(@NotNull ASTNode node) {
+ try {
+ if (myConstructor == null) {
+ myConstructor = myClass.getConstructor(PARAMETER_TYPES);
+ }
+ return myConstructor.newInstance(node);
+ }
+ catch (Exception e) {
+ throw new AssertionError(
+ String.format("Class %s must have constructor accepting single ASTNode parameter", myClass.getName()));
+ }
+ }
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementTypes.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementTypes.java
index 68a9893..9919eb6 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementTypes.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementTypes.java
@@ -3,6 +3,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;
+import com.intellij.tasks.jira.jql.psi.impl.*;
/**
* @author Mikhail Golubev
@@ -14,8 +15,9 @@
* or_clause ::= and_clause {or_op and_clause}
* and_clause ::= not_expr {and_op not_expr}
* not_expr ::= not_op not_expr
- * | "(" or_clause ")"
+ * | subclause
* | terminal_clause
+ * subclause ::= "(" or_clause ")"
* terminal_clause ::= simple_clause
* | was_clause
* | changed_clause
@@ -46,11 +48,12 @@
* field ::= string
* | NUMBER
* | CUSTOM_FIELD
- * operand ::= ("empty" | "null")
+ * operand ::= empty
* | string
* | NUMBER
* | func
* | list
+ * empty ::= "empty" | "null"
* list ::= "(" operand {"," operand} ")"
* func ::= fname "(" arg_list ")"
* # function name can be even number (!)
@@ -58,7 +61,7 @@
* arg_list ::= argument {"," argument}
* argument ::= string | NUMBER
* string ::= SQUOTED_STRING
- * | QUOTED_STRIN
+ * | QUOTED_STRING
* | UNQOUTED_STRING
* order_by ::= "order" "by" sort_key {sort_key}
* sort_key ::= field ("asc" | "desc")
@@ -66,26 +69,28 @@
*/
public interface JqlElementTypes {
IFileElementType FILE = new IFileElementType(JqlLanguage.INSTANCE);
- IElementType QUERY = new JqlElementType("QUERY");
- IElementType OR_CLAUSE = new JqlElementType("OR_CLAUSE");
- IElementType AND_CLAUSE = new JqlElementType("AND_CLAUSE");
- IElementType NOT_CLAUSE = new JqlElementType("NOT_CLAUSE");
+ IElementType QUERY = new JqlElementType("QUERY", JqlQueryImpl.class);
+ IElementType OR_CLAUSE = new JqlElementType("OR_CLAUSE", JqlOrClauseImpl.class);
+ IElementType AND_CLAUSE = new JqlElementType("AND_CLAUSE", JqlAndClauseImpl.class);
+ IElementType NOT_CLAUSE = new JqlElementType("NOT_CLAUSE", JqlNotClauseImpl.class);
+ // actually parenthesized clause, named so to be consistent with official grammar
+ IElementType SUB_CLAUSE = new JqlElementType("SUB_CLAUSE", JqlSubClauseImpl.class);
//IElementType TERMINAL_CLAUSE = new JqlElementType("TERMINAL_CLAUSE");
// field (= | != | ~ | !~ | < | > | <= | >= | is [not] | [not] in) value
- IElementType SIMPLE_CLAUSE = new JqlElementType("SIMPLE_CLAUSE");
+ IElementType SIMPLE_CLAUSE = new JqlElementType("SIMPLE_CLAUSE", JqlSimpleClauseImpl.class);
// field was [not] [in] value {history_predicate}
- IElementType WAS_CLAUSE = new JqlElementType("WAS_CLAUSE");
+ IElementType WAS_CLAUSE = new JqlElementType("WAS_CLAUSE", JqlWasClauseImpl.class);
// field changed {history_predicate}
- IElementType CHANGED_CLAUSE = new JqlElementType("CHANGED_CLAUSE");
- IElementType LIST = new JqlElementType("LIST");
- IElementType ORDER_BY = new JqlElementType("ORDER_BY");
- IElementType IDENTIFIER = new JqlElementType("IDENTIFIER");
- IElementType LITERAL = new JqlElementType("LITERAL");
- IElementType FUNCTION_CALL = new JqlElementType("FUNCTION_CALL");
- IElementType ARGUMENT_LIST = new JqlElementType("ARGUMENT_LIST");
- IElementType SORT_KEY = new JqlElementType("SORT_KEY");
- IElementType EMPTY = new JqlElementType("EMPTY");
- IElementType HISTORY_PREDICATE = new JqlElementType("HISTORY_PREDICATE");
+ IElementType CHANGED_CLAUSE = new JqlElementType("CHANGED_CLAUSE", JqlChangedClauseImpl.class);
+ IElementType LIST = new JqlElementType("LIST", JqlListImpl.class);
+ IElementType ORDER_BY = new JqlElementType("ORDER_BY", JqlOrderByImpl.class);
+ IElementType IDENTIFIER = new JqlElementType("IDENTIFIER", JqlIdentifierImpl.class);
+ IElementType LITERAL = new JqlElementType("LITERAL", JqlLiteralImpl.class);
+ IElementType FUNCTION_CALL = new JqlElementType("FUNCTION_CALL", JqlFunctionCallImpl.class);
+ IElementType ARGUMENT_LIST = new JqlElementType("ARGUMENT_LIST", JqlArgumentListImpl.class);
+ IElementType SORT_KEY = new JqlElementType("SORT_KEY", JqlSortKeyImpl.class);
+ IElementType EMPTY = new JqlElementType("EMPTY", JqlEmptyValueImpl.class);
+ IElementType HISTORY_PREDICATE = new JqlElementType("HISTORY_PREDICATE", JqlHistoryPredicateImpl.class);
TokenSet OPERAND_NODES = TokenSet.create(
JqlTokenTypes.NUMBER_LITERAL, JqlTokenTypes.STRING_LITERAL, LIST, FUNCTION_CALL
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParser.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParser.java
index 1dcac36..2021bc9 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParser.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParser.java
@@ -12,7 +12,7 @@
* @author Mikhail Golubev
*/
public class JqlParser implements PsiParser {
- private static final Logger LOG = Logger.getInstance("#com.intellij.tasks.jira.jql.JqlParser");
+ private static final Logger LOG = Logger.getInstance(JqlParser.class);
@NotNull
@Override
@@ -92,16 +92,17 @@
}
private boolean parseSubClause(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.LPAR);
+ PsiBuilder.Marker marker = builder.mark();
if (!advanceIfMatches(builder, JqlTokenTypes.LPAR)) {
+ marker.drop();
return false;
}
- if (!parseORClause(builder)) {
- return false;
- }
+ parseORClause(builder);
if (!advanceIfMatches(builder, JqlTokenTypes.RPAR)) {
builder.error("Expecting ')'");
- return false;
}
+ marker.done(JqlElementTypes.SUB_CLAUSE);
return true;
}
@@ -142,6 +143,7 @@
}
private void parseCHANGEDClause(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.CHANGED_KEYWORD);
if (!advanceIfMatches(builder, JqlTokenTypes.CHANGED_KEYWORD)) {
return;
}
@@ -151,6 +153,7 @@
}
private void parseWASClause(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.WAS_KEYWORD);
if (!advanceIfMatches(builder, JqlTokenTypes.WAS_KEYWORD)) {
return;
}
@@ -163,6 +166,7 @@
}
private void parseHistoryPredicate(PsiBuilder builder) {
+ LOG.assertTrue(JqlTokenTypes.HISTORY_PREDICATES.contains(builder.getTokenType()));
PsiBuilder.Marker marker = builder.mark();
if (!advanceIfMatches(builder, JqlTokenTypes.HISTORY_PREDICATES)) {
marker.drop();
@@ -204,6 +208,7 @@
}
private boolean parseList(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.LPAR);
PsiBuilder.Marker marker = builder.mark();
if (!advanceIfMatches(builder, JqlTokenTypes.LPAR)) {
marker.drop();
@@ -235,6 +240,7 @@
}
private void parseArgumentList(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.LPAR);
PsiBuilder.Marker marker = builder.mark();
if (!advanceIfMatches(builder, JqlTokenTypes.LPAR)) {
marker.drop();
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParserDefinition.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParserDefinition.java
index 7e3eb55..a826962 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParserDefinition.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParserDefinition.java
@@ -13,7 +13,6 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;
-import com.intellij.tasks.jira.jql.psi.impl.*;
import org.jetbrains.annotations.NotNull;
/**
@@ -59,54 +58,9 @@
@NotNull
@Override
public PsiElement createElement(ASTNode node) {
- IElementType type = node.getElementType();
- if (type == JqlElementTypes.QUERY) {
- return new JqlQueryImpl(node);
- }
- if (type == JqlElementTypes.AND_CLAUSE) {
- return new JqlAndClauseImpl(node);
- }
- if (type == JqlElementTypes.OR_CLAUSE) {
- return new JqlOrClauseImpl(node);
- }
- if (type == JqlElementTypes.NOT_CLAUSE) {
- return new JqlNotClauseImpl(node);
- }
- if (type == JqlElementTypes.SIMPLE_CLAUSE) {
- return new JqlSimpleClauseImpl(node);
- }
- if (type == JqlElementTypes.WAS_CLAUSE) {
- return new JqlWasClauseImpl(node);
- }
- if (type == JqlElementTypes.CHANGED_CLAUSE) {
- return new JqlChangedClauseImpl(node);
- }
- if (type == JqlElementTypes.FUNCTION_CALL) {
- return new JqlFunctionCallImpl(node);
- }
- if (type == JqlElementTypes.IDENTIFIER) {
- return new JqlIdentifierImpl(node);
- }
- if (type == JqlElementTypes.HISTORY_PREDICATE) {
- return new JqlHistoryPredicateImpl(node);
- }
- if (type == JqlElementTypes.ARGUMENT_LIST) {
- return new JqlArgumentListImpl(node);
- }
- if (type == JqlElementTypes.LITERAL) {
- return new JqlLiteralImpl(node);
- }
- if (type == JqlElementTypes.EMPTY) {
- return new JqlEmptyValueImpl(node);
- }
- if (type == JqlElementTypes.LIST) {
- return new JqlListImpl(node);
- }
- if (type == JqlElementTypes.SORT_KEY) {
- return new JqlSortKeyImpl(node);
- }
- if (type == JqlElementTypes.ORDER_BY) {
- return new JqlOrderByImpl(node);
+ final IElementType type = node.getElementType();
+ if (type instanceof JqlElementType) {
+ return ((JqlElementType)type).createElement(node);
}
return new ASTWrapperPsiElement(node);
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlTokenTypes.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlTokenTypes.java
index 1d0c6f1..ddb8bdf 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlTokenTypes.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlTokenTypes.java
@@ -104,12 +104,6 @@
TokenSet HISTORY_PREDICATES = TokenSet.create(
ON_KEYWORD, BEFORE_KEYWORD, AFTER_KEYWORD, DURING_KEYWORD, FROM_KEYWORD, TO_KEYWORD, BY_KEYWORD
);
- TokenSet WAS_CONSTRAINTS = TokenSet.create(
- ON_KEYWORD, BEFORE_KEYWORD, AFTER_KEYWORD, DURING_KEYWORD, BY_KEYWORD
- );
- TokenSet CHANGED_CONSTRAINTS = TokenSet.create(
- ON_KEYWORD, BEFORE_KEYWORD, AFTER_KEYWORD, DURING_KEYWORD, FROM_KEYWORD, TO_KEYWORD, BY_KEYWORD
- );
TokenSet SORT_ORDERS = TokenSet.create(ASC_KEYWORD, DESC_KEYWORD);
TokenSet EMPTY_VALUES = TokenSet.create(EMPTY_KEYWORD, NULL_KEYWORD);
TokenSet LITERALS = TokenSet.create(NUMBER_LITERAL, STRING_LITERAL);
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
index 484a357bc..e243402 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
@@ -55,15 +55,15 @@
if (!(element instanceof PsiElement)) return false;
PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf((PsiElement)element);
if (prevLeaf == null) return false;
- PsiElement enclosingClause = PsiTreeUtil.findFirstParent(prevLeaf, new Condition<PsiElement>() {
+ PsiElement parent = PsiTreeUtil.findFirstParent(prevLeaf, new Condition<PsiElement>() {
@Override
public boolean value(PsiElement element) {
return pattern.accepts(element);
}
});
- if (enclosingClause == null) return false;
- if (PsiTreeUtil.hasErrorElements(enclosingClause)) return false;
- return prevLeaf.getTextRange().getEndOffset() == enclosingClause.getTextRange().getEndOffset();
+ if (parent == null) return false;
+ if (PsiTreeUtil.hasErrorElements(parent)) return false;
+ return prevLeaf.getTextRange().getEndOffset() == parent.getTextRange().getEndOffset();
}
@Override
@@ -83,7 +83,10 @@
psiElement().and(rightAfterElement(JqlClauseWithHistoryPredicates.class));
private static final PsiElementPattern.Capture<PsiElement> AFTER_ANY_CLAUSE =
- psiElement().and(rightAfterElement(JqlTerminalClause.class));
+ psiElement().andOr(
+ rightAfterElement(JqlTerminalClause.class),
+ // in other words after closing parenthesis
+ rightAfterElement(JqlSubClause.class));
private static final PsiElementPattern.Capture<PsiElement> AFTER_ORDER_KEYWORD =
psiElement().afterLeaf(psiElement(JqlTokenTypes.ORDER_KEYWORD));
@@ -263,7 +266,6 @@
JqlFieldType operandType;
boolean listFunctionExpected;
PsiElement curElem = parameters.getPosition();
- PsiElement origElem = parameters.getOriginalPosition();
JqlHistoryPredicate predicate = PsiTreeUtil.getParentOfType(curElem, JqlHistoryPredicate.class);
if (predicate != null) {
listFunctionExpected = false;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlElementVisitor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlElementVisitor.java
index e0dc689..bbf71de 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlElementVisitor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlElementVisitor.java
@@ -3,6 +3,7 @@
import com.intellij.psi.PsiElementVisitor;
import com.intellij.tasks.jira.jql.psi.impl.JqlArgumentListImpl;
import com.intellij.tasks.jira.jql.psi.impl.JqlHistoryPredicateImpl;
+import com.intellij.tasks.jira.jql.psi.impl.JqlSubClauseImpl;
/**
* @author Mikhail Golubev
@@ -40,4 +41,6 @@
public abstract void visitJqlArgumentList(JqlArgumentListImpl list);
public abstract void visitJqlHistoryPredicate(JqlHistoryPredicateImpl predicate);
+
+ public abstract void visitJqlSubClause(JqlSubClauseImpl subClause);
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlQuery.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlQuery.java
index b832b9d..79bb3bf 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlQuery.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlQuery.java
@@ -9,7 +9,7 @@
public interface JqlQuery extends JqlElement {
@Nullable
JqlClause getClause();
- boolean isOrdered();
- @NotNull
- JqlSortKey[] getOrderKeys();
+
+ @Nullable
+ JqlOrderBy getOrderBy();
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlSubClause.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlSubClause.java
new file mode 100644
index 0000000..c28de28
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlSubClause.java
@@ -0,0 +1,11 @@
+package com.intellij.tasks.jira.jql.psi;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Mikhail Golubev
+ */
+public interface JqlSubClause extends JqlClause {
+ @Nullable
+ JqlClause getInnerClause();
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java
index d16a106..f440161 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java
@@ -10,7 +10,7 @@
/**
* @author Mikhail Golubev
*/
-public interface JqlTerminalClause extends JqlElement {
+public interface JqlTerminalClause extends JqlClause {
enum Type {
EQ(false),
NE(false),
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlQueryImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlQueryImpl.java
index c9ed11a..0565800 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlQueryImpl.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlQueryImpl.java
@@ -1,11 +1,9 @@
package com.intellij.tasks.jira.jql.psi.impl;
import com.intellij.lang.ASTNode;
-import com.intellij.tasks.jira.jql.psi.JqlClause;
-import com.intellij.tasks.jira.jql.psi.JqlElementVisitor;
-import com.intellij.tasks.jira.jql.psi.JqlSortKey;
-import com.intellij.tasks.jira.jql.psi.JqlQuery;
+import com.intellij.tasks.jira.jql.psi.*;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author Mikhail Golubev
@@ -25,13 +23,9 @@
return findChildByClass(JqlClause.class);
}
+ @Nullable
@Override
- public boolean isOrdered() {
- return getOrderKeys().length != 0;
- }
-
- @Override
- public JqlSortKey[] getOrderKeys() {
- return findChildrenByClass(JqlSortKey.class);
+ public JqlOrderBy getOrderBy() {
+ return findChildByClass(JqlOrderBy.class);
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlSubClauseImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlSubClauseImpl.java
new file mode 100644
index 0000000..05f959a
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlSubClauseImpl.java
@@ -0,0 +1,28 @@
+package com.intellij.tasks.jira.jql.psi.impl;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.tasks.jira.jql.psi.JqlClause;
+import com.intellij.tasks.jira.jql.psi.JqlElementVisitor;
+import com.intellij.tasks.jira.jql.psi.JqlSubClause;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JqlSubClauseImpl extends JqlElementImpl implements JqlSubClause {
+ public JqlSubClauseImpl(@NotNull ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void accept(JqlElementVisitor visitor) {
+ visitor.visitJqlSubClause(this);
+ }
+
+ @Nullable
+ @Override
+ public JqlClause getInnerClause() {
+ return findChildByClass(JqlClause.class);
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
index f1571fb..697e71b 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
@@ -185,10 +185,10 @@
// Ad-hoc fix for IDEA-110012
Date parsed;
try {
- parsed = (new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US)).parse(date);
+ parsed = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US).parse(date);
}
catch (ParseException e) {
- LOG.warn("Unparseable date: " + date, e);
+ LOG.warn("Unparseable date: '" + date + "'. Trying ISO-8601 format instead.");
parsed = TaskUtil.parseDate(date);
}
return parsed;
diff --git a/plugins/tasks/tasks-core/tasks-core.iml b/plugins/tasks/tasks-core/tasks-core.iml
index 11c3bc9..460f43f 100644
--- a/plugins/tasks/tasks-core/tasks-core.iml
+++ b/plugins/tasks/tasks-core/tasks-core.iml
@@ -39,7 +39,6 @@
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="module" module-name="xml" />
<orderEntry type="module" module-name="core-api" />
- <orderEntry type="module" module-name="xpath" />
<orderEntry type="module" module-name="RegExpSupport" />
<orderEntry type="module-library">
<library>
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskUtilTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskUtilTest.java
new file mode 100644
index 0000000..def2a678f2
--- /dev/null
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskUtilTest.java
@@ -0,0 +1,51 @@
+package com.intellij.tasks;
+
+import com.intellij.tasks.impl.TaskUtil;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class TaskUtilTest {
+ private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ static {
+ FORMATTER.setTimeZone(TimeZone.getTimeZone("GMT"));
+ }
+
+ private static void compareDates(@NotNull Date expected, @NotNull String formattedDate) {
+ Date parsed = TaskUtil.parseDate(formattedDate);
+ assertEquals(expected, parsed);
+ }
+
+ /**
+ * Test ISO8601 date parsing
+ */
+ @Test
+ public void testDateParsings() throws Exception {
+ final Date expected = FORMATTER.parse("2013-08-23 10:11:12.000");
+ final Date expectedWithMillis = FORMATTER.parse("2013-08-23 10:11:12.100");
+ // JIRA, Redmine and Pivotal
+ compareDates(expectedWithMillis, "2013-08-23T14:11:12.100+0400");
+ // Trello
+ compareDates(expectedWithMillis, "2013-08-23T10:11:12.100Z");
+ // Assmbla
+ compareDates(expectedWithMillis, "2013-08-23T14:11:12.100+04:00");
+
+ // Formatting variations
+ compareDates(expected, "2013/08/23 10:11:12");
+ compareDates(expectedWithMillis, "2013-08-23 14:11:12.100123+04");
+
+ // Malformed date
+ assertNull(TaskUtil.parseDate("Fri Aug 23 14:11:12 MSK 2013"));
+ assertNull(TaskUtil.parseDate("2013/00/23"));
+ assertNull(TaskUtil.parseDate("2013/08/23 10:11:12 GMT+04:00"));
+ }
+}
\ No newline at end of file
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java
index 98a3dd0..029b9a7 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java
@@ -17,6 +17,7 @@
package com.intellij.tasks.context;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.tasks.TaskManagerTestCase;
import com.intellij.xdebugger.XDebuggerManager;
@@ -93,6 +94,18 @@
manager.clearContext();
}
+ public void testContextFileName() throws Exception {
+ ProjectImpl project = (ProjectImpl)getProject();
+ String name = project.getName();
+ try {
+ project.setProjectName("invalid | name");
+ getContextManager().saveContext("foo", "bar");
+ }
+ finally {
+ project.setProjectName(name);
+ }
+ }
+
private WorkingContextManager getContextManager() {
return WorkingContextManager.getInstance(getProject());
}
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java
index d3ee5b1..6269e48 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java
@@ -104,10 +104,14 @@
checkCompletionVariants(JqlStandardFunction.allOfType(JqlFieldType.DATE, false));
}
- public void testAfterParenthesisInSubClause() throws Exception {
+ public void testAfterLeftParenthesisInSubClause() throws Exception {
checkCompletionVariants(ALL_FIELD_NAMES, "not");
}
+ public void testAfterSubClause() throws Exception {
+ checkCompletionVariants("and", "or", "order by");
+ }
+
public void testFunctionArguments() throws Exception {
// only literals accepted so we can't assume anything
checkCompletionVariants(ContainerUtil.<String>emptyList());
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java
index 1261d12..36cc584 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java
@@ -15,10 +15,17 @@
*/
package com.intellij.tasks.vcs;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsTaskHandler;
+import com.intellij.openapi.vcs.changes.*;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.tasks.BranchInfo;
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.TaskManager;
+import com.intellij.tasks.actions.OpenTaskDialog;
import com.intellij.tasks.impl.LocalTaskImpl;
import com.intellij.tasks.impl.TaskManagerImpl;
import com.intellij.testFramework.PlatformTestCase;
@@ -29,8 +36,10 @@
import git4idea.repo.GitRepository;
import git4idea.test.GitExecutor;
import git4idea.test.GitTestUtil;
+import git4idea.util.GitFileUtils;
import java.io.File;
+import java.util.Collections;
import java.util.List;
/**
@@ -41,6 +50,8 @@
public class TaskBranchesTest extends PlatformTestCase {
private TaskManagerImpl myTaskManager;
+ private ChangeListManagerImpl myChangeListManager;
+ private VcsDirtyScopeManagerImpl myDirtyScopeManager;
public void testGitTaskHandler() throws Exception {
@@ -104,6 +115,46 @@
myTaskManager.activateTask(foo, false);
}
+ public void testCommit() throws Exception {
+ GitRepository repository = initRepository("foo");
+ LocalTask defaultTask = myTaskManager.getActiveTask();
+ LocalTaskImpl foo = myTaskManager.createLocalTask("foo");
+ final LocalTask localTask = myTaskManager.activateTask(foo, false);
+ myTaskManager.createBranch(localTask, defaultTask, myTaskManager.suggestBranchName(localTask));
+
+ VirtualFile root = repository.getRoot();
+ File file = new File(root.getPath(), "foo.txt");
+ assertTrue(file.createNewFile());
+ final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+ GitFileUtils.addFiles(getProject(), root, virtualFile);
+ myDirtyScopeManager.fileDirty(virtualFile);
+ myChangeListManager.ensureUpToDate(false);
+ Change change = myChangeListManager.getChange(virtualFile);
+ assertNotNull(change);
+ ProjectLevelVcsManager.getInstance(getProject()).getAllActiveVcss()[0].getCheckinEnvironment()
+ .commit(Collections.singletonList(change), "foo");
+ myTaskManager.mergeBranch(localTask);
+
+ repository.update();
+ assertEquals("master", repository.getCurrentBranch().getName());
+ assertEquals(1, repository.getBranches().getLocalBranches().size());
+ }
+
+ public void testOpenTaskDialog() throws Exception {
+ initRepository("foo");
+ LocalTaskImpl task = myTaskManager.createLocalTask("foo");
+ OpenTaskDialog dialog = new OpenTaskDialog(getProject(), task);
+ Disposer.register(myTestRootDisposable, dialog.getDisposable());
+ dialog.createTask();
+ assertEquals("foo", myTaskManager.getActiveTask().getSummary());
+ List<BranchInfo> branches = task.getBranches(true);
+ assertEquals(1, branches.size());
+ assertEquals("master", branches.get(0).name);
+ branches = task.getBranches(false);
+ assertEquals(1, branches.size());
+ assertEquals("foo", branches.get(0).name);
+ }
+
private List<GitRepository> initRepositories(String... names) {
return ContainerUtil.map(names, new Function<String, GitRepository>() {
@Override
@@ -128,5 +179,10 @@
super.setUp();
myTaskManager = (TaskManagerImpl)TaskManager.getManager(getProject());
GitVcsSettings.getInstance(myProject).getAppSettings().setPathToGit(GitExecutor.GIT_EXECUTABLE);
+
+ myChangeListManager = (ChangeListManagerImpl)ChangeListManager.getInstance(getProject());
+ myChangeListManager.projectOpened();
+ myDirtyScopeManager = ((VcsDirtyScopeManagerImpl)VcsDirtyScopeManager.getInstance(getProject()));
+ myDirtyScopeManager.projectOpened();
}
}
diff --git a/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterParenthesisInSubClause.jql b/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterLeftParenthesisInSubClause.jql
similarity index 100%
rename from plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterParenthesisInSubClause.jql
rename to plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterLeftParenthesisInSubClause.jql
diff --git a/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterSubClause.jql b/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterSubClause.jql
new file mode 100644
index 0000000..d2ce0ae
--- /dev/null
+++ b/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterSubClause.jql
@@ -0,0 +1 @@
+(reporter was in (bob, mark)) <caret>
\ No newline at end of file
diff --git a/plugins/tasks/tasks-tests/testData/jira/jql/psi/Subclauses.txt b/plugins/tasks/tasks-tests/testData/jira/jql/psi/Subclauses.txt
index d004bc4..3ec6387 100644
--- a/plugins/tasks/tasks-tests/testData/jira/jql/psi/Subclauses.txt
+++ b/plugins/tasks/tasks-tests/testData/jira/jql/psi/Subclauses.txt
@@ -1,46 +1,50 @@
FILE(0,50)
JqlQuery((a = foo or (b > 12 and ((c < 40)))) and d ~ 'foo')(0,50)
JqlAndClause((a = foo or (b > 12 and ((c < 40)))) and d ~ 'foo')(0,50)
- PsiElement(JQL: LPAR)('(')(0,1)
- JqlOrClause(a = foo or (b > 12 and ((c < 40))))(1,35)
- JqlSimpleClause(a = foo)(1,8)
- JqlIdentifier(a)(1,2)
- PsiElement(JQL: STRING_LITERAL)('a')(1,2)
- PsiWhiteSpace(' ')(2,3)
- PsiElement(JQL: EQ)('=')(3,4)
- PsiWhiteSpace(' ')(4,5)
- JqlLiteral(foo)(5,8)
- PsiElement(JQL: STRING_LITERAL)('foo')(5,8)
- PsiWhiteSpace(' ')(8,9)
- PsiElement(JQL: OR_KEYWORD)('or')(9,11)
- PsiWhiteSpace(' ')(11,12)
- PsiElement(JQL: LPAR)('(')(12,13)
- JqlAndClause(b > 12 and ((c < 40)))(13,34)
- JqlSimpleClause(b > 12)(13,19)
- JqlIdentifier(b)(13,14)
- PsiElement(JQL: STRING_LITERAL)('b')(13,14)
- PsiWhiteSpace(' ')(14,15)
- PsiElement(JQL: GT)('>')(15,16)
- PsiWhiteSpace(' ')(16,17)
- JqlLiteral(12)(17,19)
- PsiElement(JQL: NUMBER_LITERAL)('12')(17,19)
- PsiWhiteSpace(' ')(19,20)
- PsiElement(JQL: AND_KEYWORD)('and')(20,23)
- PsiWhiteSpace(' ')(23,24)
- PsiElement(JQL: LPAR)('(')(24,25)
- PsiElement(JQL: LPAR)('(')(25,26)
- JqlSimpleClause(c < 40)(26,32)
- JqlIdentifier(c)(26,27)
- PsiElement(JQL: STRING_LITERAL)('c')(26,27)
- PsiWhiteSpace(' ')(27,28)
- PsiElement(JQL: LT)('<')(28,29)
- PsiWhiteSpace(' ')(29,30)
- JqlLiteral(40)(30,32)
- PsiElement(JQL: NUMBER_LITERAL)('40')(30,32)
- PsiElement(JQL: RPAR)(')')(32,33)
- PsiElement(JQL: RPAR)(')')(33,34)
- PsiElement(JQL: RPAR)(')')(34,35)
- PsiElement(JQL: RPAR)(')')(35,36)
+ JqlSubClause((a = foo or (b > 12 and ((c < 40)))))(0,36)
+ PsiElement(JQL: LPAR)('(')(0,1)
+ JqlOrClause(a = foo or (b > 12 and ((c < 40))))(1,35)
+ JqlSimpleClause(a = foo)(1,8)
+ JqlIdentifier(a)(1,2)
+ PsiElement(JQL: STRING_LITERAL)('a')(1,2)
+ PsiWhiteSpace(' ')(2,3)
+ PsiElement(JQL: EQ)('=')(3,4)
+ PsiWhiteSpace(' ')(4,5)
+ JqlLiteral(foo)(5,8)
+ PsiElement(JQL: STRING_LITERAL)('foo')(5,8)
+ PsiWhiteSpace(' ')(8,9)
+ PsiElement(JQL: OR_KEYWORD)('or')(9,11)
+ PsiWhiteSpace(' ')(11,12)
+ JqlSubClause((b > 12 and ((c < 40))))(12,35)
+ PsiElement(JQL: LPAR)('(')(12,13)
+ JqlAndClause(b > 12 and ((c < 40)))(13,34)
+ JqlSimpleClause(b > 12)(13,19)
+ JqlIdentifier(b)(13,14)
+ PsiElement(JQL: STRING_LITERAL)('b')(13,14)
+ PsiWhiteSpace(' ')(14,15)
+ PsiElement(JQL: GT)('>')(15,16)
+ PsiWhiteSpace(' ')(16,17)
+ JqlLiteral(12)(17,19)
+ PsiElement(JQL: NUMBER_LITERAL)('12')(17,19)
+ PsiWhiteSpace(' ')(19,20)
+ PsiElement(JQL: AND_KEYWORD)('and')(20,23)
+ PsiWhiteSpace(' ')(23,24)
+ JqlSubClause(((c < 40)))(24,34)
+ PsiElement(JQL: LPAR)('(')(24,25)
+ JqlSubClause((c < 40))(25,33)
+ PsiElement(JQL: LPAR)('(')(25,26)
+ JqlSimpleClause(c < 40)(26,32)
+ JqlIdentifier(c)(26,27)
+ PsiElement(JQL: STRING_LITERAL)('c')(26,27)
+ PsiWhiteSpace(' ')(27,28)
+ PsiElement(JQL: LT)('<')(28,29)
+ PsiWhiteSpace(' ')(29,30)
+ JqlLiteral(40)(30,32)
+ PsiElement(JQL: NUMBER_LITERAL)('40')(30,32)
+ PsiElement(JQL: RPAR)(')')(32,33)
+ PsiElement(JQL: RPAR)(')')(33,34)
+ PsiElement(JQL: RPAR)(')')(34,35)
+ PsiElement(JQL: RPAR)(')')(35,36)
PsiWhiteSpace(' ')(36,37)
PsiElement(JQL: AND_KEYWORD)('and')(37,40)
PsiWhiteSpace(' ')(40,41)
diff --git a/plugins/terminal/lib/jediterm-pty-0.08.jar b/plugins/terminal/lib/jediterm-pty-0.08.jar
index 0e3c223..f4bd386 100644
--- a/plugins/terminal/lib/jediterm-pty-0.08.jar
+++ b/plugins/terminal/lib/jediterm-pty-0.08.jar
Binary files differ
diff --git a/plugins/terminal/lib/pty4j-0.3.jar b/plugins/terminal/lib/pty4j-0.3.jar
index 67200e1..3c7f3db 100644
--- a/plugins/terminal/lib/pty4j-0.3.jar
+++ b/plugins/terminal/lib/pty4j-0.3.jar
Binary files differ
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
index c1ceb92..fcf0627 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
@@ -1,5 +1,6 @@
package org.jetbrains.plugins.terminal;
+import com.google.common.base.Predicate;
import com.intellij.execution.ExecutionManager;
import com.intellij.execution.Executor;
import com.intellij.execution.executors.DefaultRunExecutor;
@@ -8,30 +9,22 @@
import com.intellij.execution.ui.actions.CloseAction;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.ui.UIUtil;
-import com.jediterm.pty.PtyProcessTtyConnector;
import com.jediterm.terminal.TtyConnector;
-import com.jediterm.terminal.emulator.ColorPalette;
-import com.jediterm.terminal.ui.AbstractSystemSettingsProvider;
import com.jediterm.terminal.ui.TerminalSession;
import com.jediterm.terminal.ui.TerminalWidget;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.ExecutionException;
/**
@@ -90,9 +83,14 @@
protected abstract ProcessHandler createProcessHandler(T process);
public JBTabbedTerminalWidget createTerminalWidget() {
- JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
- JBTabbedTerminalWidget terminalWidget = new JBTabbedTerminalWidget(provider);
- provider.setTerminalWidget(terminalWidget);
+ final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
+ JBTabbedTerminalWidget terminalWidget = new JBTabbedTerminalWidget(provider, new Predicate<TerminalWidget>() {
+ @Override
+ public boolean apply(TerminalWidget widget) {
+ openSession(widget);
+ return true;
+ }
+ });
openSession(terminalWidget);
return terminalWidget;
}
@@ -102,9 +100,14 @@
final DefaultActionGroup toolbarActions = new DefaultActionGroup();
final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false);
- JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
- TerminalWidget widget = new JBTabbedTerminalWidget(provider);
- provider.setTerminalWidget(widget);
+ final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
+ TerminalWidget widget = new JBTabbedTerminalWidget(provider, new Predicate<TerminalWidget>() {
+ @Override
+ public boolean apply(TerminalWidget widget) {
+ openSession(widget);
+ return true;
+ }
+ });
openSession(widget, createTtyConnector(process));
@@ -160,57 +163,6 @@
return myProject;
}
- private class JBTerminalSystemSettingsProvider extends AbstractSystemSettingsProvider {
- private TerminalWidget myTerminalWidget;
-
- public void setTerminalWidget(TerminalWidget terminalWidget) {
- myTerminalWidget = terminalWidget;
- }
-
- @Override
- public AbstractAction getNewSessionAction() {
- return new AbstractAction("New Session") {
- @Override
- public void actionPerformed(ActionEvent event) {
- openSession(myTerminalWidget);
- }
- };
- }
-
- @Override
- public KeyStroke[] getCopyKeyStrokes() {
- return getKeyStrokesByActionId("$Copy");
- }
-
- @Override
- public KeyStroke[] getPasteKeyStrokes() {
- return getKeyStrokesByActionId("$Paste");
- }
-
- @Override
- public ColorPalette getPalette() {
- return SystemInfo.isWindows ? ColorPalette.WINDOWS_PALETTE : ColorPalette.XTERM_PALETTE;
- }
-
- private KeyStroke[] getKeyStrokesByActionId(String actionId) {
- List<KeyStroke> keyStrokes = new ArrayList<KeyStroke>();
- Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId);
- for (Shortcut sc : shortcuts) {
- if (sc instanceof KeyboardShortcut) {
- KeyStroke ks = ((KeyboardShortcut)sc).getFirstKeyStroke();
- keyStrokes.add(ks);
- }
- }
-
- return keyStrokes.toArray(new KeyStroke[keyStrokes.size()]);
- }
-
- @Override
- public boolean shouldCloseTabOnLogout(TtyConnector ttyConnector) {
- return ttyConnector instanceof PtyProcessTtyConnector; //close tab only on logout of local pty, not remote
- }
- }
-
public void openSession(TerminalWidget terminalWidget) {
// Create Server process
try {
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
index 051a5a5..50a7e41 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
@@ -1,12 +1,14 @@
package org.jetbrains.plugins.terminal;
+import com.google.common.base.Predicate;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAwareAction;
import com.jediterm.terminal.ui.JediTermWidget;
-import com.jediterm.terminal.ui.SystemSettingsProvider;
import com.jediterm.terminal.ui.TabbedTerminalWidget;
import com.jediterm.terminal.ui.TerminalAction;
+import com.jediterm.terminal.ui.TerminalWidget;
+import com.jediterm.terminal.ui.settings.SettingsProvider;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -17,8 +19,9 @@
* @author traff
*/
public class JBTabbedTerminalWidget extends TabbedTerminalWidget {
- public JBTabbedTerminalWidget(@NotNull SystemSettingsProvider settingsProvider) {
- super(settingsProvider);
+
+ public JBTabbedTerminalWidget(@NotNull SettingsProvider settingsProvider, @NotNull Predicate<TerminalWidget> createNewSessionAction) {
+ super(settingsProvider, createNewSessionAction);
convertActions(this, getActions());
}
@@ -28,12 +31,7 @@
AnAction a = new DumbAwareAction() {
@Override
public void actionPerformed(AnActionEvent e) {
- if (e.getInputEvent() instanceof KeyEvent) {
- action.perform((KeyEvent)e.getInputEvent());
- }
- else {
- action.perform(null);
- }
+ action.perform(e.getInputEvent() instanceof KeyEvent? (KeyEvent)e.getInputEvent() : null);
}
};
a.registerCustomShortcutSet(action.getKeyCode(), action.getModifiers(), component);
@@ -41,7 +39,7 @@
}
@Override
- protected JediTermWidget createInnerTerminalWidget() {
- return new JBTerminalWidget(getSystemSettingsProvider());
+ protected JediTermWidget createInnerTerminalWidget(SettingsProvider settingsProvider) {
+ return new JBTerminalWidget(settingsProvider);
}
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
index e5b6e53..788a4f9 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
@@ -22,17 +22,14 @@
package org.jetbrains.plugins.terminal;
-import com.intellij.openapi.editor.colors.EditorColors;
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.ide.CopyPasteManager;
+import com.intellij.util.JBHiDPIScaledImage;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
-import com.jediterm.terminal.TerminalColor;
-import com.jediterm.terminal.TextStyle;
import com.jediterm.terminal.display.BackBuffer;
import com.jediterm.terminal.display.StyleState;
-import com.jediterm.terminal.ui.SystemSettingsProvider;
import com.jediterm.terminal.ui.TerminalPanel;
+import com.jediterm.terminal.ui.settings.SettingsProvider;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
@@ -41,69 +38,57 @@
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
import java.io.IOException;
-import java.util.List;
public class JBTerminalPanel extends TerminalPanel {
- private final EditorColorsScheme myColorScheme;
-
- public JBTerminalPanel(@NotNull SystemSettingsProvider settingsProvider,
+ public JBTerminalPanel(@NotNull SettingsProvider settingsProvider,
@NotNull BackBuffer backBuffer,
- @NotNull StyleState styleState,
- @NotNull EditorColorsScheme scheme) {
+ @NotNull StyleState styleState) {
super(settingsProvider, backBuffer, styleState);
- myColorScheme = scheme;
-
- styleState.setDefaultStyle(new TextStyle(TerminalColor.awt(myColorScheme.getDefaultForeground()), TerminalColor.awt(
- myColorScheme.getDefaultBackground())));
-
- setSelectionColor(new TextStyle(TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_FOREGROUND_COLOR)),
- TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR))));
-
- setLineSpace(myColorScheme.getConsoleLineSpacing());
-
JBTabbedTerminalWidget.convertActions(this, getActions());
}
- protected Font createFont() {
-
- Font normalFont = Font.decode(getFontName());
-
- if (normalFont == null) {
- normalFont = super.createFont();
- }
-
- normalFont = normalFont.deriveFont((float)myColorScheme.getConsoleFontSize());
-
- return normalFont;
- }
-
protected void setupAntialiasing(Graphics graphics, boolean antialiasing) {
GraphicsUtil.setupAntialiasing(graphics, antialiasing, false);
}
@Override
- public Color getBackground() {
- if (myColorScheme != null) {
- return myColorScheme.getDefaultBackground();
- }
- return super.getBackground();
- }
-
- @Override
- public Color getForeground() {
- if (myColorScheme != null) {
- return myColorScheme.getDefaultForeground();
- }
- return super.getBackground();
- }
-
- @Override
protected void setCopyContents(StringSelection selection) {
CopyPasteManager.getInstance().setContents(selection);
}
+ @Override
+ protected void drawImage(Graphics2D gfx, BufferedImage image, int x, int y, ImageObserver observer) {
+ UIUtil.drawImage(gfx, image, x, y, observer);
+ }
+
+ @Override
+ protected void drawImage(Graphics2D g, BufferedImage image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) {
+ drawImage(g, image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
+ }
+
+ public static void drawImage(Graphics g, Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) {
+ if (image instanceof JBHiDPIScaledImage) {
+ final Graphics2D newG = (Graphics2D)g.create(0, 0, image.getWidth(observer), image.getHeight(observer));
+ newG.scale(0.5, 0.5);
+ Image img = ((JBHiDPIScaledImage)image).getDelegate();
+ if (img == null) {
+ img = image;
+ }
+ newG.drawImage(img, 2*dx1, 2*dy1, 2*dx2, 2*dy2, sx1, sy1, sx2, sy2, observer);
+ newG.scale(1, 1);
+ newG.dispose();
+ } else {
+ g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
+ }
+ }
+
+ @Override
+ protected boolean isRetina() {
+ return UIUtil.isRetina();
+ }
@Override
protected String getClipboardContent() throws IOException, UnsupportedFlavorException {
@@ -118,28 +103,5 @@
protected BufferedImage createBufferedImage(int width, int height) {
return UIUtil.createImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
-
- @Override
- protected void drawImage(Graphics2D g, BufferedImage image) {
- UIUtil.drawImage(g, image, null, 0, 0);
- }
-
- public String getFontName() {
- List<String> fonts = myColorScheme.getConsoleFontPreferences().getEffectiveFontFamilies();
-
- for (String font : fonts) {
- if (isApplicable(font)) {
- return font;
- }
- }
- return super.getFontName();
- }
-
- private static boolean isApplicable(String font) {
- if ("Source Code Pro".equals(font)) {
- return false;
- }
- return true;
- }
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
new file mode 100644
index 0000000..3b983e2
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
@@ -0,0 +1,367 @@
+package org.jetbrains.plugins.terminal;
+
+import com.intellij.application.options.OptionsConstants;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.actionSystem.Shortcut;
+import com.intellij.openapi.editor.colors.*;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.keymap.KeymapManager;
+import com.intellij.openapi.options.FontSize;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.util.containers.HashMap;
+import com.jediterm.pty.PtyProcessTtyConnector;
+import com.jediterm.terminal.TerminalColor;
+import com.jediterm.terminal.TextStyle;
+import com.jediterm.terminal.TtyConnector;
+import com.jediterm.terminal.emulator.ColorPalette;
+import com.jediterm.terminal.ui.settings.DefaultSettingsProvider;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author traff
+ */
+class JBTerminalSystemSettingsProvider extends DefaultSettingsProvider {
+
+ private final EditorColorsScheme myColorScheme;
+
+ JBTerminalSystemSettingsProvider() {
+ myColorScheme = getColorScheme();
+ }
+
+ @Override
+ public KeyStroke[] getCopyKeyStrokes() {
+ return getKeyStrokesByActionId("$Copy");
+ }
+
+ @Override
+ public KeyStroke[] getPasteKeyStrokes() {
+ return getKeyStrokesByActionId("$Paste");
+ }
+
+ @Override
+ public ColorPalette getTerminalColorPalette() {
+ return SystemInfo.isWindows ? ColorPalette.WINDOWS_PALETTE : ColorPalette.XTERM_PALETTE;
+ }
+
+ private KeyStroke[] getKeyStrokesByActionId(String actionId) {
+ List<KeyStroke> keyStrokes = new ArrayList<KeyStroke>();
+ Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId);
+ for (Shortcut sc : shortcuts) {
+ if (sc instanceof KeyboardShortcut) {
+ KeyStroke ks = ((KeyboardShortcut)sc).getFirstKeyStroke();
+ keyStrokes.add(ks);
+ }
+ }
+
+ return keyStrokes.toArray(new KeyStroke[keyStrokes.size()]);
+ }
+
+ @Override
+ public boolean shouldCloseTabOnLogout(TtyConnector ttyConnector) {
+ return ttyConnector instanceof PtyProcessTtyConnector; //close tab only on logout of local pty, not remote
+ }
+
+ @Override
+ public float getLineSpace() {
+ return myColorScheme.getConsoleLineSpacing();
+ }
+
+ @Override
+ public boolean useInverseSelectionColor() {
+ return false;
+ }
+
+ @Override
+ public TextStyle getSelectionColor() {
+ return new TextStyle(TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_FOREGROUND_COLOR)),
+ TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR)));
+ }
+
+ @Override
+ public TextStyle getDefaultStyle() {
+ return new TextStyle(TerminalColor.awt(myColorScheme.getDefaultForeground()), TerminalColor.awt(
+ myColorScheme.getDefaultBackground()));
+ }
+
+ @Override
+ public Font getTerminalFont() {
+ Font normalFont = Font.decode(getFontName());
+
+ if (normalFont == null) {
+ normalFont = super.getTerminalFont();
+ }
+
+ normalFont = normalFont.deriveFont(getTerminalFontSize());
+
+ return normalFont;
+ }
+
+ public String getFontName() {
+ List<String> fonts = myColorScheme.getConsoleFontPreferences().getEffectiveFontFamilies();
+
+ for (String font : fonts) {
+ if (isApplicable(font)) {
+ return font;
+ }
+ }
+ return "Monospaced-14";
+ }
+
+ private static boolean isApplicable(String font) {
+ if ("Source Code Pro".equals(font)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public float getTerminalFontSize() {
+ return (float)myColorScheme.getConsoleFontSize();
+ }
+
+ public EditorColorsScheme getColorScheme() {
+ return createBoundColorSchemeDelegate(null);
+ }
+
+ @NotNull
+ public EditorColorsScheme createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
+ return new MyColorSchemeDelegate(customGlobalScheme);
+ }
+
+ private static class MyColorSchemeDelegate implements EditorColorsScheme {
+
+ private final FontPreferences myFontPreferences = new FontPreferences();
+ private final HashMap<TextAttributesKey, TextAttributes> myOwnAttributes = new HashMap<TextAttributesKey, TextAttributes>();
+ private final HashMap<ColorKey, Color> myOwnColors = new HashMap<ColorKey, Color>();
+ private final EditorColorsScheme myCustomGlobalScheme;
+ private Map<EditorFontType, Font> myFontsMap = null;
+ private int myMaxFontSize = OptionsConstants.MAX_EDITOR_FONT_SIZE;
+ private int myFontSize = -1;
+ private String myFaceName = null;
+ private EditorColorsScheme myGlobalScheme;
+
+ private MyColorSchemeDelegate(@Nullable final EditorColorsScheme globalScheme) {
+ myCustomGlobalScheme = globalScheme;
+ updateGlobalScheme();
+ }
+
+ private EditorColorsScheme getGlobal() {
+ return myGlobalScheme;
+ }
+
+ @Override
+ public String getName() {
+ return getGlobal().getName();
+ }
+
+
+ protected void initFonts() {
+ String editorFontName = getEditorFontName();
+ int editorFontSize = getEditorFontSize();
+ myFontPreferences.clear();
+ myFontPreferences.register(editorFontName, editorFontSize);
+
+ myFontsMap = new EnumMap<EditorFontType, Font>(EditorFontType.class);
+
+ Font plainFont = new Font(editorFontName, Font.PLAIN, editorFontSize);
+ Font boldFont = new Font(editorFontName, Font.BOLD, editorFontSize);
+ Font italicFont = new Font(editorFontName, Font.ITALIC, editorFontSize);
+ Font boldItalicFont = new Font(editorFontName, Font.BOLD | Font.ITALIC, editorFontSize);
+
+ myFontsMap.put(EditorFontType.PLAIN, plainFont);
+ myFontsMap.put(EditorFontType.BOLD, boldFont);
+ myFontsMap.put(EditorFontType.ITALIC, italicFont);
+ myFontsMap.put(EditorFontType.BOLD_ITALIC, boldItalicFont);
+ }
+
+ @Override
+ public void setName(String name) {
+ getGlobal().setName(name);
+ }
+
+ @Override
+ public TextAttributes getAttributes(TextAttributesKey key) {
+ if (myOwnAttributes.containsKey(key)) return myOwnAttributes.get(key);
+ return getGlobal().getAttributes(key);
+ }
+
+ @Override
+ public void setAttributes(TextAttributesKey key, TextAttributes attributes) {
+ myOwnAttributes.put(key, attributes);
+ }
+
+ @NotNull
+ @Override
+ public Color getDefaultBackground() {
+ return getGlobal().getDefaultBackground();
+ }
+
+ @NotNull
+ @Override
+ public Color getDefaultForeground() {
+ return getGlobal().getDefaultForeground();
+ }
+
+ @Override
+ public Color getColor(ColorKey key) {
+ if (myOwnColors.containsKey(key)) return myOwnColors.get(key);
+ return getGlobal().getColor(key);
+ }
+
+ @Override
+ public void setColor(ColorKey key, Color color) {
+ myOwnColors.put(key, color);
+ }
+
+ @NotNull
+ @Override
+ public FontPreferences getFontPreferences() {
+ return myFontPreferences;
+ }
+
+ @Override
+ public void setFontPreferences(@NotNull FontPreferences preferences) {
+ preferences.copyTo(myFontPreferences);
+ initFonts();
+ }
+
+ @Override
+ public int getEditorFontSize() {
+ if (myFontSize == -1) {
+ return getGlobal().getEditorFontSize();
+ }
+ return myFontSize;
+ }
+
+ @Override
+ public void setEditorFontSize(int fontSize) {
+ if (fontSize < 8) fontSize = 8;
+ if (fontSize > myMaxFontSize) fontSize = myMaxFontSize;
+ myFontSize = fontSize;
+ initFonts();
+ }
+
+ @Override
+ public FontSize getQuickDocFontSize() {
+ return myGlobalScheme.getQuickDocFontSize();
+ }
+
+ @Override
+ public void setQuickDocFontSize(@NotNull FontSize fontSize) {
+ myGlobalScheme.setQuickDocFontSize(fontSize);
+ }
+
+ @Override
+ public String getEditorFontName() {
+ if (myFaceName == null) {
+ return getGlobal().getEditorFontName();
+ }
+ return myFaceName;
+ }
+
+ @Override
+ public void setEditorFontName(String fontName) {
+ myFaceName = fontName;
+ initFonts();
+ }
+
+ @Override
+ public Font getFont(EditorFontType key) {
+ if (myFontsMap != null) {
+ Font font = myFontsMap.get(key);
+ if (font != null) return font;
+ }
+ return getGlobal().getFont(key);
+ }
+
+ @Override
+ public void setFont(EditorFontType key, Font font) {
+ if (myFontsMap == null) {
+ initFonts();
+ }
+ myFontsMap.put(key, font);
+ }
+
+ @Override
+ public float getLineSpacing() {
+ return getGlobal().getLineSpacing();
+ }
+
+ @Override
+ public void setLineSpacing(float lineSpacing) {
+ getGlobal().setLineSpacing(lineSpacing);
+ }
+
+ @Override
+ @Nullable
+ public Object clone() {
+ return null;
+ }
+
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {
+ }
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {
+ }
+
+ public void updateGlobalScheme() {
+ myGlobalScheme = myCustomGlobalScheme == null ? EditorColorsManager.getInstance().getGlobalScheme() : myCustomGlobalScheme;
+ int globalFontSize = getGlobal().getEditorFontSize();
+ myMaxFontSize = Math.max(OptionsConstants.MAX_EDITOR_FONT_SIZE, globalFontSize);
+ }
+
+ @NotNull
+ @Override
+ public FontPreferences getConsoleFontPreferences() {
+ return getGlobal().getConsoleFontPreferences();
+ }
+
+ @Override
+ public void setConsoleFontPreferences(@NotNull FontPreferences preferences) {
+ getGlobal().setConsoleFontPreferences(preferences);
+ }
+
+ @Override
+ public String getConsoleFontName() {
+ return getGlobal().getConsoleFontName();
+ }
+
+ @Override
+ public void setConsoleFontName(String fontName) {
+ getGlobal().setConsoleFontName(fontName);
+ }
+
+ @Override
+ public int getConsoleFontSize() {
+ return getGlobal().getConsoleFontSize();
+ }
+
+ @Override
+ public void setConsoleFontSize(int fontSize) {
+ getGlobal().setConsoleFontSize(fontSize);
+ }
+
+ @Override
+ public float getConsoleLineSpacing() {
+ return getGlobal().getConsoleLineSpacing();
+ }
+
+ @Override
+ public void setConsoleLineSpacing(float lineSpacing) {
+ getGlobal().setConsoleLineSpacing(lineSpacing);
+ }
+ }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java
index 6f2e49d..99a21e8 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java
@@ -14,7 +14,7 @@
import com.jediterm.terminal.display.JediTerminal;
import com.jediterm.terminal.display.StyleState;
import com.jediterm.terminal.ui.JediTermWidget;
-import com.jediterm.terminal.ui.SystemSettingsProvider;
+import com.jediterm.terminal.ui.settings.SettingsProvider;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -26,17 +26,17 @@
public class JBTerminalWidget extends JediTermWidget {
- public JBTerminalWidget(SystemSettingsProvider settingsProvider) {
+ public JBTerminalWidget(SettingsProvider settingsProvider) {
super(settingsProvider);
JBTabbedTerminalWidget.convertActions(this, getActions());
}
@Override
- protected JBTerminalPanel createTerminalPanel(@NotNull SystemSettingsProvider settingsProvider,
+ protected JBTerminalPanel createTerminalPanel(@NotNull SettingsProvider settingsProvider,
@NotNull StyleState styleState,
@NotNull BackBuffer backBuffer) {
- return new JBTerminalPanel(settingsProvider, backBuffer, styleState, getColorScheme());
+ return new JBTerminalPanel(settingsProvider, backBuffer, styleState);
}
@Override
@@ -44,243 +44,10 @@
return new JBTerminalStarter(terminal, connector);
}
- public EditorColorsScheme getColorScheme() {
- return createBoundColorSchemeDelegate(null);
- }
-
@Override
protected JScrollBar createScrollBar() {
return new JBScrollBar();
}
- @NotNull
- public EditorColorsScheme createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
- return new MyColorSchemeDelegate(customGlobalScheme);
- }
- private static class MyColorSchemeDelegate implements EditorColorsScheme {
-
- private final FontPreferences myFontPreferences = new FontPreferences();
- private final HashMap<TextAttributesKey, TextAttributes> myOwnAttributes = new HashMap<TextAttributesKey, TextAttributes>();
- private final HashMap<ColorKey, Color> myOwnColors = new HashMap<ColorKey, Color>();
- private final EditorColorsScheme myCustomGlobalScheme;
- private Map<EditorFontType, Font> myFontsMap = null;
- private int myMaxFontSize = OptionsConstants.MAX_EDITOR_FONT_SIZE;
- private int myFontSize = -1;
- private String myFaceName = null;
- private EditorColorsScheme myGlobalScheme;
-
- private MyColorSchemeDelegate(@Nullable final EditorColorsScheme globalScheme) {
- myCustomGlobalScheme = globalScheme;
- updateGlobalScheme();
- }
-
- private EditorColorsScheme getGlobal() {
- return myGlobalScheme;
- }
-
- @Override
- public String getName() {
- return getGlobal().getName();
- }
-
-
- protected void initFonts() {
- String editorFontName = getEditorFontName();
- int editorFontSize = getEditorFontSize();
- myFontPreferences.clear();
- myFontPreferences.register(editorFontName, editorFontSize);
-
- myFontsMap = new EnumMap<EditorFontType, Font>(EditorFontType.class);
-
- Font plainFont = new Font(editorFontName, Font.PLAIN, editorFontSize);
- Font boldFont = new Font(editorFontName, Font.BOLD, editorFontSize);
- Font italicFont = new Font(editorFontName, Font.ITALIC, editorFontSize);
- Font boldItalicFont = new Font(editorFontName, Font.BOLD | Font.ITALIC, editorFontSize);
-
- myFontsMap.put(EditorFontType.PLAIN, plainFont);
- myFontsMap.put(EditorFontType.BOLD, boldFont);
- myFontsMap.put(EditorFontType.ITALIC, italicFont);
- myFontsMap.put(EditorFontType.BOLD_ITALIC, boldItalicFont);
- }
-
- @Override
- public void setName(String name) {
- getGlobal().setName(name);
- }
-
- @Override
- public TextAttributes getAttributes(TextAttributesKey key) {
- if (myOwnAttributes.containsKey(key)) return myOwnAttributes.get(key);
- return getGlobal().getAttributes(key);
- }
-
- @Override
- public void setAttributes(TextAttributesKey key, TextAttributes attributes) {
- myOwnAttributes.put(key, attributes);
- }
-
- @NotNull
- @Override
- public Color getDefaultBackground() {
- return getGlobal().getDefaultBackground();
- }
-
- @NotNull
- @Override
- public Color getDefaultForeground() {
- return getGlobal().getDefaultForeground();
- }
-
- @Override
- public Color getColor(ColorKey key) {
- if (myOwnColors.containsKey(key)) return myOwnColors.get(key);
- return getGlobal().getColor(key);
- }
-
- @Override
- public void setColor(ColorKey key, Color color) {
- myOwnColors.put(key, color);
- }
-
- @NotNull
- @Override
- public FontPreferences getFontPreferences() {
- return myFontPreferences;
- }
-
- @Override
- public void setFontPreferences(@NotNull FontPreferences preferences) {
- preferences.copyTo(myFontPreferences);
- initFonts();
- }
-
- @Override
- public int getEditorFontSize() {
- if (myFontSize == -1) {
- return getGlobal().getEditorFontSize();
- }
- return myFontSize;
- }
-
- @Override
- public void setEditorFontSize(int fontSize) {
- if (fontSize < 8) fontSize = 8;
- if (fontSize > myMaxFontSize) fontSize = myMaxFontSize;
- myFontSize = fontSize;
- initFonts();
- }
-
- @Override
- public FontSize getQuickDocFontSize() {
- return myGlobalScheme.getQuickDocFontSize();
- }
-
- @Override
- public void setQuickDocFontSize(@NotNull FontSize fontSize) {
- myGlobalScheme.setQuickDocFontSize(fontSize);
- }
-
- @Override
- public String getEditorFontName() {
- if (myFaceName == null) {
- return getGlobal().getEditorFontName();
- }
- return myFaceName;
- }
-
- @Override
- public void setEditorFontName(String fontName) {
- myFaceName = fontName;
- initFonts();
- }
-
- @Override
- public Font getFont(EditorFontType key) {
- if (myFontsMap != null) {
- Font font = myFontsMap.get(key);
- if (font != null) return font;
- }
- return getGlobal().getFont(key);
- }
-
- @Override
- public void setFont(EditorFontType key, Font font) {
- if (myFontsMap == null) {
- initFonts();
- }
- myFontsMap.put(key, font);
- }
-
- @Override
- public float getLineSpacing() {
- return getGlobal().getLineSpacing();
- }
-
- @Override
- public void setLineSpacing(float lineSpacing) {
- getGlobal().setLineSpacing(lineSpacing);
- }
-
- @Override
- @Nullable
- public Object clone() {
- return null;
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- }
-
- @Override
- public void writeExternal(Element element) throws WriteExternalException {
- }
-
- public void updateGlobalScheme() {
- myGlobalScheme = myCustomGlobalScheme == null ? EditorColorsManager.getInstance().getGlobalScheme() : myCustomGlobalScheme;
- int globalFontSize = getGlobal().getEditorFontSize();
- myMaxFontSize = Math.max(OptionsConstants.MAX_EDITOR_FONT_SIZE, globalFontSize);
- }
-
- @NotNull
- @Override
- public FontPreferences getConsoleFontPreferences() {
- return getGlobal().getConsoleFontPreferences();
- }
-
- @Override
- public void setConsoleFontPreferences(@NotNull FontPreferences preferences) {
- getGlobal().setConsoleFontPreferences(preferences);
- }
-
- @Override
- public String getConsoleFontName() {
- return getGlobal().getConsoleFontName();
- }
-
- @Override
- public void setConsoleFontName(String fontName) {
- getGlobal().setConsoleFontName(fontName);
- }
-
- @Override
- public int getConsoleFontSize() {
- return getGlobal().getConsoleFontSize();
- }
-
- @Override
- public void setConsoleFontSize(int fontSize) {
- getGlobal().setConsoleFontSize(fontSize);
- }
-
- @Override
- public float getConsoleLineSpacing() {
- return getGlobal().getConsoleLineSpacing();
- }
-
- @Override
- public void setConsoleLineSpacing(float lineSpacing) {
- getGlobal().setConsoleLineSpacing(lineSpacing);
- }
- }
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java
index 203de24..8cb28ea 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java
@@ -21,9 +21,8 @@
@Override
public void update(final AnActionEvent e) {
- boolean enabled = SystemInfo.isUnix;
- e.getPresentation().setVisible(enabled);
- e.getPresentation().setEnabled(enabled);
+ e.getPresentation().setVisible(true);
+ e.getPresentation().setEnabled(true);
}
public void actionPerformed(final AnActionEvent e) {
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java
index 7d57aac..271c8dc 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java
@@ -9,6 +9,8 @@
* @author traff
*/
public class TerminalToolWindowFactory implements ToolWindowFactory, DumbAware {
+ public static final String TOOL_WINDOW_ID = "Terminal";
+
@Override
public void createToolWindowContent(Project project, ToolWindow toolWindow) {
TerminalView terminalView = TerminalView.getInstance();
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
index bd7cfd2..188be8f 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
@@ -9,15 +9,20 @@
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
+import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
+import com.intellij.util.ui.UIUtil;
import com.jediterm.terminal.ui.JediTermWidget;
import com.jediterm.terminal.ui.TabbedTerminalWidget;
import com.jediterm.terminal.ui.TerminalWidget;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
@@ -29,25 +34,47 @@
private JBTabbedTerminalWidget myTerminalWidget;
private Project myProject;
- public void initTerminal(Project project, final ToolWindow toolWindow) {
+ public void initTerminal(final Project project, final ToolWindow toolWindow) {
myProject = project;
LocalTerminalDirectRunner terminalRunner = OpenLocalTerminalAction.createTerminalRunner(project);
-
+
toolWindow.setToHideOnEmptyContent(true);
-
+
if (terminalRunner != null) {
myTerminalWidget = terminalRunner.createTerminalWidget();
myTerminalWidget.addTabListener(new TabbedTerminalWidget.TabListener() {
@Override
public void tabClosed(JediTermWidget terminal) {
- hideIfNoActiveSessions(toolWindow, myTerminalWidget);
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ hideIfNoActiveSessions(toolWindow, myTerminalWidget);
+ }
+ });
}
});
}
Content content = createToolWindowContentPanel(terminalRunner, myTerminalWidget, toolWindow);
-
+
toolWindow.getContentManager().addContent(content);
+
+ ((ToolWindowManagerEx)ToolWindowManager.getInstance(myProject)).addToolWindowManagerListener(new ToolWindowManagerListener() {
+ @Override
+ public void toolWindowRegistered(@NotNull String id) {
+ }
+
+ @Override
+ public void stateChanged() {
+ ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(TerminalToolWindowFactory.TOOL_WINDOW_ID);
+ if (window != null) {
+ boolean visible = window.isVisible();
+ if (visible && toolWindow.getContentManager().getContentCount() == 0) {
+ initTerminal(project, window);
+ }
+ }
+ }
+ });
}
private Content createToolWindowContentPanel(@Nullable LocalTerminalDirectRunner terminalRunner,
@@ -59,6 +86,7 @@
return PlatformDataKeys.HELP_ID.is(dataId) ? EventLog.HELP_ID : super.getData(dataId);
}
};
+
if (terminalWidget != null) {
panel.setContent(terminalWidget.getComponent());
@@ -73,9 +101,8 @@
final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, "", false);
content.setCloseable(true);
- if (getComponentToFocus() != null) {
- content.setPreferredFocusableComponent(getComponentToFocus());
- }
+ content.setPreferredFocusableComponent(terminalWidget.getComponent());
+
return content;
}
@@ -129,7 +156,7 @@
}
private ActionToolbar createToolbar(@Nullable final LocalTerminalDirectRunner terminalRunner,
- final JBTabbedTerminalWidget terminal, ToolWindow toolWindow) {
+ final JBTabbedTerminalWidget terminal, ToolWindow toolWindow) {
DefaultActionGroup group = new DefaultActionGroup();
if (terminalRunner != null) {
@@ -151,16 +178,9 @@
}, true);
}
- private void hideIfNoActiveSessions(final ToolWindow toolWindow, JBTabbedTerminalWidget terminal) {
+ private static void hideIfNoActiveSessions(final ToolWindow toolWindow, JBTabbedTerminalWidget terminal) {
if (terminal.isNoActiveSessions()) {
toolWindow.getContentManager().removeAllContents(true);
-
- toolWindow.getActivation().doWhenDone(new Runnable() {
- @Override
- public void run() {
- initTerminal(myProject, toolWindow);
- }
- });
}
}
diff --git a/plugins/terminal/terminal.iml b/plugins/terminal/terminal.iml
index 86f9059..59daabb 100644
--- a/plugins/terminal/terminal.iml
+++ b/plugins/terminal/terminal.iml
@@ -48,6 +48,7 @@
<SOURCES />
</library>
</orderEntry>
+ <orderEntry type="library" name="Guava" level="project" />
</component>
</module>
diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java
index f88daee..55a6a3d 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -177,7 +177,7 @@
public String getGeneratedName(JavaRunConfigurationModule runconfigurationmodule) {
if (TestType.PACKAGE.getType().equals(TEST_OBJECT)) if (getPackageName().length() == 0) return "<default>";
else return getPackageName();
- String name = JavaExecutionUtil.getPresentableClassName(getMainClassName(), runconfigurationmodule);
+ String name = JavaExecutionUtil.getPresentableClassName(getMainClassName());
if (TestType.METHOD.getType().equals(TEST_OBJECT)) {
return name + '.' + getMethodName();
}
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index 602a51e..10c0e8e 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -141,6 +141,8 @@
<extensionPoint name="clsStubBuilderFactory" interface="com.intellij.psi.impl.compiled.ClsStubBuilderFactory"/>
<extensionPoint name="javaMainMethodProvider" interface="com.intellij.codeInsight.runner.JavaMainMethodProvider"/>
+ <extensionPoint name="importFilter" interface="com.intellij.codeInsight.ImportFilter"/>
+
<extensionPoint name="debuggerClassFilterProvider" interface="com.intellij.ui.classFilter.DebuggerClassFilterProvider"/>
<extensionPoint name="topLevelClassProvider" interface="com.intellij.debugger.engine.TopLevelParentClassProvider"/>
diff --git a/resources/src/idea/RichPlatformActions.xml b/resources/src/idea/RichPlatformActions.xml
index 0432ce6..1fd5f3d 100644
--- a/resources/src/idea/RichPlatformActions.xml
+++ b/resources/src/idea/RichPlatformActions.xml
@@ -408,7 +408,7 @@
</group>
<group>
- <action id="MarkSourceRoot" class="com.intellij.ide.projectView.actions.MarkRootAction" icon="AllIcons.Modules.SourceRoot"/>
+ <action id="MarkSourceRoot" class="com.intellij.ide.projectView.actions.MarkJavaSourceRootAction" icon="AllIcons.Modules.SourceRoot"/>
<action id="MarkTestSourceRoot" class="com.intellij.ide.projectView.actions.MarkTestSourceRootAction" icon="AllIcons.Modules.TestRoot"/>
<action id="MarkExcludeRoot" class="com.intellij.ide.projectView.actions.MarkExcludeRootAction" icon="AllIcons.Modules.ExcludeRoot"/>
<action id="UnmarkRoot" class="com.intellij.ide.projectView.actions.UnmarkRootAction"/>
diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml
index 9e841a2..ba21d55 100644
--- a/resources/src/idea/RichPlatformPlugin.xml
+++ b/resources/src/idea/RichPlatformPlugin.xml
@@ -51,7 +51,7 @@
interface="com.intellij.compiler.DependencyProcessor"/>
<extensionPoint name="compiler.optionsManager"
- interface="com.intellij.compiler.options.CompilerOptionsManager"/>
+ interface="com.intellij.compiler.options.CompilerOptionsFilter"/>
<extensionPoint name="compiler.resourceCompilerExtension"
interface="com.intellij.compiler.impl.resourceCompiler.ResourceCompilerExtension"/>
@@ -79,7 +79,7 @@
<extensionPoint name="codeInsight.wordCompletionFilter" beanClass="com.intellij.lang.LanguageExtensionPoint"/>
<extensionPoint name="projectStructureConfigurableFilter" interface="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurableFilter"/>
- <extensionPoint name="projectStructureConfigurableAdder" interface="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurableAdder"/>
+ <extensionPoint name="projectStructureConfigurableAdder" interface="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurableContributor"/>
<extensionPoint name="compiler" area="IDEA_PROJECT" interface="com.intellij.openapi.compiler.Compiler"/>
<extensionPoint name="compilerFactory" area="IDEA_PROJECT" interface="com.intellij.openapi.compiler.CompilerFactory"/>
diff --git a/spellchecker/src/com/intellij/spellchecker/actions/SpellingPopupActionGroup.java b/spellchecker/src/com/intellij/spellchecker/actions/SpellingPopupActionGroup.java
index 96eea9a..a3639c9 100644
--- a/spellchecker/src/com/intellij/spellchecker/actions/SpellingPopupActionGroup.java
+++ b/spellchecker/src/com/intellij/spellchecker/actions/SpellingPopupActionGroup.java
@@ -16,7 +16,7 @@
package com.intellij.spellchecker.actions;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
-import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
+import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ex.QuickFixWrapper;
@@ -67,7 +67,7 @@
Project project = e.getData(LangDataKeys.PROJECT);
Editor editor = e.getData(LangDataKeys.EDITOR);
if (psiFile != null && project != null && editor != null) {
- List<HighlightInfo.IntentionActionDescriptor> quickFixes = QuickFixAction.getAvailableActions(editor, psiFile, -1);
+ List<HighlightInfo.IntentionActionDescriptor> quickFixes = ShowIntentionsPass.getAvailableActions(editor, psiFile, -1);
Map<Anchor, List<AnAction>> children = new HashMap<Anchor, List<AnAction>>();
ArrayList<AnAction> first = new ArrayList<AnAction>();
children.put(Anchor.FIRST, first);
diff --git a/xml/dom-impl/src/META-INF/DomPlugin.xml b/xml/dom-impl/src/META-INF/DomPlugin.xml
index ae1e1b0..89dee6b 100644
--- a/xml/dom-impl/src/META-INF/DomPlugin.xml
+++ b/xml/dom-impl/src/META-INF/DomPlugin.xml
@@ -4,14 +4,21 @@
interface="com.intellij.util.xml.DomFileDescription"/>
<extensionPoint name="dom.implementation"
- beanClass="com.intellij.util.xml.impl.DomImplementationClassEP"/>
+ beanClass="com.intellij.util.xml.impl.DomImplementationClassEP">
+ <with attribute="interfaceName" implements="com.intellij.util.xml.DomElement"/>
+ <with attribute="implementationName" implements="com.intellij.util.xml.DomElement"/>
+ </extensionPoint>
<extensionPoint name="dom.converter"
- beanClass="com.intellij.util.xml.impl.DomImplementationClassEP"/>
+ beanClass="com.intellij.util.xml.impl.DomImplementationClassEP">
+ <with attribute="interfaceName" implements="com.intellij.util.xml.Converter"/>
+ <with attribute="implementationName" implements="com.intellij.util.xml.Converter"/>
+ </extensionPoint>
<extensionPoint name="dom.extender"
beanClass="com.intellij.util.xml.reflect.DomExtenderEP">
- <with attribute="myDomClass" implements="com.intellij.util.xml.reflect.DomExtender"/>
+ <with attribute="domClassName" implements="com.intellij.util.xml.DomElement"/>
+ <with attribute="extenderClassName" implements="com.intellij.util.xml.reflect.DomExtender"/>
</extensionPoint>
<extensionPoint name="dom.customAnnotationChecker"
diff --git a/xml/impl/resources/com/intellij/codeInsight/completion/TagNameReferenceCompletionProvider.java b/xml/impl/resources/com/intellij/codeInsight/completion/TagNameReferenceCompletionProvider.java
index 45220b0..a068f0f 100644
--- a/xml/impl/resources/com/intellij/codeInsight/completion/TagNameReferenceCompletionProvider.java
+++ b/xml/impl/resources/com/intellij/codeInsight/completion/TagNameReferenceCompletionProvider.java
@@ -29,7 +29,7 @@
import com.intellij.util.Consumer;
import com.intellij.util.PairConsumer;
import com.intellij.util.ProcessingContext;
-import com.intellij.xml.XmlTagNameProvider;
+import com.intellij.xml.XmlCompletionExtension;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -41,8 +41,10 @@
public class TagNameReferenceCompletionProvider extends CompletionProvider<CompletionParameters> {
public static LookupElement[] getTagNameVariants(final @NotNull XmlTag tag, final String prefix) {
List<LookupElement> elements = new ArrayList<LookupElement>();
- for (XmlTagNameProvider tagNameProvider : XmlTagNameProvider.EP_NAME.getExtensions()) {
- tagNameProvider.addTagNameVariants(elements, tag, prefix);
+ for (XmlCompletionExtension tagNameProvider : XmlCompletionExtension.EP_NAME.getExtensions()) {
+ if (tagNameProvider.isMyContext(tag)) {
+ tagNameProvider.addTagNameVariants(elements, tag, prefix);
+ }
}
return elements.toArray(new LookupElement[elements.size()]);
}
diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlAttributeReferenceCompletionProvider.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlAttributeReferenceCompletionProvider.java
index 6b0debb..b7710d6 100644
--- a/xml/impl/src/com/intellij/codeInsight/completion/XmlAttributeReferenceCompletionProvider.java
+++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlAttributeReferenceCompletionProvider.java
@@ -27,14 +27,14 @@
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ProcessingContext;
-import com.intellij.xml.NamespaceAwareXmlAttributeDescriptor;
-import com.intellij.xml.XmlAttributeDescriptor;
-import com.intellij.xml.XmlElementDescriptor;
-import com.intellij.xml.XmlExtension;
+import com.intellij.xml.*;
import com.intellij.xml.util.HtmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.ArrayList;
+import java.util.List;
+
import static com.intellij.codeInsight.completion.CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED;
public class XmlAttributeReferenceCompletionProvider extends CompletionProvider<CompletionParameters> {
@@ -81,9 +81,18 @@
completionData = CompletionUtil.getCompletionDataByElement(attribute, attribute.getContainingFile().getOriginalFile());
boolean caseSensitive = !(completionData instanceof HtmlCompletionData) || ((HtmlCompletionData)completionData).isCaseSensitive();
+ final List<XmlCompletionExtension> completionExtensions = new ArrayList<XmlCompletionExtension>();
+
+ for (XmlCompletionExtension completionExtension : XmlCompletionExtension.EP_NAME.getExtensions()) {
+ if (completionExtension.isMyContext(tag)) {
+ completionExtensions.add(completionExtension);
+ }
+ }
+
for (XmlAttributeDescriptor descriptor : descriptors) {
if (isValidVariant(attribute, descriptor, attributes, extension)) {
- String name = descriptor.getName(tag);
+ final String fullAttrName = descriptor.getName(tag);
+ String name = fullAttrName;
InsertHandler<LookupElement> insertHandler = XmlAttributeInsertHandler.INSTANCE;
@@ -103,7 +112,7 @@
}
if (prefix == null || name.startsWith(prefix)) {
if (prefix != null && name.length() > prefix.length()) {
- name = descriptor.getName(tag).substring(prefix.length());
+ name = fullAttrName.substring(prefix.length());
}
LookupElementBuilder element = LookupElementBuilder.create(name);
if (descriptor instanceof PsiPresentableMetaData) {
@@ -116,8 +125,21 @@
element = element
.withCaseSensitivity(caseSensitive)
.withInsertHandler(insertHandler);
- result.addElement(
- descriptor.isRequired() ? PrioritizedLookupElement.withPriority(element.appendTailText("(required)", true), 100) : element);
+ LookupElement e = null;
+
+ for (XmlCompletionExtension tagNameProvider : completionExtensions) {
+ e = tagNameProvider.setupAttributeLookupElement(tag, descriptor, fullAttrName, element);
+
+ if (e != null) {
+ break;
+ }
+ }
+ if (e == null) {
+ e = descriptor.isRequired()
+ ? PrioritizedLookupElement.withPriority(element.appendTailText("(required)", true), 100)
+ : element;
+ }
+ result.addElement(e);
}
}
}
diff --git a/xml/impl/src/com/intellij/ide/browsers/OpenFileInDefaultBrowserAction.java b/xml/impl/src/com/intellij/ide/browsers/OpenFileInDefaultBrowserAction.java
new file mode 100644
index 0000000..0062567
--- /dev/null
+++ b/xml/impl/src/com/intellij/ide/browsers/OpenFileInDefaultBrowserAction.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2000-2013 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.ide.browsers;
+
+import com.intellij.ide.BrowserUtil;
+import com.intellij.ide.GeneralSettings;
+import com.intellij.ide.browsers.impl.WebBrowserServiceImpl;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.LightVirtualFile;
+import com.intellij.xml.XmlBundle;
+import com.intellij.xml.util.HtmlUtil;
+
+import java.awt.event.InputEvent;
+
+public class OpenFileInDefaultBrowserAction extends DumbAwareAction {
+ private static final Logger LOG = Logger.getInstance(OpenFileInDefaultBrowserAction.class);
+
+ @Override
+ public void update(AnActionEvent e) {
+ final DataContext dataContext = e.getDataContext();
+ final PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
+ final Presentation presentation = e.getPresentation();
+
+ if (file == null || file.getVirtualFile() == null) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+
+ Pair<WebBrowserUrlProvider, Url> browserUrlProvider = WebBrowserServiceImpl.getProvider(file);
+ final boolean isHtmlFile = HtmlUtil.isHtmlFile(file);
+ if (browserUrlProvider == null) {
+ if (file.getVirtualFile() instanceof LightVirtualFile) {
+ presentation.setVisible(false);
+ presentation.setEnabled(false);
+ return;
+ }
+ else {
+ presentation.setEnabled(isHtmlFile);
+ }
+ }
+ else {
+ presentation.setEnabled(true);
+ }
+ presentation.setVisible(true);
+
+ String text = getTemplatePresentation().getText();
+ String description = getTemplatePresentation().getDescription();
+
+ if (browserUrlProvider != null) {
+ final String customText = browserUrlProvider.first.getOpenInBrowserActionText(file);
+ if (customText != null) {
+ text = customText;
+ }
+ final String customDescription = browserUrlProvider.first.getOpenInBrowserActionDescription(file);
+ if (customDescription != null) {
+ description = customDescription;
+ }
+ if (isHtmlFile) {
+ description += " (hold Shift to open URL of local file)";
+ }
+ }
+
+ presentation.setText(text);
+ presentation.setDescription(description);
+
+ GeneralSettings settings = GeneralSettings.getInstance();
+ if (!settings.isUseDefaultBrowser()) {
+ BrowsersConfiguration.BrowserFamily family = BrowsersConfiguration.getInstance().findFamilyByPath(settings.getBrowserPath());
+ if (family != null) {
+ presentation.setIcon(family.getIcon());
+ }
+ }
+
+ if (ActionPlaces.isPopupPlace(e.getPlace())) {
+ presentation.setVisible(presentation.isEnabled());
+ }
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ DataContext dataContext = e.getDataContext();
+ PsiFile psiFile = LangDataKeys.PSI_FILE.getData(dataContext);
+ LOG.assertTrue(psiFile != null);
+ InputEvent event = e.getInputEvent();
+ doOpen(psiFile, event != null && event.isShiftDown());
+ }
+
+ static void doOpen(PsiFile psiFile, boolean preferLocalUrl) {
+ try {
+ Url url = WebBrowserService.getInstance().getUrlToOpen(psiFile, preferLocalUrl);
+ if (url != null) {
+ ApplicationManager.getApplication().saveAll();
+ BrowserUtil.launchBrowser(url.toExternalForm());
+ }
+ }
+ catch (WebBrowserUrlProvider.BrowserException e1) {
+ Messages.showErrorDialog(e1.getMessage(), XmlBundle.message("browser.error"));
+ }
+ catch (Exception e1) {
+ LOG.error(e1);
+ }
+ }
+}
diff --git a/xml/impl/src/com/intellij/ide/browsers/SelectInDefaultBrowserTarget.java b/xml/impl/src/com/intellij/ide/browsers/SelectInDefaultBrowserTarget.java
index e223ee3..3114bb8 100644
--- a/xml/impl/src/com/intellij/ide/browsers/SelectInDefaultBrowserTarget.java
+++ b/xml/impl/src/com/intellij/ide/browsers/SelectInDefaultBrowserTarget.java
@@ -15,14 +15,11 @@
*/
package com.intellij.ide.browsers;
-import com.intellij.ide.BrowserUtil;
import com.intellij.ide.SelectInContext;
import com.intellij.ide.SelectInTargetBase;
import com.intellij.ide.StandardTargetWeights;
import com.intellij.ide.browsers.impl.WebBrowserServiceImpl;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -72,19 +69,7 @@
LOG.assertTrue(psiElement != null);
PsiFile psiFile = psiElement.getContainingFile();
LOG.assertTrue(psiFile != null);
- try {
- Url url = WebBrowserService.getInstance().getUrlToOpen(psiFile, false);
- if (url != null) {
- ApplicationManager.getApplication().saveAll();
- BrowserUtil.launchBrowser(url.toExternalForm());
- }
- }
- catch (WebBrowserUrlProvider.BrowserException e1) {
- Messages.showErrorDialog(e1.getMessage(), XmlBundle.message("browser.error"));
- }
- catch (Exception e1) {
- LOG.error(e1);
- }
+ OpenFileInDefaultBrowserAction.doOpen(psiFile, false);
}
@Override
diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/DefaultXmlTagNameProvider.java b/xml/impl/src/com/intellij/psi/impl/source/xml/DefaultXmlCompletionExtension.java
similarity index 95%
rename from xml/impl/src/com/intellij/psi/impl/source/xml/DefaultXmlTagNameProvider.java
rename to xml/impl/src/com/intellij/psi/impl/source/xml/DefaultXmlCompletionExtension.java
index 0601b92..7fca24b 100644
--- a/xml/impl/src/com/intellij/psi/impl/source/xml/DefaultXmlTagNameProvider.java
+++ b/xml/impl/src/com/intellij/psi/impl/source/xml/DefaultXmlCompletionExtension.java
@@ -23,7 +23,7 @@
import com.intellij.psi.xml.XmlTag;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.XmlExtension;
-import com.intellij.xml.XmlTagNameProvider;
+import com.intellij.xml.XmlCompletionExtension;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NotNull;
@@ -32,7 +32,7 @@
import java.util.Collections;
import java.util.List;
-public class DefaultXmlTagNameProvider implements XmlTagNameProvider {
+public class DefaultXmlCompletionExtension extends XmlCompletionExtension {
@Override
public void addTagNameVariants(List<LookupElement> elements, @NotNull XmlTag tag, String prefix) {
final List<String> namespaces;
diff --git a/xml/impl/src/com/intellij/xml/XmlCompletionExtension.java b/xml/impl/src/com/intellij/xml/XmlCompletionExtension.java
new file mode 100644
index 0000000..01aea03
--- /dev/null
+++ b/xml/impl/src/com/intellij/xml/XmlCompletionExtension.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2013 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.xml;
+
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.xml.XmlTag;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * Provides custom tag names.
+ *
+ * @see HtmlCustomTagNameProvider
+ */
+public abstract class XmlCompletionExtension {
+ public static final ExtensionPointName<XmlCompletionExtension> EP_NAME = new ExtensionPointName<XmlCompletionExtension>("com.intellij.xml.completionExtension");
+
+ public void addTagNameVariants(List<LookupElement> elements, @NotNull XmlTag tag, String prefix) {
+ }
+
+ @Nullable
+ public LookupElement setupAttributeLookupElement(@NotNull XmlTag contextTag,
+ @NotNull XmlAttributeDescriptor descriptor,
+ @NotNull String name,
+ @NotNull LookupElementBuilder elementBuilder) {
+ return null;
+ }
+
+ public boolean isMyContext(@NotNull XmlTag context) {
+ return true;
+ }
+}
diff --git a/xml/impl/src/com/intellij/xml/XmlTagNameProvider.java b/xml/impl/src/com/intellij/xml/XmlTagNameProvider.java
deleted file mode 100644
index a0b5809..0000000
--- a/xml/impl/src/com/intellij/xml/XmlTagNameProvider.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2000-2013 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.xml;
-
-import com.intellij.codeInsight.lookup.LookupElement;
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.psi.xml.XmlTag;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-/**
- * Provides custom tag names.
- *
- * @see HtmlCustomTagNameProvider
- */
-public interface XmlTagNameProvider {
- ExtensionPointName<XmlTagNameProvider> EP_NAME = new ExtensionPointName<XmlTagNameProvider>("com.intellij.xml.tagNameProvider");
-
- void addTagNameVariants(List<LookupElement> elements, @NotNull XmlTag tag, String prefix);
-}
diff --git a/xml/impl/src/com/intellij/xml/util/UserColorLookup.java b/xml/impl/src/com/intellij/xml/util/UserColorLookup.java
index dbc2480..1f39b91 100644
--- a/xml/impl/src/com/intellij/xml/util/UserColorLookup.java
+++ b/xml/impl/src/com/intellij/xml/util/UserColorLookup.java
@@ -54,13 +54,17 @@
}
public UserColorLookup(final Function<Color, String> colorToStringConverter) {
+ this(colorToStringConverter, LookupValueWithPriority.HIGH);
+ }
+
+ public UserColorLookup(final Function<Color, String> colorToStringConverter, int priority) {
super(PrioritizedLookupElement.withPriority(LookupElementBuilder.create(COLOR_STRING).withInsertHandler(
new InsertHandler<LookupElement>() {
@Override
public void handleInsert(InsertionContext context, LookupElement item) {
handleUserSelection(context, colorToStringConverter);
}
- }), LookupValueWithPriority.HIGH));
+ }), priority));
}
private static void handleUserSelection(InsertionContext context, @NotNull Function<Color, String> colorToStringConverter) {
diff --git a/xml/impl/src/com/intellij/xml/util/XmlEnumeratedValueReferenceProvider.java b/xml/impl/src/com/intellij/xml/util/XmlEnumeratedValueReferenceProvider.java
index 590ae53..c1309a5 100644
--- a/xml/impl/src/com/intellij/xml/util/XmlEnumeratedValueReferenceProvider.java
+++ b/xml/impl/src/com/intellij/xml/util/XmlEnumeratedValueReferenceProvider.java
@@ -17,15 +17,11 @@
import com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor;
import com.intellij.openapi.util.Key;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiLanguageInjectionHost;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.PsiReferenceProvider;
+import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
-import com.intellij.psi.xml.XmlAttribute;
-import com.intellij.psi.xml.XmlAttributeValue;
+import com.intellij.psi.xml.*;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.ProcessingContext;
-import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.impl.XmlEnumerationDescriptor;
import com.intellij.xml.impl.schema.XmlSchemaTagsProcessor;
import org.jetbrains.annotations.NotNull;
@@ -34,7 +30,7 @@
* @author Dmitry Avdeev
* Date: 15.08.13
*/
-public class XmlEnumeratedValueReferenceProvider extends PsiReferenceProvider {
+public class XmlEnumeratedValueReferenceProvider<T extends PsiElement> extends PsiReferenceProvider {
public final static Key<Boolean> SUPPRESS = Key.create("suppress attribute value references");
@@ -45,22 +41,49 @@
if (XmlSchemaTagsProcessor.PROCESSING_FLAG.get() != null || context.get(SUPPRESS) != null) {
return PsiReference.EMPTY_ARRAY;
}
- XmlAttributeValue value = (XmlAttributeValue)element;
- if (value instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)value)) {
+ @SuppressWarnings("unchecked") PsiElement host = getHost((T)element);
+ if (host instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)host)) {
return PsiReference.EMPTY_ARRAY;
}
- String unquotedValue = value.getValue();
- if (unquotedValue == null || XmlHighlightVisitor.skipValidation(value) || !XmlUtil.isSimpleXmlAttributeValue(unquotedValue, value)) {
+ String unquotedValue = ElementManipulators.getValueText(element);
+ if (XmlHighlightVisitor.skipValidation(element) || !XmlUtil.isSimpleValue(unquotedValue, element)) {
return PsiReference.EMPTY_ARRAY;
}
- PsiElement parent = value.getParent();
- if (parent instanceof XmlAttribute) {
- final XmlAttributeDescriptor descriptor = ((XmlAttribute)parent).getDescriptor();
- if (descriptor instanceof XmlEnumerationDescriptor &&
- (descriptor.isFixed() || descriptor.isEnumerated() || unquotedValue.equals(descriptor.getDefaultValue()))) { // todo case insensitive
- return ((XmlEnumerationDescriptor)descriptor).getValueReferences(value);
+ @SuppressWarnings("unchecked") final Object descriptor = getDescriptor((T)element);
+ if (descriptor instanceof XmlEnumerationDescriptor) {
+ XmlEnumerationDescriptor enumerationDescriptor = (XmlEnumerationDescriptor)descriptor;
+ if (enumerationDescriptor.isFixed() ||
+ enumerationDescriptor.isEnumerated((XmlElement)element) ||
+ unquotedValue.equals(enumerationDescriptor.getDefaultValue())) { // todo case insensitive
+ //noinspection unchecked
+ return enumerationDescriptor.getValueReferences((XmlElement)element, unquotedValue);
}
}
return PsiReference.EMPTY_ARRAY;
}
+
+ protected PsiElement getHost(T element) {
+ return element;
+ }
+
+ protected Object getDescriptor(T element) {
+ PsiElement parent = element.getParent();
+ return parent instanceof XmlAttribute ? ((XmlAttribute)parent).getDescriptor() : null;
+ }
+
+ public static XmlEnumeratedValueReferenceProvider forTags() {
+ return new XmlEnumeratedValueReferenceProvider<XmlTag>() {
+
+ @Override
+ protected Object getDescriptor(XmlTag element) {
+ return element.getDescriptor();
+ }
+
+ @Override
+ protected PsiElement getHost(XmlTag element) {
+ XmlText[] textElements = element.getValue().getTextElements();
+ return ArrayUtil.getFirstElement(textElements);
+ }
+ };
+ }
}
diff --git a/xml/impl/src/com/intellij/xml/util/XmlInvalidIdInspection.java b/xml/impl/src/com/intellij/xml/util/XmlInvalidIdInspection.java
index afe28ed..6f8a17a 100644
--- a/xml/impl/src/com/intellij/xml/util/XmlInvalidIdInspection.java
+++ b/xml/impl/src/com/intellij/xml/util/XmlInvalidIdInspection.java
@@ -40,7 +40,7 @@
idRef = idRef.toLowerCase();
}
- if (XmlUtil.isSimpleXmlAttributeValue(idRef, value) && refHolder.isIdReferenceValue(value)) {
+ if (XmlUtil.isSimpleValue(idRef, value) && refHolder.isIdReferenceValue(value)) {
boolean hasIdDeclaration = refHolder.hasIdDeclaration(idRef);
if (!hasIdDeclaration && tag instanceof HtmlTag) {
hasIdDeclaration = refHolder.hasIdDeclaration(value.getValue());
diff --git a/xml/impl/src/com/intellij/xml/util/XmlPrefixReferenceProvider.java b/xml/impl/src/com/intellij/xml/util/XmlPrefixReferenceProvider.java
index f1b8294..a740db0 100644
--- a/xml/impl/src/com/intellij/xml/util/XmlPrefixReferenceProvider.java
+++ b/xml/impl/src/com/intellij/xml/util/XmlPrefixReferenceProvider.java
@@ -23,6 +23,10 @@
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
XmlAttributeValue attributeValue = (XmlAttributeValue)element;
+ String value = attributeValue.getValue();
+ if (value == null) return PsiReference.EMPTY_ARRAY;
+ int i = value.indexOf(':');
+ if (i <= 0) return PsiReference.EMPTY_ARRAY;
PsiElement parent = attributeValue.getParent();
if (parent instanceof XmlAttribute && !XmlNSDescriptorImpl.checkSchemaNamespace(((XmlAttribute)parent).getParent())) {
XmlAttributeDescriptor descriptor = ((XmlAttribute)parent).getDescriptor();
@@ -32,15 +36,9 @@
String prefix = XmlUtil.findPrefixByQualifiedName(type);
String ns = ((XmlTag)descriptor.getDeclaration()).getNamespaceByPrefix(prefix);
if (XmlNSDescriptorImpl.checkSchemaNamespace(ns)) {
- String value = attributeValue.getValue();
- if (value != null) {
- int i = value.indexOf(':');
- if (i > 0) {
- return new PsiReference[] {
- new SchemaPrefixReference(attributeValue, TextRange.from(1, i), value.substring(0, i), null)
- };
- }
- }
+ return new PsiReference[] {
+ new SchemaPrefixReference(attributeValue, TextRange.from(1, i), value.substring(0, i), null)
+ };
}
}
}
diff --git a/xml/impl/src/com/intellij/xml/util/XmlRefCountHolder.java b/xml/impl/src/com/intellij/xml/util/XmlRefCountHolder.java
index 023e3a9..3d47549 100644
--- a/xml/impl/src/com/intellij/xml/util/XmlRefCountHolder.java
+++ b/xml/impl/src/com/intellij/xml/util/XmlRefCountHolder.java
@@ -266,7 +266,7 @@
private void updateMap(@NotNull final XmlAttribute attribute, @NotNull final XmlAttributeValue value, final boolean soft) {
final String id = XmlHighlightVisitor.getUnquotedValue(value, attribute.getParent());
- if (XmlUtil.isSimpleXmlAttributeValue(id, value) &&
+ if (XmlUtil.isSimpleValue(id, value) &&
PsiTreeUtil.getChildOfType(value, OuterLanguageElement.class) == null) {
myHolder.registerId(id, value, soft);
}
diff --git a/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java b/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java
index ae58862..fa04ab0 100644
--- a/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java
+++ b/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java
@@ -4,16 +4,18 @@
import com.intellij.html.impl.providers.MicrodataReferenceProvider;
import com.intellij.html.impl.util.MicrodataUtil;
import com.intellij.patterns.PlatformPatterns;
-import com.intellij.psi.PsiReferenceContributor;
-import com.intellij.psi.PsiReferenceRegistrar;
+import com.intellij.psi.*;
import com.intellij.psi.filters.*;
import com.intellij.psi.filters.position.NamespaceFilter;
import com.intellij.psi.filters.position.ParentElementFilter;
+import com.intellij.psi.impl.UrlPsiReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.DtdReferencesProvider;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.IdReferenceProvider;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.SchemaReferencesProvider;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.URIReferenceProvider;
import com.intellij.psi.xml.*;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
import static com.intellij.patterns.XmlPatterns.*;
@@ -90,5 +92,17 @@
registrar.registerReferenceProvider(xmlAttributeValue(), new XmlPrefixReferenceProvider());
registrar.registerReferenceProvider(xmlAttributeValue(), new XmlEnumeratedValueReferenceProvider(), PsiReferenceRegistrar.LOWER_PRIORITY);
+ registrar.registerReferenceProvider(xmlTag(), XmlEnumeratedValueReferenceProvider.forTags(), PsiReferenceRegistrar.LOWER_PRIORITY);
+
+ registrar.registerReferenceProvider(xmlAttributeValue().withLocalName("source")
+ .withSuperParent(2, xmlTag().withLocalName("documentation").withNamespace(XmlUtil.SCHEMA_URIS)),
+ new PsiReferenceProvider() {
+ @NotNull
+ @Override
+ public PsiReference[] getReferencesByElement(@NotNull PsiElement element,
+ @NotNull ProcessingContext context) {
+ return new PsiReference[] { new UrlPsiReference(element) };
+ }
+ });
}
}
diff --git a/xml/impl/src/com/intellij/xml/util/documentation/html5table.xml b/xml/impl/src/com/intellij/xml/util/documentation/html5table.xml
index 94c2e45..de3dbab 100644
--- a/xml/impl/src/com/intellij/xml/util/documentation/html5table.xml
+++ b/xml/impl/src/com/intellij/xml/util/documentation/html5table.xml
@@ -1,4 +1,12 @@
<html-property-table baseHelpRef="http://dev.w3.org/html5/spec/">
+<tag name = "main"
+ helpref = "grouping-content.html#the-main-element"
+ description = "represents the main content of the body of a document or application"
+ startTag = "true"
+ endTag = "true"
+ empty = "false"
+ dtd = ""
+/>
<tag name = "section"
helpref = "sections.html#the-section-element"
description = "generic document or application section"
diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java
index f9d9f7c..b05794e 100644
--- a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java
+++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java
@@ -21,7 +21,6 @@
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
@@ -32,6 +31,7 @@
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.kohsuke.rngom.digested.DAttributePattern;
import org.xml.sax.Locator;
@@ -206,10 +206,8 @@
}
@Override
- public PsiReference[] getValueReferences(final XmlAttributeValue value) {
- String text = value.getValue();
- if (text == null) return PsiReference.EMPTY_ARRAY;
- return new PsiReference[] { new XmlEnumeratedValueReference(value, this) {
+ public PsiReference[] getValueReferences(final XmlElement element, @NotNull String text) {
+ return new PsiReference[] { new XmlEnumeratedValueReference(element, this) {
@Nullable
@Override
public PsiElement resolve() {
diff --git a/xml/tests/src/com/intellij/codeInsight/completion/XmlCompletionTest.java b/xml/tests/src/com/intellij/codeInsight/completion/XmlCompletionTest.java
index b054b7f..7d6df70 100644
--- a/xml/tests/src/com/intellij/codeInsight/completion/XmlCompletionTest.java
+++ b/xml/tests/src/com/intellij/codeInsight/completion/XmlCompletionTest.java
@@ -670,5 +670,11 @@
myFixture.configureByFiles("Substitute/schema-a.xsd", "Substitute/schema-b.xsd");
myFixture.testCompletionVariants("Substitute/test.xml", "b:instance", "instance");
}
+
+ public void testEnumeratedTagValue() throws Exception {
+ myFixture.configureByFile("tagValue/enumerated.xsd");
+ myFixture.testCompletionVariants("tagValue/completeEnum.xml", "none", "standard");
+ myFixture.testCompletionVariants("tagValue/completeBoolean.xml", "false", "true");
+ }
}
diff --git a/xml/tests/testData/completion/tagValue/completeBoolean.xml b/xml/tests/testData/completion/tagValue/completeBoolean.xml
new file mode 100644
index 0000000..7e8479f
--- /dev/null
+++ b/xml/tests/testData/completion/tagValue/completeBoolean.xml
@@ -0,0 +1 @@
+<bar xmlns="foo.bar"><caret></bar>
\ No newline at end of file
diff --git a/xml/tests/testData/completion/tagValue/completeEnum.xml b/xml/tests/testData/completion/tagValue/completeEnum.xml
new file mode 100644
index 0000000..4926a63
--- /dev/null
+++ b/xml/tests/testData/completion/tagValue/completeEnum.xml
@@ -0,0 +1 @@
+<foo xmlns="foo.bar"><caret></foo>
\ No newline at end of file
diff --git a/xml/tests/testData/completion/tagValue/enumerated.xsd b/xml/tests/testData/completion/tagValue/enumerated.xsd
new file mode 100644
index 0000000..fc0a4d8
--- /dev/null
+++ b/xml/tests/testData/completion/tagValue/enumerated.xsd
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
+ targetNamespace="foo.bar">
+ <xs:element name="foo">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="none"/>
+ <xs:enumeration value="standard"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="bar" type="xs:boolean"/>
+
+ <xs:element name="def" type="xs:string" default="my default"/>
+</xs:schema>
diff --git a/xml/xml-psi-impl/resources/messages/XmlErrorMessages.properties b/xml/xml-psi-impl/resources/messages/XmlErrorMessages.properties
index 8ab43e2..166a0b8 100644
--- a/xml/xml-psi-impl/resources/messages/XmlErrorMessages.properties
+++ b/xml/xml-psi-impl/resources/messages/XmlErrorMessages.properties
@@ -20,7 +20,7 @@
invalid.id.reference=Invalid id reference
uri.is.not.registered=URI is not registered (Settings | Project Settings | Schemas and DTDs)
registered.resource.is.not.recognized=Resource registered by this uri is not recognized (Settings | Project Settings | Schemas and DTDs)
-attribute.should.have.fixed.value=Attribute should have fixed value {0}
+should.have.fixed.value={0} should have fixed value {1}
#quickfixes
insert.required.attribute.quickfix.text=Insert Required Attribute {0}
@@ -44,7 +44,7 @@
unescaped.ampersand.or.nonterminated.character.entity.reference=Unescaped \\& or nonterminated character/entity reference
expected.prologue.tag.termination.expected='?>' expected
expected.whitespace=Whitespace expected
-wrong.attribute.value=Wrong attribute value
+wrong.value=Wrong {0} value
way.too.unbalanced=Way too unbalanced. Stopping attempt to balance tags properly at this point
cannot.resolve.taglib.uri=Cannot resolve taglib with uri {0}
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java
index 674ad16..7204bf7 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java
@@ -20,6 +20,7 @@
import com.intellij.util.ArrayUtil;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
+import com.intellij.xml.impl.XmlEnumerationDescriptor;
/**
* @author Maxim.Mossienko
@@ -95,8 +96,8 @@
@Override
public PsiElement getValueDeclaration(XmlElement attributeValue, String value) {
String s = myCaseSensitive ? value : value.toLowerCase();
- return delegate instanceof BasicXmlAttributeDescriptor ?
- ((BasicXmlAttributeDescriptor)delegate).getValueDeclaration(attributeValue, s) :
+ return delegate instanceof XmlEnumerationDescriptor ?
+ ((XmlEnumerationDescriptor)delegate).getValueDeclaration(attributeValue, s) :
super.getValueDeclaration(attributeValue, value);
}
}
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java
index 8862ac8..cd1f672d 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java
@@ -410,7 +410,11 @@
class CompletionProcessor implements PsiElementProcessor<XmlTag> {
List<String> myElements = new ArrayList<String>(1);
String namespace;
- XmlTag tag;
+ final XmlTag tag;
+
+ CompletionProcessor(XmlTag tag) {
+ this.tag = tag;
+ }
public boolean execute(@NotNull final XmlTag element) {
String name = element.getAttributeValue(NAME_ATTR_NAME);
@@ -448,8 +452,7 @@
break;
}
- CompletionProcessor processor = new CompletionProcessor();
- processor.tag = tag;
+ CompletionProcessor processor = new CompletionProcessor(tag);
final XmlElement context = PsiTreeUtil.getContextOfType(myElement, XmlElement.class, false);
if (context == null) {
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/SchemaPrefixReference.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/SchemaPrefixReference.java
index 2c963a9..4d4c3aa 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/SchemaPrefixReference.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/SchemaPrefixReference.java
@@ -47,7 +47,7 @@
* @param name
* @param reference
*/
- public SchemaPrefixReference(XmlElement element, TextRange range, String name, TagNameReference reference) {
+ public SchemaPrefixReference(XmlElement element, TextRange range, String name, @Nullable TagNameReference reference) {
super(element, range);
myName = name;
myTagNameReference = reference;
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java
index fba46a2..4e2055d 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java
@@ -45,6 +45,11 @@
}
@Override
+ public boolean isEnumerated(XmlElement context) {
+ return isEnumerated();
+ }
+
+ @Override
public String toString() {
return getName();
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/XmlEnumerationDescriptor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/XmlEnumerationDescriptor.java
index bf7b988..b77ed3a 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/XmlEnumerationDescriptor.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/XmlEnumerationDescriptor.java
@@ -3,20 +3,23 @@
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
-import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
import com.intellij.xml.util.XmlEnumeratedValueReference;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author Dmitry Avdeev
* Date: 22.08.13
*/
-public abstract class XmlEnumerationDescriptor {
+public abstract class XmlEnumerationDescriptor<T extends XmlElement> {
public abstract boolean isFixed();
public abstract String getDefaultValue();
+ public abstract boolean isEnumerated(@Nullable XmlElement context);
+
public abstract String[] getEnumeratedValues();
public PsiElement getValueDeclaration(XmlElement attributeValue, String value) {
@@ -31,8 +34,7 @@
protected abstract PsiElement getDefaultValueDeclaration();
- public PsiReference[] getValueReferences(XmlAttributeValue value) {
- return new PsiReference[] { new XmlEnumeratedValueReference(value, this)};
+ public PsiReference[] getValueReferences(T element, @NotNull String text) {
+ return new PsiReference[] { new XmlEnumeratedValueReference(element, this)};
}
-
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java
index 61c33c0..3d3cab7 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java
@@ -16,14 +16,17 @@
package com.intellij.xml.impl.schema;
import com.intellij.codeInsight.daemon.Validator;
+import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiReference;
import com.intellij.psi.meta.PsiWritableMetaData;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.xml.*;
+import com.intellij.xml.util.XmlEnumeratedValueReference;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -36,7 +39,7 @@
/**
* @author Mike
*/
-public class XmlElementDescriptorImpl extends XsdEnumerationDescriptor
+public class XmlElementDescriptorImpl extends XsdEnumerationDescriptor<XmlTag>
implements XmlElementDescriptor, PsiWritableMetaData, Validator<XmlTag>,
XmlElementDescriptorAwareAboutChildren {
protected XmlTag myDescriptorTag;
@@ -473,8 +476,9 @@
}
public String getQualifiedName() {
- if (!"".equals(getNS())) {
- return getNS() + ":" + getName();
+ String ns = getNS();
+ if (ns != null && !ns.isEmpty()) {
+ return ns + ":" + getName();
}
return getName();
@@ -519,6 +523,16 @@
}
}
+ @Override
+ public PsiReference[] getValueReferences(XmlTag xmlTag, @NotNull String text) {
+ XmlTagValue value = xmlTag.getValue();
+ XmlText[] elements = value.getTextElements();
+ if (elements.length == 0 || xmlTag.getSubTags().length > 0) return PsiReference.EMPTY_ARRAY;
+ return new PsiReference[] {
+ new XmlEnumeratedValueReference(xmlTag, this, ElementManipulators.getValueTextRange(xmlTag))
+ };
+ }
+
public boolean allowElementsFromNamespace(final String namespace, final XmlTag context) {
final TypeDescriptor type = getType(context);
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XsdEnumerationDescriptor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XsdEnumerationDescriptor.java
index 0a1c341..26600b7 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XsdEnumerationDescriptor.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XsdEnumerationDescriptor.java
@@ -21,7 +21,7 @@
* @author Dmitry Avdeev
* Date: 22.08.13
*/
-public abstract class XsdEnumerationDescriptor extends XmlEnumerationDescriptor {
+public abstract class XsdEnumerationDescriptor<T extends XmlElement> extends XmlEnumerationDescriptor<T> {
private boolean myExhaustiveEnum;
@@ -60,7 +60,7 @@
}
private boolean processEnumeration(XmlElement context, PairProcessor<PsiElement, String> processor) {
- XmlTag contextTag = context != null ? PsiTreeUtil.getContextOfType(context, XmlTag.class, true) : null;
+ XmlTag contextTag = context != null ? PsiTreeUtil.getContextOfType(context, XmlTag.class, false) : null;
final XmlElementDescriptorImpl elementDescriptor = (XmlElementDescriptorImpl)XmlUtil.findXmlDescriptorByType(getDeclaration(), contextTag);
if (elementDescriptor!=null && elementDescriptor.getType() instanceof ComplexTypeDescriptor) {
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java b/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java
index a25f605..ac01d81 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java
@@ -139,7 +139,8 @@
@NonNls private static final String[] HTML5_TAGS = {
"article", "aside", "audio", "canvas", "command", "datalist", "details", "embed", "figcaption", "figure", "footer", "header", "hgroup",
- "keygen", "mark", "meter", "nav", "output", "progress", "rp", "rt", "ruby", "section", "source", "summary", "time", "video", "wbr"
+ "keygen", "mark", "meter", "nav", "output", "progress", "rp", "rt", "ruby", "section", "source", "summary", "time", "video", "wbr",
+ "main"
};
private static final Set<String> HTML5_TAGS_SET = new THashSet<String>();
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlEnumeratedValueReference.java b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlEnumeratedValueReference.java
index 5cf994a..6b1bdf4 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlEnumeratedValueReference.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlEnumeratedValueReference.java
@@ -17,9 +17,12 @@
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
import com.intellij.codeInsight.daemon.XmlErrorMessages;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReferenceBase;
-import com.intellij.psi.xml.XmlAttributeValue;
+import com.intellij.psi.xml.XmlElement;
+import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.xml.impl.XmlEnumerationDescriptor;
import org.jetbrains.annotations.NotNull;
@@ -29,14 +32,19 @@
* @author Dmitry Avdeev
* Date: 16.08.13
*/
-public class XmlEnumeratedValueReference extends PsiReferenceBase<XmlAttributeValue> implements EmptyResolveMessageProvider {
+public class XmlEnumeratedValueReference extends PsiReferenceBase<XmlElement> implements EmptyResolveMessageProvider {
private final XmlEnumerationDescriptor myDescriptor;
- public XmlEnumeratedValueReference(XmlAttributeValue value, XmlEnumerationDescriptor descriptor) {
+ public XmlEnumeratedValueReference(XmlElement value, XmlEnumerationDescriptor descriptor) {
super(value);
myDescriptor = descriptor;
}
+ public XmlEnumeratedValueReference(XmlElement value, XmlEnumerationDescriptor descriptor, TextRange range) {
+ super(value, range);
+ myDescriptor = descriptor;
+ }
+
@Nullable
@Override
public PsiElement resolve() {
@@ -59,8 +67,9 @@
@NotNull
@Override
public String getUnresolvedMessagePattern() {
+ String name = getElement() instanceof XmlTag ? "tag" : "attribute";
return myDescriptor.isFixed()
- ? XmlErrorMessages.message("attribute.should.have.fixed.value", myDescriptor.getDefaultValue())
- : XmlErrorMessages.message("wrong.attribute.value");
+ ? XmlErrorMessages.message("should.have.fixed.value", StringUtil.capitalize(name), myDescriptor.getDefaultValue())
+ : XmlErrorMessages.message("wrong.value", name);
}
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java
index e8bb8f4..abbddfcf 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java
@@ -933,6 +933,8 @@
});
}
+ private final static Set<String> doNotVisitTags = new HashSet<String>(Arrays.asList("annotation", "element", "attribute"));
+
/**
* @return true if enumeration is exhaustive
*/
@@ -954,7 +956,7 @@
exhaustiveEnum = false;
processEnumerationValues(tag, tagProcessor);
}
- else if (!localName.equals("annotation")) {
+ else if (!doNotVisitTags.contains(localName)) {
// don't go into annotation
exhaustiveEnum &= processEnumerationValues(tag, tagProcessor);
}
@@ -1070,7 +1072,7 @@
return new Pair<XmlTagChild, XmlTagChild>(first, last);
}
- public static boolean isSimpleXmlAttributeValue(@NotNull final String unquotedValue, final XmlAttributeValue context) {
+ public static boolean isSimpleValue(@NotNull final String unquotedValue, final PsiElement context) {
for (int i = 0; i < unquotedValue.length(); ++i) {
final char ch = unquotedValue.charAt(i);
if (!Character.isJavaIdentifierPart(ch) && ch != ':' && ch != '-') {