diff --git a/.idea/libraries/asm4.xml b/.idea/libraries/asm4.xml deleted file mode 100644 index 3ed48ba9daf5..000000000000 --- a/.idea/libraries/asm4.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt index d64569567334..4c4a741bfd61 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -187,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2000-2016 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/build/asm/.gitignore b/build/asm/.gitignore new file mode 100644 index 000000000000..0c64996a6a2e --- /dev/null +++ b/build/asm/.gitignore @@ -0,0 +1,2 @@ +src/ +out/ \ No newline at end of file diff --git a/build/asm/1_version_check.patch b/build/asm/1_version_check.patch new file mode 100644 index 000000000000..63ec6e0278f8 --- /dev/null +++ b/build/asm/1_version_check.patch @@ -0,0 +1,13 @@ +Index: org/objectweb/asm/ClassReader.java +=================================================================== +--- org/objectweb/asm/ClassReader.java ++++ org/objectweb/asm/ClassReader.java +@@ -167,7 +167,7 @@ + this.b = b; + // checks the class version + if (readShort(off + 6) > Opcodes.V1_8) { +- throw new IllegalArgumentException(); ++ //[JB: accept any version] throw new IllegalArgumentException(); + } + // parses the constant pool + items = new int[readUnsignedShort(off + 8)]; diff --git a/build/asm/2_coverage_fix.patch b/build/asm/2_coverage_fix.patch new file mode 100644 index 000000000000..0aa5c7dbca45 --- /dev/null +++ b/build/asm/2_coverage_fix.patch @@ -0,0 +1,13 @@ +Index: org/objectweb/asm/tree/MethodNode.java +=================================================================== +--- org/objectweb/asm/tree/MethodNode.java ++++ org/objectweb/asm/tree/MethodNode.java +@@ -623,7 +623,7 @@ + */ + protected LabelNode getLabelNode(final Label l) { + if (!(l.info instanceof LabelNode)) { +- l.info = new LabelNode(); ++ l.info = new LabelNode(l); //[JB: passing a reference to avoid exceptions in coverage] + } + return (LabelNode) l.info; + } diff --git a/build/asm/repackage.xml b/build/asm/repackage.xml new file mode 100644 index 000000000000..75336cfbe16b --- /dev/null +++ b/build/asm/repackage.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/conf/classVersions.txt b/build/conf/classVersions.txt index aef87f308a55..c956aacaa72b 100644 --- a/build/conf/classVersions.txt +++ b/build/conf/classVersions.txt @@ -49,6 +49,12 @@ 1.6 => plugins/gradle/lib/gradle-tooling-extension-api.jar 1.6 => plugins/gradle/lib/gradle-tooling-extension-impl.jar +1.6 => plugins/maven/lib/maven-server-api.jar +1.6 => plugins/maven/lib/maven2-server-impl.jar +1.6 => plugins/maven/lib/maven3-server-common.jar +1.6 => plugins/maven/lib/maven30-server-impl.jar +1.6 => plugins/maven/lib/maven32-server-impl.jar + 1.4 => plugins/xpath/lib/rt/xslt-rt.jar 1.5 => plugins/xslt-debugger/lib/xslt-debugger-engine.jar 1.5 => plugins/xslt-debugger/lib/rt/xslt-debugger-engine-impl.jar diff --git a/build/conf/nsis/desktop.ini b/build/conf/nsis/desktop.ini index 5a39b377d9ae..a35782f10af2 100644 --- a/build/conf/nsis/desktop.ini +++ b/build/conf/nsis/desktop.ini @@ -12,15 +12,15 @@ Text=Create Desktop shortcut [Field 2] Type=checkbox Left=5 -Right=105 +Right=70 Top=25 Bottom=35 State=0 [Field 3] Type=Label -Left=115 -Right=215 +Left=75 +Right=140 Top=25 Bottom=35 Text="" diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index d838e9bc8e75..5697edf7f387 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -706,7 +706,7 @@ binding.setVariable("patchPropertiesFile", { String target, Map args = [:] -> } String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase() - String settings_dir = args.system_selector.replaceFirst("\\d+", "") + String settings_dir = args.system_selector.replaceFirst("\\d+(\\.\\d+)?", "") ant.replace(file: file) { replacefilter(token: "@@product_uc@@", value: product_uc) replacefilter(token: "@@settings_dir@@", value: settings_dir) diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java index 23a85aa41e57..ebac72fdd5bb 100644 --- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java +++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java @@ -35,7 +35,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.roots.ui.configuration.PathUIUtils; +import com.intellij.openapi.roots.ui.configuration.LibrarySourceRootDetectorUtil; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListSeparator; @@ -305,7 +305,7 @@ public class AttachSourcesNotificationProvider extends EditorNotifications.Provi Library firstLibrary = libraries.get(0).getLibrary(); VirtualFile[] roots = firstLibrary != null ? firstLibrary.getFiles(OrderRootType.CLASSES) : VirtualFile.EMPTY_ARRAY; VirtualFile[] candidates = FileChooser.chooseFiles(descriptor, myProject, roots.length == 0 ? null : PathUtil.getLocalFile(roots[0])); - final VirtualFile[] files = PathUIUtils.scanAndSelectDetectedJavaSourceRoots(myParentComponent, candidates); + final VirtualFile[] files = LibrarySourceRootDetectorUtil.scanAndSelectDetectedJavaSourceRoots(myParentComponent, candidates); if (files.length == 0) { return ActionCallback.REJECTED; } diff --git a/java/idea-ui/src/com/intellij/jarFinder/InternetAttachSourceProvider.java b/java/idea-ui/src/com/intellij/jarFinder/InternetAttachSourceProvider.java index 8ee9e96245c0..f17b29a4d0b0 100644 --- a/java/idea-ui/src/com/intellij/jarFinder/InternetAttachSourceProvider.java +++ b/java/idea-ui/src/com/intellij/jarFinder/InternetAttachSourceProvider.java @@ -26,7 +26,7 @@ import com.intellij.openapi.progress.Task; import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.roots.ui.configuration.PathUIUtils; +import com.intellij.openapi.roots.ui.configuration.LibrarySourceRootDetectorUtil; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; @@ -215,7 +215,7 @@ public class InternetAttachSourceProvider implements AttachSourcesProvider { VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(srcFile); if (jarRoot == null) return; - VirtualFile[] roots = PathUIUtils.scanAndSelectDetectedJavaSourceRoots(null, new VirtualFile[]{jarRoot}); + VirtualFile[] roots = LibrarySourceRootDetectorUtil.scanAndSelectDetectedJavaSourceRoots(null, new VirtualFile[]{jarRoot}); if (roots.length == 0) { roots = new VirtualFile[]{jarRoot}; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelCombo.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelCombo.java index b3e8c77cf98c..ab412d7726b1 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelCombo.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelCombo.java @@ -34,7 +34,7 @@ import javax.swing.*; */ @SuppressWarnings("unchecked") public abstract class LanguageLevelCombo extends ComboBox { - + private boolean myDefaultWasSelectedBeforeRemoving; private final String myDefaultItem; public LanguageLevelCombo(String defaultItem) { @@ -91,18 +91,28 @@ public abstract class LanguageLevelCombo extends ComboBox { private void updateDefaultLevel(LanguageLevel newLevel, boolean isDefaultProject) { if (newLevel == null && !isDefaultProject) { - if (getSelectedItem() == myDefaultItem) { - setSelectedItem(getDefaultLevel()); + if (isDefaultItemAdded()) { + boolean defaultSelected = getSelectedItem() == myDefaultItem; + if (defaultSelected) { + setSelectedItem(getDefaultLevel()); + } + myDefaultWasSelectedBeforeRemoving = defaultSelected; + removeItem(myDefaultItem); } - removeItem(myDefaultItem); } - else if (!(getItemAt(0) instanceof String)) { + else if (!(isDefaultItemAdded())) { addDefaultItem(); - setSelectedIndex(0); + if (myDefaultWasSelectedBeforeRemoving) { + setSelectedIndex(0); + } } repaint(); } + private boolean isDefaultItemAdded() { + return getItemAt(0) instanceof String; + } + void addDefaultItem() { insertItemAt(myDefaultItem, 0); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootDetector.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryJavaSourceRootDetector.java similarity index 92% rename from java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootDetector.java rename to java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryJavaSourceRootDetector.java index 3b02e0cd0fb7..f96d8e0667ad 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaSourceRootDetector.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryJavaSourceRootDetector.java @@ -23,8 +23,8 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; -public class JavaSourceRootDetector extends RootDetector { - public JavaSourceRootDetector() { +public class LibraryJavaSourceRootDetector extends RootDetector { + public LibraryJavaSourceRootDetector() { super(OrderRootType.SOURCES, false, "sources"); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibrarySourceRootDetectorUtil.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibrarySourceRootDetectorUtil.java new file mode 100644 index 000000000000..e7b9dc016648 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibrarySourceRootDetectorUtil.java @@ -0,0 +1,61 @@ +/* + * 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.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.ui.OrderRoot; +import com.intellij.openapi.roots.libraries.ui.RootDetector; +import com.intellij.openapi.roots.libraries.ui.impl.LibraryRootsDetectorImpl; +import com.intellij.openapi.roots.libraries.ui.impl.RootDetectionUtil; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; + +import java.awt.*; +import java.util.*; +import java.util.List; + +/** + * This utility class contains utility methods for selecting paths. + * + * @author Constantine.Plotnikov + */ +public class LibrarySourceRootDetectorUtil { + public static ExtensionPointName JAVA_SOURCE_ROOT_DETECTOR = ExtensionPointName.create("com.intellij.library.javaSourceRootDetector"); + + protected LibrarySourceRootDetectorUtil() { + } + + /** + * This method takes a candidates for the project root, then scans the candidates and + * if multiple candidates or non root source directories are found within some + * directories, it shows a dialog that allows selecting or deselecting them. + * @param parent a parent parent or project + * @param rootCandidates a candidates for roots + * @return a array of source folders or empty array if non was selected or dialog was canceled. + */ + public static VirtualFile[] scanAndSelectDetectedJavaSourceRoots(Component parentComponent, final VirtualFile[] rootCandidates) { + final List orderRoots = RootDetectionUtil.detectRoots(Arrays.asList(rootCandidates), parentComponent, null, + new LibraryRootsDetectorImpl(Arrays.asList(Extensions.getExtensions(JAVA_SOURCE_ROOT_DETECTOR))), + new OrderRootType[] {OrderRootType.SOURCES}); + final List result = new ArrayList(); + for (OrderRoot root : orderRoots) { + result.add(root.getFile()); + } + return VfsUtil.toVirtualFileArray(result); + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/PathUIUtils.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/PathUIUtils.java index 3bcb1c45792c..27d947963e5b 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/PathUIUtils.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/PathUIUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -15,46 +15,12 @@ */ package com.intellij.openapi.roots.ui.configuration; -import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.libraries.ui.OrderRoot; import com.intellij.openapi.roots.libraries.ui.RootDetector; -import com.intellij.openapi.roots.libraries.ui.impl.LibraryRootsDetectorImpl; -import com.intellij.openapi.roots.libraries.ui.impl.RootDetectionUtil; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; - -import java.awt.*; -import java.util.*; -import java.util.List; /** - * This utility class contains utility methods for selecting paths. - * - * @author Constantine.Plotnikov + * @deprecated please use {@link LibrarySourceRootDetectorUtil} directly */ -public class PathUIUtils { - public static final RootDetector JAVA_SOURCE_ROOT_DETECTOR = new JavaSourceRootDetector(); +public class PathUIUtils extends LibrarySourceRootDetectorUtil { + public static final RootDetector JAVA_SOURCE_ROOT_DETECTOR = new LibraryJavaSourceRootDetector(); - private PathUIUtils() { - } - - /** - * This method takes a candidates for the project root, then scans the candidates and - * if multiple candidates or non root source directories are found within some - * directories, it shows a dialog that allows selecting or deselecting them. - * @param parent a parent parent or project - * @param rootCandidates a candidates for roots - * @return a array of source folders or empty array if non was selected or dialog was canceled. - */ - public static VirtualFile[] scanAndSelectDetectedJavaSourceRoots(Component parentComponent, final VirtualFile[] rootCandidates) { - final List orderRoots = RootDetectionUtil.detectRoots(Arrays.asList(rootCandidates), parentComponent, null, - new LibraryRootsDetectorImpl(Arrays.asList(Extensions.getExtensions(RootDetector.JAVA_SOURCE_ROOT_DETECTOR))), - new OrderRootType[] {OrderRootType.SOURCES}); - final List result = new ArrayList(); - for (OrderRoot root : orderRoots) { - result.add(root.getFile()); - } - return VfsUtil.toVirtualFileArray(result); - } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java index 3d7f31772362..a574f956e0ba 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java @@ -30,6 +30,7 @@ import com.intellij.openapi.roots.NativeLibraryOrderRootType; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.ui.*; import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory; +import com.intellij.openapi.roots.ui.configuration.LibrarySourceRootDetectorUtil; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -73,7 +74,7 @@ public class DefaultLibraryRootsComponentDescriptor extends LibraryRootsComponen List results = new ArrayList<>(); results.add(new FileTypeBasedRootFilter(OrderRootType.CLASSES, false, StdFileTypes.CLASS, "classes")); results.add(new FileTypeBasedRootFilter(OrderRootType.CLASSES, true, StdFileTypes.CLASS, "jar directory")); - results.addAll(Arrays.asList(Extensions.getExtensions(RootDetector.JAVA_SOURCE_ROOT_DETECTOR))); + results.addAll(Arrays.asList(Extensions.getExtensions(LibrarySourceRootDetectorUtil.JAVA_SOURCE_ROOT_DETECTOR))); Collections.addAll(results, new FileTypeBasedRootFilter(OrderRootType.SOURCES, true, StdFileTypes.JAVA, "source archive directory"), new JavadocRootDetector(), diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesOrderRootTypeUIFactory.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesOrderRootTypeUIFactory.java index 7bd294d5c4b3..8ed9e5c1efac 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesOrderRootTypeUIFactory.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/SourcesOrderRootTypeUIFactory.java @@ -23,7 +23,7 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.ui.SdkPathEditor; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory; -import com.intellij.openapi.roots.ui.configuration.PathUIUtils; +import com.intellij.openapi.roots.ui.configuration.LibrarySourceRootDetectorUtil; import com.intellij.openapi.vfs.VirtualFile; import javax.swing.*; @@ -61,7 +61,7 @@ public class SourcesOrderRootTypeUIFactory implements OrderRootTypeUIFactory { @Override protected VirtualFile[] adjustAddedFileSet(final Component component, final VirtualFile[] files) { if (mySdk.getSdkType() instanceof JavaSdkType) { - return PathUIUtils.scanAndSelectDetectedJavaSourceRoots(component, files); + return LibrarySourceRootDetectorUtil.scanAndSelectDetectedJavaSourceRoots(component, files); } return super.adjustAddedFileSet(component, files); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java index 13a18f075aa4..f8377eab6831 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java @@ -244,6 +244,16 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass { myDefaultConstructor = defaultConstructor; } + @NotNull + @Override + public String getQualifiedName() { + final PsiClass psiClass = getElement(); + if (psiClass == null) return super.getQualifiedName(); + final String qName = psiClass.getQualifiedName(); + if (qName == null) return super.getQualifiedName(); + return qName; + } + @Override public void buildReferences() { PsiClass psiClass = getElement(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java index 8c7ae863eb89..bb9aab62c8b4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java @@ -53,9 +53,13 @@ import java.util.Map; import java.util.Set; public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor { - private final DaemonCodeAnalyzerSettings myDaemonSettings; - private final EditorColorsManager myColorsManager; + protected final DaemonCodeAnalyzerSettings myDaemonSettings; + protected final EditorColorsManager myColorsManager; private final Option myLambdaOption = new Option("java.lambda", "Lambda", AllIcons.Gutter.ImplementingFunctionalInterface); + private final Option myOverriddenOption = new Option("java.overridden", "Overridden method", AllIcons.Gutter.OverridenMethod); + private final Option myImplementedOption = new Option("java.implemented", "Implemented method", AllIcons.Gutter.ImplementedMethod); + private final Option myOverridingOption = new Option("java.overriding", "Overriding method", AllIcons.Gutter.OverridingMethod); + private final Option myImplementingOption = new Option("java.implementing", "Implementing method", AllIcons.Gutter.ImplementingMethod); public JavaLineMarkerProvider(DaemonCodeAnalyzerSettings daemonSettings, EditorColorsManager colorsManager) { myDaemonSettings = daemonSettings; @@ -67,20 +71,29 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor { public LineMarkerInfo getLineMarkerInfo(@NotNull final PsiElement element) { PsiElement parent; if (element instanceof PsiIdentifier && (parent = element.getParent()) instanceof PsiMethod) { + if (!myOverridingOption.isEnabled() && !myImplementingOption.isEnabled()) return null; PsiMethod method = (PsiMethod)parent; MethodSignatureBackedByPsiMethod superSignature = SuperMethodsSearch.search(method, null, true, false).findFirst(); if (superSignature != null) { boolean overrides = method.hasModifierProperty(PsiModifier.ABSTRACT) == superSignature.getMethod().hasModifierProperty(PsiModifier.ABSTRACT); - final Icon icon = overrides ? AllIcons.Gutter.OverridingMethod : AllIcons.Gutter.ImplementingMethod; + final Icon icon; + if (overrides) { + if (!myOverridingOption.isEnabled()) return null; + icon = AllIcons.Gutter.OverridingMethod; + } + else { + if (!myImplementingOption.isEnabled()) return null; + icon = AllIcons.Gutter.ImplementingMethod; + } return createSuperMethodLineMarkerInfo(element, icon, Pass.UPDATE_ALL); } } final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element); final PsiElement firstChild = element.getFirstChild(); - if (interfaceMethod != null && firstChild != null && LineMarkerSettings.getSettings().isEnabled(myLambdaOption)) { + if (interfaceMethod != null && firstChild != null && myLambdaOption.isEnabled()) { return createSuperMethodLineMarkerInfo(firstChild, AllIcons.Gutter.ImplementingFunctionalInterface, Pass.UPDATE_ALL); } @@ -216,7 +229,7 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor { return range; } - public static void collectInheritingClasses(@NotNull PsiClass aClass, + protected void collectInheritingClasses(@NotNull PsiClass aClass, @NotNull Collection result, @NotNull Map subClassCache) { if (aClass.hasModifierProperty(PsiModifier.FINAL)) { @@ -226,7 +239,15 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor { PsiClass subClass = subClassCache.get(aClass); if (subClass != null || FunctionalExpressionSearch.search(aClass).findFirst() != null) { - final Icon icon = aClass.isInterface() ? AllIcons.Gutter.ImplementedMethod : AllIcons.Gutter.OverridenMethod; + final Icon icon; + if (aClass.isInterface()) { + if (!myImplementedOption.isEnabled()) return; + icon = AllIcons.Gutter.ImplementedMethod; + } + else { + if (!myOverriddenOption.isEnabled()) return; + icon = AllIcons.Gutter.OverridenMethod; + } PsiElement range = aClass.getNameIdentifier(); if (range == null) { range = aClass; @@ -241,7 +262,8 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor { } } - private static void collectOverridingMethods(@NotNull final Collection methods, @NotNull Collection result) { + private void collectOverridingMethods(@NotNull final Collection methods, @NotNull Collection result) { + if (!myOverriddenOption.isEnabled() && !myImplementedOption.isEnabled()) return; final Set overridden = new HashSet(); Set classes = new THashSet(); for (PsiMethod method : methods) { @@ -281,7 +303,12 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor { for (PsiMethod method : overridden) { ProgressManager.checkCanceled(); boolean overrides = !method.hasModifierProperty(PsiModifier.ABSTRACT); - + if (overrides) { + if (!myOverriddenOption.isEnabled()) return; + } + else { + if (!myImplementedOption.isEnabled()) return; + } PsiElement range = getMethodRange(method); final MarkerType type = MarkerType.OVERRIDDEN_METHOD; final Icon icon = overrides ? AllIcons.Gutter.OverridenMethod : AllIcons.Gutter.ImplementedMethod; @@ -301,7 +328,7 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor { @Override public Option[] getOptions() { - return new Option[] {myLambdaOption}; + return new Option[] {myLambdaOption, myOverriddenOption, myImplementedOption, myOverridingOption, myImplementingOption}; } private static class ArrowUpLineMarkerInfo extends MergeableLineMarkerInfo { diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java index 6ede7a3b710d..542119679ec6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -16,8 +16,12 @@ package com.intellij.codeInsight.intention.impl; import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.CodeInsightUtilCore; import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.codeInsight.template.*; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -29,12 +33,16 @@ import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.introduceVariable.IntroduceVariableBase; +import com.intellij.refactoring.ui.TypeSelectorManagerImpl; +import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.Processor; +import com.intellij.util.ObjectUtils; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import java.util.List; +import java.util.stream.Stream; public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { @Override @@ -42,16 +50,20 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) return false; if (!PsiUtil.getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_7)) return false; - final PsiLocalVariable variable = PsiTreeUtil.getParentOfType(element, PsiLocalVariable.class); - if (variable == null) return false; - final PsiExpression initializer = variable.getInitializer(); - if (initializer == null) return false; - final PsiElement declaration = variable.getParent(); - if (!(declaration instanceof PsiDeclarationStatement)) return false; - final PsiElement codeBlock = declaration.getParent(); - if (!(codeBlock instanceof PsiCodeBlock)) return false; + PsiType type = null; - return InheritanceUtil.isInheritor(variable.getType(), CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE); + PsiLocalVariable variable = findVariable(element); + if (variable != null) { + type = variable.getType(); + } + else { + PsiExpression expression = findExpression(element); + if (expression != null) { + type = expression.getType(); + } + } + + return type != null && InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE); } @Override @@ -60,35 +72,85 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { return; } - final PsiLocalVariable variable = PsiTreeUtil.getParentOfType(element, PsiLocalVariable.class); - if (variable == null) return; - final PsiExpression initializer = variable.getInitializer(); - if (initializer == null) return; - final PsiElement declaration = variable.getParent(); - if (!(declaration instanceof PsiDeclarationStatement)) return; - final PsiElement codeBlock = declaration.getParent(); - if (!(codeBlock instanceof PsiCodeBlock)) return; + PsiLocalVariable variable = findVariable(element); + if (variable != null) { + processVariable(project, editor, variable); + } + else { + PsiExpression expression = findExpression(element); + if (expression != null) { + processExpression(project, editor, expression); + } + } + } - final LocalSearchScope scope = new LocalSearchScope(codeBlock); + private static PsiLocalVariable findVariable(PsiElement element) { + PsiLocalVariable variable = PsiTreeUtil.getParentOfType(element, PsiLocalVariable.class); + + if (variable != null && + variable.getInitializer() != null && + variable.getParent() instanceof PsiDeclarationStatement && + variable.getParent().getParent() instanceof PsiCodeBlock) { + return variable; + } + + if (variable == null && element instanceof PsiWhiteSpace) { + PsiElement sibling = element.getPrevSibling(); + if (sibling instanceof PsiDeclarationStatement) { + PsiElement lastVar = ArrayUtil.getLastElement(((PsiDeclarationStatement)sibling).getDeclaredElements()); + if (lastVar instanceof PsiLocalVariable) { + return (PsiLocalVariable)lastVar; + } + } + } + + return null; + } + + private static PsiExpression findExpression(PsiElement element) { + PsiExpression expression = PsiTreeUtil.getParentOfType(element, PsiExpression.class); + + if (expression != null && + expression.getParent() instanceof PsiExpressionStatement && + expression.getParent().getParent() instanceof PsiCodeBlock) { + return expression; + } + + if (expression == null && element instanceof PsiWhiteSpace) { + PsiElement sibling = element.getPrevSibling(); + if (sibling instanceof PsiExpressionStatement) { + return ((PsiExpressionStatement)sibling).getExpression(); + } + } + + return null; + } + + private static void processVariable(Project project, Editor editor, PsiLocalVariable variable) { + PsiExpression initializer = ObjectUtils.assertNotNull(variable.getInitializer()); + PsiElement declaration = variable.getParent(); + PsiElement codeBlock = declaration.getParent(); + + LocalSearchScope scope = new LocalSearchScope(codeBlock); PsiElement last = null; for (PsiReference reference : ReferencesSearch.search(variable, scope).findAll()) { - final PsiElement usage = PsiTreeUtil.findPrevParent(codeBlock, reference.getElement()); + PsiElement usage = PsiTreeUtil.findPrevParent(codeBlock, reference.getElement()); if ((last == null || usage.getTextOffset() > last.getTextOffset())) { last = usage; } } - final String text = "try (" + variable.getTypeElement().getText() + " " + variable.getName() + " = " + initializer.getText() + ") {}"; - final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); - final PsiTryStatement armStatement = (PsiTryStatement)declaration.replace(factory.createStatementFromText(text, codeBlock)); + String text = "try (" + variable.getTypeElement().getText() + " " + variable.getName() + " = " + initializer.getText() + ") {}"; + PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + PsiTryStatement armStatement = (PsiTryStatement)declaration.replace(factory.createStatementFromText(text, codeBlock)); List toFormat = null; if (last != null) { toFormat = moveStatements(last, armStatement); } - final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); - final PsiElement formattedElement = codeStyleManager.reformat(armStatement); + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); + PsiElement formattedElement = codeStyleManager.reformat(armStatement); if (toFormat != null) { for (PsiElement psiElement : toFormat) { codeStyleManager.reformat(psiElement); @@ -96,9 +158,9 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { } if (last == null) { - final PsiCodeBlock tryBlock = ((PsiTryStatement)formattedElement).getTryBlock(); + PsiCodeBlock tryBlock = ((PsiTryStatement)formattedElement).getTryBlock(); if (tryBlock != null) { - final PsiJavaToken brace = tryBlock.getLBrace(); + PsiJavaToken brace = tryBlock.getLBrace(); if (brace != null) { editor.getCaretModel().moveToOffset(brace.getTextOffset() + 1); } @@ -110,8 +172,9 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { PsiCodeBlock tryBlock = statement.getTryBlock(); assert tryBlock != null : statement.getText(); PsiElement parent = statement.getParent(); + LocalSearchScope scope = new LocalSearchScope(parent); - List toFormat = new SmartList(); + List toFormat = new SmartList<>(); PsiElement stopAt = last.getNextSibling(); PsiElement i = statement.getNextSibling(); @@ -125,13 +188,8 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { for (PsiElement declared : ((PsiDeclarationStatement)child).getDeclaredElements()) { if (!(declared instanceof PsiLocalVariable)) continue; - final int endOffset = last.getTextRange().getEndOffset(); - boolean contained = ReferencesSearch.search(declared, new LocalSearchScope(parent)).forEach(new Processor() { - @Override - public boolean process(PsiReference ref) { - return ref.getElement().getTextOffset() <= endOffset; - } - }); + int endOffset = last.getTextRange().getEndOffset(); + boolean contained = ReferencesSearch.search(declared, scope).forEach(ref -> ref.getElement().getTextOffset() <= endOffset); if (!contained) { PsiLocalVariable var = (PsiLocalVariable)declared; @@ -163,6 +221,38 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { return toFormat; } + private static void processExpression(Project project, Editor editor, PsiExpression expression) { + PsiType type = ObjectUtils.assertNotNull(expression.getType()); + PsiElement statement = expression.getParent(); + PsiElement codeBlock = statement.getParent(); + + String text = "try (" + type.getCanonicalText(true) + " r = " + expression.getText() + ") {}"; + PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + PsiTryStatement tryStatement = (PsiTryStatement)statement.replace(factory.createStatementFromText(text, codeBlock)); + + tryStatement = (PsiTryStatement)CodeStyleManager.getInstance(project).reformat(tryStatement); + + tryStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(tryStatement); + + PsiResourceList resourceList = tryStatement.getResourceList(); + if (resourceList != null) { + PsiResourceVariable var = (PsiResourceVariable)resourceList.iterator().next(); + PsiIdentifier id = var.getNameIdentifier(); + PsiExpression initializer = var.getInitializer(); + if (id != null && initializer != null) { + type = initializer.getType(); + String[] names = IntroduceVariableBase.getSuggestedName(type, initializer).names; + PsiType[] types = Stream.of(new TypeSelectorManagerImpl(project, type, initializer, PsiExpression.EMPTY_ARRAY).getTypesForAll()) + .filter(t -> InheritanceUtil.isInheritor(t, CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE)) + .toArray(PsiType[]::new); + TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(var); + builder.replaceElement(id, new NamesExpression(names)); + builder.replaceElement(var.getTypeElement(), new TypeExpression(project, types)); + builder.run(editor, true); + } + } + } + @NotNull @Override public String getFamilyName() { @@ -174,4 +264,27 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { public String getText() { return getFamilyName(); } -} + + private static class NamesExpression extends Expression { + private final String[] myNames; + + public NamesExpression(String[] names) { + myNames = names; + } + + @Override + public Result calculateResult(ExpressionContext context) { + return calculateQuickResult(context); + } + + @Override + public Result calculateQuickResult(ExpressionContext context) { + return new TextResult(myNames[0]); + } + + @Override + public LookupElement[] calculateLookupItems(ExpressionContext context) { + return Stream.of(myNames).map(LookupElementBuilder::create).toArray(LookupElement[]::new); + } + } +} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index 570d4d57f563..0368e04bfa49 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -1728,6 +1728,22 @@ public class ExtractMethodProcessor implements MatchProvider { myExtractedMethod = suggester.getExtractedMethod(); myMethodCall = suggester.getMethodCall(); myVariableDatum = suggester.getVariableData(); + + final List outputVariables = new ArrayList<>(); + for (PsiReturnStatement statement : PsiUtil.findReturnStatements(myExtractedMethod)) { + final PsiExpression returnValue = statement.getReturnValue(); + if (returnValue instanceof PsiReferenceExpression) { + final PsiElement resolve = ((PsiReferenceExpression)returnValue).resolve(); + if (resolve instanceof PsiLocalVariable) { + outputVariables.add((PsiVariable)resolve); + } + } + } + + if (outputVariables.size() == 1) { + myOutputVariable = outputVariables.get(0); + } + return null; } } diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java index ceac680e7c47..0748b6f83351 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java @@ -334,6 +334,12 @@ public class ExtractMethodSignatureSuggester { for (PsiParameter parameter : parameters) { uniqueNameGenerator.addExistingName(parameter.getName()); } + + SyntaxTraverser.psiTraverser().withRoot(myExtractedMethod.getBody()) + .filter(element -> element instanceof PsiVariable) + .forEach(element -> uniqueNameGenerator.addExistingName(((PsiVariable)element).getName())); + + final THashMap unique = new THashMap(ourEquivalenceStrategy); final Map replacement = new HashMap(); for (PsiExpression expr : exprs) { diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java index b7bd9384442a..1dcf6ba48d2d 100644 --- a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java @@ -256,6 +256,27 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase { return null; } + @Override + public Collection findConflicts(PsiElement element, PsiElement[] elements, UsageInfo[] usages) { + String methodRefFound = null; + if (!ApplicationManager.getApplication().isUnitTestMode() && (element instanceof PsiMethod || element instanceof PsiParameter)) { + for (UsageInfo usage : usages) { + final PsiElement refElement = usage.getElement(); + if (refElement instanceof PsiMethodReferenceExpression) { + methodRefFound = RefactoringBundle.message("expand.method.reference.warning"); + break; + } + } + } + if (methodRefFound != null) { + Collection result = new ArrayList<>(); + result.add(methodRefFound); + result.addAll(super.findConflicts(element, elements, usages)); + return result; + } + return super.findConflicts(element, elements, usages); + } + public Collection findConflicts(@NotNull final PsiElement element, @NotNull final PsiElement[] allElementsToDelete) { if (element instanceof PsiMethod) { final PsiClass containingClass = ((PsiMethod)element).getContainingClass(); 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 e6b846f33644..3aa98a200e69 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -17,6 +17,8 @@ package com.intellij.psi; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.RecursionGuard; +import com.intellij.openapi.util.RecursionManager; import com.intellij.openapi.util.registry.Registry; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.infos.MethodCandidateInfo; @@ -35,6 +37,7 @@ import java.util.*; * Date: 7/17/12 */ public class LambdaUtil { + public static final RecursionGuard ourParameterGuard = RecursionManager.createGuard("lambdaParameterGuard"); public static ThreadLocal> ourFunctionTypes = new ThreadLocal>(); private static final Logger LOG = Logger.getInstance("#" + LambdaUtil.class.getName()); @@ -667,6 +670,10 @@ public class LambdaUtil { return null; } + public static boolean isLambdaParameterCheck() { + return !ourParameterGuard.currentStack().isEmpty(); + } + public static class TypeParamsChecker extends PsiTypeVisitor { private PsiMethod myMethod; private final PsiClass myClass; diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java index 5a896d6d1245..2d1ef7b4f8cd 100644 --- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java +++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java @@ -294,7 +294,9 @@ public class MethodCandidateInfo extends CandidateInfo{ if (!stackStamp.mayCacheNow() || isOverloadCheck() || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) || - getMarkerList() != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(getMarkerList().getParent())) { + getMarkerList() != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(getMarkerList().getParent()) || + LambdaUtil.isLambdaParameterCheck() + ) { return inferredSubstitutor; } diff --git a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java index 470b48033987..346465171177 100644 --- a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java @@ -435,7 +435,7 @@ public class PsiDiamondTypeImpl extends PsiDiamondType { public PsiType[] getArgumentTypes() { if (myExpressionTypes == null) { final PsiType[] expressionTypes = argumentList.getExpressionTypes(); - if (MethodCandidateInfo.isOverloadCheck()) { + if (MethodCandidateInfo.isOverloadCheck() || LambdaUtil.isLambdaParameterCheck()) { return expressionTypes; } myExpressionTypes = expressionTypes; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java index 08018fa46594..ee6c93bb41e0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java @@ -19,6 +19,7 @@ import com.intellij.lang.ASTNode; import com.intellij.navigation.ItemPresentation; import com.intellij.navigation.ItemPresentationProviders; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Computable; import com.intellij.psi.*; import com.intellij.psi.impl.CheckUtil; import com.intellij.psi.impl.ElementPresentationUtil; @@ -67,8 +68,14 @@ public class PsiParameterImpl extends JavaStubPsiElement imple if (parameterIndex > -1) { final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(param, PsiLambdaExpression.class); if (lambdaExpression != null) { - - PsiType type = FunctionalInterfaceParameterizationUtil.getGroundTargetType(LambdaUtil.getFunctionalInterfaceType(lambdaExpression, true), lambdaExpression); + final PsiType functionalInterfaceType = LambdaUtil.ourParameterGuard.doPreventingRecursion(param, false, + new Computable() { + @Override + public PsiType compute() { + return LambdaUtil.getFunctionalInterfaceType(lambdaExpression, true); + } + }); + PsiType type = FunctionalInterfaceParameterizationUtil.getGroundTargetType(functionalInterfaceType, lambdaExpression); if (type instanceof PsiIntersectionType) { final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts(); for (PsiType conjunct : conjuncts) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java index 003b8e9a96b2..e521f36e145d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java @@ -90,7 +90,7 @@ public class JavaResolveCache { } //cache standalone expression types as they do not depend on the context - final boolean isOverloadCheck = MethodCandidateInfo.isOverloadCheck(); + final boolean isOverloadCheck = MethodCandidateInfo.isOverloadCheck() || LambdaUtil.isLambdaParameterCheck(); if (isOverloadCheck && PsiPolyExpressionUtil.isPolyExpression(expr)) { return type; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index da0367913aa1..ad9b5f50f0f2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -361,11 +361,13 @@ public class InferenceSession { if (parameters != null && args != null && !isOverloadCheck()) { final Set additionalConstraints = new LinkedHashSet(); + final HashSet ignoredConstraints = new HashSet(); if (parameters.length > 0) { - collectAdditionalConstraints(parameters, args, properties.getMethod(), mySiteSubstitutor, additionalConstraints, properties.isVarargs(), initialSubstitutor); + collectAdditionalConstraints(parameters, args, properties.getMethod(), mySiteSubstitutor, additionalConstraints, + ignoredConstraints, properties.isVarargs(), initialSubstitutor); } - if (!additionalConstraints.isEmpty() && !proceedWithAdditionalConstraints(additionalConstraints)) { + if (!additionalConstraints.isEmpty() && !proceedWithAdditionalConstraints(additionalConstraints, ignoredConstraints)) { return; } } @@ -416,21 +418,29 @@ public class InferenceSession { PsiMethod parentMethod, PsiSubstitutor siteSubstitutor, Set additionalConstraints, + Set ignoredConstraints, boolean varargs, PsiSubstitutor initialSubstitutor) { for (int i = 0; i < args.length; i++) { final PsiExpression arg = PsiUtil.skipParenthesizedExprDown(args[i]); if (arg != null) { - if (MethodCandidateInfo.isOverloadCheck() && arg instanceof PsiLambdaExpression) { - for (Object expr : MethodCandidateInfo.ourOverloadGuard.currentStack()) { - if (PsiTreeUtil.getParentOfType((PsiElement)expr, PsiLambdaExpression.class) == arg) { - return; - } - } - } final PsiSubstitutor nestedSubstitutor = myInferenceSessionContainer.findNestedSubstitutor(arg, myInferenceSubstitution); final PsiType parameterType = nestedSubstitutor.substitute(getParameterType(parameters, i, siteSubstitutor, varargs)); if (!isPertinentToApplicability(arg, parentMethod)) { + if (arg instanceof PsiLambdaExpression) { + for (Object expr : MethodCandidateInfo.ourOverloadGuard.currentStack()) { + if (PsiTreeUtil.getParentOfType((PsiElement)expr, PsiLambdaExpression.class) == arg) { + return; + } + } + + for (Object expr : LambdaUtil.ourParameterGuard.currentStack()) { + if (expr instanceof PsiParameter && ((PsiParameter)expr).getDeclarationScope() == arg) { + ignoredConstraints.add(new ExpressionCompatibilityConstraint(arg, parameterType)); + return; + } + } + } additionalConstraints.add(new ExpressionCompatibilityConstraint(arg, parameterType)); } additionalConstraints.add(new CheckedExceptionCompatibilityConstraint(arg, parameterType)); @@ -439,12 +449,12 @@ public class InferenceSession { //the set contains all constraint formulas that would appear in the set C when determining the poly expression's invocation type. final PsiMethod calledMethod = getCalledMethod((PsiCall)arg); if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(arg, calledMethod)) { - collectAdditionalConstraints(additionalConstraints, (PsiCall)arg, initialSubstitutor); + collectAdditionalConstraints(additionalConstraints, ignoredConstraints, (PsiCall)arg, initialSubstitutor); } } else if (arg instanceof PsiLambdaExpression && isPertinentToApplicability(arg, parentMethod)) { - collectLambdaReturnExpression(additionalConstraints, (PsiLambdaExpression)arg, parameterType, + collectLambdaReturnExpression(additionalConstraints, ignoredConstraints, (PsiLambdaExpression)arg, parameterType, !isProperType(initialSubstitutor.substitute(parameterType)), initialSubstitutor); } @@ -472,19 +482,22 @@ public class InferenceSession { } private void collectLambdaReturnExpression(Set additionalConstraints, + Set ignoredConstraints, PsiLambdaExpression lambdaExpression, PsiType parameterType, - boolean addConstraint, PsiSubstitutor initialSubstitutor) { + boolean addConstraint, + PsiSubstitutor initialSubstitutor) { final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(parameterType); if (interfaceReturnType != null) { final List returnExpressions = LambdaUtil.getReturnExpressions(lambdaExpression); for (PsiExpression returnExpression : returnExpressions) { - processReturnExpression(additionalConstraints, returnExpression, interfaceReturnType, addConstraint, initialSubstitutor); + processReturnExpression(additionalConstraints, ignoredConstraints, returnExpression, interfaceReturnType, addConstraint, initialSubstitutor); } } } private void processReturnExpression(Set additionalConstraints, + Set ignoredConstraints, PsiExpression returnExpression, PsiType functionalType, boolean addConstraint, @@ -493,7 +506,7 @@ public class InferenceSession { if (addConstraint) { final PsiMethod calledMethod = getCalledMethod((PsiCallExpression)returnExpression); if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(returnExpression, calledMethod)) { - collectAdditionalConstraints(additionalConstraints, (PsiCallExpression)returnExpression, initialSubstitutor); + collectAdditionalConstraints(additionalConstraints, ignoredConstraints, (PsiCallExpression)returnExpression, initialSubstitutor); } } else { @@ -501,19 +514,20 @@ public class InferenceSession { } } else if (returnExpression instanceof PsiParenthesizedExpression) { - processReturnExpression(additionalConstraints, ((PsiParenthesizedExpression)returnExpression).getExpression(), functionalType, addConstraint, initialSubstitutor); + processReturnExpression(additionalConstraints, ignoredConstraints, ((PsiParenthesizedExpression)returnExpression).getExpression(), functionalType, addConstraint, initialSubstitutor); } else if (returnExpression instanceof PsiConditionalExpression) { - processReturnExpression(additionalConstraints, ((PsiConditionalExpression)returnExpression).getThenExpression(), functionalType, addConstraint, initialSubstitutor); - processReturnExpression(additionalConstraints, ((PsiConditionalExpression)returnExpression).getElseExpression(), functionalType, addConstraint, initialSubstitutor); + processReturnExpression(additionalConstraints, ignoredConstraints, ((PsiConditionalExpression)returnExpression).getThenExpression(), functionalType, addConstraint, initialSubstitutor); + processReturnExpression(additionalConstraints, ignoredConstraints, ((PsiConditionalExpression)returnExpression).getElseExpression(), functionalType, addConstraint, initialSubstitutor); } else if (returnExpression instanceof PsiLambdaExpression) { - collectLambdaReturnExpression(additionalConstraints, (PsiLambdaExpression)returnExpression, functionalType, myErased, initialSubstitutor); + collectLambdaReturnExpression(additionalConstraints, ignoredConstraints, (PsiLambdaExpression)returnExpression, functionalType, myErased, initialSubstitutor); } } private void collectAdditionalConstraints(final Set additionalConstraints, - final PsiCall callExpression, + final Set ignoredConstraints, + final PsiCall callExpression, PsiSubstitutor initialSubstitutor) { PsiExpressionList argumentList = callExpression.getArgumentList(); if (argumentList != null) { @@ -524,7 +538,8 @@ public class InferenceSession { final PsiExpression[] newArgs = argumentList.getExpressions(); final PsiParameter[] newParams = method.getParameterList().getParameters(); if (newParams.length > 0) { - collectAdditionalConstraints(newParams, newArgs, method, chooseSiteSubstitutor(properties, result, method), additionalConstraints, chooseVarargsMode(properties, result), initialSubstitutor); + collectAdditionalConstraints(newParams, newArgs, method, chooseSiteSubstitutor(properties, result, method), additionalConstraints, + ignoredConstraints, chooseVarargsMode(properties, result), initialSubstitutor); } } } @@ -1290,7 +1305,7 @@ public class InferenceSession { } } - private boolean proceedWithAdditionalConstraints(Set additionalConstraints) { + private boolean proceedWithAdditionalConstraints(Set additionalConstraints, Set ignoredConstraints) { //empty substitutor should be used to resolve input variables: //all types in additional constraints are already substituted during collecting phase, //recursive site substitutors (T -> List) would make additional constraints work with multiple times substituted types, which is incorrect. @@ -1300,7 +1315,7 @@ public class InferenceSession { while (!additionalConstraints.isEmpty()) { //extract subset of constraints - final Set subset = buildSubset(additionalConstraints); + final Set subset = buildSubset(additionalConstraints, ignoredConstraints); //collect all input variables of selection final Set varsToResolve = new LinkedHashSet(); @@ -1312,7 +1327,7 @@ public class InferenceSession { final PsiSubstitutor substitutor = resolveSubsetOrdered(varsToResolve, siteSubstitutor); for (ConstraintFormula formula : subset) { - if (!processOneConstraint(formula, additionalConstraints, substitutor)) return false; + if (!processOneConstraint(formula, additionalConstraints, substitutor, ignoredConstraints)) return false; } } return true; @@ -1329,8 +1344,9 @@ public class InferenceSession { } private boolean processOneConstraint(ConstraintFormula formula, - Set additionalConstraints, - PsiSubstitutor substitutor) { + Set additionalConstraints, + PsiSubstitutor substitutor, + Set ignoredConstraints) { if (myContext instanceof PsiCall) { PsiExpressionList argumentList = ((PsiCall)myContext).getArgumentList(); @@ -1348,27 +1364,20 @@ public class InferenceSession { if (formula instanceof ExpressionCompatibilityConstraint) { PsiExpression expression = ((ExpressionCompatibilityConstraint)formula).getExpression(); if (expression instanceof PsiLambdaExpression) { - PsiType parameterType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(((ExpressionCompatibilityConstraint)formula).getT(), - (PsiLambdaExpression)expression); - collectLambdaReturnExpression(additionalConstraints, (PsiLambdaExpression)expression, parameterType, !isProperType(parameterType), substitutor); + PsiType parameterType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(((ExpressionCompatibilityConstraint)formula).getT(), (PsiLambdaExpression)expression); + collectLambdaReturnExpression(additionalConstraints, ignoredConstraints, (PsiLambdaExpression)expression, parameterType, !isProperType(parameterType), substitutor); } } return true; } - private Set buildSubset(final Set additionalConstraints) { + private Set buildSubset(final Set additionalConstraints, + final Set ignoredConstraints) { + + final Set outputVariables = getOutputVariables(additionalConstraints); + final Set ignoredOutputVariables = getOutputVariables(ignoredConstraints); Set subset = new LinkedHashSet(); - final Set outputVariables = new HashSet(); - for (ConstraintFormula constraint : additionalConstraints) { - if (constraint instanceof InputOutputConstraintFormula) { - final Set inputVariables = ((InputOutputConstraintFormula)constraint).getInputVariables(this); - final Set outputVars = ((InputOutputConstraintFormula)constraint).getOutputVariables(inputVariables, this); - if (outputVars != null) { - outputVariables.addAll(outputVars); - } - } - } Set noInputVariables = new LinkedHashSet(); for (ConstraintFormula constraint : additionalConstraints) { @@ -1382,11 +1391,13 @@ public class InferenceSession { final Set dependencies = inputVariable.getDependencies(this); dependencies.add(inputVariable); if (!hasCapture(inputVariable)) { - for (InferenceVariable outputVariable : outputVariables) { - if (ContainerUtil.intersects(outputVariable.getDependencies(this), dependencies)) { - dependsOnOutput = true; - break; - } + if (dependsOnOutput(ignoredOutputVariables, dependencies)) { + dependsOnOutput = true; + ignoredConstraints.add(constraint); + break; + } + else { + dependsOnOutput = dependsOnOutput(outputVariables, dependencies); } } @@ -1414,7 +1425,10 @@ public class InferenceSession { } } if (subset.isEmpty()) { - subset.add(additionalConstraints.iterator().next()); //todo choose one constraint + additionalConstraints.removeAll(ignoredConstraints); + if (!additionalConstraints.isEmpty()) { + subset.add(additionalConstraints.iterator().next()); //todo choose one constraint + } } if (!noInputVariables.isEmpty()) { @@ -1425,6 +1439,30 @@ public class InferenceSession { return subset; } + private boolean dependsOnOutput(Set outputVariables, Set dependencies) { + for (InferenceVariable outputVariable : outputVariables) { + if (ContainerUtil.intersects(outputVariable.getDependencies(this), dependencies)) { + return true; + } + } + return false; + } + + @NotNull + private Set getOutputVariables(Set constraintFormulas) { + final Set outputVariables = new HashSet(); + for (ConstraintFormula constraint : constraintFormulas) { + if (constraint instanceof InputOutputConstraintFormula) { + final Set inputVariables = ((InputOutputConstraintFormula)constraint).getInputVariables(this); + final Set outputVars = ((InputOutputConstraintFormula)constraint).getOutputVariables(inputVariables, this); + if (outputVars != null) { + outputVariables.addAll(outputVars); + } + } + } + return outputVariables; + } + public PsiSubstitutor collectApplicabilityConstraints(final PsiMethodReferenceExpression reference, final MethodCandidateInfo candidateInfo, final PsiType functionalInterfaceType) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java index 86b9e490ccde..eed5d51b7bf5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java @@ -81,7 +81,7 @@ public class InferenceSessionContainer { if (topLevelCall != null) { final InferenceSession session; - if (MethodCandidateInfo.isOverloadCheck() || !PsiDiamondType.ourDiamondGuard.currentStack().isEmpty()) { + if (MethodCandidateInfo.isOverloadCheck() || !PsiDiamondType.ourDiamondGuard.currentStack().isEmpty() || LambdaUtil.isLambdaParameterCheck()) { session = startTopLevelInference(topLevelCall); } else { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java index 94e4f6b6eb96..cae20db0f0c5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java @@ -134,9 +134,7 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm if (method != null && !method.isConstructor()) { returnType = method.getReturnType(); - if (returnType != null) { - typeParams = method.getTypeParameters(); - } + typeParams = method.getTypeParameters(); } else if (resolveResult != null) { final PsiClass psiClass = method != null ? method.getContainingClass() : (PsiClass)resolveResult.getElement(); @@ -162,7 +160,9 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm return callSession; } - callSession.registerReturnTypeConstraints(siteSubstitutor.substitute(returnType), targetType); + if (returnType != null) { + callSession.registerReturnTypeConstraints(siteSubstitutor.substitute(returnType), targetType); + } if (callSession.repeatInferencePhases()) { return callSession; } @@ -175,8 +175,8 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm session.registerIncompatibleErrorMessage(message); } } - return null; } + return null; } return session; } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index c391fdc71382..b64e4594a124 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -80,7 +80,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ myArgumentsList.getText() + "; " + "file=" + (method == null ? "" : method.getContainingFile())); } - return MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(myArgumentsList, true, new Computable() { + return MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(myArgumentsList, false, new Computable() { @Override public CandidateInfo compute() { return guardedOverloadResolution(conflicts); diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java index ab8cf74dd1b1..78b8a42dad26 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java @@ -104,7 +104,7 @@ public class MethodCandidatesProcessor extends MethodsProcessor{ public PsiType[] getArgumentTypes() { if (myExpressionTypes == null && argumentList != null) { final PsiType[] expressionTypes = getExpressionTypes(argumentList); - if (MethodCandidateInfo.isOverloadCheck()) { + if (MethodCandidateInfo.isOverloadCheck() || LambdaUtil.isLambdaParameterCheck()) { return expressionTypes; } myExpressionTypes = expressionTypes; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CacheUnresolvedMethods4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CacheUnresolvedMethods4.java new file mode 100644 index 000000000000..0691aa06a18d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CacheUnresolvedMethods4.java @@ -0,0 +1,14 @@ +import java.util.function.Function; +import java.util.stream.Stream; + +class Test { + void foo(Function f1) {} + + Stream bar(T ts) { + return null; + } + + void f(){ + foo(y -> bar(y.toString()).map(a -> a.length())); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CacheUnresolvedMethods5.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CacheUnresolvedMethods5.java new file mode 100644 index 000000000000..17a1cc1a6fb1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CacheUnresolvedMethods5.java @@ -0,0 +1,10 @@ +import java.util.Collections; +import java.util.Map; +import java.util.Optional; + +class StreamMainSimplified { + public static void main(Optional> first) { + String s1 = first.map((e) -> e.getValue()).orElse("").substring(9); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference.java index 49c813e2a878..4525426bf58e 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference.java @@ -3,8 +3,8 @@ import java.util.*; class Main { void foo(List list) { - bar(list, i -> i.intValue(), i -> i.unknown()); - bar1(list, i -> i.intValue(), i -> i.unknown()); + bar(list, i -> i.intValue(), i -> i.unknown()); + bar1(list, i -> i.intValue(), i -> i.unknown()); } R bar(List list, diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IDEA148841.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IDEA148841.java index 6b12c71ed73e..bdfe3324957b 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IDEA148841.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IDEA148841.java @@ -36,3 +36,12 @@ final class Collectors { downstream.characteristics().toArray(new Collector.Characteristics[downstream.characteristics().size()])); } } + +class SimplifiedTest { + + public static void a(Stream classifier) { + flatMapping(classifier.map(k -> new AbstractMap.SimpleEntry(k,k.toString())), Map.Entry::getKey); + } + + public static void flatMapping(Stream stream, Function downstream) {} +} diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/Expression.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/Expression.java new file mode 100644 index 000000000000..977f25de92d1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/Expression.java @@ -0,0 +1,7 @@ +import java.io.*; + +class C { + void m(File file) throws IOException { + new FileInputStream(file); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/ExpressionIncomplete.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/ExpressionIncomplete.java new file mode 100644 index 000000000000..554e8b4f07c2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/ExpressionIncomplete.java @@ -0,0 +1,7 @@ +import java.io.*; + +class C { + void m(File file) throws IOException { + new FileInputStream(file) + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/ExpressionIncomplete_after.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/ExpressionIncomplete_after.java new file mode 100644 index 000000000000..cca3b0a3b6a1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/ExpressionIncomplete_after.java @@ -0,0 +1,8 @@ +import java.io.*; + +class C { + void m(File file) throws IOException { + try (FileInputStream fileInputStream = new FileInputStream(file)) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/Expression_after.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/Expression_after.java new file mode 100644 index 000000000000..cca3b0a3b6a1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/Expression_after.java @@ -0,0 +1,8 @@ +import java.io.*; + +class C { + void m(File file) throws IOException { + try (FileInputStream fileInputStream = new FileInputStream(file)) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/SimplePast.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/SimplePast.java new file mode 100644 index 000000000000..70667bd29c21 --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/SimplePast.java @@ -0,0 +1,8 @@ +import java.io.*; +import java.net.*; + +class C { + public void read(URLConnection connection) { + InputStream stream = connection.getInputStream(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/SimplePast_after.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/SimplePast_after.java new file mode 100644 index 000000000000..5e61534c9fff --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/SimplePast_after.java @@ -0,0 +1,9 @@ +import java.io.*; +import java.net.*; + +class C { + public void read(URLConnection connection) { + try (InputStream stream = connection.getInputStream()) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables.java new file mode 100644 index 000000000000..d2d648133430 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables.java @@ -0,0 +1,25 @@ + +class Test { + + private BigDecimal getRevenue() { + final String query = createNamedQuery("revenues"); + String revenues = ""; + final String revenue; + revenue = "a"; + + return revenue; + } + + public BigDecimal getExpense() { + final String query = createNamedQuery("expenses"); + String expenses = ""; + final String expense; + expense = "a"; + + return expense; + } + + private String createNamedQuery(String expenses) { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables_after.java b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables_after.java new file mode 100644 index 000000000000..2397db581d4c --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/SuggestChangeSignatureWithOutputVariables_after.java @@ -0,0 +1,29 @@ +import org.jetbrains.annotations.NotNull; + +class Test { + + private BigDecimal getRevenue() { + final String revenue = newMethod("revenues"); + + return revenue; + } + + @NotNull + private String newMethod(String revenues2) { + final String query = createNamedQuery(revenues2); + String revenues = ""; + final String revenue; + revenue = "a"; + return revenue; + } + + public BigDecimal getExpense() { + final String expense = newMethod("expenses"); + + return expense; + } + + private String createNamedQuery(String expenses) { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java index 06eed02912de..9729078a1f07 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; @@ -419,18 +420,17 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase } } - assertTrue(tooltips.contains("
" + - "identity( ) in Function cannot be applied
to() " + - - "

" + - "reason: no instance(s) of type variable(s) K, U exist so that Map<K, U> conforms to Function<U, V>" + - "")); - assertTrue(tooltips.contains( - "
" + - "identity( ) in Function cannot be applied
to() " + - "

" + - "reason: no instance(s) of type variable(s) K, U exist so that Map<K, U> conforms to Function<U, V>" + - "")); + boolean found = false; + for (String tooltip : tooltips) { + if (tooltip.contains("reason: no instance(s) of type variable(s) K, U exist so that Map<K, U> conforms to Function<U, V>")) { + found = true; + break; + } + } + + if (!found) { + fail(StringUtil.join(tooltips, ", ")); + } } private void doTest() throws Exception { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java index 5ff44e47aa19..57d8965d132e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java @@ -63,6 +63,14 @@ public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase { doTestCachedUnresolved(); } + public void testCacheUnresolvedMethods4() throws Exception { + doTestCachedUnresolved(); + } + + public void testCacheUnresolvedMethods5() throws Exception { + doTestCachedUnresolved(); + } + public void testMethodOverloadsInsideLambdaHierarchy() throws Exception { doTestAllMethodCallExpressions(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java index 5ac793868072..cb36749e1784 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -27,14 +27,17 @@ public class SurroundAutoCloseableActionTest extends LightCodeInsightFixtureTest } public void testSimple() { doTest(); } + public void testSimplePast() { doTest(); } public void testUsage() { doTest(); } public void testMixedUsages() { doTest(); } public void testLastDeclaration() { doTest(); } public void testSplitVar() { doTest(); } + public void testExpression() { doTest(); } + public void testExpressionIncomplete() { doTest(); } private void doTest() { String name = getTestName(false); String intention = CodeInsightBundle.message("intention.surround.resource.with.ARM.block"); CodeInsightTestUtil.doIntentionTest(myFixture, intention, name + ".java", name + "_after.java"); } -} +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/navigation/RunLineMarkerTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/RunLineMarkerTest.java index 11c8c6486cc7..885de50fdc49 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/navigation/RunLineMarkerTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/RunLineMarkerTest.java @@ -15,15 +15,19 @@ */ package com.intellij.codeInsight.navigation; +import com.intellij.application.options.editor.GutterIconsConfigurable; +import com.intellij.codeInsight.daemon.GutterIconDescriptor; import com.intellij.codeInsight.daemon.GutterMark; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.editor.markup.GutterIconRenderer; import com.intellij.testFramework.TestActionEvent; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import java.util.List; +import java.util.Set; /** * @author Dmitry Avdeev @@ -68,4 +72,17 @@ public class RunLineMarkerTest extends LightCodeInsightFixtureTestCase { list.get(1).update(event); assertEquals("Run 'MainTest'", event.getPresentation().getText()); } + + public void testConfigurable() throws Exception { + GutterIconsConfigurable configurable = new GutterIconsConfigurable(); + configurable.createComponent(); + List descriptors = configurable.getDescriptors(); + Set strings = ContainerUtil.map2Set(descriptors, new Function() { + @Override + public String fun(GutterIconDescriptor descriptor) { + return descriptor.getId(); + } + }); + assertEquals(descriptors.size(), strings.size()); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/SurroundWithTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/SurroundWithTemplateTest.groovy deleted file mode 100644 index e8c51544388e..000000000000 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/SurroundWithTemplateTest.groovy +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2000-2015 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.template - -import com.intellij.codeInsight.template.impl.InvokeTemplateAction -import com.intellij.codeInsight.template.impl.SurroundWithTemplateHandler -import com.intellij.openapi.actionSystem.DefaultActionGroup -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase - -class SurroundWithTemplateTest extends LightCodeInsightFixtureTestCase { - public void testSurroundWithTryWithResources() { - myFixture.configureByText "C.java", """\ - import java.io.*; - class C { - void m() { - new FileReader("/dev/null") - } - }""".stripIndent() - - invokeTemplate("TR") - - myFixture.checkResult """\ - import java.io.*; - class C { - void m() { - try (FileReader fileReader = new FileReader("/dev/null")) { - - } - - } - }""".stripIndent() - } - - private void invokeTemplate(String template) { - DefaultActionGroup group = SurroundWithTemplateHandler.createActionGroup(project, editor, file) - assertNotNull(group) - InvokeTemplateAction action = group.childActionsOrStubs.find { - it instanceof InvokeTemplateAction && (it as InvokeTemplateAction).template.key == template - } as InvokeTemplateAction - assertNotNull(action) - action.perform() - } -} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java index 27032f4532cf..650badbd68c0 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java @@ -675,6 +675,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { doDuplicatesTest(); } + public void testSuggestChangeSignatureWithOutputVariables() throws Exception { + doDuplicatesTest(); + } + public void testSuggestChangeSignatureWithChangedParameterName() throws Exception { configureByFile(BASE_PATH + getTestName(false) + ".java"); boolean success = performExtractMethod(true, true, getEditor(), getFile(), getProject(), false, null, false, "p"); diff --git a/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspManager.java b/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspManager.java index 3fb2155d4b6a..ed39d662fc97 100644 --- a/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspManager.java +++ b/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspManager.java @@ -68,6 +68,7 @@ public abstract class JspManager implements IBaseJspManager { public abstract String[] getPossibleTldUris(@NotNull Module module); + @NotNull public abstract Collection getPossibleTldFiles(@NotNull Module module); @Nullable diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java index f1d4635a8c0e..8150a1e8720f 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java @@ -25,6 +25,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.AtomicNotNullLazyValue; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.GlobalSearchScopes; +import com.intellij.psi.search.GlobalSearchScopesCore; import com.intellij.psi.search.SearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; @@ -218,7 +220,8 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool { return false; } PsiClass aClass = method.getContainingClass(); - return aClass != null && GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName()); + return aClass != null && (GuavaOptionalConversionRule.GUAVA_OPTIONAL.equals(aClass.getQualifiedName()) || + GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName())); } private PsiMethodCallExpression findGuavaMethodChain(PsiMethodCallExpression expression) { @@ -352,7 +355,6 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool { private static boolean performTypeMigration(List elements, List types) { PsiFile containingFile = null; - SearchScope typeMigrationScope = GlobalSearchScope.EMPTY_SCOPE; for (PsiElement element : elements) { final PsiFile currentContainingFile = element.getContainingFile(); if (containingFile == null) { @@ -361,13 +363,13 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool { else { LOG.assertTrue(containingFile.isEquivalentTo(currentContainingFile)); } - typeMigrationScope = typeMigrationScope.union(element.getUseScope()); } LOG.assertTrue(containingFile != null); if (!FileModificationService.getInstance().prepareFileForWrite(containingFile)) return false; try { final TypeMigrationRules rules = new TypeMigrationRules(); - rules.setBoundScope(typeMigrationScope); + rules.setBoundScope(GlobalSearchScopesCore.projectProductionScope(containingFile.getProject()) + .union(GlobalSearchScopesCore.projectTestScope(containingFile.getProject()))); TypeMigrationProcessor.runHighlightingTypeMigration(containingFile.getProject(), null, rules, diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaConversionUtil.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaConversionUtil.java index cb714ba10b9f..608ba2b4b46f 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaConversionUtil.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaConversionUtil.java @@ -98,8 +98,17 @@ public class GuavaConversionUtil { } else { final GuavaLambda lambda = GuavaLambda.findFor(evaluator.evaluateType(expression)); - return lambda == null ? expression - : addMethodReference(expression, lambda); + if (lambda == null) { + return expression; + } + else { + final PsiExpression expressionWithMethodReference = addMethodReference(expression, lambda); + if (insertTypeCase) { + return adjustLambdaContainingExpression(expressionWithMethodReference, true, targetType, evaluator); + } else { + return expressionWithMethodReference; + } + } } } if (expression instanceof PsiMethodReferenceExpression) { diff --git a/lib/asm-all.jar b/lib/asm-all.jar index a8baaebad318..74c0eeb3f466 100644 Binary files a/lib/asm-all.jar and b/lib/asm-all.jar differ diff --git a/lib/asm4-all.jar b/lib/asm4-all.jar deleted file mode 100644 index b0c7335acb3d..000000000000 Binary files a/lib/asm4-all.jar and /dev/null differ diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt index fb2139ab8933..864b4ca0440d 100644 --- a/lib/required_for_dist.txt +++ b/lib/required_for_dist.txt @@ -1,6 +1,5 @@ asm-commons.jar asm.jar -asm4-all.jar asm-all.jar automaton.jar cglib-2.2.2.jar diff --git a/lib/src/asm4-src.zip b/lib/src/asm4-src.zip deleted file mode 100644 index 5c7b737a8b15..000000000000 Binary files a/lib/src/asm4-src.zip and /dev/null differ diff --git a/lib/src/asm5-src.zip b/lib/src/asm5-src.zip index ec367a6574f5..b6ad94bd199f 100644 Binary files a/lib/src/asm5-src.zip and b/lib/src/asm5-src.zip differ diff --git a/platform/core-impl/src/com/intellij/core/MockDocumentCommitProcessor.java b/platform/core-impl/src/com/intellij/core/MockDocumentCommitProcessor.java index e308fe4872c5..aef33bbd9aef 100644 --- a/platform/core-impl/src/com/intellij/core/MockDocumentCommitProcessor.java +++ b/platform/core-impl/src/com/intellij/core/MockDocumentCommitProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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,7 +26,7 @@ import org.jetbrains.annotations.NotNull; /** * @author nik */ -class MockDocumentCommitProcessor extends DocumentCommitProcessor { +class MockDocumentCommitProcessor implements DocumentCommitProcessor { @Override public void commitSynchronously(@NotNull Document document, @NotNull Project project, @NotNull PsiFile psiFile) { } diff --git a/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java b/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java index 8efba1ca9037..e516d80eff30 100644 --- a/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java +++ b/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java @@ -26,6 +26,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Consumer; +import com.intellij.util.SystemProperties; import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.concurrency.AppScheduledExecutorService; import com.intellij.util.containers.ContainerUtil; @@ -69,8 +70,8 @@ public class PerformanceWatcher implements ApplicationComponent { private volatile ApdexData myGeneralApdex = ApdexData.EMPTY; private volatile long myLastSampling = System.currentTimeMillis(); private volatile long myLastAliveEdt = System.currentTimeMillis(); - private long myLastDumpTime = 0; - private long myFreezeStart = 0; + private long myLastDumpTime; + private long myFreezeStart; /** * If the product is unresponsive for UNRESPONSIVE_THRESHOLD_SECONDS, dump threads every UNRESPONSIVE_INTERVAL_SECONDS @@ -104,55 +105,36 @@ public class PerformanceWatcher implements ApplicationComponent { @Override public void initComponent() { - if (!shouldWatch()) return; + UNRESPONSIVE_THRESHOLD_SECONDS = SystemProperties.getIntProperty("performance.watcher.threshold", 5); + UNRESPONSIVE_INTERVAL_SECONDS = SystemProperties.getIntProperty("performance.watcher.interval", 5); - final AppScheduledExecutorService service = (AppScheduledExecutorService)AppExecutorUtil.getAppScheduledExecutorService(); - service.setNewThreadListener(new Consumer() { - private final int ourReasonableThreadPoolSize = Registry.intValue("core.pooled.threads"); + if (shouldWatch()) { + final AppScheduledExecutorService service = (AppScheduledExecutorService)AppExecutorUtil.getAppScheduledExecutorService(); + service.setNewThreadListener(new Consumer() { + private final int ourReasonableThreadPoolSize = Registry.intValue("core.pooled.threads"); - @Override - public void consume(Thread thread) { - if (service.getBackendPoolExecutorSize() > ourReasonableThreadPoolSize - && ApplicationInfoImpl.getShadowInstance().isEAP()) { - File file = dumpThreads("newPooledThread/", true); - LOG.info("Not enough pooled threads" + (file != null ? "; dumped threads into file '" + file.getPath() + "'" : "")); + @Override + public void consume(Thread thread) { + if (service.getBackendPoolExecutorSize() > ourReasonableThreadPoolSize + && ApplicationInfoImpl.getShadowInstance().isEAP()) { + File file = dumpThreads("newPooledThread/", true); + LOG.info("Not enough pooled threads" + (file != null ? "; dumped threads into file '" + file.getPath() + "'" : "")); + } } - } - }); + }); - final String threshold = System.getProperty("performance.watcher.threshold"); - if (threshold != null) { - try { - UNRESPONSIVE_THRESHOLD_SECONDS = Integer.parseInt(threshold); - } - catch (NumberFormatException e) { - // ignore - } - } - final String interval = System.getProperty("performance.watcher.interval"); - if (interval != null) { - try { - UNRESPONSIVE_INTERVAL_SECONDS = Integer.parseInt(interval); - } - catch (NumberFormatException e) { - // ignore - } - } - if (UNRESPONSIVE_THRESHOLD_SECONDS == 0 || UNRESPONSIVE_INTERVAL_SECONDS == 0) { - return; - } + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + deleteOldThreadDumps(); + } + }); - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - @Override - public void run() { - deleteOldThreadDumps(); - } - }); - - for (MemoryPoolMXBean bean : ManagementFactory.getMemoryPoolMXBeans()) { - if ("Code Cache".equals(bean.getName())) { - watchCodeCache(bean); - return; + for (MemoryPoolMXBean bean : ManagementFactory.getMemoryPoolMXBeans()) { + if ("Code Cache".equals(bean.getName())) { + watchCodeCache(bean); + break; + } } } } @@ -206,8 +188,7 @@ public class PerformanceWatcher implements ApplicationComponent { } private boolean shouldWatch() { - return !ApplicationManager.getApplication().isUnitTestMode() && - !ApplicationManager.getApplication().isHeadlessEnvironment() && + return !ApplicationManager.getApplication().isHeadlessEnvironment() && UNRESPONSIVE_INTERVAL_SECONDS != 0 && UNRESPONSIVE_THRESHOLD_SECONDS != 0; } diff --git a/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java b/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java index cec29fed579a..ed7574c87c25 100644 --- a/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java +++ b/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java @@ -30,12 +30,14 @@ import com.intellij.util.containers.DoubleArrayList; import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Set; public class AbstractProgressIndicatorBase extends UserDataHolderBase implements ProgressIndicatorStacked { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.ProgressIndicatorBase"); - private static final CoreProgressManager ourProgressManager = (CoreProgressManager)ProgressManager.getInstance(); + @Nullable private final CoreProgressManager myProgressManager = + ApplicationManager.getApplication() == null ? null : (CoreProgressManager)ProgressManager.getInstance(); private volatile String myText; private volatile double myFraction; @@ -128,7 +130,7 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements if (isCanceled() && isCancelable()) { throw new ProcessCanceledException(); } - if (ourProgressManager.sleepIfNeeded()) { + if (myProgressManager != null && myProgressManager.sleepIfNeeded()) { if (isCanceled() && isCancelable()) { throw new ProcessCanceledException(); } diff --git a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java index da698e6e94e3..a45b88b060e9 100644 --- a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java +++ b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java @@ -282,7 +282,7 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel { private void reparseFile(@NotNull final PsiFile file, @NotNull FileElement treeElement, @NotNull CharSequence newText) { PsiToDocumentSynchronizer synchronizer =((PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject)).getSynchronizer(); - TextRange changedPsiRange = DocumentCommitProcessor.getChangedPsiRange(file, treeElement, newText); + TextRange changedPsiRange = DocumentCommitThread.getChangedPsiRange(file, treeElement, newText); if (changedPsiRange == null) return; final DiffLog log = BlockSupport.getInstance(myProject).reparseRange(file, treeElement, changedPsiRange, newText, new EmptyProgressIndicator(), diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java index 8677e218969f..ca04c2cfaeb4 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java @@ -15,300 +15,17 @@ */ package com.intellij.psi.impl; -import com.intellij.lang.ASTNode; -import com.intellij.lang.FileASTNode; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; -import com.intellij.openapi.diagnostic.Attachment; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.ex.DocumentEx; -import com.intellij.openapi.progress.EmptyProgressIndicator; -import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.*; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.pom.PomManager; -import com.intellij.pom.PomModel; -import com.intellij.pom.event.PomModelEvent; -import com.intellij.pom.impl.PomTransactionBase; -import com.intellij.pom.tree.TreeAspect; -import com.intellij.pom.tree.TreeAspectEvent; -import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiLock; -import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.impl.source.PsiFileImpl; -import com.intellij.psi.impl.source.text.DiffLog; -import com.intellij.psi.impl.source.tree.FileElement; -import com.intellij.psi.impl.source.tree.ForeignLeafPsiElement; -import com.intellij.psi.impl.source.tree.TreeUtil; -import com.intellij.psi.text.BlockSupport; -import com.intellij.util.Processor; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.List; - -public abstract class DocumentCommitProcessor { - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.DocumentCommitThread"); - - public abstract void commitSynchronously(@NotNull Document document, @NotNull Project project, @NotNull PsiFile psiFile); - public abstract void commitAsynchronously(@NotNull final Project project, - @NotNull final Document document, - @NonNls @NotNull Object reason, - @NotNull ModalityState currentModalityState); - - protected static class CommitTask { - static final Key CANCEL_REASON = Key.create("CANCEL_REASON"); - @NotNull final Document document; - @NotNull final Project project; - private final int modificationSequence; // store initial document modification sequence here to check if it changed later before commit in EDT - - // when queued it's not started - // when dequeued it's started - // when failed it's canceled - @NotNull final ProgressIndicator indicator; // progress to commit this doc under. - @NotNull final Object reason; - @NotNull final ModalityState myCreationModalityState; - private final CharSequence myLastCommittedText; - @NotNull final List> myOldFileNodes; - - protected CommitTask(@NotNull final Project project, - @NotNull final Document document, - @NotNull final List> oldFileNodes, - @NotNull ProgressIndicator indicator, - @NotNull Object reason, - @NotNull ModalityState currentModalityState) { - this.document = document; - this.project = project; - this.indicator = indicator; - this.reason = reason; - myCreationModalityState = currentModalityState; - myLastCommittedText = PsiDocumentManager.getInstance(project).getLastCommittedText(document); - myOldFileNodes = oldFileNodes; - modificationSequence = ((DocumentEx)document).getModificationSequence(); - } - - @NonNls - @Override - public String toString() { - return "Doc: " + document + " (\"" + StringUtil.first(document.getImmutableCharSequence(), 40, true).toString().replaceAll("\n", " ") + "\")" - + (indicator.isCanceled() ? " (Canceled: " + ((UserDataHolder)indicator).getUserData(CANCEL_REASON) + ")":"") - +" Reason: " + reason - + (isStillValid() ? "" : "; changed: old seq="+modificationSequence+", new seq="+ ((DocumentEx)document).getModificationSequence()) - ; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof CommitTask)) return false; - - CommitTask task = (CommitTask)o; - - return document.equals(task.document) && project.equals(task.project); - } - - @Override - public int hashCode() { - int result = document.hashCode(); - result = 31 * result + project.hashCode(); - return result; - } - - public boolean isStillValid() { - return ((DocumentEx)document).getModificationSequence() == modificationSequence; - } - - public void cancel(@NotNull Object reason, @NotNull DocumentCommitProcessor commitProcessor) { - if (!indicator.isCanceled()) { - commitProcessor.log(project, "indicator cancel", this); - - indicator.cancel(); - ((UserDataHolder)indicator).putUserData(CANCEL_REASON, reason); - } - } - } - - // public for Upsource - @Nullable("returns runnable to execute under write action in AWT to finish the commit") - public Processor doCommit(@NotNull final CommitTask task, - @NotNull final PsiFile file, - @NotNull final FileASTNode oldFileNode) { - Document document = task.document; - final CharSequence newDocumentText = document.getImmutableCharSequence(); - final TextRange changedPsiRange = getChangedPsiRange(file, task.myLastCommittedText, newDocumentText); - if (changedPsiRange == null) { - return null; - } - - final Boolean data = document.getUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY); - if (data != null) { - document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, null); - file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, data); - } - - BlockSupport blockSupport = BlockSupport.getInstance(file.getProject()); - final DiffLog diffLog = blockSupport.reparseRange(file, oldFileNode, changedPsiRange, newDocumentText, task.indicator, task.myLastCommittedText); - - return new Processor() { - @Override - public boolean process(Document document) { - ApplicationManager.getApplication().assertWriteAccessAllowed(); - if (!task.isStillValid() || - ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject())).getCachedViewProvider(document) != file.getViewProvider()) { - return false; // optimistic locking failed - } - - doActualPsiChange(file, diffLog); - - assertAfterCommit(document, file, (FileElement)oldFileNode); - - return true; - } - }; - } - - private static int getLeafMatchingLength(CharSequence leafText, CharSequence pattern, int patternIndex, int finalPatternIndex, int direction) { - int leafIndex = direction == 1 ? 0 : leafText.length() - 1; - int finalLeafIndex = direction == 1 ? leafText.length() - 1 : 0; - int result = 0; - while (leafText.charAt(leafIndex) == pattern.charAt(patternIndex)) { - result++; - if (leafIndex == finalLeafIndex || patternIndex == finalPatternIndex) { - break; - } - leafIndex += direction; - patternIndex += direction; - } - return result; - } - - private static int getMatchingLength(@NotNull FileElement treeElement, @NotNull CharSequence text, boolean fromStart) { - int patternIndex = fromStart ? 0 : text.length() - 1; - int finalPatternIndex = fromStart ? text.length() - 1 : 0; - int direction = fromStart ? 1 : -1; - ASTNode leaf = fromStart ? TreeUtil.findFirstLeaf(treeElement, false) : TreeUtil.findLastLeaf(treeElement, false); - int result = 0; - while (leaf != null && (fromStart ? patternIndex <= finalPatternIndex : patternIndex >= finalPatternIndex)) { - if (!(leaf instanceof ForeignLeafPsiElement)) { - CharSequence chars = leaf.getChars(); - if (chars.length() > 0) { - int matchingLength = getLeafMatchingLength(chars, text, patternIndex, finalPatternIndex, direction); - result += matchingLength; - if (matchingLength != chars.length()) { - break; - } - patternIndex += fromStart ? matchingLength : -matchingLength; - } - } - leaf = fromStart ? TreeUtil.nextLeaf(leaf, false) : TreeUtil.prevLeaf(leaf, false); - } - return result; - } - - @Nullable - public static TextRange getChangedPsiRange(@NotNull PsiFile file, @NotNull FileElement treeElement, @NotNull CharSequence newDocumentText) { - int psiLength = treeElement.getTextLength(); - if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) { - return new TextRange(0, psiLength); - } - - int commonPrefixLength = getMatchingLength(treeElement, newDocumentText, true); - if (commonPrefixLength == newDocumentText.length() && newDocumentText.length() == psiLength) { - return null; - } - - int commonSuffixLength = Math.min(getMatchingLength(treeElement, newDocumentText, false), psiLength - commonPrefixLength); - return new TextRange(commonPrefixLength, psiLength - commonSuffixLength); - } - - @Nullable - private static TextRange getChangedPsiRange(@NotNull PsiFile file, - @NotNull CharSequence oldDocumentText, - @NotNull CharSequence newDocumentText) { - int psiLength = oldDocumentText.length(); - if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) { - return new TextRange(0, psiLength); - } - - int commonPrefixLength = StringUtil.commonPrefixLength(oldDocumentText, newDocumentText); - if (commonPrefixLength == newDocumentText.length() && newDocumentText.length() == psiLength) { - return null; - } - - int commonSuffixLength = Math.min(StringUtil.commonSuffixLength(oldDocumentText, newDocumentText), psiLength - commonPrefixLength); - return new TextRange(commonPrefixLength, psiLength - commonSuffixLength); - } - - public static void doActualPsiChange(@NotNull final PsiFile file, @NotNull final DiffLog diffLog) { - CodeStyleManager.getInstance(file.getProject()).performActionWithFormatterDisabled(new Runnable() { - @Override - public void run() { - synchronized (PsiLock.LOCK) { - file.getViewProvider().beforeContentsSynchronized(); - - final Document document = file.getViewProvider().getDocument(); - PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject()); - PsiToDocumentSynchronizer.DocumentChangeTransaction transaction = documentManager.getSynchronizer().getTransaction(document); - - final PsiFileImpl fileImpl = (PsiFileImpl)file; - - if (transaction == null) { - final PomModel model = PomManager.getModel(fileImpl.getProject()); - - model.runTransaction(new PomTransactionBase(fileImpl, model.getModelAspect(TreeAspect.class)) { - @Override - public PomModelEvent runInner() { - return new TreeAspectEvent(model, diffLog.performActualPsiChange(file)); - } - }); - } - else { - diffLog.performActualPsiChange(file); - } - } - } - }); - } - - private void assertAfterCommit(@NotNull Document document, - @NotNull final PsiFile file, - @NotNull FileElement oldFileNode) { - if (oldFileNode.getTextLength() != document.getTextLength()) { - final String documentText = document.getText(); - String fileText = file.getText(); - boolean sameText = Comparing.equal(fileText, documentText); - LOG.error("commitDocument() left PSI inconsistent: " + DebugUtil.diagnosePsiDocumentInconsistency(file, document) + - "; node.length=" + oldFileNode.getTextLength() + - "; doc.text" + (sameText ? "==" : "!=") + "file.text", - new Attachment("file psi text", fileText), - new Attachment("old text", documentText)); - - file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, Boolean.TRUE); - try { - BlockSupport blockSupport = BlockSupport.getInstance(file.getProject()); - final DiffLog diffLog = blockSupport.reparseRange(file, file.getNode(), new TextRange(0, documentText.length()), documentText, createProgressIndicator(), - oldFileNode.getText()); - doActualPsiChange(file, diffLog); - - if (oldFileNode.getTextLength() != document.getTextLength()) { - LOG.error("PSI is broken beyond repair in: " + file); - } - } - finally { - file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, null); - } - } - } - - public void log(Project project, @NonNls String msg, @Nullable CommitTask task, @NonNls Object... args) { - } - - @NotNull - protected ProgressIndicator createProgressIndicator() { - return new EmptyProgressIndicator(); - } +public interface DocumentCommitProcessor { + void commitSynchronously(@NotNull Document document, @NotNull Project project, @NotNull PsiFile psiFile); + void commitAsynchronously(@NotNull final Project project, + @NotNull final Document document, + @NonNls @NotNull Object reason, + @NotNull ModalityState currentModalityState); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java index 85cfb9c75e20..881e5a29bf49 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java @@ -16,6 +16,7 @@ package com.intellij.psi.impl; import com.intellij.diagnostic.ThreadDumper; +import com.intellij.lang.ASTNode; import com.intellij.lang.FileASTNode; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationAdapter; @@ -23,8 +24,10 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.diagnostic.Attachment; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -32,10 +35,23 @@ import com.intellij.openapi.progress.util.StandardProgressIndicatorBase; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.pom.PomManager; +import com.intellij.pom.PomModel; +import com.intellij.pom.event.PomModelEvent; +import com.intellij.pom.impl.PomTransactionBase; +import com.intellij.pom.tree.TreeAspect; +import com.intellij.pom.tree.TreeAspectEvent; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiLock; +import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.impl.source.text.DiffLog; +import com.intellij.psi.impl.source.tree.FileElement; +import com.intellij.psi.impl.source.tree.ForeignLeafPsiElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.text.BlockSupport; import com.intellij.util.ExceptionUtil; import com.intellij.util.Function; import com.intellij.util.Processor; @@ -60,7 +76,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; -public class DocumentCommitThread extends DocumentCommitProcessor implements Runnable, Disposable { +public class DocumentCommitThread implements Runnable, Disposable, DocumentCommitProcessor { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.DocumentCommitThread"); private final ExecutorService executor = new BoundedTaskExecutor(PooledThreadExecutor.INSTANCE, 1, this); @@ -74,7 +90,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run private int runningWriteActions; // accessed in EDT only public static DocumentCommitThread getInstance() { - return ServiceManager.getService(DocumentCommitThread.class); + return (DocumentCommitThread)ServiceManager.getService(DocumentCommitProcessor.class); } public DocumentCommitThread(final ApplicationEx application) { myApplication = application; @@ -158,13 +174,6 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run @NotNull final Document document, @NonNls @NotNull Object reason, @NotNull ModalityState currentModalityState) { - queueCommit(project, document, reason, currentModalityState); - } - - void queueCommit(@NotNull final Project project, - @NotNull final Document document, - @NonNls @NotNull Object reason, - @NotNull ModalityState currentModalityState) { assert !isDisposed : "already disposed"; if (!project.isInitialized()) return; @@ -213,7 +222,6 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run final StringBuilder log = new StringBuilder(); @SuppressWarnings({"NonConstantStringShouldBeStringBuffer", "StringConcatenationInLoop"}) - @Override public void log(Project project, @NonNls String msg, @Nullable CommitTask task, @NonNls Object... args) { if (true) return; @@ -486,7 +494,6 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run } @NotNull - @Override protected ProgressIndicator createProgressIndicator() { return new StandardProgressIndicatorBase(); } @@ -589,7 +596,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run } else { // add document back to the queue - queueCommit(project, document, "Re-added back", task.myCreationModalityState); + commitAsynchronously(project, document, "Re-added back", task.myCreationModalityState); } } catch (Error e) { @@ -637,4 +644,247 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run ((BoundedTaskExecutor)executor).waitAllTasksExecuted(100, TimeUnit.SECONDS); UIUtil.dispatchAllInvocationEvents(); } + + + private static class CommitTask { + static final Key CANCEL_REASON = Key.create("CANCEL_REASON"); + @NotNull final Document document; + @NotNull final Project project; + private final int modificationSequence; // store initial document modification sequence here to check if it changed later before commit in EDT + + // when queued it's not started + // when dequeued it's started + // when failed it's canceled + @NotNull final ProgressIndicator indicator; // progress to commit this doc under. + @NotNull final Object reason; + @NotNull final ModalityState myCreationModalityState; + private final CharSequence myLastCommittedText; + @NotNull final List> myOldFileNodes; + + protected CommitTask(@NotNull final Project project, + @NotNull final Document document, + @NotNull final List> oldFileNodes, + @NotNull ProgressIndicator indicator, + @NotNull Object reason, + @NotNull ModalityState currentModalityState) { + this.document = document; + this.project = project; + this.indicator = indicator; + this.reason = reason; + myCreationModalityState = currentModalityState; + myLastCommittedText = PsiDocumentManager.getInstance(project).getLastCommittedText(document); + myOldFileNodes = oldFileNodes; + modificationSequence = ((DocumentEx)document).getModificationSequence(); + } + + @NonNls + @Override + public String toString() { + return "Doc: " + document + " (\"" + StringUtil.first(document.getImmutableCharSequence(), 40, true).toString().replaceAll("\n", " ") + "\")" + + (indicator.isCanceled() ? " (Canceled: " + ((UserDataHolder)indicator).getUserData(CANCEL_REASON) + ")":"") + +" Reason: " + reason + + (isStillValid() ? "" : "; changed: old seq="+modificationSequence+", new seq="+ ((DocumentEx)document).getModificationSequence()) + ; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof CommitTask)) return false; + + CommitTask task = (CommitTask)o; + + return document.equals(task.document) && project.equals(task.project); + } + + @Override + public int hashCode() { + int result = document.hashCode(); + result = 31 * result + project.hashCode(); + return result; + } + + public boolean isStillValid() { + return ((DocumentEx)document).getModificationSequence() == modificationSequence; + } + + private void cancel(@NotNull Object reason, @NotNull DocumentCommitThread commitProcessor) { + if (!indicator.isCanceled()) { + commitProcessor.log(project, "indicator cancel", this); + + indicator.cancel(); + ((UserDataHolder)indicator).putUserData(CANCEL_REASON, reason); + } + } + } + + // public for Upsource + @Nullable("returns runnable to execute under write action in AWT to finish the commit") + public Processor doCommit(@NotNull final CommitTask task, + @NotNull final PsiFile file, + @NotNull final FileASTNode oldFileNode) { + Document document = task.document; + final CharSequence newDocumentText = document.getImmutableCharSequence(); + final TextRange changedPsiRange = getChangedPsiRange(file, task.myLastCommittedText, newDocumentText); + if (changedPsiRange == null) { + return null; + } + + final Boolean data = document.getUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY); + if (data != null) { + document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, null); + file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, data); + } + + BlockSupport blockSupport = BlockSupport.getInstance(file.getProject()); + final DiffLog diffLog = blockSupport.reparseRange(file, oldFileNode, changedPsiRange, newDocumentText, task.indicator, task.myLastCommittedText); + + return new Processor() { + @Override + public boolean process(Document document) { + ApplicationManager.getApplication().assertWriteAccessAllowed(); + if (!task.isStillValid() || + ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject())).getCachedViewProvider(document) != file.getViewProvider()) { + return false; // optimistic locking failed + } + + doActualPsiChange(file, diffLog); + + assertAfterCommit(document, file, (FileElement)oldFileNode); + + return true; + } + }; + } + + private static int getLeafMatchingLength(CharSequence leafText, CharSequence pattern, int patternIndex, int finalPatternIndex, int direction) { + int leafIndex = direction == 1 ? 0 : leafText.length() - 1; + int finalLeafIndex = direction == 1 ? leafText.length() - 1 : 0; + int result = 0; + while (leafText.charAt(leafIndex) == pattern.charAt(patternIndex)) { + result++; + if (leafIndex == finalLeafIndex || patternIndex == finalPatternIndex) { + break; + } + leafIndex += direction; + patternIndex += direction; + } + return result; + } + + private static int getMatchingLength(@NotNull FileElement treeElement, @NotNull CharSequence text, boolean fromStart) { + int patternIndex = fromStart ? 0 : text.length() - 1; + int finalPatternIndex = fromStart ? text.length() - 1 : 0; + int direction = fromStart ? 1 : -1; + ASTNode leaf = fromStart ? TreeUtil.findFirstLeaf(treeElement, false) : TreeUtil.findLastLeaf(treeElement, false); + int result = 0; + while (leaf != null && (fromStart ? patternIndex <= finalPatternIndex : patternIndex >= finalPatternIndex)) { + if (!(leaf instanceof ForeignLeafPsiElement)) { + CharSequence chars = leaf.getChars(); + if (chars.length() > 0) { + int matchingLength = getLeafMatchingLength(chars, text, patternIndex, finalPatternIndex, direction); + result += matchingLength; + if (matchingLength != chars.length()) { + break; + } + patternIndex += fromStart ? matchingLength : -matchingLength; + } + } + leaf = fromStart ? TreeUtil.nextLeaf(leaf, false) : TreeUtil.prevLeaf(leaf, false); + } + return result; + } + + @Nullable + public static TextRange getChangedPsiRange(@NotNull PsiFile file, @NotNull FileElement treeElement, @NotNull CharSequence newDocumentText) { + int psiLength = treeElement.getTextLength(); + if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) { + return new TextRange(0, psiLength); + } + + int commonPrefixLength = getMatchingLength(treeElement, newDocumentText, true); + if (commonPrefixLength == newDocumentText.length() && newDocumentText.length() == psiLength) { + return null; + } + + int commonSuffixLength = Math.min(getMatchingLength(treeElement, newDocumentText, false), psiLength - commonPrefixLength); + return new TextRange(commonPrefixLength, psiLength - commonSuffixLength); + } + + @Nullable + private static TextRange getChangedPsiRange(@NotNull PsiFile file, + @NotNull CharSequence oldDocumentText, + @NotNull CharSequence newDocumentText) { + int psiLength = oldDocumentText.length(); + if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) { + return new TextRange(0, psiLength); + } + + int commonPrefixLength = StringUtil.commonPrefixLength(oldDocumentText, newDocumentText); + if (commonPrefixLength == newDocumentText.length() && newDocumentText.length() == psiLength) { + return null; + } + + int commonSuffixLength = Math.min(StringUtil.commonSuffixLength(oldDocumentText, newDocumentText), psiLength - commonPrefixLength); + return new TextRange(commonPrefixLength, psiLength - commonSuffixLength); + } + + public static void doActualPsiChange(@NotNull final PsiFile file, @NotNull final DiffLog diffLog) { + CodeStyleManager.getInstance(file.getProject()).performActionWithFormatterDisabled(new Runnable() { + @Override + public void run() { + synchronized (PsiLock.LOCK) { + file.getViewProvider().beforeContentsSynchronized(); + + final Document document = file.getViewProvider().getDocument(); + PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject()); + PsiToDocumentSynchronizer.DocumentChangeTransaction transaction = documentManager.getSynchronizer().getTransaction(document); + + final PsiFileImpl fileImpl = (PsiFileImpl)file; + + if (transaction == null) { + final PomModel model = PomManager.getModel(fileImpl.getProject()); + + model.runTransaction(new PomTransactionBase(fileImpl, model.getModelAspect(TreeAspect.class)) { + @Override + public PomModelEvent runInner() { + return new TreeAspectEvent(model, diffLog.performActualPsiChange(file)); + } + }); + } + else { + diffLog.performActualPsiChange(file); + } + } + } + }); + } + + private void assertAfterCommit(@NotNull Document document, @NotNull final PsiFile file, @NotNull FileElement oldFileNode) { + if (oldFileNode.getTextLength() != document.getTextLength()) { + final String documentText = document.getText(); + String fileText = file.getText(); + boolean sameText = Comparing.equal(fileText, documentText); + LOG.error("commitDocument() left PSI inconsistent: " + DebugUtil.diagnosePsiDocumentInconsistency(file, document) + + "; node.length=" + oldFileNode.getTextLength() + + "; doc.text" + (sameText ? "==" : "!=") + "file.text", + new Attachment("file psi text", fileText), + new Attachment("old text", documentText)); + + file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, Boolean.TRUE); + try { + BlockSupport blockSupport = BlockSupport.getInstance(file.getProject()); + final DiffLog diffLog = blockSupport.reparseRange(file, file.getNode(), new TextRange(0, documentText.length()), documentText, createProgressIndicator(), + oldFileNode.getText()); + doActualPsiChange(file, diffLog); + + if (oldFileNode.getTextLength() != document.getTextLength()) { + LOG.error("PSI is broken beyond repair in: " + file); + } + } + finally { + file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, null); + } + } + } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/SyntheticFileSystemItem.java b/platform/core-impl/src/com/intellij/psi/impl/SyntheticFileSystemItem.java index 782643410849..ef0d1e89e0c9 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/SyntheticFileSystemItem.java +++ b/platform/core-impl/src/com/intellij/psi/impl/SyntheticFileSystemItem.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public abstract class SyntheticFileSystemItem extends PsiElementBase implements PsiFileSystemItem { - public static final Logger LOG = Logger.getInstance("#" + SyntheticFileSystemItem.class.getPackage().getName()); + private static final Logger LOG = Logger.getInstance("#" + SyntheticFileSystemItem.class.getPackage().getName()); protected final Project myProject; protected final PsiManager myManager; diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/DvcsCommitAdditionalComponent.java b/platform/dvcs-impl/src/com/intellij/dvcs/DvcsCommitAdditionalComponent.java index 943748a87a6f..fdc3432fe924 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/DvcsCommitAdditionalComponent.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/DvcsCommitAdditionalComponent.java @@ -25,6 +25,7 @@ import com.intellij.openapi.util.ThrowableComputable; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.CheckinProjectPanel; import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.VcsConfiguration; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.ui.RefreshableOnComponent; import com.intellij.openapi.vfs.VirtualFile; @@ -49,7 +50,7 @@ public abstract class DvcsCommitAdditionalComponent implements RefreshableOnComp protected final JPanel myPanel; protected final JCheckBox myAmend; - @Nullable private String myPreviousMessage; + @Nullable private final String myPreviousMessage; @Nullable private String myAmendedMessage; @NotNull protected final CheckinProjectPanel myCheckinPanel; @Nullable private Map myMessagesForRoots; @@ -140,8 +141,8 @@ public abstract class DvcsCommitAdditionalComponent implements RefreshableOnComp } private void substituteCommitMessage(@NotNull String newMessage) { - myPreviousMessage = myCheckinPanel.getCommitMessage(); if (!myPreviousMessage.trim().equals(newMessage.trim())) { + VcsConfiguration.getInstance(myCheckinPanel.getProject()).saveCommitMessage(myPreviousMessage); myCheckinPanel.setCommitMessage(newMessage); } } diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java index 21aba543141b..530fbfc2962a 100644 --- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java +++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java @@ -606,7 +606,7 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme { Element element = new Element(OPTION_ELEMENT); element.setAttribute(NAME_ATTR, key.getExternalName()); if (baseKey != null && value.isFallbackEnabled()) { - if (defaultFallbackAttr != null && defaultAttr != null && defaultAttr != defaultFallbackAttr) { + if (isParentOverwritingInheritance(key)) { element.setAttribute(BASE_ATTRIBUTES_ATTR, baseKey.getExternalName()); attrElements.addContent(element); } @@ -622,6 +622,15 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme { } } + private boolean isParentOverwritingInheritance(@NotNull TextAttributesKey key) { + TextAttributes parentAttrs = + myParentScheme instanceof AbstractColorsScheme ? ((AbstractColorsScheme)myParentScheme).getDirectlyDefinedAttributes(key) : null; + if (parentAttrs != null) { + return !parentAttrs.isFallbackEnabled(); + } + return false; + } + protected Color getOwnColor(ColorKey key) { return myColorsMap.get(key); } diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/GutterIconDescriptor.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/GutterIconDescriptor.java index 8e5ad8cb46d0..db8e10de0890 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/daemon/GutterIconDescriptor.java +++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/GutterIconDescriptor.java @@ -73,6 +73,10 @@ public abstract class GutterIconDescriptor { myIcon = icon; } + public boolean isEnabled() { + return LineMarkerSettings.getSettings().isEnabled(this); + } + @Nullable @Override public Icon getIcon() { diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java index dd6415419249..840b03b4eb50 100644 --- a/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java +++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java @@ -31,6 +31,7 @@ import com.intellij.openapi.vfs.ex.http.HttpFileSystem; import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.util.PlatformIcons; +import com.intellij.util.containers.Convertor; import com.intellij.util.containers.HashSet; import com.intellij.util.ui.UIUtil; import gnu.trove.TIntArrayList; @@ -107,6 +108,12 @@ public class PathEditor { public JComponent createComponent() { myList = new JBList(getListModel()); myList.setCellRenderer(createListCellRenderer(myList)); + TreeUIHelper.getInstance().installListSpeedSearch(myList, new Convertor() { + @Override + public String convert(Object file) { + return ((VirtualFile)file).getPresentableUrl(); + } + }); ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myList) .disableUpDownActions() diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/GutterIconsConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/editor/GutterIconsConfigurable.java index 5c2cd0f75dea..8a79f9e86a42 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/GutterIconsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/GutterIconsConfigurable.java @@ -32,10 +32,12 @@ import com.intellij.util.Function; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; +import com.intellij.util.containers.hash.HashSet; import com.intellij.util.ui.EmptyIcon; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import javax.swing.*; import java.awt.*; @@ -80,6 +82,7 @@ public class GutterIconsConfigurable implements Configurable, Configurable.NoScr }; MultiMap> map = ContainerUtil.groupBy(Arrays.asList(extensions), function); Map pluginDescriptorMap = ContainerUtil.newHashMap(); + Set ids = new HashSet<>(); myDescriptors = new ArrayList(); for (final PluginDescriptor descriptor : map.keySet()) { Collection> points = map.get(descriptor); @@ -87,16 +90,21 @@ public class GutterIconsConfigurable implements Configurable, Configurable.NoScr GutterIconDescriptor instance = (GutterIconDescriptor)extensionPoint.getInstance(); if (instance.getOptions().length > 0) { for (GutterIconDescriptor option : instance.getOptions()) { - myDescriptors.add(option); + if (ids.add(option.getId())) { + myDescriptors.add(option); + } pluginDescriptorMap.put(option, descriptor); } } else { - myDescriptors.add(instance); + if (ids.add(instance.getId())) { + myDescriptors.add(instance); + } pluginDescriptorMap.put(instance, descriptor); } } } + /* List options = new ArrayList(); for (Iterator iterator = myDescriptors.iterator(); iterator.hasNext(); ) { GutterIconDescriptor descriptor = iterator.next(); @@ -106,6 +114,7 @@ public class GutterIconsConfigurable implements Configurable, Configurable.NoScr } } myDescriptors.addAll(options); + */ myDescriptors.sort(new Comparator() { @Override public int compare(GutterIconDescriptor o1, GutterIconDescriptor o2) { @@ -203,4 +212,7 @@ public class GutterIconsConfigurable implements Configurable, Configurable.NoScr }; myList.setBorder(BorderFactory.createEmptyBorder()); } + + @TestOnly + public List getDescriptors() { return myDescriptors; } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index b0b6e7c007ef..51f8daee7706 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -60,6 +60,7 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.psi.ReferenceRange; +import com.intellij.ui.GuiUtils; import com.intellij.ui.LightweightHint; import com.intellij.util.Alarm; import com.intellij.util.ObjectUtils; @@ -76,7 +77,6 @@ import javax.swing.*; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; @@ -129,7 +129,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement private volatile boolean myHasPsiElements; private boolean myLookupUpdated; private final ConcurrentMap myItemSorters = - ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy()); + ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy()); private final PropertyChangeListener myLookupManagerListener; private final Queue myAdvertiserChanges = new ConcurrentLinkedQueue(); private final List myDelayedMiddleMatches = ContainerUtil.newArrayList(); @@ -152,24 +152,16 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myLookup = lookup; myStartCaret = myEditor.getCaretModel().getOffset(); - myAdvertiserChanges.offer(new Runnable() { - @Override - public void run() { - myLookup.getAdvertiser().clearAdvertisements(); - } - }); + myAdvertiserChanges.offer(() -> myLookup.getAdvertiser().clearAdvertisements()); myLookup.setArranger(new CompletionLookupArranger(parameters, this)); myLookup.addLookupListener(myLookupListener); myLookup.setCalculating(true); - myLookupManagerListener = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (evt.getNewValue() != null) { - LOG.error("An attempt to change the lookup during completion, phase = " + CompletionServiceImpl.getCompletionPhase()); - } + myLookupManagerListener = evt -> { + if (evt.getNewValue() != null) { + LOG.error("An attempt to change the lookup during completion, phase = " + CompletionServiceImpl.getCompletionPhase()); } }; LookupManager.getInstance(getProject()).addPropertyChangeListener(myLookupManagerListener); @@ -508,43 +500,40 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myQueue.cancelAllUpdates(); myFreezeSemaphore.up(); - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - final CompletionPhase phase = CompletionServiceImpl.getCompletionPhase(); - if (!(phase instanceof CompletionPhase.BgCalculation) || phase.indicator != CompletionProgressIndicator.this) return; + GuiUtils.invokeLaterIfNeeded(() -> { + final CompletionPhase phase = CompletionServiceImpl.getCompletionPhase(); + if (!(phase instanceof CompletionPhase.BgCalculation) || phase.indicator != this) return; - LOG.assertTrue(!getProject().isDisposed(), "project disposed"); + LOG.assertTrue(!getProject().isDisposed(), "project disposed"); - if (myEditor.isDisposed()) { - myLookup.hideLookup(false); - CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion); - return; - } + if (myEditor.isDisposed()) { + myLookup.hideLookup(false); + CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion); + return; + } - if (myEditor instanceof EditorWindow) { - LOG.assertTrue(((EditorWindow)myEditor).getInjectedFile().isValid(), "injected file !valid"); - LOG.assertTrue(((DocumentWindow)myEditor.getDocument()).isValid(), "docWindow !valid"); - } - PsiFile file = myLookup.getPsiFile(); - LOG.assertTrue(file == null || file.isValid(), "file !valid"); + if (myEditor instanceof EditorWindow) { + LOG.assertTrue(((EditorWindow)myEditor).getInjectedFile().isValid(), "injected file !valid"); + LOG.assertTrue(((DocumentWindow)myEditor.getDocument()).isValid(), "docWindow !valid"); + } + PsiFile file = myLookup.getPsiFile(); + LOG.assertTrue(file == null || file.isValid(), "file !valid"); - myLookup.setCalculating(false); + myLookup.setCalculating(false); - if (myCount == 0) { - myLookup.hideLookup(false); - if (!isAutopopupCompletion()) { - final CompletionProgressIndicator current = CompletionServiceImpl.getCompletionService().getCurrentCompletion(); - LOG.assertTrue(current == null, current + "!=" + CompletionProgressIndicator.this); + if (myCount == 0) { + myLookup.hideLookup(false); + if (!isAutopopupCompletion()) { + final CompletionProgressIndicator current = CompletionServiceImpl.getCompletionService().getCurrentCompletion(); + LOG.assertTrue(current == null, current + "!=" + this); - handleEmptyLookup(!((CompletionPhase.BgCalculation)phase).modifiersChanged); - } - } - else { - CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(CompletionProgressIndicator.this)); - updateLookup(); + handleEmptyLookup(!((CompletionPhase.BgCalculation)phase).modifiersChanged); } } + else { + CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(this)); + updateLookup(); + } }, myQueue.getModalityState()); } @@ -740,12 +729,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement private static LightweightHint showErrorHint(Project project, Editor editor, String text) { final LightweightHint[] result = {null}; - final EditorHintListener listener = new EditorHintListener() { - @Override - public void hintShown(final Project project, final LightweightHint hint, final int flags) { - result[0] = hint; - } - }; + final EditorHintListener listener = (project1, hint, flags) -> result[0] = hint; final MessageBusConnection connection = project.getMessageBus().connect(); connection.subscribe(EditorHintListener.TOPIC, listener); assert text != null; @@ -774,12 +758,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement boolean sync = ApplicationManager.getApplication().isUnitTestMode() && !CompletionAutoPopupHandler.ourTestingAutopopup; final CompletionThreading strategy = sync ? new SyncCompletion() : new AsyncCompletion(); - strategy.startThread(ProgressWrapper.wrap(this), new Runnable() { - @Override - public void run() { - scheduleAdvertising(); - } - }); + strategy.startThread(ProgressWrapper.wrap(this), this::scheduleAdvertising); final WeighingDelegate weigher = strategy.delegateWeighing(this); class CalculateItems implements Runnable { @@ -812,12 +791,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } public void addAdvertisement(@NotNull final String text, @Nullable final Color bgColor) { - myAdvertiserChanges.offer(new Runnable() { - @Override - public void run() { - myLookup.addAdvertisement(text, bgColor); - } - }); + myAdvertiserChanges.offer(() -> myLookup.addAdvertisement(text, bgColor)); myQueue.queue(myUpdate); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java index 8139591df006..ca9c21e1c952 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java @@ -59,6 +59,7 @@ import com.intellij.util.Consumer; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.JBDimension; +import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -626,7 +627,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr EditorColorsManager colorsManager = EditorColorsManager.getInstance(); EditorColorsScheme scheme = colorsManager.getGlobalScheme(); - StyleConstants.setFontSize(myFontSizeStyle, scheme.getQuickDocFontSize().getSize()); + StyleConstants.setFontSize(myFontSizeStyle, JBUI.scale(scheme.getQuickDocFontSize().getSize())); if (Registry.is("documentation.component.editor.font")) { StyleConstants.setFontFamily(myFontSizeStyle, scheme.getEditorFontName()); } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java index ad5177524678..57aa4fb59cbf 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -93,7 +93,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp private final NotNullLazyValue myContentManager; private InspectionResultsView myView; private Content myContent; - private volatile boolean myUseView; + private volatile boolean myViewClosed = true; @NotNull private AnalysisUIOptions myUIOptions; @@ -319,7 +319,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp if (!ApplicationManager.getApplication().isUnitTestMode()) { myUIOptions = AnalysisUIOptions.getInstance(getProject()).copy(); } - myUseView = true; + myViewClosed = false; super.launchInspections(scope); } @@ -589,7 +589,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp if (virtualFile == null) return null; if (isBinary(file)) return null; //do not inspect binary files - if (!myUseView && !headlessEnvironment) { + if (myViewClosed && !headlessEnvironment) { throw new ProcessCanceledException(); } @@ -785,7 +785,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp final ContentManager contentManager = getContentManager(); contentManager.removeContent(myContent, true); } - myUseView = false; + myViewClosed = true; myView = null; super.close(noSuspisiousCodeFound); } @@ -977,7 +977,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp return file instanceof PsiBinaryFile || file.getFileType().isBinary(); } - public boolean useView() { - return myUseView; + public boolean isViewClosed() { + return myViewClosed; } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java index 1d5c4ebb6045..aa0d8a117ca3 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java @@ -329,7 +329,8 @@ public abstract class InspectionRVContentProvider { } } else if (current instanceof RefElementNode) { - if (((RefElementNode)current).getElement().getName().compareTo(((RefElementNode)child).getElement().getName()) == 0) { + if (((RefElementNode)current).getElement().getName().compareTo(((RefElementNode)child).getElement().getName()) == 0 && + ((RefElementNode)current).getElement().getQualifiedName().compareTo(((RefElementNode)child).getElement().getQualifiedName()) == 0) { processDepth(model, child, current); return; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java index abd82c1a8789..1b75f63bcb83 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java @@ -46,6 +46,9 @@ import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; import java.util.*; /** @@ -170,6 +173,15 @@ public class QuickFixAction extends AnAction { }, templatePresentationText, null); refreshViews(project, ignoredElements, myToolWrapper); + final InspectionTree tree = context.getView().getTree(); + final TreePath[] selected = tree.getSelectionPaths(); + if (selected != null) { + for (TreePath path : selected) { + path.getLastPathComponent(); + ((DefaultTreeModel) tree.getModel()).reload((TreeNode)path.getLastPathComponent()); + } + } + tree.restoreExpansionAndSelection(); } finally { //to make offline view lazy if (initial) refManager.inspectionReadActionStarted(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java index 37b7e6775c7d..8f9faf3d3661 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java @@ -222,7 +222,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro } final GlobalInspectionContextImpl context = getContext(); - if (!context.useView() || !(refElement instanceof RefElement)) { + if (context.isViewClosed() || !(refElement instanceof RefElement)) { return; } if (myToolWrapper instanceof LocalInspectionToolWrapper) { @@ -393,24 +393,34 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro if (descriptors != null) { ArrayList newDescriptors = new ArrayList(Arrays.asList(descriptors)); newDescriptors.remove(problem); + CommonProblemDescriptor[] newDescriptorsAsArray = newDescriptors.toArray(new CommonProblemDescriptor[newDescriptors.size()]); getQuickFixActions().put(refEntity, null); if (!newDescriptors.isEmpty()) { - problemElements.put(refEntity, newDescriptors.toArray(new CommonProblemDescriptor[newDescriptors.size()])); + problemElements.put(refEntity, newDescriptorsAsArray); for (CommonProblemDescriptor descriptor : newDescriptors) { collectQuickFixes(descriptor.getFixes(), refEntity); } } - else { - ignoreProblemElement(refEntity); - } + ignoreProblemElement(refEntity, newDescriptorsAsArray, problem); } } } } - private void ignoreProblemElement(RefEntity refEntity){ - final CommonProblemDescriptor[] problemDescriptors = getProblemElements().remove(refEntity); - getIgnoredElements().put(refEntity, problemDescriptors); + private void ignoreProblemElement(RefEntity refEntity, CommonProblemDescriptor[] newDescriptors, CommonProblemDescriptor toIgnore){ + if (newDescriptors != null && newDescriptors.length == 0) { + newDescriptors = null; + } + if (newDescriptors == null) { + getProblemElements().remove(refEntity); + } else { + getProblemElements().put(refEntity, newDescriptors); + } + CommonProblemDescriptor[] oldIgnored = getIgnoredElements().getOrDefault(refEntity, CommonProblemDescriptor.EMPTY_ARRAY); + CommonProblemDescriptor[] update = new CommonProblemDescriptor[oldIgnored.length + 1]; + System.arraycopy(oldIgnored, 0, update, 0, oldIgnored.length); + update[update.length - 1] = toIgnore; + getIgnoredElements().put(refEntity, update); } @Override @@ -594,7 +604,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro myModulesProblems.add((RefModule)element); } else { - String groupName = element instanceof RefElement ? element.getRefManager().getGroupName((RefElement)element) : null; + String groupName = element instanceof RefElement ? element.getRefManager().getGroupName((RefElement)element) : element.getQualifiedName() ; Set content = myContents.get(groupName); if (content == null) { content = new HashSet(); @@ -733,6 +743,11 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro public boolean isElementIgnored(final RefEntity element) { for (RefEntity entity : getIgnoredElements().keySet()) { if (Comparing.equal(entity, element)) { + for (RefEntity entity1 : getProblemElements().keySet()) { + if (Comparing.equal(entity1, element)) { + return false; + } + } return true; } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java index c39505934441..c9a24ed64356 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java @@ -46,7 +46,7 @@ public class InspectionNodeInfo extends JPanel { public InspectionNodeInfo(final InspectionToolWrapper toolWrapper, Project project) { setLayout(new GridBagLayout()); - setBorder(IdeBorderFactory.createEmptyBorder(5, 3, 0, 0)); + setBorder(IdeBorderFactory.createEmptyBorder(5, 12, 0, 0)); myProject = project; myTitle = new SimpleColoredComponent(); myCurrentProfile = (InspectionProfileImpl)InspectionProjectProfileManager.getInstance(project).getProjectProfileImpl(); @@ -55,7 +55,7 @@ public class InspectionNodeInfo extends JPanel { myButton = new JButton(); add(myTitle, - new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new JBInsets(0, 2, 0, 0), + new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); JEditorPane description = new JEditorPane(); @@ -64,14 +64,14 @@ public class InspectionNodeInfo extends JPanel { description.setOpaque(false); description.addHyperlinkListener(BrowserHyperlinkListener.INSTANCE); final String toolDescription = toolWrapper.loadDescription(); - SingleInspectionProfilePanel.readHTML(description, SingleInspectionProfilePanel.toHTML(description, toolDescription == null ? "" : toolDescription, true)); + SingleInspectionProfilePanel.readHTML(description, SingleInspectionProfilePanel.toHTML(description, toolDescription == null ? "" : toolDescription, false)); add(ScrollPaneFactory.createScrollPane(description, true), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, - new JBInsets(5, 5, 0, 0), 0, 0)); + new Insets(0, 0, 0, 0), 0, 0)); add(myButton, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, - new JBInsets(15, 0, 0, 0), 0, 0)); + new Insets(15, 0, 0, 0), 0, 0)); updateEnableButtonText(false); new ClickListener() { @@ -99,9 +99,9 @@ public class InspectionNodeInfo extends JPanel { } myButton.setText((isEnabled ? "Disable" : "Enable") + " inspection"); myTitle.clear(); - myTitle.append(myName, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + myTitle.append(myName + " inspection", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); if (!isEnabled) { - myTitle.append(" Disabled", SimpleTextAttributes.GRAYED_ATTRIBUTES); + myTitle.append(" Disabled", SimpleTextAttributes.GRAYED_ATTRIBUTES); } } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java index 0ecc43093349..c8e77bc948cc 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -90,7 +90,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren private static final Logger LOG = Logger.getInstance(InspectionResultsView.class); public static final DataKey DATA_KEY = DataKey.create("inspectionView"); - private static final Key PREVIEW_EDITOR_IS_REUSED_KEY = Key.create("inspection.tool.window.preview.editor.is.reused."); + private static final Key PREVIEW_EDITOR_IS_REUSED_KEY = Key.create("inspection.tool.window.preview.editor.is.reused"); private final Project myProject; private final InspectionTree myTree; @@ -627,7 +627,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren severityGroupNode = ConcurrencyUtil.cacheOrGet(mySeverityGroupNodes, level, newNode); if (severityGroupNode == newNode) { InspectionTreeNode root = myTree.getRoot(); - insertByIndex(root, severityGroupNode); + insertByIndex(severityGroupNode, root); } } return severityGroupNode; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java index b36ab755a9ac..fb4a25075f8f 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java @@ -80,7 +80,11 @@ public class InspectionResultsViewComparator implements Comparator { if (node2 instanceof InspectionModuleNode) return 1; if (node1 instanceof InspectionPackageNode && node2 instanceof InspectionPackageNode) { - return ((InspectionPackageNode)node1).getPackageName().compareToIgnoreCase(((InspectionPackageNode)node2).getPackageName()); + final int nonQualified = ((InspectionPackageNode)node1).getPackageName().compareToIgnoreCase(((InspectionPackageNode)node2).getPackageName()); + if (nonQualified != 0) { + return nonQualified; + } + return nonQualified; } if (node1 instanceof InspectionPackageNode) return -1; if (node2 instanceof InspectionPackageNode) return 1; @@ -159,10 +163,17 @@ public class InspectionResultsViewComparator implements Comparator { private static int compareEntities(final RefEntity entity1, final RefEntity entity2) { if (entity1 instanceof RefElement && entity2 instanceof RefElement) { - return PsiUtilCore.compareElementsByPosition(((RefElement)entity1).getElement(), ((RefElement)entity2).getElement()); + final int positionComparing = PsiUtilCore.compareElementsByPosition(((RefElement)entity1).getElement(), ((RefElement)entity2).getElement()); + if (positionComparing != 0) { + return positionComparing; + } } if (entity1 != null && entity2 != null) { - return entity1.getName().compareToIgnoreCase(entity2.getName()); + final int nameComparing = entity1.getName().compareToIgnoreCase(entity2.getName()); + if (nameComparing != 0) { + return nameComparing; + } + return entity1.getQualifiedName().compareToIgnoreCase(entity2.getQualifiedName()); } if (entity1 != null) return -1; return entity2 != null ? 1 : 0; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixToolbar.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixToolbar.java index d178b8e5ebb6..19921a01ac70 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixToolbar.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixToolbar.java @@ -31,7 +31,9 @@ import com.intellij.ui.ClickListener; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,6 +41,7 @@ import javax.swing.*; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; import java.util.function.Supplier; /** @@ -57,7 +60,7 @@ public class QuickFixToolbar extends JPanel { final boolean multipleDescriptors = problemCount > 1; setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); - setBorder(IdeBorderFactory.createEmptyBorder(hasFixes ? 0 : 5, 5, 0, 0)); + setBorder(IdeBorderFactory.createEmptyBorder(7 + (hasFixes ? 0 : 5), hasFixes ? 12 : 9, hasFixes ? 0 : 6, 0)); fill(multipleDescriptors, () -> getLabel(fixes, tree.getSelectionCount() == 1 ? (InspectionTreeNode)tree.getSelectionPath().getLastPathComponent() : null, problemCount), this); fill(hasFixes, () -> createFixPanel(fixes, multipleDescriptors), this); @@ -74,11 +77,11 @@ public class QuickFixToolbar extends JPanel { label.append(problemsCount + " problems" + (targetName == null ? "" : (" in " + targetName)) + (problemsCount > 1 && (fixes != null && fixes.length == MAX_FIX_COUNT) ? " Fix all:" : "") + - (hasFixesNonIntersectedFixes ? ":" : "" ), - SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + (hasFixesNonIntersectedFixes ? ":" : "" )); if (hasFixesNonIntersectedFixes) { label.append(" select a single problem to see its quick fixes"); } + label.setBorder(IdeBorderFactory.createEmptyBorder(0, 0, 0, 2)); return label; } @@ -86,16 +89,18 @@ public class QuickFixToolbar extends JPanel { @NotNull final TreePath[] paths, @NotNull final Project project, boolean multipleDescriptors) { + final AnAction[] suppressors = new SuppressActionWrapper(project, toolWrapper, paths).getChildren(null); final ComboBoxAction action = new ComboBoxAction() { { getTemplatePresentation().setText(multipleDescriptors ? "Suppress All" : "Suppress"); + getTemplatePresentation().setEnabledAndVisible(suppressors.length != 0); } @NotNull @Override protected DefaultActionGroup createPopupActionGroup(JComponent button) { DefaultActionGroup group = new DefaultActionGroup(); - group.addAll(new SuppressActionWrapper(project, toolWrapper, paths).getChildren(null)); + group.addAll(suppressors); return group; } }; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java index 809705237f49..d78474b6a557 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java @@ -77,7 +77,7 @@ public class RefElementNode extends InspectionTreeNode { if (element == null || !element.isValid()) { return InspectionsBundle.message("inspection.reference.invalid"); } - return element.getRefManager().getRefinedElement(element).getQualifiedName(); + return element.getRefManager().getRefinedElement(element).getName(); } @Override diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleBuffer.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleBuffer.java index 45d259a526bd..8ad45fc099cc 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleBuffer.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -22,6 +22,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.SystemProperties; import gnu.trove.TIntArrayList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -132,14 +133,7 @@ public class ConsoleBuffer { } public static int getLegacyCycleBufferSize() { - String cycleBufferSizeProperty = System.getProperty("idea.cycle.buffer.size"); - if (cycleBufferSizeProperty == null) return 1024 * 1024; - try { - return Integer.parseInt(cycleBufferSizeProperty) * 1024; - } - catch (NumberFormatException e) { - return 1024 * 1024; - } + return SystemProperties.getIntProperty("idea.cycle.buffer.size", 1024) * 1024; } public boolean isUseCyclicBuffer() { diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java b/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java index 064c07943ad2..304903a2fb88 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java @@ -85,7 +85,7 @@ public class RunContentBuilder extends RunTab { } initLogConsoles(profile, contentDescriptor, console); } - myUi.getOptions().setLeftToolbar(createActionToolbar(contentDescriptor), ActionPlaces.UNKNOWN); + myUi.getOptions().setLeftToolbar(createActionToolbar(contentDescriptor), ActionPlaces.RUNNER_TOOLBAR); if (profile instanceof RunConfigurationBase) { if (console instanceof ObservableConsoleView && !ApplicationManager.getApplication().isUnitTestMode()) { @@ -131,7 +131,7 @@ public class RunContentBuilder extends RunTab { } } - consoleContent.setActions(consoleActions, ActionPlaces.UNKNOWN, console.getComponent()); + consoleContent.setActions(consoleActions, ActionPlaces.RUNNER_TOOLBAR, console.getComponent()); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java index 9f154ec6a5f4..53ee3aff3093 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java @@ -871,7 +871,8 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac final AnAction[] actions = groupToBuild.getChildren(null); if (!Arrays.equals(actions, myContextActions.get(entry.getKey()))) { - ActionToolbar tb = myActionManager.createActionToolbar(myActionsPlace, groupToBuild, true); + String adjustedPlace = myActionsPlace == ActionPlaces.UNKNOWN ? ActionPlaces.TOOLBAR : myActionsPlace; + ActionToolbar tb = myActionManager.createActionToolbar(adjustedPlace, groupToBuild, true); tb.getComponent().setBorder(null); tb.setTargetComponent(contextComponent); eachPlaceholder.setContent(tb.getComponent()); diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/LRUPopupBuilder.java b/platform/lang-impl/src/com/intellij/ide/scratch/LRUPopupBuilder.java index 2676a3f9a1f4..77601cc4b877 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/LRUPopupBuilder.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/LRUPopupBuilder.java @@ -169,13 +169,13 @@ public abstract class LRUPopupBuilder { new BaseListPopupStep(myTitle, combinedItems) { @NotNull @Override - public String getTextFor(@NotNull T t) { - return getPresentation(t).first; + public String getTextFor(T t) { + return t == null ? "" : getPresentation(t).first; } @Override - public Icon getIconFor(@NotNull T t) { - return getPresentation(t).second; + public Icon getIconFor(T t) { + return t == null ? null : getPresentation(t).second; } @Override diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/RootDetector.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/RootDetector.java index 48f01c80feb8..14aa9321f7bc 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/RootDetector.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/RootDetector.java @@ -62,6 +62,4 @@ public abstract class RootDetector { */ @NotNull public abstract Collection detectRoots(@NotNull VirtualFile rootCandidate, @NotNull ProgressIndicator progressIndicator); - - public static ExtensionPointName JAVA_SOURCE_ROOT_DETECTOR = ExtensionPointName.create("com.intellij.library.javaSourceRootDetector"); } diff --git a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java index cd9621776324..300109e226d0 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -171,7 +171,7 @@ public class RegistryUi implements Disposable { public void update(AnActionEvent e) { e.getPresentation().setEnabled(!myTable.isEditing() && myTable.getSelectedRow() >= 0); e.getPresentation().setText("Revert to Default"); - e.getPresentation().setIcon(AllIcons.General.Remove); + e.getPresentation().setIcon(AllIcons.General.Reset); if (e.getPresentation().isEnabled()) { final RegistryValue rv = myModel.getRegistryValue(myTable.getSelectedRow()); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java index 16daf7fe15f8..d60418926487 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java @@ -56,14 +56,14 @@ import java.util.List; //todo listen & notifyListeners readonly events? public class PsiDocumentManagerImpl extends PsiDocumentManagerBase implements SettingsSavingComponent { - private final DocumentCommitThread myDocumentCommitThread; + private final DocumentCommitProcessor myDocumentCommitThread; private final boolean myUnitTestMode = ApplicationManager.getApplication().isUnitTestMode(); public PsiDocumentManagerImpl(@NotNull final Project project, @NotNull PsiManager psiManager, @NotNull EditorFactory editorFactory, @NotNull MessageBus bus, - @NonNls @NotNull final DocumentCommitThread documentCommitThread) { + @NonNls @NotNull final DocumentCommitProcessor documentCommitThread) { super(project, psiManager, bus, documentCommitThread); myDocumentCommitThread = documentCommitThread; editorFactory.getEventMulticaster().addDocumentListener(this, project); @@ -71,19 +71,15 @@ public class PsiDocumentManagerImpl extends PsiDocumentManagerBase implements Se busConnection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerAdapter() { @Override public void fileContentLoaded(@NotNull final VirtualFile virtualFile, @NotNull Document document) { - PsiFile psiFile = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiFile compute() { - return myProject.isDisposed() || !virtualFile.isValid() ? null : getCachedPsiFile(virtualFile); - } - }); + PsiFile psiFile = ApplicationManager.getApplication().runReadAction( + (Computable)() -> myProject.isDisposed() || !virtualFile.isValid() ? null : getCachedPsiFile(virtualFile)); fireDocumentCreated(document, psiFile); } }); busConnection.subscribe(DocumentBulkUpdateListener.TOPIC, new DocumentBulkUpdateListener.Adapter() { @Override public void updateFinished(@NotNull Document doc) { - documentCommitThread.queueCommit(project, doc, "Bulk update finished", ApplicationManager.getApplication().getDefaultModalityState()); + documentCommitThread.commitAsynchronously(project, doc, "Bulk update finished", ApplicationManager.getApplication().getDefaultModalityState()); } }); } @@ -161,15 +157,12 @@ public class PsiDocumentManagerImpl extends PsiDocumentManagerBase implements Se @Override public void save() { // Ensure all documents are committed on save so file content dependent indices, that use PSI to build have consistent content. - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - try { - commitAllDocuments(); - } - catch (Exception e) { - LOG.error(e); - } + UIUtil.invokeLaterIfNeeded(() -> { + try { + commitAllDocuments(); + } + catch (Exception e) { + LOG.error(e); } }); } @@ -178,7 +171,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManagerBase implements Se @TestOnly public void clearUncommittedDocuments() { super.clearUncommittedDocuments(); - myDocumentCommitThread.clearQueue(); + ((DocumentCommitThread)myDocumentCommitThread).clearQueue(); } @NonNls diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java index b4c63a9b7687..38d060ebaeda 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java @@ -39,7 +39,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.DebugUtil; -import com.intellij.psi.impl.DocumentCommitProcessor; +import com.intellij.psi.impl.DocumentCommitThread; import com.intellij.psi.impl.PsiDocumentManagerBase; import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; import com.intellij.psi.impl.source.PsiFileImpl; @@ -467,7 +467,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT try { final DiffLog diffLog = BlockSupportImpl.mergeTrees(oldFile, oldFileNode, injectedNode, new DaemonProgressIndicator(), oldFileNode.getText()); - DocumentCommitProcessor.doActualPsiChange(oldFile, diffLog); + DocumentCommitThread.doActualPsiChange(oldFile, diffLog); } finally { DebugUtil.finishPsiModification(); diff --git a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java index 4bb3de24b553..9470cd71c0a3 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java @@ -26,7 +26,6 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.DumbModePermission; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; @@ -188,7 +187,9 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor { for (PsiElement element : myElements) { for(SafeDeleteProcessorDelegate delegate: Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) { if (delegate.handlesElement(element)) { - Collection foundConflicts = delegate.findConflicts(element, myElements); + Collection foundConflicts = delegate instanceof SafeDeleteProcessorDelegateBase + ? ((SafeDeleteProcessorDelegateBase)delegate).findConflicts(element, myElements, usages) + : delegate.findConflicts(element, myElements); if (foundConflicts != null) { conflicts.addAll(foundConflicts); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessorDelegateBase.java b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessorDelegateBase.java index f50343dda6c6..d67692b2f10a 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessorDelegateBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessorDelegateBase.java @@ -42,4 +42,8 @@ public abstract class SafeDeleteProcessorDelegateBase implements SafeDeleteProce public UsageView showUsages(UsageInfo[] usages, UsageViewPresentation presentation, UsageViewManager manager, PsiElement[] elements) { return null; } + + public Collection findConflicts(PsiElement element, PsiElement[] elements, UsageInfo[] usages) { + return findConflicts(element, elements); + } } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java index cdf989ceea35..b688c45cf18a 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java @@ -15,9 +15,11 @@ */ package com.intellij.openapi.actionSystem; -import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import java.util.Set; + /** * Possible places in the IDEA user interface where an action can appear. */ @@ -25,6 +27,7 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings({"HardCodedStringLiteral"}) public abstract class ActionPlaces { public static final String UNKNOWN = "unknown"; + public static final String TOOLBAR = "toolbar"; /** * consider to use {@link #isMainMenuOrActionSearch(String)} instead @@ -63,13 +66,13 @@ public abstract class ActionPlaces { public static final String CALL_HIERARCHY_VIEW_TOOLBAR = "CallHierarchyViewToolbar"; public static final String J2EE_ATTRIBUTES_VIEW_POPUP = "J2EEAttributesViewPopup"; public static final String J2EE_VIEW_POPUP = "J2EEViewPopup"; + public static final String RUNNER_TOOLBAR = "RunnerToolbar"; public static final String DEBUGGER_TOOLBAR = "DebuggerToolbar"; public static final String USAGE_VIEW_POPUP = "UsageViewPopup"; public static final String USAGE_VIEW_TOOLBAR = "UsageViewToolbar"; public static final String STRUCTURE_VIEW_POPUP = "StructureViewPopup"; public static final String STRUCTURE_VIEW_TOOLBAR = "StructureViewToolbar"; public static final String NAVIGATION_BAR_POPUP = "NavBar"; - @Deprecated public static final String NAVIGATION_BAR = NAVIGATION_BAR_POPUP; public static final String NAVIGATION_BAR_TOOLBAR = "NavBarToolbar"; public static final String TODO_VIEW_POPUP = "TodoViewPopup"; @@ -128,22 +131,25 @@ public abstract class ActionPlaces { public static final String V8_HEAP_PROFILING_POPUP = "V8_HEAP_PROFILING_POPUP"; public static final String V8_HEAP_DIFF_PROFILING_POPUP = "V8_HEAP_DIFF_PROFILING_POPUP"; - private static final String[] ourToolbarPlaces = {EDITOR_TOOLBAR, PROJECT_VIEW_TOOLBAR, TESTTREE_VIEW_TOOLBAR, MAIN_TOOLBAR, + private static final Set ourToolbarPlaces = ContainerUtil.newHashSet( + EDITOR_TOOLBAR, PROJECT_VIEW_TOOLBAR, TESTTREE_VIEW_TOOLBAR, MAIN_TOOLBAR, TOOLBAR, RUNNER_TOOLBAR, ANT_EXPLORER_TOOLBAR, ANT_MESSAGES_TOOLBAR, COMPILER_MESSAGES_TOOLBAR, TODO_VIEW_TOOLBAR, STRUCTURE_VIEW_TOOLBAR, USAGE_VIEW_TOOLBAR, DEBUGGER_TOOLBAR, CALL_HIERARCHY_VIEW_TOOLBAR, METHOD_HIERARCHY_VIEW_TOOLBAR, TYPE_HIERARCHY_VIEW_TOOLBAR, JAVADOC_TOOLBAR, FILE_HISTORY_TOOLBAR, FILEHISTORY_VIEW_TOOLBAR, LVCS_DIRECTORY_HISTORY_TOOLBAR, CHANGES_VIEW_TOOLBAR, PHING_EXPLORER_TOOLBAR, - PHING_MESSAGES_TOOLBAR, ANALYZE_STACKTRACE_PANEL_TOOLBAR}; + PHING_MESSAGES_TOOLBAR, ANALYZE_STACKTRACE_PANEL_TOOLBAR + ); public static boolean isToolbarPlace(@NotNull String place) { - return ArrayUtil.find(ourToolbarPlaces, place) != -1; + return ourToolbarPlaces.contains(place); } public static boolean isMainMenuOrActionSearch(String place) { return MAIN_MENU.equals(place) || ACTION_SEARCH.equals(place); } - private static final String[] ourPopupPlaces = {EDITOR_POPUP, EDITOR_TAB_POPUP, COMMANDER_POPUP, + private static final Set ourPopupPlaces = ContainerUtil.newHashSet( + EDITOR_POPUP, EDITOR_TAB_POPUP, COMMANDER_POPUP, PROJECT_VIEW_POPUP, FAVORITES_VIEW_POPUP, SCOPE_VIEW_POPUP, TESTTREE_VIEW_POPUP, TESTSTATISTICS_VIEW_POPUP, TYPE_HIERARCHY_VIEW_POPUP, METHOD_HIERARCHY_VIEW_POPUP, CALL_HIERARCHY_VIEW_POPUP, J2EE_ATTRIBUTES_VIEW_POPUP, J2EE_VIEW_POPUP, USAGE_VIEW_POPUP, STRUCTURE_VIEW_POPUP, TODO_VIEW_POPUP, COMPILER_MESSAGES_POPUP, ANT_MESSAGES_POPUP, ANT_EXPLORER_POPUP, UPDATE_POPUP, @@ -152,9 +158,9 @@ public abstract class ActionPlaces { CREATE_EJB_POPUP, CHANGES_VIEW_POPUP, REMOTE_HOST_VIEW_POPUP, REMOTE_HOST_DIALOG_POPUP, TFS_TREE_POPUP, ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP, NAVIGATION_BAR_POPUP, JS_BUILD_TOOL_POPUP, DIFF_TOOLBAR, V8_CPU_PROFILING_POPUP, V8_HEAP_PROFILING_POPUP, V8_HEAP_PROFILING_POPUP - }; + ); public static boolean isPopupPlace(@NotNull String place) { - return ArrayUtil.find(ourPopupPlaces, place) != -1; + return ourPopupPlaces.contains(place); } } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java index 1f6e017c529f..f6056927ebaa 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java @@ -147,8 +147,9 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent public ComboBoxButton(Presentation presentation) { myPresentation = presentation; - setEnabled(myPresentation.isEnabled()); setModel(new MyButtonModel()); + getModel().setEnabled(myPresentation.isEnabled()); + setVisible(presentation.isVisible()); setHorizontalAlignment(LEFT); setFocusable(false); if (isSmallVariant()) { diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogEarthquakeShaker.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogEarthquakeShaker.java index 32824573c228..7684b43d758a 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/DialogEarthquakeShaker.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogEarthquakeShaker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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,23 +18,22 @@ package com.intellij.openapi.ui; import com.intellij.openapi.util.Disposer; import com.intellij.util.ui.Animator; -import javax.swing.*; import java.awt.*; /** * @author Konstantin Bulenkov */ public class DialogEarthquakeShaker { - private JDialog myDialog; + private Window myWindow; private Point myNaturalLocation; private long myStartTime; - private DialogEarthquakeShaker(JDialog dialog) { - myDialog = dialog; + private DialogEarthquakeShaker(Window window) { + myWindow = window; } public void startShake() { - myNaturalLocation = myDialog.getLocation(); + myNaturalLocation = myWindow.getLocation(); myStartTime = System.currentTimeMillis(); new Animator("EarthQuake", 10, 70, true) { @Override @@ -43,19 +42,19 @@ public class DialogEarthquakeShaker { final double waveOffset = (elapsed % 70) / 70d; final double angle = waveOffset * 2d * Math.PI; final int shakenX = (int)((Math.sin(angle) * 10) + myNaturalLocation.x); - myDialog.setLocation(shakenX, myNaturalLocation.y); - myDialog.repaint(); + myWindow.setLocation(shakenX, myNaturalLocation.y); + myWindow.repaint(); if (elapsed > 150) { suspend(); - myDialog.setLocation(myNaturalLocation); - myDialog.repaint(); + myWindow.setLocation(myNaturalLocation); + myWindow.repaint(); Disposer.dispose(this); } } }.resume(); } - public static void shake(JDialog dialog) { - new DialogEarthquakeShaker(dialog).startShake(); + public static void shake(Window window) { + new DialogEarthquakeShaker(window).startShake(); } } diff --git a/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java b/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java index 6b4852319899..6efaa2cffef4 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/IdeFocusManager.java @@ -139,7 +139,7 @@ public abstract class IdeFocusManager implements FocusRequestor { public abstract Component getFocusOwner(); /** - * Runs runnable for whicj DataContext will no be computed from the current focus owner, + * Runs runnable for which DataContext will no be computed from the current focus owner, * but used the given one */ public abstract void runOnOwnContext(@NotNull DataContext context, @NotNull Runnable runnable); diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java index e8215fe5d190..cda22b602cfc 100644 --- a/platform/platform-api/src/com/intellij/util/Alarm.java +++ b/platform/platform-api/src/com/intellij/util/Alarm.java @@ -25,6 +25,7 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.wm.IdeFrame; import com.intellij.util.concurrency.AppExecutorUtil; +import com.intellij.util.concurrency.EdtExecutorService; import com.intellij.util.concurrency.QueueProcessor; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; @@ -52,8 +53,8 @@ public class Alarm implements Disposable { private volatile boolean myDisposed; - private final List myRequests = new SmartList(); // guarded by LOCK - private final List myPendingRequests = new SmartList(); // guarded by LOCK + private final List myRequests = new SmartList<>(); // guarded by LOCK + private final List myPendingRequests = new SmartList<>(); // guarded by LOCK private final ScheduledExecutorService myExecutorService; @@ -68,7 +69,9 @@ public class Alarm implements Disposable { myDisposed = true; cancelAllRequests(); - myExecutorService.shutdownNow(); + if (myThreadToUse != ThreadToUse.SWING_THREAD) { + myExecutorService.shutdownNow(); + } } } @@ -123,7 +126,12 @@ public class Alarm implements Disposable { public Alarm(@NotNull ThreadToUse threadToUse, @Nullable Disposable parentDisposable) { myThreadToUse = threadToUse; - myExecutorService = // have to restrict the number of running tasks because otherwise the (implicit) contract of + myExecutorService = threadToUse == ThreadToUse.SWING_THREAD ? + // pass straight to EDT + EdtExecutorService.getScheduledExecutorInstance() : + + // or pass to app pooled thread. + // have to restrict the number of running tasks because otherwise the (implicit) contract of // "addRequests with the same delay are executed in order" will be broken AppExecutorUtil.createBoundedScheduledExecutorService(1); @@ -258,7 +266,7 @@ public class Alarm implements Disposable { return; } - requests = new SmartList>(); + requests = new SmartList<>(); for (Request request : myRequests) { Runnable existingTask = request.cancel(); if (existingTask != null) { @@ -280,7 +288,7 @@ public class Alarm implements Disposable { void waitForAllExecuted(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { List requests; synchronized (LOCK) { - requests = new ArrayList(myRequests); + requests = new ArrayList<>(myRequests); } for (Request request : requests) { @@ -357,12 +365,9 @@ public class Alarm implements Disposable { if (myThreadToUse == ThreadToUse.SWING_THREAD && !isEdt()) { //noinspection SSBasedInspection - EdtInvocationManager.getInstance().invokeLater(new Runnable() { - @Override - public void run() { - if (!myDisposed) { - QueueProcessor.runSafely(task); - } + EdtInvocationManager.getInstance().invokeLater(() -> { + if (!myDisposed) { + QueueProcessor.runSafely(task); } }); } diff --git a/platform/platform-impl/src/com/intellij/execution/process/ProcessInfo.java b/platform/platform-impl/src/com/intellij/execution/process/ProcessInfo.java index 86dc10894e84..700432978815 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/ProcessInfo.java +++ b/platform/platform-impl/src/com/intellij/execution/process/ProcessInfo.java @@ -17,6 +17,11 @@ package com.intellij.execution.process; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.util.Optional; public class ProcessInfo { @@ -24,6 +29,7 @@ public class ProcessInfo { private final int myPid; @NotNull private final String myCommandLine; + @NotNull private final Optional myExecutablePath; @NotNull private final String myExecutableName; @NotNull private final String myArgs; @@ -33,10 +39,23 @@ public class ProcessInfo { @NotNull String args) { myPid = pid; myCommandLine = commandLine; + myExecutablePath = Optional.empty(); myExecutableName = executableName; myArgs = args; } + public ProcessInfo(int pid, + @NotNull String commandLine, + @NotNull String executableName, + @NotNull String args, + @Nullable String executablePath) { + myPid = pid; + myCommandLine = commandLine; + myExecutableName = executableName; + myExecutablePath = StringUtil.isNotEmpty(executablePath) ? Optional.of(executablePath) : Optional.empty(); + myArgs = args; + } + public int getPid() { return myPid; } @@ -51,6 +70,18 @@ public class ProcessInfo { return myExecutableName; } + @NotNull + public Optional getExecutableCannonicalPath() { + return myExecutablePath.map(s -> { + try { + return new File(s).getCanonicalPath(); + } + catch (IOException e) { + return s; + } + }); + } + @NotNull public String getExecutableDisplayName() { return StringUtil.trimEnd(myExecutableName, ".exe", true); diff --git a/platform/platform-impl/src/com/intellij/execution/process/impl/ProcessListUtil.java b/platform/platform-impl/src/com/intellij/execution/process/impl/ProcessListUtil.java index 34614d4ed790..fa42c2837020 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/impl/ProcessListUtil.java +++ b/platform/platform-impl/src/com/intellij/execution/process/impl/ProcessListUtil.java @@ -90,7 +90,7 @@ public class ProcessListUtil { ProcessOutput processOutput = ExecUtil.execAndGetOutput(new GeneralCommandLine(command)); int exitCode = processOutput.getExitCode(); if (exitCode != 0) { - LOG.error("Cannot get process list, 'ps' exited with code " + exitCode + ", stdout:\n" + LOG.error("Cannot get process list, 'ps' exited with code " + exitCode + ", stdout:\n" + processOutput.getStdout() + "\nstderr:\n" + processOutput.getStderr()); @@ -98,7 +98,7 @@ public class ProcessListUtil { output = processOutput.getStdout(); } catch (ExecutionException e) { - LOG.error("Cannot get process list", e); + LOG.error("Cannot get process list", e); return null; } return parser.fun(output); @@ -110,7 +110,7 @@ public class ProcessListUtil { File[] processes = proc.listFiles(); if (processes == null) { - LOG.error("Cannot read /proc, not mounted?"); + LOG.error("Cannot read /proc, not mounted?"); return null; } @@ -137,9 +137,22 @@ public class ProcessListUtil { } if (cmdline.isEmpty()) continue; + String executablePath = null; + + try { + File exe = new File(each, "exe"); + if (!exe.getAbsolutePath().equals(exe.getCanonicalPath())) { + executablePath = exe.getCanonicalPath(); + } + } + catch (IOException e) { + // couldn't resolve symlink + } + result.add(new ProcessInfo(pid, StringUtil.join(cmdline, " "), PathUtil.getFileName(cmdline.get(0)), - StringUtil.join(cmdline.subList(1, cmdline.size()), " ") + StringUtil.join(cmdline.subList(1, cmdline.size()), " "), + executablePath )); } return result; @@ -192,7 +205,7 @@ public class ProcessListUtil { String name = PathUtil.getFileName(command); String args = each.commandLine.substring(command.length()).trim(); - result.add(new ProcessInfo(each.pid, each.commandLine, name, args)); + result.add(new ProcessInfo(each.pid, each.commandLine, name, args, command)); } return result; } @@ -219,16 +232,21 @@ public class ProcessListUtil { for (int i = 1; i < lines.length; i++) { String line = lines[i]; - int pid = StringUtil.parseInt(line.substring(0, statStart).trim(), -1); - if (pid == -1) continue; + try { + int pid = StringUtil.parseInt(line.substring(0, statStart).trim(), -1); + if (pid == -1) continue; - String state = line.substring(statStart, userStart).trim(); - if (state.contains("Z")) continue; // zombie + String state = line.substring(statStart, userStart).trim(); + if (state.contains("Z")) continue; // zombie - String user = line.substring(userStart, commandStart).trim(); - String commandLine = line.substring(commandStart).trim(); + String user = line.substring(userStart, commandStart).trim(); + String commandLine = line.substring(commandStart).trim(); - result.add(new MacProcessInfo(pid, commandLine, user, state)); + result.add(new MacProcessInfo(pid, commandLine, user, state)); + } + catch (Exception e) { + LOG.error("Can't parse line '" + line + "'", e); + } } return result; } @@ -249,7 +267,7 @@ public class ProcessListUtil { @Nullable static List getProcessList_WindowsWMIC() { - return parseCommandOutput(Arrays.asList("wmic.exe", "path", "win32_process", "get", "Caption,Processid,Commandline"), + return parseCommandOutput(Arrays.asList("wmic.exe", "path", "win32_process", "get", "Caption,Processid,Commandline,ExecutablePath"), new NullableFunction>() { @Nullable @Override @@ -272,12 +290,18 @@ public class ProcessListUtil { int pidStart = header.indexOf("ProcessId"); if (pidStart == -1) return null; + int executablePathStart = header.indexOf("ExecutablePath"); + if (executablePathStart == -1) return null; + + for (int i = 1; i < lines.length; i++) { String line = lines[i]; int pid = StringUtil.parseInt(line.substring(pidStart, line.length()).trim(), -1); if (pid == -1 || pid == 0) continue; + String executablePath = line.substring(executablePathStart, pidStart).trim(); + String name = line.substring(0, commandLineStart).trim(); if (name.isEmpty()) continue; @@ -294,7 +318,7 @@ public class ProcessListUtil { } } - result.add(new ProcessInfo(pid, commandLine, name, args)); + result.add(new ProcessInfo(pid, commandLine, name, args, executablePath)); } return result; } diff --git a/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java b/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java index dea9ecaff2b7..93971bfd8aa9 100644 --- a/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java +++ b/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -69,7 +69,6 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter { public void initComponent() { checkJvm(); checkIBus(); - checkJAyatana(); startDiskSpaceMonitoring(); } @@ -100,16 +99,6 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter { } } - @SuppressWarnings("SpellCheckingInspection") - private void checkJAyatana() { - if (SystemInfo.isXWindow) { - String originalOpts = System.getenv("_ORIGINAL_JAVA_TOOL_OPTIONS"); - if (originalOpts != null && originalOpts.contains("jayatanaag.jar")) { - showNotification("ayatana.menu.warn.message"); - } - } - } - private void showNotification(@PropertyKey(resourceBundle = "messages.IdeBundle") String key) { final String ignoreKey = "ignore." + key; boolean ignored = myProperties.isValueSet(ignoreKey); diff --git a/platform/platform-impl/src/com/intellij/ide/actions/AboutPopup.java b/platform/platform-impl/src/com/intellij/ide/actions/AboutPopup.java index 580d23109fae..89876f78a4e4 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/AboutPopup.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/AboutPopup.java @@ -398,7 +398,7 @@ public class AboutPopup { g2.setFont(myFont); g2.setColor(myLinkColor); final int xOffset = myImage.getIconWidth() - width - 10; - final GraphicsConfig config = GraphicsUtil.paintWithAlpha(g2, myShowCopyAlpha); + final GraphicsConfig config = GraphicsUtil.paintWithAlpha(g2, Math.max(0, Math.min(1, myShowCopyAlpha))); g2.drawString(copyString, xOffset, yBase + y); config.restore(); myLinks.add(new Link(new Rectangle(xOffset, yBase + y - fontAscent, width, fontHeight), COPY_URL)); diff --git a/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java b/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java index 6bf381304711..dce643c02e9a 100644 --- a/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java +++ b/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java @@ -121,14 +121,14 @@ public class PluginGroups { "com.intellij.spring," + "com.intellij.spring.webflow," + "com.intellij.spring.ws,com.intellij.aop", - "J2EE:com.intellij.javaee.batch," + + "Java EE:com.intellij.javaee.batch," + "com.intellij.beanValidation," + "com.intellij.cdi," + "com.intellij.javaee," + "com.intellij.jsf," + "com.intellij.javaee.extensions," + "com.jetbrains.restWebServices," + - "Java EE: Web Services (JAX-WS)," + + "Web Services (JAX-WS)," + "com.intellij.javaee.webSocket," + "com.intellij.jsp," + "com.intellij.persistence", @@ -220,7 +220,7 @@ public class PluginGroups { "Tools Integration:Integration for Atlassian JIRA, Bamboo, Cricible, FishEye:atlassian-idea-plugin"); } - protected static void addVcsGroup(Map>> tree) { + public static void addVcsGroup(Map>> tree) { tree.put("Version Controls", Pair.create(PlatformImplIcons.VersionControls, Arrays.asList( "ClearcasePlugin", "CVS", @@ -233,24 +233,28 @@ public class PluginGroups { ))); } - protected static void addVimPlugin(Map featuredPlugins) { + public static void addVimPlugin(Map featuredPlugins) { featuredPlugins.put("IdeaVim", "Editor:Emulates Vim editor:" + IDEA_VIM_PLUGIN_ID); } - protected static void addLuaPlugin(Map featuredPlugins) { - featuredPlugins.put("Lua", "Custom Languages:Lua language integration:Lua"); + public static void addLuaPlugin(Map featuredPlugins) { + featuredPlugins.put("Lua", "Custom Languages:Lua language support:Lua"); } - protected static void addMarkdownPlugin(Map featuredPlugins) { + public static void addGoPlugin(Map featuredPlugins) { + featuredPlugins.put("Go", "Custom Languages:Go language supprt:ro.redeul.google.go"); + } + + public static void addMarkdownPlugin(Map featuredPlugins) { featuredPlugins.put("Markdown", "Custom Languages:Markdown language support:org.intellij.plugins.markdown"); } - protected static void addConfigurationServerPlugin(Map featuredPlugins) { + public static void addConfigurationServerPlugin(Map featuredPlugins) { featuredPlugins.put("Configuration Server", "Team Work:Supports sharing settings between installations of IntelliJ Platform based products used by the same developer on different computers:IdeaServerPlugin"); } - protected static void addTeamCityPlugin(Map featuredPlugins) { + public static void addTeamCityPlugin(Map featuredPlugins) { featuredPlugins.put("TeamCity Integration", "Tools Integration:Integration with JetBrains TeamCity - innovative solution for continuous integration and build management:Jetbrains TeamCity Plugin"); } diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index 2fc4fcbeb05b..f36817b461c5 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -307,6 +307,11 @@ public class StartupUtil { Main.showMessage("Too Many Instances", message, true); } + if (status == SocketLock.ActivateStatus.ACTIVATED) { + System.out.println("Already running"); + System.exit(0); + } + return false; } diff --git a/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java b/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java index 8b16d37f281b..bdfc46a4bc11 100644 --- a/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java +++ b/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java @@ -20,22 +20,24 @@ import com.intellij.execution.impl.ConsoleViewUtil; import com.intellij.execution.impl.EditorHyperlinkSupport; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.icons.AllIcons; +import com.intellij.notification.impl.NotificationSettings; +import com.intellij.notification.impl.NotificationsConfigurationImpl; import com.intellij.notification.impl.NotificationsManagerImpl; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.EditorFactory; -import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.event.EditorMouseEvent; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.EditorMarkupModel; +import com.intellij.openapi.editor.ex.RangeHighlighterEx; +import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerAdapter; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; @@ -43,6 +45,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.JBColor; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.EditorPopupHandler; +import com.intellij.util.Processor; import com.intellij.util.text.DateFormatUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -57,6 +60,8 @@ import java.util.List; * @author peter */ class EventLogConsole { + private static final Key GROUP_ID = Key.create("GROUP_ID"); + private final NotNullLazyValue myLogEditor = new NotNullLazyValue() { @NotNull @Override @@ -99,7 +104,8 @@ class EventLogConsole { editor.addEditorMouseListener(new EditorPopupHandler() { public void invokePopup(final EditorMouseEvent event) { final ActionManager actionManager = ActionManager.getInstance(); - final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.EDITOR_POPUP, createPopupActions(actionManager, clearLog)); + DefaultActionGroup actions = createPopupActions(actionManager, clearLog, editor, event); + final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.EDITOR_POPUP, actions); final MouseEvent mouseEvent = event.getMouseEvent(); menu.getComponent().show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); } @@ -107,14 +113,83 @@ class EventLogConsole { return editor; } - private DefaultActionGroup createPopupActions(ActionManager actionManager, ClearLogAction action) { + private static DefaultActionGroup createPopupActions(ActionManager actionManager, + ClearLogAction action, + EditorEx editor, + EditorMouseEvent event) { AnAction[] children = ((ActionGroup)actionManager.getAction(IdeActions.GROUP_CONSOLE_EDITOR_POPUP)).getChildren(null); - DefaultActionGroup group = new DefaultActionGroup(children); + DefaultActionGroup group = new DefaultActionGroup(); + addConfigureNotificationAction(editor, event, group); + group.addAll(children); group.addSeparator(); group.add(action); return group; } + private static void addConfigureNotificationAction(@NotNull EditorEx editor, + @NotNull EditorMouseEvent event, + @NotNull DefaultActionGroup actions) { + LogicalPosition position = editor.xyToLogicalPosition(event.getMouseEvent().getPoint()); + if (EditorUtil.inVirtualSpace(editor, position)) { + return; + } + int offset = editor.logicalPositionToOffset(position); + editor.getMarkupModel().processRangeHighlightersOverlappingWith(offset, offset, new Processor() { + @Override + public boolean process(RangeHighlighterEx rangeHighlighter) { + String groupId = GROUP_ID.get(rangeHighlighter); + if (groupId != null) { + addConfigureNotificationAction(actions, groupId); + return false; + } + return true; + } + }); + } + + private static void addConfigureNotificationAction(@NotNull DefaultActionGroup actions, @NotNull String groupId) { + DefaultActionGroup displayTypeGroup = new DefaultActionGroup("Notification Display Type", true); + NotificationSettings settings = NotificationsConfigurationImpl.getSettings(groupId); + NotificationDisplayType current = settings.getDisplayType(); + + for (NotificationDisplayType type : NotificationDisplayType.values()) { + if (type != NotificationDisplayType.TOOL_WINDOW || + NotificationsConfigurationImpl.getInstanceImpl().hasToolWindowCapability(groupId)) { + displayTypeGroup.add(new DisplayTypeAction(settings, type, current)); + } + } + + actions.add(displayTypeGroup); + actions.addSeparator(); + } + + private static class DisplayTypeAction extends ToggleAction { + private final NotificationSettings mySettings; + private final NotificationDisplayType myType; + private final NotificationDisplayType myCurrent; + + public DisplayTypeAction(@NotNull NotificationSettings settings, + @NotNull NotificationDisplayType type, + @NotNull NotificationDisplayType current) { + super(type.getTitle()); + mySettings = settings; + myType = type; + myCurrent = current; + } + + @Override + public boolean isSelected(AnActionEvent e) { + return myType == myCurrent; + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + if (state) { + NotificationsConfigurationImpl.getInstanceImpl().changeSettings(mySettings.withDisplayType(myType)); + } + } + } + void doPrintNotification(final Notification notification) { Editor editor = myLogEditor.getValue(); if (editor.isDisposed()) { @@ -144,7 +219,9 @@ class EventLogConsole { TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(key); int layer = HighlighterLayer.CARET_ROW + 1; - editor.getMarkupModel().addRangeHighlighter(msgStart, document.getTextLength(), layer, attributes, HighlighterTargetArea.EXACT_RANGE); + RangeHighlighter highlighter = + editor.getMarkupModel().addRangeHighlighter(msgStart, document.getTextLength(), layer, attributes, HighlighterTargetArea.EXACT_RANGE); + GROUP_ID.set(highlighter, notification.getGroupId()); for (Pair link : pair.links) { final RangeHighlighter rangeHighlighter = myHyperlinkSupport.getValue() diff --git a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java index 739078c70f73..69426368fb40 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java @@ -15,9 +15,11 @@ */ package com.intellij.notification.impl.ui; +import com.intellij.icons.AllIcons; import com.intellij.ide.ui.UISettings; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; +import com.intellij.notification.impl.NotificationsManagerImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.Pair; @@ -157,7 +159,23 @@ public class NotificationsUtil { @NotNull public static Icon getIcon(@NotNull final Notification notification) { Icon icon = notification.getIcon(); - return icon != null ? icon : getMessageType(notification).getDefaultIcon(); + if (icon != null) { + return icon; + } + + if (!NotificationsManagerImpl.newEnabled()) { + return getMessageType(notification).getDefaultIcon(); + } + + switch (notification.getType()) { + case WARNING: + return AllIcons.General.BalloonWarning; + case ERROR: + return AllIcons.Ide.FatalError; + case INFORMATION: + default: + return AllIcons.General.BalloonInformation; + } } @NotNull diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index b00595645c10..2030906c2e9a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -51,6 +51,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.project.impl.ProjectManagerImpl; +import com.intellij.openapi.ui.DialogEarthquakeShaker; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.MessageDialogBuilder; import com.intellij.openapi.ui.Messages; @@ -61,6 +62,7 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.impl.IdeFrameImpl; import com.intellij.psi.PsiLock; import com.intellij.ui.Splash; import com.intellij.util.*; @@ -215,7 +217,12 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App final Project project = CommandLineProcessor.processExternalCommandLine(realArgs, currentDirectory); JFrame frame = project == null ? WindowManager.getInstance().findVisibleFrame() : (JFrame)WindowManager.getInstance().getIdeFrame(project); - if (frame != null) frame.requestFocus(); + if (frame != null) { + frame.toFront(); + if (!(frame instanceof IdeFrameImpl && ((IdeFrameImpl)frame).isInFullScreen())) { + DialogEarthquakeShaker.shake(frame); + } + } } }); } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateStrategy.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateStrategy.java index d295dd9cfbe6..85ba0bab8a07 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateStrategy.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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,7 +66,9 @@ public class UpdateStrategy { List activeChannels = getActiveChannels(product); for (UpdateChannel channel : activeChannels) { BuildInfo latestBuild = channel.getLatestBuild(myCurrentBuild.getBaselineVersion()); - if (latestBuild == null) latestBuild = channel.getLatestBuild(); + if (latestBuild == null || latestBuild.getNumber().compareTo(myCurrentBuild) <= 0) { + latestBuild = channel.getLatestBuild(); + } if (isNewVersion(latestBuild)) { updatedChannel = channel; newBuild = latestBuild; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/CanonicalPathMap.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/CanonicalPathMap.java index 4ae9ebe3366c..69e7afd871bc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/CanonicalPathMap.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/CanonicalPathMap.java @@ -20,16 +20,20 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileSystemUtil; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.concurrency.BoundedTaskExecutor; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.ide.PooledThreadExecutor; import java.io.File; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; import java.util.stream.Stream; import static com.intellij.openapi.util.Pair.pair; @@ -62,11 +66,19 @@ class CanonicalPathMap { } private static Map resolvePaths(Collection recursiveRoots, Collection flatRoots) { - return Stream.concat(recursiveRoots.stream(), flatRoots.stream()) - .parallel() - .map((root) -> pair(root, FileSystemUtil.resolveSymLink(root))) - .filter((p) -> p.second != null) - .collect(Collectors.toMap((p) -> p.first, (p) -> p.second)); + Map result = ContainerUtil.newConcurrentMap(); + + ExecutorService pool = new BoundedTaskExecutor(PooledThreadExecutor.INSTANCE, Runtime.getRuntime().availableProcessors()); + CompletableFuture[] futures = Stream.concat(recursiveRoots.stream(), flatRoots.stream()) + .map(root -> CompletableFuture.runAsync(() -> ContainerUtil.putIfNotNull(root, FileSystemUtil.resolveSymLink(root), result), pool)) + .toArray(CompletableFuture[]::new); + + try { CompletableFuture.allOf(futures).get(); } + catch (InterruptedException | ExecutionException e) { + LOG.error(e); + } + + return result; } private static List mapPaths(Map resolvedPaths, List paths, Collection> mapping) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 7ab4838cdaa0..d1c004d40e25 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -312,7 +312,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); Shortcut[] baseShortcut = keymap.getShortcuts("ActivateProjectToolWindow"); - int baseModifiers = 0; + int baseModifiers = SystemInfo.isMac ? InputEvent.META_MASK : InputEvent.ALT_MASK; for (Shortcut each : baseShortcut) { if (each instanceof KeyboardShortcut) { KeyStroke keyStroke = ((KeyboardShortcut)each).getFirstKeyStroke(); diff --git a/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java b/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java index b21e9d1580cb..2f18c3499e89 100644 --- a/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java +++ b/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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,6 +37,14 @@ public interface DirectoryProjectGenerator { @Nls String getName(); + /** + * @deprecated todo[vokin]: delete in 2016.3 + */ + @Nullable + default T showGenerationSettings(final VirtualFile baseDir) throws ProcessCanceledException { + return null; + } + /** * @return 16x16 icon or null, if no icon is available */ diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java index ddff55521bf7..b61191c0162f 100644 --- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java @@ -25,11 +25,11 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.util.PlatformUtils; import com.intellij.util.ReflectionUtil; +import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -127,7 +127,7 @@ public class AppUIUtil { } public static void registerBundledFonts() { - if (Boolean.getBoolean("ide.register.bundled.fonts")) { + if (SystemProperties.getBooleanProperty("ide.register.bundled.fonts", true)) { registerFont("/fonts/Inconsolata.ttf"); registerFont("/fonts/SourceCodePro-Regular.ttf"); registerFont("/fonts/SourceCodePro-Bold.ttf"); diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index 0a29bfd06c53..b478f7f829a6 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -25,6 +25,7 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.ex.AnActionListener; +import com.intellij.openapi.actionSystem.impl.ActionMenu; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.GraphicsConfig; @@ -324,7 +325,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { myDialogMode = true; return true; } - } else if (component instanceof JCheckBox) { + } + else if (component instanceof JCheckBox) { JCheckBox checkBox = (JCheckBox)component; if (checkBox.getMnemonic() >= 0 || checkBox.getDisplayedMnemonicIndex() >= 0) { myDialogMode = true; @@ -437,15 +439,18 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { JDialog dialog = IJSwingUtilities.findParentOfType(comp, JDialog.class); if (dialog != null) { root = dialog.getRootPane(); - } else { + } + else { JWindow jwindow = IJSwingUtilities.findParentOfType(comp, JWindow.class); if (jwindow != null) { root = jwindow.getRootPane(); - } else { + } + else { JFrame frame = IJSwingUtilities.findParentOfType(comp, JFrame.class); if (frame != null) { root = frame.getRootPane(); - } else { + } + else { assert false; } } @@ -522,7 +527,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { } if (myPosition != position) { - myTargetPoint = myPosition.getShiftedPoint(myTracker.recalculateLocation(this).getPoint(myLayeredPane), myCalloutShift > 0 ? myCalloutShift + positionChangeFix : positionChangeFix); + myTargetPoint = myPosition.getShiftedPoint(myTracker.recalculateLocation(this).getPoint(myLayeredPane), + myCalloutShift > 0 ? myCalloutShift + positionChangeFix : positionChangeFix); } createComponent(); @@ -531,13 +537,15 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { Rectangle rec = myComp.getContentBounds(); - if (myShowPointer && !myPosition.isOkToHavePointer(myTargetPoint, rec, getPointerLength(myPosition), getPointerWidth(myPosition), getArc())) { + if (myShowPointer && + !myPosition.isOkToHavePointer(myTargetPoint, rec, getPointerLength(myPosition), getPointerWidth(myPosition), getArc())) { myShowPointer = false; myComp.removeAll(); myLayeredPane.remove(myComp); createComponent(); - if (!new Rectangle(myLayeredPane.getSize()).contains(new Rectangle(myComp.getSize()))) { // Balloon is bigger than window, don't show it at all. + if (!new Rectangle(myLayeredPane.getSize()) + .contains(new Rectangle(myComp.getSize()))) { // Balloon is bigger than window, don't show it at all. myComp.removeAll(); myLayeredPane.remove(myComp); myLayeredPane = null; @@ -667,7 +675,9 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { Icon icon = getCloseButton(); int iconWidth = icon.getIconWidth(); int iconHeight = icon.getIconHeight(); - Rectangle r = new Rectangle(lpBounds.x + lpBounds.width - iconWidth + (int)(iconWidth * 0.3), lpBounds.y - (int)(iconHeight * 0.3), iconWidth, iconHeight); + Rectangle r = + new Rectangle(lpBounds.x + lpBounds.width - iconWidth + (int)(iconWidth * 0.3), lpBounds.y - (int)(iconHeight * 0.3), iconWidth, + iconHeight); Insets border = getShadowBorderInsets(); r.x -= border.left; @@ -765,7 +775,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { @Override public void showInCenterOf(JComponent component) { final Dimension size = component.getSize(); - show(new RelativePoint(component, new Point(size.width/2, size.height/2)), Balloon.Position.above); + show(new RelativePoint(component, new Point(size.width / 2, size.height / 2)), Balloon.Position.above); } public void show(JLayeredPane pane, @Nullable Rectangle bounds) { @@ -843,7 +853,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { int getPointerWidth(AbstractPosition position) { if (myDialogMode) { return position.isTopBottomPointer() ? DIALOG_TOPBOTTOM_POINTER_WIDTH : DIALOG_POINTER_WIDTH; - } else { + } + else { return position.isTopBottomPointer() ? TOPBOTTOM_POINTER_WIDTH : POINTER_WIDTH; } } @@ -859,7 +870,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { static int getPointerLength(AbstractPosition position, boolean dialogMode) { if (dialogMode) { return position.isTopBottomPointer() ? DIALOG_TOPBOTTOM_POINTER_LENGTH : DIALOG_POINTER_LENGTH; - } else { + } + else { return position.isTopBottomPointer() ? TOPBOTTOM_POINTER_LENGTH : POINTER_LENGTH; } } @@ -905,7 +917,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { Toolkit.getDefaultToolkit().removeAWTEventListener(myAwtActivityListener); if (myLayeredPane != null) { myLayeredPane.removeComponentListener(myComponentListener); - Disposer.register(ApplicationManager.getApplication(), this); // to be safe if Application suddenly exits and animation wouldn't have a chance to complete + Disposer.register(ApplicationManager.getApplication(), + this); // to be safe if Application suddenly exits and animation wouldn't have a chance to complete runAnimation(false, myLayeredPane, disposeRunnable); } @@ -924,7 +937,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { } } - protected void onDisposed() { } + protected void onDisposed() { + } @Override public void addListener(@NotNull JBPopupListener listener) { @@ -1080,7 +1094,12 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { final BalloonImpl balloon); public boolean isOkToHavePointer(Point targetPoint, Rectangle bounds, int pointerLength, int pointerWidth, int arc) { - if (bounds.x < targetPoint.x && bounds.x + bounds.width > targetPoint.x && bounds.y < targetPoint.y && bounds.y + bounds.height < targetPoint.y) return false; + if (bounds.x < targetPoint.x && + bounds.x + bounds.width > targetPoint.x && + bounds.y < targetPoint.y && + bounds.y + bounds.height < targetPoint.y) { + return false; + } Rectangle pointless = getPointlessContentRec(bounds, pointerLength); @@ -1184,7 +1203,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { @Override protected Shape getPointingShape(final Rectangle bounds, final Point pointTarget, final BalloonImpl balloon) { final Shaper shaper = new Shaper(balloon, bounds, pointTarget, SwingConstants.TOP); - shaper.line(balloon.getPointerWidth(this) / 2, balloon.getPointerLength(this)).toRightCurve().roundRightDown().toBottomCurve().roundLeftDown() + shaper.line(balloon.getPointerWidth(this) / 2, balloon.getPointerLength(this)).toRightCurve().roundRightDown().toBottomCurve() + .roundLeftDown() .toLeftCurve().roundLeftUp().toTopCurve().roundUpRight() .lineTo(pointTarget.x - balloon.getPointerWidth(this) / 2, shaper.getCurrent().y).lineTo(pointTarget.x, pointTarget.y); shaper.close(); @@ -1247,7 +1267,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { final Shaper shaper = new Shaper(balloon, bounds, pointTarget, SwingConstants.BOTTOM); shaper.line(-balloon.getPointerWidth(this) / 2, -balloon.getPointerLength(this) + 1); shaper.toLeftCurve().roundLeftUp().toTopCurve().roundUpRight().toRightCurve().roundRightDown().toBottomCurve().line(0, 2) - .roundLeftDown().lineTo(pointTarget.x + balloon.getPointerWidth(this) / 2, shaper.getCurrent().y).lineTo(pointTarget.x, pointTarget.y) + .roundLeftDown().lineTo(pointTarget.x + balloon.getPointerWidth(this) / 2, shaper.getCurrent().y) + .lineTo(pointTarget.x, pointTarget.y) .close(); @@ -1307,7 +1328,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { @Override protected Shape getPointingShape(final Rectangle bounds, final Point pointTarget, final BalloonImpl balloon) { final Shaper shaper = new Shaper(balloon, bounds, pointTarget, SwingConstants.LEFT); - shaper.line(balloon.getPointerLength(this), -balloon.getPointerWidth(this) / 2).toTopCurve().roundUpRight().toRightCurve().roundRightDown() + shaper.line(balloon.getPointerLength(this), -balloon.getPointerWidth(this) / 2).toTopCurve().roundUpRight().toRightCurve() + .roundRightDown() .toBottomCurve().roundLeftDown().toLeftCurve().roundLeftUp() .lineTo(shaper.getCurrent().x, pointTarget.y + balloon.getPointerWidth(this) / 2).lineTo(pointTarget.x, pointTarget.y).close(); @@ -1368,7 +1390,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { @Override protected Shape getPointingShape(final Rectangle bounds, final Point pointTarget, final BalloonImpl balloon) { final Shaper shaper = new Shaper(balloon, bounds, pointTarget, SwingConstants.RIGHT); - shaper.lineTo((int)bounds.getMaxX() - shaper.getTargetDelta(SwingConstants.RIGHT) - 1, pointTarget.y + balloon.getPointerWidth(this) / 2); + shaper + .lineTo((int)bounds.getMaxX() - shaper.getTargetDelta(SwingConstants.RIGHT) - 1, pointTarget.y + balloon.getPointerWidth(this) / 2); shaper.toBottomCurve().roundLeftDown().toLeftCurve().roundLeftUp().toTopCurve().roundUpRight().toRightCurve().roundRightDown() .lineTo(shaper.getCurrent().x, pointTarget.y - balloon.getPointerWidth(this) / 2).lineTo(pointTarget.x, pointTarget.y).close(); return shaper.getShape(); @@ -1385,12 +1408,14 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { public class ActionButton extends NonOpaquePanel { private final Icon myIcon; private final Icon myHoverIcon; + private final String myHint; private final Consumer myListener; protected final BaseButtonBehavior myButton; - public ActionButton(@NotNull Icon icon, @Nullable Icon hoverIcon, @NotNull Consumer listener) { + public ActionButton(@NotNull Icon icon, @Nullable Icon hoverIcon, @Nullable String hint, @NotNull Consumer listener) { myIcon = icon; myHoverIcon = hoverIcon; + myHint = hint; myListener = listener; myButton = new BaseButtonBehavior(this, TimedDeadzone.NULL) { @@ -1412,13 +1437,21 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { if (hasPaint()) { if (myHoverIcon != null && myButton.isHovered()) { paintIcon(g, myHoverIcon); + showHint(true); } else { paintIcon(g, myIcon); + showHint(false); } } } + private void showHint(boolean show) { + if (myHint != null) { + ActionMenu.showDescriptionInStatusBar(true, this, show ? myHint : null); + } + } + public boolean hasPaint() { return getWidth() > 0 && myLastMoveWasInsideBalloon; } @@ -1430,7 +1463,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { private class CloseButton extends ActionButton { private CloseButton(@NotNull Consumer listener) { - super(getCloseButton(), null, listener); + super(getCloseButton(), null, null, listener); setVisible(myEnableButtons); } @@ -1474,8 +1507,6 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { myContent.setOpaque(false); add(myContent); - - } public Rectangle getContentBounds() { @@ -1522,7 +1553,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { private void paintChildrenImpl(Graphics g) { // Paint to an image without alpha to preserve fonts subpixel antialiasing @SuppressWarnings("UndesirableClassUsage") - BufferedImage image = UIUtil.createImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);//new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB); + BufferedImage image = UIUtil.createImage(getWidth(), getHeight(), + BufferedImage.TYPE_INT_RGB);//new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D imageGraphics = image.createGraphics(); //noinspection UseJBColor imageGraphics.setColor(new Color(myFillColor.getRGB())); // create a copy to remove alpha @@ -1611,7 +1643,8 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { shape = myBalloon.myPosition.getPointingShape(bounds, pointTarget, myBalloon); } else { - shape = new RoundRectangle2D.Double(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1, myBalloon.getArc(), myBalloon.getArc()); + shape = + new RoundRectangle2D.Double(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1, myBalloon.getArc(), myBalloon.getArc()); } return shape.contains(x, y); } diff --git a/platform/platform-impl/src/com/intellij/ui/NotificationBalloonActionProvider.java b/platform/platform-impl/src/com/intellij/ui/NotificationBalloonActionProvider.java index 2890db7e87c5..736fc07420b7 100644 --- a/platform/platform-impl/src/com/intellij/ui/NotificationBalloonActionProvider.java +++ b/platform/platform-impl/src/com/intellij/ui/NotificationBalloonActionProvider.java @@ -61,6 +61,7 @@ public class NotificationBalloonActionProvider implements BalloonImpl.ActionProv else { mySettingButton = myBalloon.new ActionButton( AllIcons.Ide.Notification.Gear, AllIcons.Ide.Notification.GearHover, + "Configure Notification", new Consumer() { @Override public void consume(MouseEvent event) { @@ -101,6 +102,7 @@ public class NotificationBalloonActionProvider implements BalloonImpl.ActionProv myCloseButton = myBalloon.new ActionButton( AllIcons.Ide.Notification.Close, AllIcons.Ide.Notification.CloseHover, + "Close Notification (Alt-Click close all notifications)", new Consumer() { @Override public void consume(MouseEvent event) { diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index 0aadec9a3d6a..01eece58bb2a 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -427,7 +427,6 @@ livetemplate.description.surround.cdata.in.xmlorhtmlorjsp=Surround with CDATA se livetemplate.description.surround.with.callable=Surround with Callable livetemplate.description.surround.with.read.lock=Surround with ReadWriteLock.readLock livetemplate.description.surround.with.write.lock=Surround with ReadWriteLock.writeLock -livetemplate.description.surround.with.ARM=Surround with try-with-resources quickfix.add.variable.text=Initialize variable ''{0}'' quickfix.add.variable.family.name=Initialize variable inspection.i18n.quickfix.annotate.as=Annotate as @{0} diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index d6a8ff8af935..f153c9455837 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -1128,8 +1128,6 @@ unsupported.jvm.ea.message=Early Access Java versions may cause compatibility is ibus.blocking.warn.message=IBus prior to 1.5.11 may cause input problems. See IDEA-78860 for details. -ayatana.menu.warn.message=JAyatana may cause menus not working, hence disabled. See IDEA-141725 for details. - sys.health.acknowledge.link=
Do not show again. low.disk.space.message=Low disk space on a {0} system directory partition diff --git a/platform/platform-resources-en/src/messages/XmlBundle.properties b/platform/platform-resources-en/src/messages/XmlBundle.properties index 6fbf7fb1da98..7e076c192308 100644 --- a/platform/platform-resources-en/src/messages/XmlBundle.properties +++ b/platform/platform-resources-en/src/messages/XmlBundle.properties @@ -99,6 +99,7 @@ xml.dtd.unresolved.entity.reference=Unresolved Entity Reference {0} xml.dtd.unresolved.element.reference=Unresolved Dtd Element Reference {0} change.root.element.to=Change root tag name to {0} insert.required.tag.fix=Insert required child tag {0} +insert.required.tag.fix.family=Insert required child tag # rename refactoring rename.current.tag=Rename {0} to: diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index b8e0729da2b4..ca09d5f97caf 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -151,7 +151,8 @@ - + diff --git a/platform/platform-resources/src/brokenPlugins.txt b/platform/platform-resources/src/brokenPlugins.txt index f8f57dfd4829..c6cb23d867f5 100644 --- a/platform/platform-resources/src/brokenPlugins.txt +++ b/platform/platform-resources/src/brokenPlugins.txt @@ -17,6 +17,7 @@ SBT 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0 1.5.1 1.6.0 1.6.1 1.7.0 AngularJS 141.1237 141.991 142.2481 142.4081 142.1935 141.2 140.1968 139.1112 139.12 134.1243 134.1341 134.1444 135.1063 135.565 135.831 135.937 138.1242 138.1988 134.1094 0.1.8 0.1.9 com.jetbrains.plugins.ini4idea 0.4 0.5 0.6 0.7 0.8 0.8.1 0.9 0.9.1 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 130.1176 org.jetbrains.plugins.vagrant 0.1 0.2 0.3 0.4 0.5 0.6.143.3 +com.intellij.apacheConfig 143.381.48 org.intellij.clojure 0.2.1.178 net.nicoulaj.idea.markdown 0.9.5 0.9.4 0.9.3 0.9.2 0.9.1 0.8.3 0.8.2 0.8.1 0.8 0.7 0.6.1 0.6 0.5.1 0.5 0.4 0.3 0.2 0.1 zielu.gittoolbox 13.1.0 13.5.2 @@ -34,7 +35,7 @@ com.jetbrains.plugins.meteor 143.1183 143.1088 143.379 143.360 143.88 142.2481 org.bitbucket.connector 1.1.10 1.1.12 1.2 1.2.1 ro.redeul.google.go 0.5.0 0.5.1 0.9.1 0.9.10 0.9.11 0.9.12 0.9.13 0.9.2 0.9.3 0.9.4 0.9.5 0.9.6 0.9.9 0.9.15 0.9.15.1 0.9.15.2 0.9.15.3 0.9.220 0.9.221 0.9.201 0.9.223 0.9.230 0.9.231 0.9.234 0.9.238 0.9.241 0.9.242 0.9.244 0.9.249 0.9.250 0.9.251 TFS 121.185 121.390 124.218 124.297 124.344 124.533 126.254 126.309 127.14 129.105 -"Haxe Support" "0.9.7 for IDEA 14.1.4" +com.intellij.plugins.haxe "0.9.7 for IDEA 14.1.4" com.sencha.idea.IdeaPlugin 6.0.6.456 6.0.4.438 6.0.3.430 6.0.2.414 6.0.1.396 6.0.0.390 "0.4.325 (SenchaCon 2015 EA)" "0.3.323 (SenchaCon 2015 EA)" "0.3.312 (SenchaCon 2015 EA)" "0.2.251 (SenchaCon 2015 EA)" "0.1.211 (SenchaCon 2015 EA)" "0.1.210.1 (SenchaCon 2015 EA)" "0.1.210 (SenchaCon 2015 EA)" com.intellij.swift 144.SNAPSHOT SpellChecker 1.0 diff --git a/platform/platform-tests/testSrc/com/intellij/ide/updates/UpdateStrategyTest.java b/platform/platform-tests/testSrc/com/intellij/ide/updates/UpdateStrategyTest.java index b4cdf84242c2..3cae33381c18 100644 --- a/platform/platform-tests/testSrc/com/intellij/ide/updates/UpdateStrategyTest.java +++ b/platform/platform-tests/testSrc/com/intellij/ide/updates/UpdateStrategyTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -195,6 +195,20 @@ public class UpdateStrategyTest { assertEquals("143.888", build.getNumber().toString()); } + @Test + public void testCrossingParallelCampaignsInChannel() { + BuildNumber currentBuild = BuildNumber.fromString("IU-143.888"); + TestUpdateSettings settings = new TestUpdateSettings(ChannelStatus.EAP); + UpdateStrategyCustomization customization = new UpdateStrategyCustomization(); + UpdateStrategy strategy = new UpdateStrategy(15, currentBuild, InfoReader.read("idea-2eap.xml"), settings, customization); + + CheckForUpdateResult result = strategy.checkForUpdates(); + assertEquals(UpdateStrategy.State.LOADED, result.getState()); + BuildInfo build = result.getNewBuildInSelectedChannel(); + assertNotNull(build); + assertEquals("144.888", build.getNumber().toString()); + } + private static class TestUpdateSettings implements UserUpdateSettings { private final ChannelStatus myChannelStatus; private final List myIgnoredBuildNumbers; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImplTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImplTest.java index 81029fb59ccb..87f159200272 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/colors/impl/EditorColorsSchemeImplTest.java @@ -20,6 +20,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.colors.FontPreferences; import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.markup.EffectType; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.WriteExternalException; @@ -45,20 +46,21 @@ import java.util.Collections; import static com.intellij.openapi.editor.colors.FontPreferencesTest.*; import static java.util.Collections.singletonList; +@SuppressWarnings("Duplicates") public class EditorColorsSchemeImplTest extends LightPlatformCodeInsightTestCase { EditorColorsSchemeImpl myScheme = new EditorColorsSchemeImpl(null); public void testDefaults() { checkState(myScheme.getFontPreferences(), - Collections.emptyList(), - Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), FontPreferences.DEFAULT_FONT_NAME, FontPreferences.DEFAULT_FONT_NAME, null); assertEquals(FontPreferences.DEFAULT_FONT_NAME, myScheme.getEditorFontName()); assertEquals(FontPreferences.DEFAULT_FONT_SIZE, myScheme.getEditorFontSize()); checkState(myScheme.getConsoleFontPreferences(), - Collections.emptyList(), - Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), FontPreferences.DEFAULT_FONT_NAME, FontPreferences.DEFAULT_FONT_NAME, null); assertEquals(FontPreferences.DEFAULT_FONT_NAME, myScheme.getConsoleFontName()); @@ -290,6 +292,37 @@ public class EditorColorsSchemeImplTest extends LightPlatformCodeInsightTestCase } } + + @SuppressWarnings("unused") + public void testIdea152156() throws Exception { + EditorColorsScheme defaultScheme = EditorColorsManager.getInstance().getScheme(EditorColorsScheme.DEFAULT_SCHEME_NAME); + EditorColorsScheme parentScheme = (EditorColorsScheme)defaultScheme.clone(); + parentScheme.setName("DefaultTest"); + EditorColorsScheme editorColorsScheme = new EditorColorsSchemeImpl(parentScheme); + editorColorsScheme.setName("test"); + TextAttributes defaultAttributes = new TextAttributes(null, null, Color.BLACK, EffectType.LINE_UNDERSCORE, Font.PLAIN); + TextAttributes attributes = new TextAttributes(null, null, null, EffectType.BOXED, Font.PLAIN); + attributes.setEnforceEmpty(false); + assertTrue(attributes.isFallbackEnabled()); + TextAttributesKey testKey = TextAttributesKey.createTextAttributesKey("TEST_KEY", DefaultLanguageHighlighterColors.PARAMETER); + parentScheme.setAttributes(testKey, defaultAttributes); + editorColorsScheme.setAttributes(testKey, attributes); + try { + Element root = new Element("scheme"); + ((AbstractColorsScheme)editorColorsScheme).writeExternal(root); + EditorColorsScheme targetScheme = new EditorColorsSchemeImpl(parentScheme); + for (final Element child : root.getChildren()) { + if ("attributes".equals(child.getName())) { + ((EditorColorsSchemeImpl)targetScheme).readAttributes(child); + } + } + TextAttributes targetAttributes = ((AbstractColorsScheme)targetScheme).getDirectlyDefinedAttributes(testKey); + assertTrue(targetAttributes != null && targetAttributes.isFallbackEnabled()); + } + finally { + TextAttributesKey.removeTextAttributesKey(testKey.getExternalName()); + } + } private static EditorColorsScheme loadScheme(@NotNull String docText) throws ParserConfigurationException, IOException, SAXException { diff --git a/platform/platform-tests/testSrc/com/intellij/util/AlarmTest.java b/platform/platform-tests/testSrc/com/intellij/util/AlarmTest.java index 10106c38cbd9..b2f8f747cbd3 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/AlarmTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/AlarmTest.java @@ -1,4 +1,4 @@ -/* + /* * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,12 +15,20 @@ */ package com.intellij.util; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.testFramework.PlatformTestCase; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class AlarmTest extends PlatformTestCase { public void testTwoAddsWithZeroDelayMustExecuteSequentially() throws Exception { @@ -43,7 +51,7 @@ public class AlarmTest extends PlatformTestCase { assertRequestsExecuteSequentially(alarm); } - private static void assertRequestsExecuteSequentially(Alarm alarm) throws InterruptedException, ExecutionException, TimeoutException { + private static void assertRequestsExecuteSequentially(@NotNull Alarm alarm) throws InterruptedException, ExecutionException, TimeoutException { int N = 100000; StringBuffer log = new StringBuffer(N*4); StringBuilder expected = new StringBuilder(N * 4); @@ -55,9 +63,50 @@ public class AlarmTest extends PlatformTestCase { for (int i = 0; i < N; i++) { expected.append(i).append(" "); } - alarm.waitForAllExecuted(100, TimeUnit.SECONDS); - UIUtil.dispatchAllInvocationEvents(); + Future future = ApplicationManager.getApplication().executeOnPooledThread(() -> { + try { + alarm.waitForAllExecuted(100, TimeUnit.SECONDS); + } + catch (Exception e) { + throw new RuntimeException(e); + } + }); + while (!future.isDone()) { + UIUtil.dispatchAllInvocationEvents(); + } + future.get(); assertEquals(0, alarm.getActiveRequestCount()); assertEquals(expected.toString(), log.toString()); } + + public void testOneAlarmDoesNotStartTooManyThreads() throws InterruptedException, ExecutionException, TimeoutException { + Alarm alarm = new Alarm(getTestRootDisposable()); + Map before = Thread.getAllStackTraces(); + AtomicInteger executed = new AtomicInteger(); + int N = 100000; + for (int i = 0; i < N; i++) { + alarm.addRequest(executed::incrementAndGet, 100); + } + while (executed.get() != N) { + UIUtil.dispatchAllInvocationEvents(); + } + Map after = Thread.getAllStackTraces(); + System.out.println("before: "+before.size()+"; after: "+after.size()); + assertTrue(Math.abs(before.size() - after.size()) < 10); + } + + public void testManyAlarmsDoNotStartTooManyThreads() throws InterruptedException, ExecutionException, TimeoutException { + Map before = Thread.getAllStackTraces(); + AtomicInteger executed = new AtomicInteger(); + int N = 100000; + List alarms = Collections.nCopies(N, "").stream().map(__ -> new Alarm(getTestRootDisposable())).collect(Collectors.toList()); + alarms.forEach(alarm -> alarm.addRequest(executed::incrementAndGet, 100)); + + while (executed.get() != N) { + UIUtil.dispatchAllInvocationEvents(); + } + Map after = Thread.getAllStackTraces(); + System.out.println("before: "+before.size()+"; after: "+after.size()); + assertTrue(Math.abs(before.size() - after.size()) < 10); + } } \ No newline at end of file diff --git a/platform/script-debugger/backend/src/Vm.kt b/platform/script-debugger/backend/src/Vm.kt index 03b01f6afdc4..ebe9e23325f3 100644 --- a/platform/script-debugger/backend/src/Vm.kt +++ b/platform/script-debugger/backend/src/Vm.kt @@ -44,4 +44,7 @@ interface Vm : UserDataHolderEx { fun setBreakOnException(catchMode: ExceptionCatchMode) = resolvedPromise() var captureAsyncStackTraces: Boolean + + val name: String? + get() = null } \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/BasicDebuggerViewSupport.kt b/platform/script-debugger/debugger-ui/src/BasicDebuggerViewSupport.kt index 0634eb7aedb5..1de2f77211c6 100644 --- a/platform/script-debugger/debugger-ui/src/BasicDebuggerViewSupport.kt +++ b/platform/script-debugger/debugger-ui/src/BasicDebuggerViewSupport.kt @@ -16,13 +16,13 @@ package org.jetbrains.debugger import com.intellij.xdebugger.frame.XValueNode -import org.jetbrains.concurrency.Promise +import org.jetbrains.concurrency.resolvedPromise import org.jetbrains.debugger.values.ObjectValue import org.jetbrains.debugger.values.Value import javax.swing.Icon open class BasicDebuggerViewSupport : MemberFilter, DebuggerViewSupport { - protected val defaultMemberFilterPromise = Promise.resolve(this) + protected val defaultMemberFilterPromise = resolvedPromise(this) override fun propertyNamesToString(list: List, quotedAware: Boolean) = ValueModifierUtil.propertyNamesToString(list, quotedAware) diff --git a/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt b/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt index da01f4825b81..090b5b301951 100644 --- a/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt +++ b/platform/script-debugger/debugger-ui/src/DebugProcessImpl.kt @@ -30,17 +30,24 @@ import com.intellij.xdebugger.breakpoints.XBreakpointHandler import com.intellij.xdebugger.breakpoints.XBreakpointType import com.intellij.xdebugger.breakpoints.XLineBreakpoint import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider +import com.intellij.xdebugger.frame.XSuspendContext import com.intellij.xdebugger.stepping.XSmartStepIntoHandler import org.jetbrains.concurrency.Promise import org.jetbrains.debugger.connection.VmConnection import java.util.concurrent.ConcurrentMap import java.util.concurrent.atomic.AtomicBoolean +interface MultiVmDebugProcess { + val mainVm: Vm? + val activeOrMainVm: Vm? + val childConnections: List> +} + abstract class DebugProcessImpl>(session: XDebugSession, val connection: C, private val editorsProvider: XDebuggerEditorsProvider, private val smartStepIntoHandler: XSmartStepIntoHandler<*>? = null, - protected val executionResult: ExecutionResult? = null) : XDebugProcess(session) { + protected val executionResult: ExecutionResult? = null) : XDebugProcess(session), MultiVmDebugProcess { protected val repeatStepInto: AtomicBoolean = AtomicBoolean() @Volatile var lastStep: StepAction? = null @Volatile protected var lastCallFrame: CallFrame? = null @@ -56,6 +63,29 @@ abstract class DebugProcessImpl>(session: XDebugSession, private val _breakpointHandlers: Array> by lazy(LazyThreadSafetyMode.NONE) { createBreakpointHandlers() } + protected final val realProcessHandler: ProcessHandler? + get() = executionResult?.processHandler + + override final fun getSmartStepIntoHandler() = smartStepIntoHandler + + override final fun getBreakpointHandlers() = when (connection.state.status) { + ConnectionStatus.DISCONNECTED, ConnectionStatus.DETACHED, ConnectionStatus.CONNECTION_FAILED -> XBreakpointHandler.EMPTY_ARRAY + else -> _breakpointHandlers + } + + override final fun getEditorsProvider() = editorsProvider + + val vm: Vm? + get() = connection.vm + + override final val mainVm: Vm? + get() = connection.vm + + override final val activeOrMainVm: Vm? + get() = (session.suspendContext?.activeExecutionStack as? ExecutionStackView)?.suspendContext?.vm ?: mainVm + + override final val childConnections = ContainerUtil.createConcurrentList() + init { connection.stateChanged { when (it.status) { @@ -79,27 +109,6 @@ abstract class DebugProcessImpl>(session: XDebugSession, } } - protected final val realProcessHandler: ProcessHandler? - get() = executionResult?.processHandler - - override final fun getSmartStepIntoHandler() = smartStepIntoHandler - - override final fun getBreakpointHandlers() = when (connection.state.status) { - ConnectionStatus.DISCONNECTED, ConnectionStatus.DETACHED, ConnectionStatus.CONNECTION_FAILED -> XBreakpointHandler.EMPTY_ARRAY - else -> _breakpointHandlers - } - - override final fun getEditorsProvider() = editorsProvider - - val vm: Vm? - get() = connection.vm - - val mainVm: Vm? - get() = connection.vm - - val activeOrMainVm: Vm? - get() = (session.suspendContext?.activeExecutionStack as? ExecutionStackView)?.suspendContext?.vm ?: mainVm - protected abstract fun createBreakpointHandlers(): Array> private fun updateLastCallFrame(vm: Vm) { @@ -110,25 +119,28 @@ abstract class DebugProcessImpl>(session: XDebugSession, override final fun isValuesCustomSorted() = true - override final fun startStepOver() { - val vm = activeOrMainVm!! + override final fun startStepOver(context: XSuspendContext?) { + val vm = context.vm updateLastCallFrame(vm) continueVm(vm, StepAction.OVER) } + val XSuspendContext?.vm: Vm + get() = (this as? SuspendContextView)?.activeExecutionStack?.suspendContext?.vm ?: mainVm!! + override final fun startForceStepInto() { isForceStep = true startStepInto() } - override final fun startStepInto() { - val vm = activeOrMainVm!! + override final fun startStepInto(context: XSuspendContext?) { + val vm = context.vm updateLastCallFrame(vm) continueVm(vm, if (vm.captureAsyncStackTraces) StepAction.IN_ASYNC else StepAction.IN) } - override final fun startStepOut() { - val vm = activeOrMainVm!! + override final fun startStepOut(context: XSuspendContext?) { + val vm = context.vm if (isVmStepOutCorrect()) { lastCallFrame = null } @@ -141,10 +153,8 @@ abstract class DebugProcessImpl>(session: XDebugSession, // some VM (firefox for example) doesn't implement step out correctly, so, we need to fix it protected open fun isVmStepOutCorrect() = true - @Deprecated("Pass vm explicitly", ReplaceWith("resume(vm!!)")) - override fun resume() { - @Suppress("DEPRECATION") - continueVm(activeOrMainVm!!, StepAction.CONTINUE) + override fun resume(context: XSuspendContext?) { + continueVm(context.vm, StepAction.CONTINUE) } open fun resume(vm: Vm) { @@ -257,6 +267,15 @@ abstract class DebugProcessImpl>(session: XDebugSession, } } } + + open protected fun initChildConnection(childConnection: C) { + childConnections.add(childConnection) + childConnection.stateChanged { + if (it.status == ConnectionStatus.CONNECTION_FAILED || it.status == ConnectionStatus.DISCONNECTED || it.status == ConnectionStatus.DETACHED) { + childConnections.remove(childConnection) + } + } + } } @Suppress("UNCHECKED_CAST") diff --git a/platform/script-debugger/debugger-ui/src/SuspendContextBase.kt b/platform/script-debugger/debugger-ui/src/SuspendContextView.kt similarity index 69% rename from platform/script-debugger/debugger-ui/src/SuspendContextBase.kt rename to platform/script-debugger/debugger-ui/src/SuspendContextView.kt index 6f1834382413..9e6c577e1d3f 100644 --- a/platform/script-debugger/debugger-ui/src/SuspendContextBase.kt +++ b/platform/script-debugger/debugger-ui/src/SuspendContextView.kt @@ -30,9 +30,48 @@ import org.jetbrains.debugger.frame.CallFrameView import org.jetbrains.debugger.values.StringValue import java.util.* -abstract class SuspendContextView(protected val activeStack: ExecutionStackView) : XSuspendContext() { +const val MAIN_LOOP_NAME = "main loop" + +abstract class SuspendContextView(protected val debugProcess: MultiVmDebugProcess, protected val activeStack: ExecutionStackView) : XSuspendContext() { protected open val stacks by lazy { - arrayOf(activeStack) + val childConnections = debugProcess.childConnections + if (childConnections.isNotEmpty()) { + val list = ArrayList(1 + childConnections.size) + + val mainVm = debugProcess.mainVm + if (activeStack.suspendContext.vm == mainVm) { + list.add(activeStack) + } + else { + list.add(createStackView(mainVm?.suspendContextManager?.context, MAIN_LOOP_NAME)) + } + + childConnections.mapNotNullTo(list) { + it.vm?.let { + val context = it.suspendContextManager.context + if (context == activeStack.suspendContext) { + activeStack + } + else { + val displayName = it.name ?: throw IllegalStateException("Name must be not null for child VM") + createStackView(context, displayName) + } + } + } + list.toTypedArray() + } + else { + arrayOf(activeStack) + } + } + + private fun createStackView(context: SuspendContext<*>?, displayName: String): XExecutionStack { + return if (context == null) { + RunningThreadExecutionStackView(displayName) + } + else { + ExecutionStackView(context, activeStack.viewSupport, null, null, displayName) + } } override fun getActiveExecutionStack() = activeStack @@ -56,14 +95,21 @@ abstract class SuspendContextView(protected val activeStack: ExecutionStackView) } } -const val MAIN_LOOP_NAME = "main loop" +class RunningThreadExecutionStackView(displayName: String) : XExecutionStack(displayName, AllIcons.Debugger.ThreadRunning) { + override fun computeStackFrames(firstFrameIndex: Int, container: XStackFrameContainer?) { + // add dependency to DebuggerBundle? + container?.errorOccurred("Frames not available for unsuspended thread") + } + + override fun getTopFrame(): XStackFrame? = null +} // icon ThreadCurrent would be preferred for active thread, but it won't be updated on stack change -open class ExecutionStackView(val suspendContext: SuspendContext<*>, - private val viewSupport: DebuggerViewSupport, - private val topFrameScript: Script?, - private val topFrameSourceInfo: SourceInfo? = null, - displayName: String = "") : XExecutionStack(displayName, AllIcons.Debugger.ThreadAtBreakpoint) { +class ExecutionStackView(val suspendContext: SuspendContext<*>, + internal val viewSupport: DebuggerViewSupport, + private val topFrameScript: Script?, + private val topFrameSourceInfo: SourceInfo? = null, + displayName: String = "") : XExecutionStack(displayName, AllIcons.Debugger.ThreadAtBreakpoint) { private var topCallFrameView: CallFrameView? = null override fun getTopFrame(): CallFrameView? { diff --git a/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java b/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java index 4cd93630874e..c5c0d8f78e21 100644 --- a/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java +++ b/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java @@ -92,6 +92,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase { { "control EQUALS", "ExpandAll", "ExpandRegion"}, { "control F5", "Refresh", "Rerun"}, { "control D", "EditorDuplicate", "Diff.ShowDiff", "CompareTwoFiles", "SendEOF", "FileChooser.GotoDesktop"}, + { "control L", "FindNext", "Vcs.Log.FocusTextFilter"}, { "control M", "EditorScrollToCenter", "Vcs.ShowMessageHistory"}, { "control N", "FileChooser.NewFolder", "GotoClass", "GotoChangedFile"}, { "control P", "FileChooser.TogglePathShowing", "ParameterInfo"}, @@ -143,6 +144,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase { { "control UP", "EditorLookupUp", "MethodUp"}, { "control TAB", "Switcher", "Diff.FocusOppositePane"}, { "shift control TAB", "Switcher", "Diff.FocusOppositePaneAndScroll"}, + { "meta L", "Vcs.Log.FocusTextFilter", "GotoLine"}, { "meta R", "Refresh", "Rerun", "Replace", "org.jetbrains.plugins.ruby.rails.console.ReloadSources"}, { "control O", "ExportToTextFile", "OverrideMethods", }, { "control ENTER", "Generate", "NewElement"}, @@ -188,6 +190,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase { { "control 3", "GotoBookmark3", "FileChooser.GotoModule"}, { "control D", "$Delete", "Diff.ShowDiff", "CompareTwoFiles", "SendEOF", "FileChooser.GotoDesktop"}, { "control K", "EditorCutLineEnd", "CheckinProject"}, + { "control L", "EditorScrollToCenter", "Vcs.Log.FocusTextFilter"}, { "control M", "EditorEnter", "EditorChooseLookupItem", "NextTemplateVariable", "Console.Execute"}, { "control N", "EditorDown", "FileChooser.NewFolder"}, { "control P", "EditorUp", "FileChooser.TogglePathShowing"}, @@ -259,6 +262,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase { { "control F10", "ShowPopupMenu", "javaee.UpdateRunningApplication", "liveedit.UpdateRunningApplication"}, { "control F11", "Rerun", "ToggleBookmarkWithMnemonic"}, { "control D", "EditorDeleteLine", "Diff.ShowDiff", "CompareTwoFiles", "SendEOF", "FileChooser.GotoDesktop"}, + { "control L", "Vcs.Log.FocusTextFilter", "GotoLine"}, { "control N", "ShowPopupMenu", "FileChooser.NewFolder"}, { "control P", "FileChooser.TogglePathShowing", "Print"}, { "control R", "RunToCursor", "Console.TableResult.Reload", "org.jetbrains.plugins.ruby.rails.console.ReloadSources"}, 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 449323a395a9..456a0ac0d5c0 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -852,7 +852,8 @@ public class StringUtil extends StringUtilRt { return suggestion.substring(0, len - 2) + "en"; } - if (endsWithIgnoreCase(suggestion, "s") || endsWithIgnoreCase(suggestion, "x") || endsWithIgnoreCase(suggestion, "ch")) { + if (endsWithIgnoreCase(suggestion, "s") || endsWithIgnoreCase(suggestion, "x") || + endsWithIgnoreCase(suggestion, "ch") || endsWithIgnoreCase(suggestion, "sh")) { return suggestion + "es"; } diff --git a/platform/util/src/com/intellij/util/Restarter.java b/platform/util/src/com/intellij/util/Restarter.java index ab11afd067b8..6e8441d0312a 100644 --- a/platform/util/src/com/intellij/util/Restarter.java +++ b/platform/util/src/com/intellij/util/Restarter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -40,15 +40,7 @@ public class Restarter { } private static int getRestartCode() { - String s = System.getProperty("jb.restart.code"); - if (s != null) { - try { - return Integer.parseInt(s); - } - catch (NumberFormatException ignore) { - } - } - return 0; + return SystemProperties.getIntProperty("jb.restart.code", 0); } public static boolean isSupported() { diff --git a/platform/util/src/com/intellij/util/concurrency/AppScheduledExecutorService.java b/platform/util/src/com/intellij/util/concurrency/AppScheduledExecutorService.java index d1c309d9f7ca..81e03f3fd5b9 100644 --- a/platform/util/src/com/intellij/util/concurrency/AppScheduledExecutorService.java +++ b/platform/util/src/com/intellij/util/concurrency/AppScheduledExecutorService.java @@ -79,7 +79,7 @@ public class AppScheduledExecutorService extends SchedulingWrapper { error(); } - private static List error() { + static List error() { throw new IncorrectOperationException("You must not call this method on the global app pool"); } diff --git a/platform/util/src/com/intellij/util/concurrency/EdtExecutorService.java b/platform/util/src/com/intellij/util/concurrency/EdtExecutorService.java new file mode 100644 index 000000000000..61c81e4c10e7 --- /dev/null +++ b/platform/util/src/com/intellij/util/concurrency/EdtExecutorService.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2016 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.util.concurrency; + +import com.intellij.util.ui.EdtInvocationManager; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.concurrent.AbstractExecutorService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * ExecutorService implementation which delegates tasks for execution to the SwingUtilities.invokeLater(task) + */ +public class EdtExecutorService extends AbstractExecutorService { + @NotNull + public static ExecutorService getInstance() { + return INSTANCE; + } + + @NotNull + public static ScheduledExecutorService getScheduledExecutorInstance() { + return SCHEDULED_INSTANCE; + } + + @Override + public void execute(@NotNull Runnable command) { + EdtInvocationManager.getInstance().invokeLater(command); + } + + @Override + public void shutdown() { + AppScheduledExecutorService.error(); + } + + @NotNull + @Override + public List shutdownNow() { + return AppScheduledExecutorService.error(); + } + + @Override + public boolean isShutdown() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public boolean awaitTermination(long timeout, @NotNull TimeUnit unit) throws InterruptedException { + AppScheduledExecutorService.error(); + return false; + } + + private static final ExecutorService INSTANCE = new EdtExecutorService(); + private static final ScheduledExecutorService SCHEDULED_INSTANCE = new SchedulingWrapper(INSTANCE, ((AppScheduledExecutorService)AppExecutorUtil.getAppScheduledExecutorService()).delayQueue){ + @NotNull + @Override + public List shutdownNow() { + return AppScheduledExecutorService.error(); + } + + @Override + public void shutdown() { + AppScheduledExecutorService.error(); + } + + @Override + public boolean awaitTermination(long timeout, @NotNull TimeUnit unit) throws InterruptedException { + AppScheduledExecutorService.error(); + return false; + } + }; +} diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentHashSet.java b/platform/util/src/com/intellij/util/containers/ConcurrentHashSet.java index aa8844c239fb..cfae26778ee9 100644 --- a/platform/util/src/com/intellij/util/containers/ConcurrentHashSet.java +++ b/platform/util/src/com/intellij/util/containers/ConcurrentHashSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -74,13 +74,13 @@ public class ConcurrentHashSet implements Set { } @Override - public boolean add(K o) { + public boolean add(@NotNull K o) { return map.putIfAbsent(o, Boolean.TRUE) == null; } @Override - public boolean remove(Object o) { - return map.keySet().remove(o); + public boolean remove(@NotNull Object o) { + return map.remove(o) != null; } @Override diff --git a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java index d851d3868302..e800f22f33c5 100644 --- a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java +++ b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -16,6 +16,7 @@ package com.intellij.util.io; import com.intellij.util.Processor; +import com.intellij.util.SystemProperties; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,14 +34,7 @@ public class PersistentBTreeEnumerator extends PersistentEnumeratorBase CASE_SENSITIVE_STRATEGY = FilePathHashingStrategy.create(true); @NotNull private final String myPath; + @NotNull private final File myIOFile; private final boolean myIsDirectory; public RemoteFilePath(@NotNull String path, boolean isDirectory) { myPath = path; + myIOFile = new File(myPath); myIsDirectory = isDirectory; } @@ -59,7 +61,7 @@ public class RemoteFilePath implements FilePath { @NotNull @Override public File getIOFile() { - return new File(myPath); + return myIOFile; } @NotNull diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java index d45f1d15807c..5c897523ac24 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java @@ -21,6 +21,7 @@ import com.intellij.history.LocalHistoryAction; import com.intellij.ide.util.DelegatingProgressIndicator; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -47,6 +48,7 @@ import com.intellij.util.NullableFunction; import com.intellij.util.WaitForProgressToShow; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.ui.ConfirmationDialog; +import org.jetbrains.annotations.CalledInAwt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -114,38 +116,30 @@ public class CommitHelper { } private boolean doCommit(final GeneralCommitProcessor processor) { + Task.Backgroundable task = new Task.Backgroundable(myProject, myActionName, true, myConfiguration.getCommitOption()) { + public void run(@NotNull final ProgressIndicator indicator) { + final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); + vcsManager.startBackgroundVcsOperation(); + try { + delegateCommitToVcsThread(processor); + } + finally { + vcsManager.stopBackgroundVcsOperation(); + } + } - final Runnable action = new Runnable() { - public void run() { - delegateCommitToVcsThread(processor); + @Override + public boolean shouldStartInBackground() { + return !myForceSyncCommit && super.shouldStartInBackground(); + } + + @Override + public boolean isConditionalModal() { + return myForceSyncCommit; } }; - - if (myForceSyncCommit) { - ProgressManager.getInstance().runProcessWithProgressSynchronously(action, myActionName, true, myProject); - boolean success = doesntContainErrors(processor.getVcsExceptions()); - if (success) { - reportResult(processor); - } - return success; - } - else { - Task.Backgroundable task = - new Task.Backgroundable(myProject, myActionName, true, myConfiguration.getCommitOption()) { - public void run(@NotNull final ProgressIndicator indicator) { - final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); - vcsManager.startBackgroundVcsOperation(); - try { - action.run(); - } - finally { - vcsManager.stopBackgroundVcsOperation(); - } - } - }; - ProgressManager.getInstance().run(task); - return false; - } + ProgressManager.getInstance().run(task); + return doesntContainErrors(processor.getVcsExceptions()); } private void delegateCommitToVcsThread(final GeneralCommitProcessor processor) { @@ -202,6 +196,9 @@ public class CommitHelper { @NotNull private String getCommitSummary(@NotNull GeneralCommitProcessor processor) { StringBuilder content = new StringBuilder(getFileSummaryReport(processor.getChangesFailedToCommit())); + if (!StringUtil.isEmpty(myCommitMessage)) { + content.append(": ").append(escape(myCommitMessage)); + } if (!myFeedback.isEmpty()) { content.append("
"); content.append(StringUtil.join(myFeedback, "
")); @@ -269,8 +266,6 @@ public class CommitHelper { } processor.doBeforeRefresh(); - - AbstractVcsHelper.getInstance(myProject).showErrors(processor.getVcsExceptions(), myActionName); } catch (ProcessCanceledException pce) { throw pce; @@ -443,8 +438,13 @@ public class CommitHelper { } public void afterFailedCheckIn() { - moveToFailedList(myChangeList, myCommitMessage, getChangesFailedToCommit(), - VcsBundle.message("commit.dialog.failed.commit.template", myChangeList.getName()), myProject); + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + moveToFailedList(myChangeList, myCommitMessage, getChangesFailedToCommit(), + VcsBundle.message("commit.dialog.failed.commit.template", myChangeList.getName()), myProject); + } + }, ModalityState.defaultModalityState(), o -> myProject.isDisposed()); } public void doBeforeRefresh() { @@ -626,6 +626,7 @@ public class CommitHelper { } } + @CalledInAwt public static void moveToFailedList(final ChangeList changeList, final String commitMessage, final List failedChanges, diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/Hash.java b/platform/vcs-log/api/src/com/intellij/vcs/log/Hash.java index 5c86bd5921b3..09c1fb95bdfc 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/Hash.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/Hash.java @@ -4,9 +4,9 @@ import org.jetbrains.annotations.NotNull; /** *

Represents a unique reference to a VCS commit.

- * + *

*

It is called "Hash", because in DVCSs it is represented by a SHA-hash value.

- * + *

* TODO move to vcs-api * * @author Kirill Likhodedov @@ -22,13 +22,12 @@ public interface Hash { /** *

- * Returns a short part of the {@link #asString() hash string}, - * which may be non-unique, but usually enough to be a commit reference, and it is easier to read than the complete hash string. + * Returns a short part of the {@link #asString() hash string}, + * which may be non-unique, but usually enough to be a commit reference, and it is easier to read than the complete hash string. *

- * + *

*

Usually (e.g. it is default for Git) the short hash is 7 symbols long.

*/ @NotNull String toShortString(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/InvalidRequestException.java b/platform/vcs-log/api/src/com/intellij/vcs/log/InvalidRequestException.java index 20ac29980c18..dcf66b55bb23 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/InvalidRequestException.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/InvalidRequestException.java @@ -22,5 +22,4 @@ public class InvalidRequestException extends RuntimeException { public InvalidRequestException(@NotNull String message) { super(message); } - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/RefGroup.java b/platform/vcs-log/api/src/com/intellij/vcs/log/RefGroup.java index fbc643235988..3f54510a1060 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/RefGroup.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/RefGroup.java @@ -35,5 +35,4 @@ public interface RefGroup { */ @NotNull Color getBgColor(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsCommitMetadata.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsCommitMetadata.java index 051ba41c2662..089de7b31b0c 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsCommitMetadata.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsCommitMetadata.java @@ -10,7 +10,7 @@ import java.util.List; * These details will be shown in dedicated panels displayed near the log, and can be used for in-memory filtering. *

* An instance of this object can be obtained via - * {@link VcsLogObjectsFactory#createCommitMetadata(Hash, List, long, VirtualFile, String, String, String, String, String, String,long) + * {@link VcsLogObjectsFactory#createCommitMetadata(Hash, List, long, VirtualFile, String, String, String, String, String, String, long) * VcsLogObjectsFactory#createCommitMetadata} *

* It is not recommended to create a custom implementation of this interface, but if you need it, make sure to implement {@code equals()} diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsFullCommitDetails.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsFullCommitDetails.java index dc7e74c96054..412bc8c04264 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsFullCommitDetails.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsFullCommitDetails.java @@ -38,5 +38,4 @@ public interface VcsFullCommitDetails extends VcsCommitMetadata { @NotNull Collection getChanges(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLog.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLog.java index 2b2fcd2a18e4..ce41d475d111 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLog.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLog.java @@ -21,10 +21,8 @@ import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.awt.*; import java.util.Collection; import java.util.List; -import java.util.Set; import java.util.concurrent.Future; /** @@ -50,7 +48,7 @@ public interface VcsLog { * Details are loaded in background. If a progress indicator is specified it is used during loading process. * After all details are loaded they are provided to the consumer in the EDT. * - * @param consumer called in EDT after all details are loaded. + * @param consumer called in EDT after all details are loaded. * @param indicator progress indicator to use in loading process, can be null. */ void requestSelectedDetails(@NotNull Consumer> consumer, @Nullable ProgressIndicator indicator); diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDataKeys.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDataKeys.java index b945615edc1e..3123abef1828 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDataKeys.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDataKeys.java @@ -25,5 +25,4 @@ public class VcsLogDataKeys { public static final DataKey VCS_LOG = DataKey.create("Vcs.Log"); public static final DataKey VCS_LOG_UI = DataKey.create("Vcs.Log.Ui"); public static final DataKey VCS_LOG_DATA_PROVIDER = DataKey.create("Vcs.Log.DataProvider"); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDataProvider.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDataProvider.java index 597afd40082b..7d489035de2e 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDataProvider.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDataProvider.java @@ -17,14 +17,14 @@ package com.intellij.vcs.log; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** */ public interface VcsLogDataProvider { - @NotNull + @Nullable CommitId getCommitId(int commitIndex); int getCommitIndex(@NotNull Hash hash, @NotNull VirtualFile root); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDateFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDateFilter.java index aa59bb6e2bf3..fc5a06a0347b 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDateFilter.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDateFilter.java @@ -36,5 +36,4 @@ public interface VcsLogDateFilter extends VcsLogDetailsFilter { */ @Nullable Date getBefore(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDetailsFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDetailsFilter.java index 838e95c306b4..113a1bce9e29 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDetailsFilter.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDetailsFilter.java @@ -10,5 +10,4 @@ import org.jetbrains.annotations.NotNull; public interface VcsLogDetailsFilter extends VcsLogFilter { boolean matches(@NotNull VcsCommitMetadata details); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java index 365d9968010d..83ed9580527e 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java @@ -55,5 +55,4 @@ public interface VcsLogFilterCollection { @NotNull List getDetailsFilters(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterUi.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterUi.java index a4cf4b903d2e..93faf610e9a2 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterUi.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterUi.java @@ -18,5 +18,4 @@ public interface VcsLogFilterUi { * Note: only VcsLogBranchFilter is currently supported. */ void setFilter(@NotNull VcsLogFilter filter); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java index 71a14e1f732d..98da8710657f 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java @@ -23,5 +23,4 @@ public interface VcsLogHashFilter { @NotNull Collection getHashes(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHighlighter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHighlighter.java index fbb2c270a624..d3926f0edabf 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHighlighter.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHighlighter.java @@ -27,15 +27,17 @@ public interface VcsLogHighlighter { /** * Return the style which should be used for the log table commit entry, or VcsCommitStyle.DEFAULT if this highlighter does not specify any style for this commit. + * * @param commitDetails details of selected commit. - * @param isSelected if true, the row currently has selection on it. + * @param isSelected if true, the row currently has selection on it. */ @NotNull VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails commitDetails, boolean isSelected); /** * This method is called when new data arrives to the ui. - * @param dataPack new visible pack. + * + * @param dataPack new visible pack. * @param refreshHappened true if permanent graph has changed. */ void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened); diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogListener.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogListener.java index 2d5dc5fbb5af..cee57c3608a7 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogListener.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogListener.java @@ -31,5 +31,4 @@ public interface VcsLogListener { * @param refreshHappened true if a refresh initiated this log change, i.e. PermanentGraph changed. */ void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogObjectsFactory.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogObjectsFactory.java index 1a0d0a3697ac..36978da53914 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogObjectsFactory.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogObjectsFactory.java @@ -44,5 +44,4 @@ public interface VcsLogObjectsFactory { @NotNull VcsRef createRef(@NotNull Hash commitHash, @NotNull String name, @NotNull VcsRefType type, @NotNull VirtualFile root); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProperties.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProperties.java index effece19984f..5d22d7e2f49f 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProperties.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProperties.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; public class VcsLogProperties { public static class VcsLogProperty { private final T defaultValue; + private VcsLogProperty(@NotNull T defaultValue) { this.defaultValue = defaultValue; } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java index 896df0e96b87..d2f3cd17e6e9 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java @@ -69,11 +69,11 @@ public interface VcsLogProvider { /** *

Starts listening to events from the certain VCS, which should lead to the log refresh.

*

Returns disposable that unsubscribes from events. - * Using a {@link MessageBus} topic can help to accomplish that.

+ * Using a {@link MessageBus} topic can help to accomplish that.

* * @param roots VCS roots which should be listened to. * @param refresher The refresher which should be notified about the need of refresh. - * @return Disposable that unsubscribes from events on dispose. + * @return Disposable that unsubscribes from events on dispose. */ @NotNull Disposable subscribeToRootRefreshEvents(@NotNull Collection roots, @NotNull VcsLogRefresher refresher); @@ -102,9 +102,10 @@ public interface VcsLogProvider { /** * In order to tune log for it's VCS, provider may set value to one of the properties specified in {@link com.intellij.vcs.log.VcsLogProperties}. + * * @param property Property instance to return value for. * @param Type of property value. - * @return Property value or null if unset. + * @return Property value or null if unset. */ @Nullable T getPropertyValue(VcsLogProperties.VcsLogProperty property); @@ -125,23 +126,27 @@ public interface VcsLogProvider { * (of course it may return less commits if the repository is small) */ int getCommitCount(); - } /** * Container for references and users. */ interface LogData { - @NotNull Set getRefs(); - @NotNull Set getUsers(); + @NotNull + Set getRefs(); + + @NotNull + Set getUsers(); } /** * Container for the ordered list of commits together with their details, and references. */ interface DetailedLogData { - @NotNull List getCommits(); - @NotNull Set getRefs(); - } + @NotNull + List getCommits(); + @NotNull + Set getRefs(); + } } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProviderRequirementsEx.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProviderRequirementsEx.java index 68623a6852f9..ba72e9f14095 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProviderRequirementsEx.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProviderRequirementsEx.java @@ -39,5 +39,4 @@ public interface VcsLogProviderRequirementsEx extends Requirements { */ @NotNull Set getPreviousRefs(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogRefManager.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogRefManager.java index affe800ceff9..d2f507322897 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogRefManager.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogRefManager.java @@ -59,5 +59,4 @@ public interface VcsLogRefManager { */ @NotNull List group(Collection refs); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogSettings.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogSettings.java index 05849361a4a7..c8f892cf12ed 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogSettings.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogSettings.java @@ -18,7 +18,7 @@ package com.intellij.vcs.log; /** * TODO remove in IDEA 17 - * + *

*

Vcs Log user settings, which may have a UI representation, or be implicitly selected based on user actions.

*

Most of the settings are workspace-specific, i. e. they are stored in {@link com.intellij.openapi.components.StoragePathMacros#WORKSPACE_FILE workspace.xml}.

* @@ -33,5 +33,4 @@ public interface VcsLogSettings { boolean isShowBranchesPanel(); void setShowBranchesPanel(boolean show); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogStructureFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogStructureFilter.java index 9826e55d1a46..4ce48ed0c35e 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogStructureFilter.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogStructureFilter.java @@ -16,7 +16,6 @@ package com.intellij.vcs.log; import com.intellij.openapi.vcs.FilePath; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -28,9 +27,9 @@ public interface VcsLogStructureFilter extends VcsLogDetailsFilter { /** *

Returns files which are affected by matching commits, and folders containing such files.

- * + *

*

That is: the commit A (made in the given VCS root) modifying file f.txt matches this filter, - * if this method returns a set which includes a folder containing f.txt, or the file f.txt itself.

+ * if this method returns a set which includes a folder containing f.txt, or the file f.txt itself.

*/ @NotNull Collection getFiles(); diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogTextFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogTextFilter.java index 2ae3ac389bf8..e6270b973869 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogTextFilter.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogTextFilter.java @@ -27,5 +27,4 @@ public interface VcsLogTextFilter extends VcsLogDetailsFilter { */ @NotNull String getText(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUserFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUserFilter.java index 449b08708769..e0cb3a586d40 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUserFilter.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUserFilter.java @@ -12,6 +12,7 @@ public interface VcsLogUserFilter extends VcsLogDetailsFilter { /** * Returns user names selected in the filter, concerning the passed VCS root. + * * @param root has no effect if user chooses some user name; * it is needed if user selects the predefined value "me" which means the current user. * Since current user name can be defined differently for different roots, we pass the root for which this value is @@ -19,5 +20,4 @@ public interface VcsLogUserFilter extends VcsLogDetailsFilter { */ @NotNull Collection getUserNames(@NotNull VirtualFile root); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsRef.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsRef.java index 95031ff1c2d8..2f89ba6bb5f0 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsRef.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsRef.java @@ -48,5 +48,4 @@ public interface VcsRef { */ @NotNull VirtualFile getRoot(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsRefType.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsRefType.java index 9952003f6eed..a8acae6592da 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsRefType.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsRefType.java @@ -11,18 +11,18 @@ public interface VcsRefType { /** *

Tells if this reference type should be considered a branch.

- * + *

*

Although there are different ref types across different VCSs, generally they can be divided into development branches producing - * separate branches in the graph, and tags which are just handy labels to specific repository states. - * This difference is not clear enough for Git branches or Mercurial bookmarks, which internally have no differences with tags, - * but they are still considered as branches due to their purpose, rather than to their internal structure.

- * + * separate branches in the graph, and tags which are just handy labels to specific repository states. + * This difference is not clear enough for Git branches or Mercurial bookmarks, which internally have no differences with tags, + * but they are still considered as branches due to their purpose, rather than to their internal structure.

+ *

*

Although this is implementation specific and may change, here are some examples of the difference between branches and not-branches - * considering the VCS Log: - *

    - *
  • branch references stop collapsing of long linear branches, while tags don't.
  • - *
  • branches try to keep their color through time, while tags don't affect colors of branches.
  • - *

+ * considering the VCS Log: + *
    + *
  • branch references stop collapsing of long linear branches, while tags don't.
  • + *
  • branches try to keep their color through time, while tags don't affect colors of branches.
  • + *

*/ boolean isBranch(); @@ -32,5 +32,4 @@ public interface VcsRefType { */ @NotNull Color getBackgroundColor(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsUser.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsUser.java index fb2ea21927a9..5e8b13d8bf86 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsUser.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsUser.java @@ -27,5 +27,4 @@ public interface VcsUser { @NotNull String getEmail(); - } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/graph/GraphColorManager.java b/platform/vcs-log/api/src/com/intellij/vcs/log/graph/GraphColorManager.java index aa51a9e336d1..686bfb4fa462 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/graph/GraphColorManager.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/graph/GraphColorManager.java @@ -21,6 +21,7 @@ public interface GraphColorManager { /** * Returns the color which should be used to draw the given branch. + * * @param headCommit branch head commit index. */ int getColorOfBranch(CommitId headCommit); @@ -55,5 +56,4 @@ public interface GraphColorManager { * @see VcsLogRefManager#getBranchLayoutComparator() */ int compareHeads(CommitId head1, CommitId head2); - } diff --git a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/EdgePrintElement.java b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/EdgePrintElement.java index 8c20356fb754..8844b1fb3062 100644 --- a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/EdgePrintElement.java +++ b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/EdgePrintElement.java @@ -39,5 +39,4 @@ public interface EdgePrintElement extends PrintElement { DASHED, DOTTED } - } diff --git a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/GraphCommit.java b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/GraphCommit.java index 5ac49d28da9d..eb1ed7f7e4f5 100644 --- a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/GraphCommit.java +++ b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/GraphCommit.java @@ -32,9 +32,8 @@ public interface GraphCommit { /** *

Returns the timestamp indicating the date & time when this commit was made.

*

This time is displayed in the table by default; - * it is used for joining commits from different repositories; - * it is used for ordering commits in a single repository (keeping the preference of the topological ordering of course).

+ * it is used for joining commits from different repositories; + * it is used for ordering commits in a single repository (keeping the preference of the topological ordering of course).

*/ long getTimestamp(); - } diff --git a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/PermanentGraphBuilder.java b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/PermanentGraphBuilder.java index dbbf73ff5cba..0c4492c4a5f7 100644 --- a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/PermanentGraphBuilder.java +++ b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/PermanentGraphBuilder.java @@ -25,5 +25,4 @@ public interface PermanentGraphBuilder { @NotNull PermanentGraph build(@NotNull List> commits); - } diff --git a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/PrintElement.java b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/PrintElement.java index d9e4b8c83822..84c35c84f593 100644 --- a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/PrintElement.java +++ b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/PrintElement.java @@ -26,5 +26,4 @@ public interface PrintElement { int getColorId(); boolean isSelected(); - } diff --git a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowInfo.java b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowInfo.java index a5248b2834ea..efa5a8445d95 100644 --- a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowInfo.java +++ b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowInfo.java @@ -34,5 +34,4 @@ public interface RowInfo { @NotNull RowType getRowType(); - } diff --git a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/VisibleGraph.java b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/VisibleGraph.java index 76c590dbee50..fe78dee97348 100644 --- a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/VisibleGraph.java +++ b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/VisibleGraph.java @@ -36,5 +36,4 @@ public interface VisibleGraph { @NotNull ActionController getActionController(); - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/PermanentGraphBuilderImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/PermanentGraphBuilderImpl.java index ab353e5335f4..757081c4b7bd 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/PermanentGraphBuilderImpl.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/PermanentGraphBuilderImpl.java @@ -45,5 +45,4 @@ public class PermanentGraphBuilderImpl implements PermanentGraphBuilde public PermanentGraph build(@NotNull List> commits) { return PermanentGraphImpl.newInstance(commits, STUB_COLOR_MANAGER, Collections.emptySet()); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/elements/GraphNode.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/elements/GraphNode.java index 2f8118fc63c2..bcc0b0f6138e 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/elements/GraphNode.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/elements/GraphNode.java @@ -59,5 +59,4 @@ public final class GraphNode implements GraphElement { result = 31 * result + myType.hashCode(); return result; } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/permanent/PermanentGraphInfo.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/permanent/PermanentGraphInfo.java index 0b3975aee144..34388b22aa43 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/permanent/PermanentGraphInfo.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/permanent/PermanentGraphInfo.java @@ -34,5 +34,4 @@ public interface PermanentGraphInfo { @NotNull Set getBranchNodeIds(); - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/CollapsedActionManager.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/CollapsedActionManager.java index 05bd86de772e..1e452cbfb0cf 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/CollapsedActionManager.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/CollapsedActionManager.java @@ -157,7 +157,6 @@ class CollapsedActionManager { return new GraphEdge(upNodeIndex, downNodeIndex, compiledEdge.getTargetId(), compiledEdge.getType()); } - } private static class FragmentGenerators { diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/DottedFilterEdgesGenerator.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/DottedFilterEdgesGenerator.java index 6f31ad03fe02..6aab79489baa 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/DottedFilterEdgesGenerator.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/DottedFilterEdgesGenerator.java @@ -214,5 +214,4 @@ public class DottedFilterEdgesGenerator { } } } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/EdgeStorage.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/EdgeStorage.java index 4be3809357fe..31f1af180a69 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/EdgeStorage.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/EdgeStorage.java @@ -99,5 +99,4 @@ public class EdgeStorage { public void removeAll() { myEdges.clear(); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/EdgeStorageWrapper.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/EdgeStorageWrapper.java index fa551398f52d..fc47c894981e 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/EdgeStorageWrapper.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/EdgeStorageWrapper.java @@ -146,6 +146,6 @@ public class EdgeStorageWrapper { } public static EdgeStorageWrapper createSimpleEdgeStorage() { - return new EdgeStorageWrapper(new EdgeStorage(), Functions.id() , Functions.id()); + return new EdgeStorageWrapper(new EdgeStorage(), Functions.id(), Functions.id()); } } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/FragmentGenerator.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/FragmentGenerator.java index 8bb161ea71dd..7fe3080c6839 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/FragmentGenerator.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/collapsing/FragmentGenerator.java @@ -157,5 +157,4 @@ public class FragmentGenerator { } }; } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/CascadeController.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/CascadeController.java index 438d1d0b8ef0..e95e0099d26d 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/CascadeController.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/CascadeController.java @@ -74,5 +74,4 @@ public abstract class CascadeController implements LinearGraphController { // null mean that this action must be performed by delegateGraphController @Nullable protected abstract LinearGraphAnswer performAction(@NotNull LinearGraphAction action); - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/PermanentGraphImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/PermanentGraphImpl.java index a54cf611131a..2560a41cecc2 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/PermanentGraphImpl.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/PermanentGraphImpl.java @@ -207,11 +207,6 @@ public class PermanentGraphImpl implements PermanentGraph, P return myPermanentGraphLayout; } - @NotNull - public GraphColorManager getGraphColorManager() { - return myGraphColorManager; - } - @NotNull public Set getBranchNodeIds() { return myBranchNodeIds; diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/ReachableNodes.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/ReachableNodes.java index 0f67c3c73897..dbeefd534ed2 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/ReachableNodes.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/ReachableNodes.java @@ -104,7 +104,6 @@ public class ReachableNodes { } }); } - } } } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/SimpleGraphInfo.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/SimpleGraphInfo.java index 4943ef6a9820..d6b11f4ef5c3 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/SimpleGraphInfo.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/SimpleGraphInfo.java @@ -18,7 +18,6 @@ package com.intellij.vcs.log.graph.impl.facade; import com.intellij.util.Function; import com.intellij.util.NotNullFunction; import com.intellij.util.containers.ContainerUtil; -import com.intellij.vcs.log.graph.GraphColorManager; import com.intellij.vcs.log.graph.GraphCommit; import com.intellij.vcs.log.graph.GraphCommitImpl; import com.intellij.vcs.log.graph.api.GraphLayout; diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/VisibleGraphImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/VisibleGraphImpl.java index 9f2f517de78c..b05fcba42334 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/VisibleGraphImpl.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/VisibleGraphImpl.java @@ -46,7 +46,9 @@ public class VisibleGraphImpl implements VisibleGraph { private PrintElementGenerator myPrintElementGenerator; private boolean myShowLongEdges = false; - public VisibleGraphImpl(@NotNull LinearGraphController graphController, @NotNull PermanentGraphInfo permanentGraph, @NotNull GraphColorManager colorManager) { + public VisibleGraphImpl(@NotNull LinearGraphController graphController, + @NotNull PermanentGraphInfo permanentGraph, + @NotNull GraphColorManager colorManager) { myGraphController = graphController; myPermanentGraph = permanentGraph; myColorManager = colorManager; @@ -161,11 +163,13 @@ public class VisibleGraphImpl implements VisibleGraph { if (action.getType() == GraphAction.Type.MOUSE_OVER) { myPrintElementManager.setSelectedElement(affectedElement); - return new GraphAnswerImpl(getCursor(true), myPermanentGraph.getPermanentCommitsInfo().getCommitId(targetId), null, false); + return new GraphAnswerImpl(getCursor(true), myPermanentGraph.getPermanentCommitsInfo().getCommitId(targetId), null, + false); } if (action.getType() == GraphAction.Type.MOUSE_CLICK) { - return new GraphAnswerImpl(getCursor(false), myPermanentGraph.getPermanentCommitsInfo().getCommitId(targetId), null, true); + return new GraphAnswerImpl(getCursor(false), myPermanentGraph.getPermanentCommitsInfo().getCommitId(targetId), null, + true); } return null; diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekBranchCreator.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekBranchCreator.java index df2d13e14c0c..47bd5c863c83 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekBranchCreator.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekBranchCreator.java @@ -98,5 +98,4 @@ class BekBranchCreator { return nodeIndexes; } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekChecker.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekChecker.java index 6e6cd7e0316a..e211e0ebbb7b 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekChecker.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekChecker.java @@ -51,5 +51,4 @@ public class BekChecker { } return null; } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekEdgeRestrictions.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekEdgeRestrictions.java index ad1e1b85f8e8..803894112868 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekEdgeRestrictions.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekEdgeRestrictions.java @@ -37,5 +37,4 @@ class BekEdgeRestrictions { boolean hasRestriction(int upNode) { return myUpToEdge.containsKey(upNode); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekSorter.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekSorter.java index 72b323ce6926..3d3567af1f6d 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekSorter.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekSorter.java @@ -94,5 +94,4 @@ public class BekSorter { BekBranchMerger bekBranchMerger = new BekBranchMerger(branches.first, branches.second, myTimestampGetter); return bekBranchMerger.getResult(); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/permanent/GraphLayoutBuilder.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/permanent/GraphLayoutBuilder.java index 920c0b6f66c9..4e649281b221 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/permanent/GraphLayoutBuilder.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/permanent/GraphLayoutBuilder.java @@ -35,7 +35,7 @@ public class GraphLayoutBuilder { private static final Logger LOG = Logger.getInstance(GraphLayoutBuilder.class); @NotNull - public static GraphLayoutImpl build(@NotNull LinearGraph graph, @NotNull Comparator headerNodeIndexComparator) { + public static GraphLayoutImpl build(@NotNull LinearGraph graph, @NotNull Comparator headNodeIndexComparator) { List heads = new ArrayList(); for (int i = 0; i < graph.nodesCount(); i++) { if (getUpNodes(graph, i).size() == 0) { @@ -43,7 +43,7 @@ public class GraphLayoutBuilder { } } try { - heads = ContainerUtil.sorted(heads, headerNodeIndexComparator); + heads = ContainerUtil.sorted(heads, headNodeIndexComparator); } catch (ProcessCanceledException pce) { throw pce; @@ -52,7 +52,7 @@ public class GraphLayoutBuilder { // protection against possible comparator flaws LOG.error(e); } - GraphLayoutBuilder builder = new GraphLayoutBuilder(graph, heads, new DfsUtil()); + GraphLayoutBuilder builder = new GraphLayoutBuilder(graph, heads); return builder.build(); } @@ -62,18 +62,16 @@ public class GraphLayoutBuilder { @NotNull private final List myHeadNodeIndex; @NotNull private final int[] myStartLayoutIndexForHead; - @NotNull private final DfsUtil myDfsUtil; + @NotNull private final DfsUtil myDfsUtil = new DfsUtil(); private int currentLayoutIndex = 1; - private GraphLayoutBuilder(@NotNull LinearGraph graph, @NotNull List headNodeIndex, @NotNull DfsUtil dfsUtil) { + private GraphLayoutBuilder(@NotNull LinearGraph graph, @NotNull List headNodeIndex) { myGraph = graph; - myDfsUtil = dfsUtil; myLayoutIndex = new int[graph.nodesCount()]; myHeadNodeIndex = headNodeIndex; myStartLayoutIndexForHead = new int[headNodeIndex.size()]; - } private void dfs(int nodeIndex) { @@ -114,5 +112,4 @@ public class GraphLayoutBuilder { return new GraphLayoutImpl(myLayoutIndex, myHeadNodeIndex, myStartLayoutIndexForHead); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/permanent/PermanentCommitsInfoImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/permanent/PermanentCommitsInfoImpl.java index e713341b4c03..c1b5644c9df5 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/permanent/PermanentCommitsInfoImpl.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/permanent/PermanentCommitsInfoImpl.java @@ -25,7 +25,6 @@ import com.intellij.vcs.log.graph.utils.IntList; import com.intellij.vcs.log.graph.utils.TimestampGetter; import com.intellij.vcs.log.graph.utils.impl.CompressedIntList; import com.intellij.vcs.log.graph.utils.impl.IntTimestampGetter; -import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -35,7 +34,7 @@ public class PermanentCommitsInfoImpl implements PermanentCommitsInfo< @NotNull public static PermanentCommitsInfoImpl newInstance(@NotNull final List> graphCommits, - @NotNull Map notLoadedCommits) { + @NotNull Map notLoadedCommits) { TimestampGetter timestampGetter = createTimestampGetter(graphCommits); boolean isIntegerCase = !graphCommits.isEmpty() && graphCommits.get(0).getId().getClass() == Integer.class; @@ -192,5 +191,4 @@ public class PermanentCommitsInfoImpl implements PermanentCommitsInfo< } return result; } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/ColorGetterByLayoutIndex.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/ColorGetterByLayoutIndex.java index 7c37d9ae5c08..824d01bc924c 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/ColorGetterByLayoutIndex.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/ColorGetterByLayoutIndex.java @@ -71,7 +71,6 @@ public class ColorGetterByLayoutIndex { else { return myColorManager.getColorOfFragment(headCommitId, upLayoutIndex); } - } private int getHeadNodeId(int upNodeIndex) { @@ -93,5 +92,4 @@ public class ColorGetterByLayoutIndex { private int getNodeId(int upNodeIndex) { return myLinearGraph.getNodeId(upNodeIndex); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/PrintElementGeneratorImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/PrintElementGeneratorImpl.java index 751949e37031..92dcd18e8895 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/PrintElementGeneratorImpl.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/PrintElementGeneratorImpl.java @@ -163,7 +163,6 @@ public class PrintElementGeneratorImpl extends AbstractPrintElementGenerator { if (edgeSize >= myLongEdgeSize) addArrowIfNeeded(result, edge, position, upOffset, downOffset, myVisiblePartSize); if (edgeSize >= myEdgeWithArrowSize) addArrowIfNeeded(result, edge, position, upOffset, downOffset, 1); - } else { // special edges switch (edge.getType()) { @@ -248,5 +247,4 @@ public class PrintElementGeneratorImpl extends AbstractPrintElementGenerator { cache.put(rowIndex, result); return result; } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/EdgePrintElementImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/EdgePrintElementImpl.java index 1eae3c586f74..5aefa2cce4ae 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/EdgePrintElementImpl.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/EdgePrintElementImpl.java @@ -105,5 +105,4 @@ public class EdgePrintElementImpl extends PrintElementWithGraphElement implement result = 31 * result + (myHasArrow ? 1 : 0); return result; } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/SimplePrintElementImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/SimplePrintElementImpl.java index ed28cf196f08..826ef87b1948 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/SimplePrintElementImpl.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/SimplePrintElementImpl.java @@ -49,5 +49,4 @@ public class SimplePrintElementImpl extends PrintElementWithGraphElement impleme result = 31 * result + myPositionInCurrentRow; return result; } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/linearBek/LinearBekController.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/linearBek/LinearBekController.java index 634c72c62d5a..e6a4cc83f846 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/linearBek/LinearBekController.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/linearBek/LinearBekController.java @@ -269,5 +269,4 @@ public class LinearBekController extends CascadeController { return bekIndexes; } } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/linearBek/LinearBekGraphBuilder.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/linearBek/LinearBekGraphBuilder.java index e982ce652b4f..c013d042a71d 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/linearBek/LinearBekGraphBuilder.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/linearBek/LinearBekGraphBuilder.java @@ -133,7 +133,6 @@ class LinearBekGraphBuilder { else { return null; } - } else { if ((li > leftLi && li < rightLi) || (li == leftLi)) { @@ -162,7 +161,6 @@ class LinearBekGraphBuilder { } } } - } if (blockSize >= MAX_BLOCK_SIZE) { diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/LinearGraphUtils.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/LinearGraphUtils.java index 713af61cc8a6..456d23567731 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/LinearGraphUtils.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/LinearGraphUtils.java @@ -182,5 +182,4 @@ public class LinearGraphUtils { }); return ContainerUtil.newHashSet(result); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/TimestampGetter.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/TimestampGetter.java index 5433318bfb06..42350cde46e0 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/TimestampGetter.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/TimestampGetter.java @@ -23,5 +23,4 @@ public interface TimestampGetter { int size(); long getTimestamp(int index); - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/BitSetFlags.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/BitSetFlags.java index 6ba77764aebc..933a0dbeb4e7 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/BitSetFlags.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/BitSetFlags.java @@ -65,6 +65,4 @@ public class BitSetFlags implements Flags { if (index < 0) throw new IndexOutOfBoundsException("index is " + index + " which is less then zero"); if (index >= mySize) throw new IndexOutOfBoundsException("index is " + index + " and set size is " + mySize); } - - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/CompressedIntList.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/CompressedIntList.java index 778d123cbdb2..8dd48f9ea33a 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/CompressedIntList.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/CompressedIntList.java @@ -90,5 +90,4 @@ public class CompressedIntList implements IntList { int strongIndex = index / myBlockSize; return myStrongValues[strongIndex] + myCompressedDeltas.get(index); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/IntDeltaCompressor.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/IntDeltaCompressor.java index 16ae06be67ff..bddf8aab2605 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/IntDeltaCompressor.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/IntDeltaCompressor.java @@ -93,5 +93,4 @@ import org.jetbrains.annotations.NotNull; } return myStartedDeltaIndex.size(); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/ListIntToIntMap.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/ListIntToIntMap.java index 692335b30888..49fb698ad6b7 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/ListIntToIntMap.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/ListIntToIntMap.java @@ -160,6 +160,4 @@ public class ListIntToIntMap extends AbstractIntToIntMap implements UpdatableInt mySubSumOfBlocks[blockIndex] += sumDelta; } } - - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/PermanentListIntToIntMap.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/PermanentListIntToIntMap.java index 8b5d4595a735..28145af7de7f 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/PermanentListIntToIntMap.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/PermanentListIntToIntMap.java @@ -112,5 +112,4 @@ public class PermanentListIntToIntMap extends AbstractIntToIntMap implements Int throw new IllegalStateException( "Not found long index for short index: " + shortIndex + ". Long & short size is: " + myLongSize + ", " + myShortSize + "."); } - } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/TreeIntToIntMap.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/TreeIntToIntMap.java index f016be045bca..fe61bd704073 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/TreeIntToIntMap.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/utils/impl/TreeIntToIntMap.java @@ -139,5 +139,4 @@ public class TreeIntToIntMap extends AbstractIntToIntMap implements UpdatableInt return myTree[node]; } } - } diff --git a/platform/vcs-log/impl/src/META-INF/vcs-log.xml b/platform/vcs-log/impl/src/META-INF/vcs-log.xml index c9fc0d0f0ca6..fe0edad81a20 100644 --- a/platform/vcs-log/impl/src/META-INF/vcs-log.xml +++ b/platform/vcs-log/impl/src/META-INF/vcs-log.xml @@ -30,7 +30,8 @@ - + @@ -46,6 +47,10 @@ + + + + @@ -63,6 +68,7 @@ + @@ -73,14 +79,27 @@ - + - - - + + + + + + + + + + + + + + + + - + diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/UserNameRegex.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/UserNameRegex.java index f3a2fe4f4845..b2c61a690fa3 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/UserNameRegex.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/UserNameRegex.java @@ -20,7 +20,8 @@ import com.intellij.util.Function; public class UserNameRegex implements Function { public static final UserNameRegex INSTANCE = new UserNameRegex(); - private UserNameRegex(){} + private UserNameRegex() { + } @Override public String fun(String s) { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/VcsLogHashMap.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/VcsLogHashMap.java index b72dae236d0a..1b571e06e98b 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/VcsLogHashMap.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/VcsLogHashMap.java @@ -15,8 +15,8 @@ */ package com.intellij.vcs.log; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,7 +27,7 @@ public interface VcsLogHashMap { int getCommitIndex(@NotNull Hash hash, @NotNull VirtualFile root); - @NotNull + @Nullable CommitId getCommitId(int commitIndex); /** diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/AbstractDataGetter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/AbstractDataGetter.java index 99edd7ce9fde..10246abd9977 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/AbstractDataGetter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/AbstractDataGetter.java @@ -16,10 +16,7 @@ import com.intellij.util.ThrowableConsumer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.UIUtil; -import com.intellij.vcs.log.CommitId; -import com.intellij.vcs.log.VcsLogHashMap; -import com.intellij.vcs.log.VcsLogProvider; -import com.intellij.vcs.log.VcsShortCommitDetails; +import com.intellij.vcs.log.*; import com.intellij.vcs.log.util.SequentialLimitedLifoExecutor; import gnu.trove.TIntHashSet; import gnu.trove.TIntIntHashMap; @@ -252,7 +249,9 @@ abstract class AbstractDataGetter implements Di @Override public boolean execute(int commit) { CommitId commitId = myHashMap.getCommitId(commit); - rootsAndHashes.putValue(commitId.getRoot(), commitId.getHash().asString()); + if (commitId != null) { + rootsAndHashes.putValue(commitId.getRoot(), commitId.getHash().asString()); + } return true; } }); @@ -263,7 +262,8 @@ abstract class AbstractDataGetter implements Di List details = readDetails(logProvider, entry.getKey(), ContainerUtil.newArrayList(entry.getValue())); result.addAll(details); saveInCache(details); - } else { + } + else { LOG.error("No log provider for root " + entry.getKey().getPath() + ". All known log providers " + myLogProviders); } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/CommitDetailsGetter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/CommitDetailsGetter.java index e2a331f07805..49a6bd6a0a6c 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/CommitDetailsGetter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/CommitDetailsGetter.java @@ -32,8 +32,7 @@ public class CommitDetailsGetter extends AbstractDataGetter readDetails(@NotNull VcsLogProvider logProvider, @NotNull VirtualFile root, - @NotNull List hashes) throws VcsException { + @NotNull List hashes) throws VcsException { return logProvider.readFullDetails(root, hashes); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java index a4fb4cfcf819..681097dda8ad 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java @@ -16,7 +16,7 @@ package com.intellij.vcs.log.data; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.NotNullFunction; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.*; import com.intellij.vcs.log.graph.GraphColorManagerImpl; @@ -26,6 +26,7 @@ import com.intellij.vcs.log.graph.impl.facade.PermanentGraphImpl; import com.intellij.vcs.log.util.StopWatch; import gnu.trove.TIntHashSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -56,26 +57,27 @@ public class DataPack extends DataPackBase { } else { refsModel = new RefsModel(refs, getHeads(commits), hashMap); - NotNullFunction hashGetter = createHashGetter(hashMap); + Function hashGetter = createHashGetter(hashMap); GraphColorManagerImpl colorManager = new GraphColorManagerImpl(refsModel, hashGetter, getRefManagerMap(providers)); Set branches = getBranchCommitHashIndexes(refsModel.getBranches(), hashMap); StopWatch sw = StopWatch.start("building graph"); permanentGraph = PermanentGraphImpl.newInstance(commits, colorManager, branches); sw.report(); - } return new DataPack(refsModel, permanentGraph, providers, full); } @NotNull - public static NotNullFunction createHashGetter(@NotNull final VcsLogHashMap hashMap) { - return new NotNullFunction() { - @NotNull + public static Function createHashGetter(@NotNull final VcsLogHashMap hashMap) { + return new Function() { + @Nullable @Override public Hash fun(Integer commitIndex) { - return hashMap.getCommitId(commitIndex).getHash(); + CommitId commitId = hashMap.getCommitId(commitIndex); + if (commitId == null) return null; + return commitId.getHash(); } }; } @@ -118,7 +120,8 @@ public class DataPack extends DataPackBase { @NotNull private static DataPack createEmptyInstance() { - RefsModel emptyModel = new RefsModel(Collections.>emptyMap(), ContainerUtil.newHashSet(), VcsLogHashMapImpl.EMPTY); + RefsModel emptyModel = + new RefsModel(Collections.>emptyMap(), ContainerUtil.newHashSet(), VcsLogHashMapImpl.EMPTY); return new DataPack(emptyModel, EmptyPermanentGraph.getInstance(), Collections.emptyMap(), false); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPackChangeListener.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPackChangeListener.java index 6ec81fda8762..7c1869434b7c 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPackChangeListener.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPackChangeListener.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; public interface DataPackChangeListener { /** * Is called after a new data pack is calculated. + * * @param newDataPack new data pack */ @CalledInAwt diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyPermanentGraph.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyPermanentGraph.java index 170dcda0025c..3bc0a305da7e 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyPermanentGraph.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyPermanentGraph.java @@ -67,5 +67,4 @@ public class EmptyPermanentGraph implements PermanentGraph { public Condition getContainedInBranchCondition(@NotNull Collection currentBranchHead) { return Conditions.alwaysFalse(); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyVisibleGraph.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyVisibleGraph.java index a0b3ea7e6b80..db5ade1b4e46 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyVisibleGraph.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyVisibleGraph.java @@ -20,8 +20,8 @@ import com.intellij.vcs.log.graph.RowInfo; import com.intellij.vcs.log.graph.RowType; import com.intellij.vcs.log.graph.VisibleGraph; import com.intellij.vcs.log.graph.actions.ActionController; -import com.intellij.vcs.log.graph.actions.GraphAnswer; import com.intellij.vcs.log.graph.actions.GraphAction; +import com.intellij.vcs.log.graph.actions.GraphAnswer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/FakeVisiblePackBuilder.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/FakeVisiblePackBuilder.java index 7de7a0ea53b8..02eb202b6588 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/FakeVisiblePackBuilder.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/FakeVisiblePackBuilder.java @@ -32,7 +32,6 @@ import com.intellij.vcs.log.impl.VcsLogUtil; import org.jetbrains.annotations.NotNull; import java.util.Collection; -import java.util.Map; import java.util.Set; public class FakeVisiblePackBuilder { @@ -55,7 +54,9 @@ public class FakeVisiblePackBuilder { } @NotNull - private VisiblePack build(@NotNull DataPackBase oldPack, @NotNull VisibleGraphImpl oldGraph, @NotNull VcsLogFilterCollection filters) { + private VisiblePack build(@NotNull DataPackBase oldPack, + @NotNull VisibleGraphImpl oldGraph, + @NotNull VcsLogFilterCollection filters) { final PermanentGraphInfo info = oldGraph.buildSimpleGraphInfo(); Set heads = ContainerUtil.map2Set(info.getPermanentGraphLayout().getHeadNodeIndex(), new Function() { @Override diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/InMemoryHashMap.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/InMemoryHashMap.java index e1791964a9ee..5e607c4b0686 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/InMemoryHashMap.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/InMemoryHashMap.java @@ -18,11 +18,9 @@ package com.intellij.vcs.log.data; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.BiDirectionalEnumerator; -import com.intellij.util.containers.Enumerator; import com.intellij.vcs.log.CommitId; import com.intellij.vcs.log.Hash; import com.intellij.vcs.log.VcsLogHashMap; -import gnu.trove.TIntObjectHashMap; import gnu.trove.TObjectHashingStrategy; import gnu.trove.TObjectProcedure; import org.jetbrains.annotations.NotNull; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/MiniDetailsGetter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/MiniDetailsGetter.java index 1c63f4c762a7..a9d5fd2f3162 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/MiniDetailsGetter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/MiniDetailsGetter.java @@ -34,8 +34,7 @@ public class MiniDetailsGetter extends AbstractDataGetter @NotNull @Override protected List readDetails(@NotNull VcsLogProvider logProvider, @NotNull VirtualFile root, - @NotNull List hashes) throws VcsException { + @NotNull List hashes) throws VcsException { return logProvider.readShortDetails(root, hashes); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java index 0b9c0b540df0..3f7df1ddc9f5 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java @@ -108,5 +108,4 @@ public abstract class SingleTaskController { } } } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsCommitCache.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsCommitCache.java index 4330006a296d..66ea9caddef7 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsCommitCache.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsCommitCache.java @@ -25,8 +25,8 @@ import java.awt.*; /** *

The cache of commit details.

*

It is not actually a cache, but rather a limited map, because there is intentionally no way to get the non-cached value if it was not - * found in the cache: such functionality is implemented by the {@link DataGetter} which is able to receive - * non-cached details more efficiently, in a batch.

+ * found in the cache: such functionality is implemented by the {@link DataGetter} which is able to receive + * non-cached details more efficiently, in a batch.

*

Any access to the Cache MUST be performed from the EDT thread.

*/ class VcsCommitCache { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataManager.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataManager.java index 64d0d13bf31e..1e62c1bbc3b6 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataManager.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataManager.java @@ -33,6 +33,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.*; import com.intellij.vcs.log.util.StopWatch; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.Collection; @@ -69,11 +70,14 @@ public class VcsLogDataManager implements Disposable, VcsLogDataProvider { @NotNull private final VcsLogRefresherImpl myRefresher; @NotNull private final List myDataPackChangeListeners = ContainerUtil.createLockFreeCopyOnWriteList(); - public VcsLogDataManager(@NotNull Project project, @NotNull Map logProviders) { + @NotNull private final Consumer myFatalErrorsConsumer; + + public VcsLogDataManager(@NotNull Project project, @NotNull Map logProviders, @NotNull Consumer fatalErrorsConsumer) { myProject = project; myLogProviders = logProviders; myDataLoaderQueue = new BackgroundTaskQueue(project, "Loading history..."); myUserRegistry = (VcsUserRegistryImpl)ServiceManager.getService(project, VcsUserRegistry.class); + myFatalErrorsConsumer = fatalErrorsConsumer; myHashMap = createLogHashMap(); myMiniDetailsGetter = new MiniDetailsGetter(myHashMap, logProviders, myTopCommitsDetailsCache, this); @@ -101,7 +105,7 @@ public class VcsLogDataManager implements Disposable, VcsLogDataProvider { private VcsLogHashMap createLogHashMap() { VcsLogHashMap hashMap; try { - hashMap = new VcsLogHashMapImpl(myProject, myLogProviders); + hashMap = new VcsLogHashMapImpl(myProject, myLogProviders, myFatalErrorsConsumer); } catch (IOException e) { hashMap = new InMemoryHashMap(); @@ -140,7 +144,7 @@ public class VcsLogDataManager implements Disposable, VcsLogDataProvider { } @Override - @NotNull + @Nullable public CommitId getCommitId(int commitIndex) { return myHashMap.getCommitId(commitIndex); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilterImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilterImpl.java index 1173016e2c15..e4165c804742 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilterImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilterImpl.java @@ -57,5 +57,4 @@ public class VcsLogDateFilterImpl implements VcsLogDateFilter, VcsLogDetailsFilt public Date getBefore() { return myBefore; } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java index ad3ba41056b7..9428beb4dfad 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java @@ -17,7 +17,6 @@ package com.intellij.vcs.log.data; import com.intellij.vcs.log.VcsLogFilterCollection; import com.intellij.vcs.log.graph.PermanentGraph; -import org.jetbrains.annotations.CalledInAwt; import org.jetbrains.annotations.NotNull; /** diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFiltererImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFiltererImpl.java index da1b814bc501..d40989caeddc 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFiltererImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFiltererImpl.java @@ -23,7 +23,6 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.progress.impl.ProgressManagerImpl; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMapImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMapImpl.java index 0a86045ed5e1..6ee80098aec8 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMapImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMapImpl.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.CommonProcessors; +import com.intellij.util.Consumer; import com.intellij.util.io.KeyDescriptor; import com.intellij.util.io.PersistentEnumerator; import com.intellij.vcs.log.CommitId; @@ -72,10 +73,13 @@ public class VcsLogHashMapImpl implements Disposable, VcsLogHashMap { @NotNull private static final Logger LOG = Logger.getInstance(VcsLogHashMap.class); @NotNull private static final String LOG_KIND = "hashes"; private static final int VERSION = 2; + private static final int NO_INDEX = -1; @NotNull private final PersistentEnumerator myPersistentEnumerator; + @NotNull private final Consumer myExceptionReporter; - public VcsLogHashMapImpl(@NotNull final Project project, @NotNull Map logProviders) throws IOException { + public VcsLogHashMapImpl(@NotNull final Project project, @NotNull Map logProviders, @NotNull Consumer exceptionReporter) throws IOException { + myExceptionReporter = exceptionReporter; myPersistentEnumerator = PersistentUtil.createPersistentEnumerator(new MyCommitIdKeyDescriptor(project), LOG_KIND, PersistentUtil.calcLogId(project, logProviders), VERSION); @@ -97,23 +101,25 @@ public class VcsLogHashMapImpl implements Disposable, VcsLogHashMap { return getOrPut(hash, root); } catch (IOException e) { - throw new RuntimeException(e); // TODO the map is corrupted => need to rebuild + myExceptionReporter.consume(e); } + return NO_INDEX; } @Override - @NotNull + @Nullable public CommitId getCommitId(int commitIndex) { try { CommitId commitId = doGetCommitId(commitIndex); if (commitId == null) { - throw new RuntimeException("Unknown commit index: " + commitIndex); // TODO this shouldn't happen => need to recreate the map + myExceptionReporter.consume(new RuntimeException("Unknown commit index: " + commitIndex)); } return commitId; } catch (IOException e) { - throw new RuntimeException(e); // TODO map is corrupted => need to recreate it + myExceptionReporter.consume(e); } + return null; } @Override @@ -134,7 +140,7 @@ public class VcsLogHashMapImpl implements Disposable, VcsLogHashMap { return hashRef.get(); } catch (IOException e) { - LOG.error(e); + myExceptionReporter.consume(e); return null; } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java index d221970d1874..06973a90144a 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java @@ -36,17 +36,17 @@ public class VcsLogJoiner> { /** * Attaches the block of latest commits, which was read from the VCS, to the existing log structure. * - * @param savedLog currently available part of the log. - * @param previousRefs references saved from the previous refresh. - * @param firstBlock the first n commits read from the VCS. - * @param newRefs all references (branches) of the repository. + * @param savedLog currently available part of the log. + * @param previousRefs references saved from the previous refresh. + * @param firstBlock the first n commits read from the VCS. + * @param newRefs all references (branches) of the repository. * @return Total saved log with new commits properly attached to it + number of new commits attached to the log. */ @NotNull public Pair, Integer> addCommits(@NotNull List savedLog, - @NotNull Collection previousRefs, - @NotNull List firstBlock, - @NotNull Collection newRefs) { + @NotNull Collection previousRefs, + @NotNull List firstBlock, + @NotNull Collection newRefs) { Pair> newCommitsAndSavedGreenIndex = getNewCommitsAndSavedGreenIndex(savedLog, previousRefs, firstBlock, newRefs); Pair> redCommitsAndSavedRedIndex = @@ -69,12 +69,11 @@ public class VcsLogJoiner> { } - @NotNull private Pair> getNewCommitsAndSavedGreenIndex(@NotNull List savedLog, - @NotNull Collection previousRefs, - @NotNull List firstBlock, - @NotNull Collection newRefs) { + @NotNull Collection previousRefs, + @NotNull List firstBlock, + @NotNull Collection newRefs) { Set allUnresolvedLinkedHashes = new THashSet(newRefs); allUnresolvedLinkedHashes.removeAll(previousRefs); // at this moment allUnresolvedLinkedHashes contains only NEW refs @@ -96,17 +95,19 @@ public class VcsLogJoiner> { int lastIndex; for (lastIndex = 0; lastIndex < commits.size(); lastIndex++) { Commit commit = commits.get(lastIndex); - if (searchHashes.size() == 0) + if (searchHashes.size() == 0) { return lastIndex; + } searchHashes.remove(commit.getId()); } - if (searchHashes.size() != 0) + if (searchHashes.size() != 0) { throw new VcsLogRefreshNotEnoughDataException(); + } return lastIndex; } private Set getAllNewCommits(@NotNull List unsafeGreenPartSavedLog, - @NotNull List firstBlock) { + @NotNull List firstBlock) { Set existedCommitHashes = ContainerUtil.newHashSet(); for (Commit commit : unsafeGreenPartSavedLog) { existedCommitHashes.add(commit.getId()); @@ -152,8 +153,9 @@ public class VcsLogJoiner> { } private void markRealRedNode(@NotNull CommitId node) { - if (!currentRed.remove(node)) + if (!currentRed.remove(node)) { throw new IllegalStateException(ILLEGAL_DATA_RELOAD_ALL); // see VcsLogJoinerTest#illegalStateExceptionTest2 + } allRedCommit.add(node); } @@ -170,8 +172,9 @@ public class VcsLogJoiner> { currentRed.addAll(commit.getParents()); } - if (currentRed.isEmpty()) + if (currentRed.isEmpty()) { return lastIndex + 1; + } } throw new IllegalStateException(ILLEGAL_DATA_RELOAD_ALL); // see VcsLogJoinerTest#illegalStateExceptionTest } @@ -212,17 +215,20 @@ public class VcsLogJoiner> { } } - if (!allParentsWereAdded) + if (!allParentsWereAdded) { continue; + } int insertIndex; Set parents = new THashSet(currentCommit.getParents()); for (insertIndex = 0; insertIndex < list.size(); insertIndex++) { Commit someCommit = list.get(insertIndex); - if (parents.contains(someCommit.getId())) + if (parents.contains(someCommit.getId())) { break; - if (someCommit.getTimestamp() < currentCommit.getTimestamp()) + } + if (someCommit.getTimestamp() < currentCommit.getTimestamp()) { break; + } } list.add(insertIndex, currentCommit); @@ -238,6 +244,4 @@ public class VcsLogJoiner> { return list; } } - - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java index f36b26a74d94..ac95e7214c84 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java @@ -55,5 +55,4 @@ public class VcsLogMultiRepoJoiner rootsToRefresh); - } \ No newline at end of file diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java index c6c7c05f4a2c..4a03713edcaf 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java @@ -41,7 +41,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; public class VcsLogRefresherImpl implements VcsLogRefresher { - + private static final Logger LOG = Logger.getInstance(VcsLogRefresherImpl.class); @NotNull private final Project myProject; @@ -459,6 +459,5 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { public Set getRefs(@NotNull VirtualFile root) { return myRefs.get(root); } - } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogSorter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogSorter.java index 3f9d742eef34..5c4306cd50fc 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogSorter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogSorter.java @@ -29,5 +29,4 @@ public class VcsLogSorter { public static List sortByDateTopoOrder(@NotNull Collection commits) { return new VcsLogJoiner.NewCommitIntegrator(new ArrayList(), commits).getResultList(); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiPropertiesImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiPropertiesImpl.java index c2a52f9f3c20..5bb2f6a1cc17 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiPropertiesImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiPropertiesImpl.java @@ -20,7 +20,6 @@ import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.VcsLogSettings; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.*; @@ -173,5 +172,4 @@ public abstract class VcsLogUiPropertiesImpl implements PersistentStateComponent return users.hashCode(); } } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePack.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePack.java index 0a32c37ad79d..130575489606 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePack.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePack.java @@ -28,14 +28,18 @@ import java.util.Map; public class VisiblePack implements VcsLogDataPack { @NotNull - public static final VisiblePack EMPTY = new VisiblePack(DataPack.EMPTY, EmptyVisibleGraph.getInstance(), false, VcsLogFilterCollectionImpl.EMPTY); + public static final VisiblePack EMPTY = + new VisiblePack(DataPack.EMPTY, EmptyVisibleGraph.getInstance(), false, VcsLogFilterCollectionImpl.EMPTY); @NotNull private final DataPackBase myDataPack; @NotNull private final VisibleGraph myVisibleGraph; private final boolean myCanRequestMore; @NotNull private final VcsLogFilterCollection myFilters; - VisiblePack(@NotNull DataPackBase dataPack, @NotNull VisibleGraph graph, boolean canRequestMore, @NotNull VcsLogFilterCollection filters) { + VisiblePack(@NotNull DataPackBase dataPack, + @NotNull VisibleGraph graph, + boolean canRequestMore, + @NotNull VcsLogFilterCollection filters) { myDataPack = dataPack; myVisibleGraph = graph; myCanRequestMore = canRequestMore; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePackBuilder.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePackBuilder.java index 78e8f534f090..201a6ebafb0f 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePackBuilder.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePackBuilder.java @@ -119,11 +119,14 @@ class VisiblePackBuilder { } }); VisibleGraph visibleGraph = dataPack.getPermanentGraph().createVisibleGraph(sortType, null, indices); - return new VisiblePack(dataPack, visibleGraph, false, new VcsLogFilterCollectionImpl(null, null, new VcsLogHashFilterImpl(hashes), null, null, null, null)); + return new VisiblePack(dataPack, visibleGraph, false, + new VcsLogFilterCollectionImpl(null, null, new VcsLogHashFilterImpl(hashes), null, null, null, null)); } @Nullable - private Set getMatchingHeads(@NotNull VcsLogRefs refs, @NotNull Set roots, @NotNull VcsLogFilterCollection filters) { + private Set getMatchingHeads(@NotNull VcsLogRefs refs, + @NotNull Set roots, + @NotNull VcsLogFilterCollection filters) { VcsLogBranchFilter branchFilter = filters.getBranchFilter(); VcsLogRootFilter rootFilter = filters.getRootFilter(); VcsLogStructureFilter structureFilter = filters.getStructureFilter(); @@ -167,8 +170,8 @@ class VisiblePackBuilder { @NotNull private Collection filterInMemory(@NotNull PermanentGraph permanentGraph, - @NotNull List detailsFilters, - @Nullable Set matchingHeads) { + @NotNull List detailsFilters, + @Nullable Set matchingHeads) { Collection result = ContainerUtil.newArrayList(); for (GraphCommit commit : permanentGraph.getAllCommits()) { VcsCommitMetadata data = getDetailsFromCache(commit.getId()); @@ -223,8 +226,8 @@ class VisiblePackBuilder { @NotNull private static Collection getFilteredDetailsFromTheVcs(@NotNull Map providers, - @NotNull VcsLogFilterCollection filterCollection, - int maxCount) throws VcsException { + @NotNull VcsLogFilterCollection filterCollection, + int maxCount) throws VcsException { Set visibleRoots = VcsLogUtil.getAllVisibleRoots(providers.keySet(), filterCollection.getRootFilter(), filterCollection.getStructureFilter()); @@ -240,7 +243,8 @@ class VisiblePackBuilder { VcsLogFilterCollection rootSpecificCollection = filterCollection; if (rootSpecificCollection.getStructureFilter() != null) { - rootSpecificCollection = replaceStructureFilter(filterCollection, ContainerUtil.newHashSet(VcsLogUtil.getFilteredFilesForRoot(root, filterCollection))); + rootSpecificCollection = + replaceStructureFilter(filterCollection, ContainerUtil.newHashSet(VcsLogUtil.getFilteredFilesForRoot(root, filterCollection))); } List matchingCommits = entry.getValue().getCommitsMatchingFilter(root, rootSpecificCollection, maxCount); @@ -277,5 +281,4 @@ class VisiblePackBuilder { } }); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/graph/GraphColorManagerImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/graph/GraphColorManagerImpl.java index c62e93d43588..174009c3a14b 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/graph/GraphColorManagerImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/graph/GraphColorManagerImpl.java @@ -17,14 +17,13 @@ package com.intellij.vcs.log.graph; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.NotNullFunction; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.hash.LinkedHashMap; import com.intellij.vcs.log.Hash; import com.intellij.vcs.log.VcsLogRefManager; import com.intellij.vcs.log.VcsRef; import com.intellij.vcs.log.data.RefsModel; -import com.intellij.vcs.log.impl.VcsLogUtil; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -42,7 +41,7 @@ public class GraphColorManagerImpl implements GraphColorManager { @NotNull private final Map myRefManagers; public GraphColorManagerImpl(@NotNull RefsModel refsModel, - @NotNull NotNullFunction hashGetter, + @NotNull Function hashGetter, @NotNull Map refManagers) { myRefsModel = refsModel; myRefManagers = refManagers; @@ -79,7 +78,7 @@ public class GraphColorManagerImpl implements GraphColorManager { public static class HeadsComparator implements Comparator { @NotNull private final RefsModel myRefsModel; @NotNull private final Map myRefManagers; - @NotNull private final NotNullFunction myHashGetter; + @NotNull private final Function myHashGetter; @NotNull private final LinkedHashMap myErrorWasReported = new LinkedHashMap(10) { @Override @@ -90,7 +89,7 @@ public class GraphColorManagerImpl implements GraphColorManager { public HeadsComparator(@NotNull RefsModel refsModel, @NotNull Map refManagers, - @NotNull NotNullFunction hashGetter) { + @NotNull Function hashGetter) { myRefsModel = refsModel; myRefManagers = refManagers; myHashGetter = hashGetter; @@ -132,7 +131,7 @@ public class GraphColorManagerImpl implements GraphColorManager { VcsLogRefManager refManager1 = myRefManagers.get(root1); VcsLogRefManager refManager2 = myRefManagers.get(root2); if (!refManager1.equals(refManager2)) { - return VcsLogUtil.compareRoots(root1, root2); + return refManager1.toString().compareTo(refManager2.toString()); } VcsRef bestRef = ContainerUtil.sorted(ContainerUtil.concat(refs1, refs2), refManager1.getBranchLayoutComparator()).get(0); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/TimedVcsCommitImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/TimedVcsCommitImpl.java index d09ab814b0a3..6b6ceca622a9 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/TimedVcsCommitImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/TimedVcsCommitImpl.java @@ -11,9 +11,9 @@ import java.util.List; /** *

We suppose that the Hash is the unique identifier of the Commit, - * i. e. it is the only value that should be checked in equals() and hashCode().

+ * i. e. it is the only value that should be checked in equals() and hashCode().

*

equals() and hashCode() are made final to ensure that any descendants of this class are considered equal - * if and only if their hashes are equals.

+ * if and only if their hashes are equals.

*

It is highly recommended to use this standard implementation of the VcsCommit because of the above reasons.

* * @author erokhins @@ -73,5 +73,4 @@ public class TimedVcsCommitImpl implements TimedVcsCommit { public final long getTimestamp() { return myTime; } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java index 0dba920a0d23..1685d1ff2754 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java @@ -58,5 +58,4 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme return Collections.emptyList(); } } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogContentProvider.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogContentProvider.java index 621b391e4177..980a9a0601f0 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogContentProvider.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogContentProvider.java @@ -51,6 +51,12 @@ public class VcsLogContentProvider implements ChangesViewContentProvider { public VcsLogContentProvider(@NotNull Project project, @NotNull VcsLogManager logManager) { myProject = project; myLogManager = logManager; + myLogManager.setRecreateMainLogHandler(new Runnable() { + @Override + public void run() { + recreateLog(); + } + }); } @Override @@ -89,20 +95,25 @@ public class VcsLogContentProvider implements ChangesViewContentProvider { @NotNull String shortName) { logManager.watchTab(ContentUtilEx.getFullName(TAB_NAME, shortName), logUi); logUi.requestFocus(); - ContentUtilEx.addTabbedContent(toolWindow.getContentManager(), logUi.getMainFrame().getMainComponent(), TAB_NAME, shortName, true, logUi); + ContentUtilEx + .addTabbedContent(toolWindow.getContentManager(), logUi.getMainFrame().getMainComponent(), TAB_NAME, shortName, true, logUi); toolWindow.activate(null); } + private void recreateLog() { + myContainer.removeAll(); + myLogManager.disposeLog(); + + initContentInternal(); + } + private class MyVcsListener implements VcsListener { @Override public void directoryMappingChanged() { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - myContainer.removeAll(); - myLogManager.disposeLog(); - - initContentInternal(); + recreateLog(); } }); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java index 4d6fe2cfe8b2..39ef50b66335 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java @@ -103,5 +103,4 @@ public class VcsLogFilterCollectionImpl implements VcsLogFilterCollection { public List getDetailsFilters() { return ContainerUtil.skipNulls(Arrays.asList(myUserFilter, myDateFilter, myTextFilter, myStructureFilter)); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogImpl.java index 698e40882af4..0cd51d547fe0 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogImpl.java @@ -28,7 +28,8 @@ import com.intellij.vcs.log.ui.frame.VcsLogGraphTable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.AbstractList; +import java.util.Collection; import java.util.List; import java.util.concurrent.Future; @@ -46,7 +47,7 @@ public class VcsLogImpl implements VcsLog { public List getSelectedCommits() { final int[] rows = myUi.getTable().getSelectedRows(); return new AbstractList() { - @NotNull + @Nullable @Override public CommitId get(int index) { return getTable().getGraphTableModel().getCommitIdAtRow(rows[index]); @@ -84,7 +85,8 @@ public class VcsLogImpl implements VcsLog { @Override public void requestSelectedDetails(@NotNull Consumer> consumer, @Nullable ProgressIndicator indicator) { List rowsList = Ints.asList(myUi.getTable().getSelectedRows()); - myDataManager.getCommitDetailsGetter().loadCommitsData(getTable().getGraphTableModel().convertToHashesAndRoots(rowsList), consumer, indicator); + myDataManager.getCommitDetailsGetter() + .loadCommitsData(getTable().getGraphTableModel().convertToHashesAndRoots(rowsList), consumer, indicator); } @Nullable @@ -122,5 +124,4 @@ public class VcsLogImpl implements VcsLog { public Collection getLogProviders() { return myDataManager.getLogProviders(); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java index 07ff58997350..784b54cda055 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java @@ -22,15 +22,17 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsRoot; +import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.intellij.vcs.log.VcsLogProvider; -import com.intellij.vcs.log.VcsLogRefresher; import com.intellij.vcs.log.data.*; import com.intellij.vcs.log.graph.PermanentGraph; import com.intellij.vcs.log.ui.VcsLogColorManagerImpl; @@ -51,6 +53,8 @@ public class VcsLogManager implements Disposable { @NotNull private final Project myProject; @NotNull private final VcsLogTabsProperties myUiProperties; + @Nullable private Runnable myRecreateMainLogHandler; + private volatile VcsLogUiImpl myUi; private VcsLogDataManager myDataManager; private VcsLogColorManagerImpl myColorManager; @@ -135,7 +139,7 @@ public class VcsLogManager implements Disposable { if (myDataManager != null) return true; Map logProviders = findLogProviders(getVcsRoots(), myProject); - myDataManager = new VcsLogDataManager(myProject, logProviders); + myDataManager = new VcsLogDataManager(myProject, logProviders, new MyFatalErrorsConsumer()); myTabsLogRefresher = new VcsLogTabsRefresher(myProject, myDataManager); refreshLogOnVcsEvents(logProviders, myTabsLogRefresher); @@ -146,7 +150,8 @@ public class VcsLogManager implements Disposable { return false; } - private static void refreshLogOnVcsEvents(@NotNull Map logProviders, @NotNull VcsLogTabsRefresher refresher) { + private static void refreshLogOnVcsEvents(@NotNull Map logProviders, + @NotNull VcsLogTabsRefresher refresher) { MultiMap providers2roots = MultiMap.create(); for (Map.Entry entry : logProviders.entrySet()) { providers2roots.putValue(entry.getValue(), entry.getKey()); @@ -180,6 +185,10 @@ public class VcsLogManager implements Disposable { return logProviders; } + public void setRecreateMainLogHandler(@Nullable Runnable recreateMainLogHandler) { + myRecreateMainLogHandler = recreateMainLogHandler; + } + /** * The instance of the {@link VcsLogUiImpl} or null if the log was not initialized yet. */ @@ -205,4 +214,35 @@ public class VcsLogManager implements Disposable { public void dispose() { disposeLog(); } + + private class MyFatalErrorsConsumer implements Consumer { + private boolean myIsBroken = false; + + @Override + public void consume(@NotNull final Exception e) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (!myIsBroken) { + myIsBroken = true; + processErrorFirstTime(e); + } + else { + LOG.debug(e); + } + } + }); + } + + protected void processErrorFirstTime(@NotNull Exception e) { + if (myRecreateMainLogHandler != null) { + LOG.info(e); + VcsBalloonProblemNotifier.showOverChangesView(myProject, "Fatal error, VCS Log recreated: " + e.getMessage(), MessageType.ERROR); + myRecreateMainLogHandler.run(); + } + else { + LOG.error(e); + } + } + } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogObjectsFactoryImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogObjectsFactoryImpl.java index 881530d732ad..d268293bac45 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogObjectsFactoryImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogObjectsFactoryImpl.java @@ -4,7 +4,6 @@ import com.intellij.openapi.util.ThrowableComputable; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.WeakInterner; -import com.intellij.util.containers.WeakStringInterner; import com.intellij.vcs.log.*; import org.jetbrains.annotations.NotNull; @@ -65,7 +64,8 @@ public class VcsLogObjectsFactoryImpl implements VcsLogObjectsFactory { @NotNull ThrowableComputable, ? extends Exception> changesGetter) { VcsUser author = createUser(authorName, authorEmail); VcsUser committer = createUser(committerName, committerEmail); - return new VcsChangesLazilyParsedDetails(hash, parents, commitTime, root, subject, author, message, committer, authorTime, changesGetter); + return new VcsChangesLazilyParsedDetails(hash, parents, commitTime, root, subject, author, message, committer, authorTime, + changesGetter); } @NotNull @@ -79,5 +79,4 @@ public class VcsLogObjectsFactoryImpl implements VcsLogObjectsFactory { public VcsRef createRef(@NotNull Hash commitHash, @NotNull String name, @NotNull VcsRefType type, @NotNull VirtualFile root) { return myRefsInterner.intern(new VcsRefImpl(commitHash, name, type, root)); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogUtil.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogUtil.java index 89d402f136dc..c90f4c729c38 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogUtil.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogUtil.java @@ -18,12 +18,10 @@ package com.intellij.vcs.log.impl; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.FilePath; -import com.intellij.openapi.vcs.changes.ChangesUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.MultiMap; import com.intellij.vcs.log.*; import com.intellij.vcs.log.data.LoadingDetails; import com.intellij.vcs.log.graph.VisibleGraph; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRefImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRefImpl.java index 5a4bb10c0568..9398f8c64bbc 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRefImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRefImpl.java @@ -78,5 +78,4 @@ public final class VcsRefImpl implements VcsRef { result = 31 * result + (myType.hashCode()); return result; } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRootsRegistry.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRootsRegistry.java index 4018ec9de92a..dd083047d067 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRootsRegistry.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRootsRegistry.java @@ -19,9 +19,11 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; + public interface VcsRootsRegistry { - int getId(@NotNull VirtualFile root); + int getId(@NotNull VirtualFile root) throws IOException; @Nullable - VirtualFile getRootById(int id); + VirtualFile getRootById(int id) throws IOException; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRootsRegistryImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRootsRegistryImpl.java index c130efc44dd7..0f00dc29840f 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRootsRegistryImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRootsRegistryImpl.java @@ -61,32 +61,20 @@ public class VcsRootsRegistryImpl implements VcsRootsRegistry, Disposable { } @Override - public int getId(@NotNull VirtualFile root) { - try { - return myEnumerator.enumerate(root.getPath()); - } - catch (IOException e) { - LOG.error(e); - throw new RuntimeException(e); // to be dealt with in rr/julia/persistenthashmap branch - } + public int getId(@NotNull VirtualFile root) throws IOException { + return myEnumerator.enumerate(root.getPath()); } @Override @Nullable - public VirtualFile getRootById(int id) { - try { - String path = myEnumerator.valueOf(id); - if (path == null) throw new RuntimeException("Can not find path by id " + id); - VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); - if (file == null) { - LOG.info("Can not find file by path " + path); - return null; - } - return file; - } - catch (IOException e) { - LOG.error(e); - throw new RuntimeException(e); // to be dealt with in rr/julia/persistenthashmap branch + public VirtualFile getRootById(int id) throws IOException { + String path = myEnumerator.valueOf(id); + if (path == null) throw new RuntimeException("Can not find path by id " + id); + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); + if (file == null) { + LOG.info("Can not find file by path " + path); + return null; } + return file; } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsShortCommitDetailsImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsShortCommitDetailsImpl.java index 695045414bbc..30a77d6a2fe2 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsShortCommitDetailsImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsShortCommitDetailsImpl.java @@ -64,5 +64,4 @@ public class VcsShortCommitDetailsImpl extends TimedVcsCommitImpl implements Vcs public String toString() { return getId().toShortString() + "(" + getSubject() + ")"; } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsUserImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsUserImpl.java index 4fb1a3a77be5..e3d6ec53ae70 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsUserImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsUserImpl.java @@ -16,12 +16,10 @@ package com.intellij.vcs.log.impl; import com.intellij.openapi.util.Pair; -import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.VcsUser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/paint/GraphCellPainter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/paint/GraphCellPainter.java index 917bb7ebee07..fe44fb1ed7c5 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/paint/GraphCellPainter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/paint/GraphCellPainter.java @@ -31,6 +31,5 @@ public interface GraphCellPainter { @Nullable PrintElement getElementUnderCursor(@NotNull Collection printElements, int x, int y); - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogActionPlaces.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogActionPlaces.java index 3e40084743c3..805e89e5eadc 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogActionPlaces.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogActionPlaces.java @@ -22,4 +22,5 @@ public class VcsLogActionPlaces { public static final String VCS_LOG_TABLE_PLACE = "Vcs.Log.ContextMenu"; public static final String VCS_LOG_INTELLI_SORT_ACTION = "Vcs.Log.IntelliSortChooser"; public static final String VCS_LOG_QUICK_SETTINGS_ACTION = "Vcs.Log.QuickSettings"; + public static final String VCS_LOG_FOCUS_TEXT_FILTER = "Vcs.Log.FocusTextFilter"; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogColorManager.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogColorManager.java index 6999f9a0f2ba..eebcdcb4e869 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogColorManager.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogColorManager.java @@ -22,5 +22,4 @@ public interface VcsLogColorManager { * Tells if there are several repositories currently shown in the log. */ boolean isMultipleRoots(); - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java index 15d592cd7c02..9717573af084 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java @@ -11,8 +11,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; -import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.util.PairFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseGraphAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseGraphAction.java index fc2b267d23b4..5e747e168037 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseGraphAction.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseGraphAction.java @@ -22,6 +22,12 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; public class CollapseGraphAction extends CollapseOrExpandGraphAction { + @NotNull private static final String COLLAPSE = "Collapse"; + + public CollapseGraphAction() { + super(COLLAPSE); + } + @Override protected void executeAction(@NotNull VcsLogUiImpl vcsLogUi) { vcsLogUi.collapseAll(); @@ -42,6 +48,6 @@ public class CollapseGraphAction extends CollapseOrExpandGraphAction { @NotNull @Override protected String getPrefix() { - return "Collapse "; + return COLLAPSE + " "; } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseOrExpandGraphAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseOrExpandGraphAction.java index 53d1f3bf4254..15558b48b35c 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseOrExpandGraphAction.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseOrExpandGraphAction.java @@ -32,8 +32,8 @@ abstract class CollapseOrExpandGraphAction extends DumbAwareAction { private static final String MERGES = "Merges"; private static final String MERGES_DESCRIPTION = "merges"; - public CollapseOrExpandGraphAction() { - super("Collapse or Expand " + LINEAR_BRANCHES, "Collapse or Expand " + LINEAR_BRANCHES_DESCRIPTION, null); + public CollapseOrExpandGraphAction(@NotNull String action) { + super(action + " " + LINEAR_BRANCHES, action + " " + LINEAR_BRANCHES_DESCRIPTION, null); } @Override @@ -89,5 +89,4 @@ abstract class CollapseOrExpandGraphAction extends DumbAwareAction { private static boolean isIconHidden(@NotNull AnActionEvent e) { return e.getPlace().equals(ToolWindowContentUi.POPUP_PLACE); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/ExpandGraphAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/ExpandGraphAction.java index 199468f7e3f7..a219989abddb 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/ExpandGraphAction.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/ExpandGraphAction.java @@ -22,6 +22,12 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; public class ExpandGraphAction extends CollapseOrExpandGraphAction { + @NotNull private static final String EXPAND = "Expand"; + + public ExpandGraphAction() { + super(EXPAND); + } + @Override protected void executeAction(@NotNull VcsLogUiImpl vcsLogUi) { vcsLogUi.expandAll(); @@ -42,6 +48,6 @@ public class ExpandGraphAction extends CollapseOrExpandGraphAction { @NotNull @Override protected String getPrefix() { - return "Expand "; + return EXPAND + " "; } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/FocusTextFilterAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/FocusTextFilterAction.java new file mode 100644 index 000000000000..7358e0d7501a --- /dev/null +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/FocusTextFilterAction.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2016 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.vcs.log.ui.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.vcs.log.VcsLogDataKeys; +import com.intellij.vcs.log.VcsLogUi; +import com.intellij.vcs.log.ui.VcsLogUiImpl; +import com.intellij.vcs.log.ui.frame.MainFrame; +import org.jetbrains.annotations.NotNull; + +public class FocusTextFilterAction extends DumbAwareAction { + public FocusTextFilterAction() { + super("Focus Text Filter", "Focus text filter or move focus back to the commits list", null); + } + + @Override + public void update(@NotNull AnActionEvent e) { + Project project = e.getProject(); + VcsLogUi ui = e.getData(VcsLogDataKeys.VCS_LOG_UI); + e.getPresentation().setEnabledAndVisible(project != null && ui != null && ui instanceof VcsLogUiImpl); + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + Project project = e.getRequiredData(CommonDataKeys.PROJECT); + MainFrame mainFrame = ((VcsLogUiImpl)e.getRequiredData(VcsLogDataKeys.VCS_LOG_UI)).getMainFrame(); + if (mainFrame.getTextFilter().getTextEditor().hasFocus()) { + IdeFocusManager.getInstance(project).requestFocus(mainFrame.getGraphTable(), true); + } + else { + IdeFocusManager.getInstance(project).requestFocus(mainFrame.getTextFilter(), true); + } + } +} diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/GoToHashOrRefAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/GoToHashOrRefAction.java index 2f4943b3a3f8..c4b040444966 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/GoToHashOrRefAction.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/GoToHashOrRefAction.java @@ -25,7 +25,10 @@ import com.intellij.vcs.log.impl.VcsLogUtil; import com.intellij.vcs.log.ui.VcsLogUiImpl; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; +import java.util.Set; import java.util.concurrent.Future; public class GoToHashOrRefAction extends DumbAwareAction { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/RefreshLogAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/RefreshLogAction.java index 90d27af5f2ea..9ebdc0bf043b 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/RefreshLogAction.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/RefreshLogAction.java @@ -40,7 +40,8 @@ public class RefreshLogAction extends RefreshAction { Project project = e.getProject(); if (project == null) { e.getPresentation().setEnabledAndVisible(false); - } else { + } + else { VcsLogDataManager dataManager = VcsLogManager.getInstance(project).getDataManager(); e.getPresentation().setEnabledAndVisible(dataManager != null && e.getData(VcsLogDataKeys.VCS_LOG_UI) != null); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/TextFieldWithProgress.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/TextFieldWithProgress.java index 49ceb65b254d..ae7a3e9c6c4d 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/TextFieldWithProgress.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/TextFieldWithProgress.java @@ -41,32 +41,32 @@ public abstract class TextFieldWithProgress extends JPanel { myProgressIcon = new AsyncProcessIcon("Loading commits"); myTextField = new TextFieldWithAutoCompletion(project, completionProvider, false, null) { - @Override - public void setBackground(Color bg) { - super.setBackground(bg); - myProgressIcon.setBackground(bg); - } + @Override + public void setBackground(Color bg) { + super.setBackground(bg); + myProgressIcon.setBackground(bg); + } - @Override - protected EditorEx createEditor() { - EditorEx editor = super.createEditor(); - editor.putUserData(AutoPopupController.ALWAYS_AUTO_POPUP, true); - EditorCustomization customization = SpellCheckingEditorCustomizationProvider.getInstance().getDisabledCustomization(); - if (customization != null) { - customization.customize(editor); - } - return editor; + @Override + protected EditorEx createEditor() { + EditorEx editor = super.createEditor(); + editor.putUserData(AutoPopupController.ALWAYS_AUTO_POPUP, true); + EditorCustomization customization = SpellCheckingEditorCustomizationProvider.getInstance().getDisabledCustomization(); + if (customization != null) { + customization.customize(editor); } + return editor; + } - @Override - protected boolean processKeyBinding(KeyStroke ks, final KeyEvent e, int condition, boolean pressed) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - onOk(); - return true; - } - return false; + @Override + protected boolean processKeyBinding(KeyStroke ks, final KeyEvent e, int condition, boolean pressed) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + onOk(); + return true; } - }; + return false; + } + }; myTextField.setBorder(IdeBorderFactory.createEmptyBorder()); myProgressIcon.setOpaque(true); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/VcsLogCreatePatchAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/VcsLogCreatePatchAction.java index f0c4e837d1bc..d49e2bbbf45e 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/VcsLogCreatePatchAction.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/VcsLogCreatePatchAction.java @@ -27,5 +27,4 @@ public class VcsLogCreatePatchAction extends CreatePatchFromChangesAction { Change[] changes; e.getPresentation().setEnabled((changes = e.getData(VcsDataKeys.CHANGES)) != null && changes.length > 0); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/FilterModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/FilterModel.java index 4d32ceaa6897..ed5b784897e2 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/FilterModel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/FilterModel.java @@ -55,5 +55,4 @@ class FilterModel { void addSetFilterListener(@NotNull Runnable runnable) { mySetFilterListeners.add(runnable); } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultilinePopupBuilder.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultilinePopupBuilder.java index ea57622cb17c..728bd2fc9045 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultilinePopupBuilder.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultilinePopupBuilder.java @@ -47,7 +47,7 @@ import java.util.Collection; class MultilinePopupBuilder { - private static final char[] SEPARATORS = { ',', '|', '\n' }; + private static final char[] SEPARATORS = {',', '|', '\n'}; @NotNull private final EditorTextField myTextField; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultipleValueFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultipleValueFilterPopupComponent.java index c8590170f70e..00de611c7551 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultipleValueFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultipleValueFilterPopupComponent.java @@ -15,7 +15,10 @@ */ package com.intellij.vcs.log.ui.filter; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; @@ -157,10 +160,10 @@ abstract class MultipleValueFilterPopupComponent ex }); popup.showUnderneathOf(MultipleValueFilterPopupComponent.this); } + @NotNull private String getPopupText(@Nullable Collection selectedValues) { return selectedValues == null || selectedValues.isEmpty() ? "" : StringUtil.join(selectedValues, "\n"); } } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index 94a4e58a9b0d..7efdb6a6be55 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -92,7 +92,7 @@ class StructureFilterPopupComponent extends FilterPopupComponent(myLogDataManager.getRoots()), myStructureFilterModel.getFilter()); + myBranchFilterModel + .onStructureFilterChanged(new HashSet(myLogDataManager.getRoots()), myStructureFilterModel.getFilter()); } }); } @@ -115,7 +119,7 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { } @NotNull - public JComponent createTextFilter() { + public SearchTextField createTextFilter() { final SearchTextFieldWithStoredHistory textFilter = new SearchTextFieldWithStoredHistory(VCS_LOG_TEXT_FILTER_HISTORY) { @Override protected void onFieldCleared() { @@ -141,6 +145,10 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { } } }); + String shortcutText = KeymapUtil.getFirstKeyboardShortcutText(VcsLogActionPlaces.VCS_LOG_FOCUS_TEXT_FILTER); + if (!shortcutText.isEmpty()) { + textFilter.getTextEditor().setToolTipText("Use " + shortcutText + " to switch between text filter and commits list"); + } return textFilter; } @@ -187,8 +195,12 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { filtersFromText.second, myDateFilterModel.getFilter(), filtersFromText.first, - myStructureFilterModel.getFilter() == null ? null : myStructureFilterModel.getFilter().getStructureFilter(), - myStructureFilterModel.getFilter() == null ? null : myStructureFilterModel.getFilter().getRootFilter()); + myStructureFilterModel.getFilter() == null + ? null + : myStructureFilterModel.getFilter().getStructureFilter(), + myStructureFilterModel.getFilter() == null + ? null + : myStructureFilterModel.getFilter().getRootFilter()); } @NotNull @@ -268,7 +280,8 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { public void onStructureFilterChanged(@NotNull Set roots, @Nullable VcsLogFileFilter filter) { if (filter == null) { myVisibleRoots = null; - } else { + } + else { myVisibleRoots = VcsLogUtil.getAllVisibleRoots(roots, filter.getRootFilter(), filter.getStructureFilter()); } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilterImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilterImpl.java index 80a0989c2c7f..bd3f93a72b34 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilterImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilterImpl.java @@ -16,8 +16,8 @@ package com.intellij.vcs.log.ui.filter; import com.intellij.vcs.log.VcsCommitMetadata; -import com.intellij.vcs.log.VcsLogTextFilter; import com.intellij.vcs.log.VcsLogDetailsFilter; +import com.intellij.vcs.log.VcsLogTextFilter; import org.jetbrains.annotations.NotNull; public class VcsLogTextFilterImpl implements VcsLogDetailsFilter, VcsLogTextFilter { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsStructureChooser.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsStructureChooser.java index 4d4a48ecbbba..43daaa3ded84 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsStructureChooser.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsStructureChooser.java @@ -27,7 +27,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.ui.VirtualFileListCellRenderer; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/BranchesPanel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/BranchesPanel.java index 75e33d95c226..19bebe9287a6 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/BranchesPanel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/BranchesPanel.java @@ -4,8 +4,10 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.components.JBScrollPane; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; -import com.intellij.vcs.log.*; -import com.intellij.vcs.log.data.RefsModel; +import com.intellij.vcs.log.RefGroup; +import com.intellij.vcs.log.VcsLogFilterCollection; +import com.intellij.vcs.log.VcsLogRefs; +import com.intellij.vcs.log.VcsRef; import com.intellij.vcs.log.data.VcsLogDataManager; import com.intellij.vcs.log.data.VisiblePack; import com.intellij.vcs.log.impl.SingletonRefGroup; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java index b2d76aa8d301..4f6facb7f54c 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/DetailsPanel.java @@ -336,7 +336,7 @@ class DetailsPanel extends JPanel implements ListSelectionListener { int[] means = new int[BRANCHES_TABLE_COLUMN_COUNT - 1]; int[] max = new int[BRANCHES_TABLE_COLUMN_COUNT - 1]; - for (int i = 0; i < rowCount; i++){ + for (int i = 0; i < rowCount; i++) { for (int j = 0; j < BRANCHES_TABLE_COLUMN_COUNT - 1; j++) { int index = rowCount * j + i; if (index < myBranches.size()) { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java index d4e7c5a607f9..38044fb66905 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java @@ -16,10 +16,7 @@ import com.intellij.openapi.vcs.changes.committed.RepositoryChangesBrowser; import com.intellij.openapi.vcs.changes.ui.ChangesBrowser; import com.intellij.openapi.vcs.history.VcsRevisionNumber; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.OnePixelSplitter; -import com.intellij.ui.ScrollPaneFactory; -import com.intellij.ui.SideBorder; +import com.intellij.ui.*; import com.intellij.ui.components.JBLoadingPanel; import com.intellij.ui.components.panels.Wrapper; import com.intellij.util.ArrayUtil; @@ -58,7 +55,7 @@ import static com.intellij.util.containers.ContainerUtil.getFirstItem; public class MainFrame extends JPanel implements DataProvider, Disposable { @NotNull private final VcsLogDataManager myLogDataManager; - @NotNull private final VcsLogUiImpl myUI; + @NotNull private final VcsLogUiImpl myUi; @NotNull private final VcsLog myLog; @NotNull private final VcsLogClassicFilterUi myFilterUi; @@ -69,29 +66,31 @@ public class MainFrame extends JPanel implements DataProvider, Disposable { @NotNull private final Splitter myDetailsSplitter; @NotNull private final JComponent myToolbar; @NotNull private final RepositoryChangesBrowser myChangesBrowser; + @NotNull private final Splitter myChangesBrowserSplitter; + @NotNull private final SearchTextField myTextFilter; + @NotNull private Runnable myTaskCompletedListener; @NotNull private Runnable myFullDetailsLoadedListener; @NotNull private Runnable myMiniDetailsLoadedListener; - private Splitter myChangesBrowserSplitter; public MainFrame(@NotNull VcsLogDataManager logDataManager, - @NotNull VcsLogUiImpl vcsLogUI, + @NotNull VcsLogUiImpl ui, @NotNull Project project, @NotNull VcsLogUiProperties uiProperties, @NotNull VcsLog log, @NotNull VisiblePack initialDataPack) { // collect info myLogDataManager = logDataManager; - myUI = vcsLogUI; + myUi = ui; myLog = log; - myFilterUi = new VcsLogClassicFilterUi(myUI, logDataManager, uiProperties, initialDataPack); + myFilterUi = new VcsLogClassicFilterUi(myUi, logDataManager, uiProperties, initialDataPack); // initialize components - myGraphTable = new VcsLogGraphTable(vcsLogUI, logDataManager, initialDataPack); - myBranchesPanel = new BranchesPanel(logDataManager, vcsLogUI, initialDataPack.getRefs()); + myGraphTable = new VcsLogGraphTable(ui, logDataManager, initialDataPack); + myBranchesPanel = new BranchesPanel(logDataManager, ui, initialDataPack.getRefs()); JComponent branchScrollPane = myBranchesPanel.createScrollPane(); branchScrollPane.setVisible(uiProperties.isShowBranchesPanel()); - myDetailsPanel = new DetailsPanel(logDataManager, myGraphTable, vcsLogUI.getColorManager(), initialDataPack); + myDetailsPanel = new DetailsPanel(logDataManager, myGraphTable, ui.getColorManager(), initialDataPack); myChangesBrowser = new RepositoryChangesBrowser(project, null, Collections.emptyList(), null); myChangesBrowser.getViewer().setScrollPaneBorder(IdeBorderFactory.createBorder(SideBorder.TOP)); @@ -106,7 +105,7 @@ public class MainFrame extends JPanel implements DataProvider, Disposable { myGraphTable.getSelectionModel().addListSelectionListener(myDetailsPanel); updateWhenDetailsAreLoaded(); - // layout + myTextFilter = myFilterUi.createTextFilter(); myToolbar = createActionsToolbar(); myDetailsSplitter = new OnePixelSplitter(true, 0.7f); @@ -217,7 +216,7 @@ public class MainFrame extends JPanel implements DataProvider, Disposable { mainGroup.add(toolbarGroup); ActionToolbar toolbar = createActionsToolbar(mainGroup); - Wrapper textFilter = new Wrapper(myFilterUi.createTextFilter()); + Wrapper textFilter = new Wrapper(myTextFilter); textFilter.setVerticalSizeReferent(toolbar.getComponent()); textFilter.setBorder(JBUI.Borders.emptyLeft(5)); @@ -261,7 +260,7 @@ public class MainFrame extends JPanel implements DataProvider, Disposable { return myLog; } else if (VcsLogDataKeys.VCS_LOG_UI.is(dataId)) { - return myUI; + return myUi; } else if (VcsLogDataKeys.VCS_LOG_DATA_PROVIDER.is(dataId)) { return myLogDataManager; @@ -321,6 +320,11 @@ public class MainFrame extends JPanel implements DataProvider, Disposable { return myToolbar; } + @NotNull + public SearchTextField getTextFilter() { + return myTextFilter; + } + public boolean areGraphActionsEnabled() { return myGraphTable.getRowCount() > 0; } @@ -400,8 +404,7 @@ public class MainFrame extends JPanel implements DataProvider, Disposable { @NotNull @Override protected List getOrderedComponents() { - return Arrays.asList(myGraphTable, myChangesBrowser.getPreferredFocusedComponent()); + return Arrays.asList(myGraphTable, myChangesBrowser.getPreferredFocusedComponent(), myTextFilter.getTextEditor()); } } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/ReferencePopupBuilder.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/ReferencePopupBuilder.java index 5bcacc245df2..89f235940190 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/ReferencePopupBuilder.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/ReferencePopupBuilder.java @@ -97,18 +97,18 @@ class ReferencePopupBuilder { private JBPopup createPopup() { return JBPopupFactory.getInstance() .createComponentPopupBuilder(ListWithFilter.wrap(myList, ScrollPaneFactory.createScrollPane(myList), new Function() { - @Override - public String fun(VcsRef vcsRef) { - return vcsRef.getName(); - } - }), myList). - setCancelOnClickOutside(true). - setCancelOnWindowDeactivation(true). - setFocusable(true). - setRequestFocus(true). - setResizable(true). - setDimensionServiceKey(myUi.getProject(), "Vcs.Log.Branch.Panel.RefGroup.Popup", false). - createPopup(); + @Override + public String fun(VcsRef vcsRef) { + return vcsRef.getName(); + } + }), myList). + setCancelOnClickOutside(true). + setCancelOnWindowDeactivation(true). + setFocusable(true). + setRequestFocus(true). + setResizable(true). + setDimensionServiceKey(myUi.getProject(), "Vcs.Log.Branch.Panel.RefGroup.Popup", false). + createPopup(); } private static DefaultListModel createListModel(RefGroup group) { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java index 778fd6abd5ed..e3d806a9e047 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java @@ -71,7 +71,9 @@ import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.*; +import java.util.Collection; +import java.util.Date; +import java.util.EventObject; import java.util.List; public class VcsLogGraphTable extends JBTable implements DataProvider, CopyProvider { @@ -569,7 +571,6 @@ public class VcsLogGraphTable extends JBTable implements DataProvider, CopyProvi } return Pair.create(rowsToSelect, rowToScroll); } - } private class MyMouseAdapter extends MouseAdapter { @@ -634,7 +635,6 @@ public class VcsLogGraphTable extends JBTable implements DataProvider, CopyProvi public void mouseExited(MouseEvent e) { // Do nothing } - } @NotNull @@ -751,7 +751,6 @@ public class VcsLogGraphTable extends JBTable implements DataProvider, CopyProvi append(value.toString(), applyHighlighters(this, row, column, value.toString(), hasFocus, selected)); setBorder(null); } - } private class MyDummyTableCellEditor implements TableCellEditor { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCell.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCell.java index 2a9f49390906..8e08e4ddc492 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCell.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCell.java @@ -24,5 +24,4 @@ public class GraphCommitCell { public Collection getRefsToThisCommit() { return myRefsToThisCommit; } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java index a8afdde01995..f8cc0da0b4c6 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java @@ -1,22 +1,16 @@ package com.intellij.vcs.log.ui.tables; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.EmptyRunnable; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.NotNullFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.DateFormatUtil; import com.intellij.vcs.log.*; import com.intellij.vcs.log.data.CommitIdByStringCondition; -import com.intellij.vcs.log.Hash; -import com.intellij.vcs.log.VcsFullCommitDetails; -import com.intellij.vcs.log.VcsRef; -import com.intellij.vcs.log.VcsShortCommitDetails; +import com.intellij.vcs.log.data.DataGetter; import com.intellij.vcs.log.data.VcsLogDataManager; import com.intellij.vcs.log.data.VisiblePack; -import com.intellij.vcs.log.data.*; import com.intellij.vcs.log.impl.VcsLogUtil; import com.intellij.vcs.log.ui.VcsLogUiImpl; import com.intellij.vcs.log.ui.render.GraphCommitCell; @@ -78,7 +72,7 @@ public class GraphTableModel extends AbstractTableModel { return myDataPack.getVisibleGraph().getRowInfo(row).getCommit(); } - @NotNull + @Nullable public CommitId getCommitIdAtRow(int row) { return myLogDataManager.getCommitId(getIdAtRow(row)); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java index d0eeea575980..f483892c0a2a 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/SequentialLimitedLifoExecutor.java @@ -64,5 +64,4 @@ public class SequentialLimitedLifoExecutor implements Disposable { } } } - } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/StopWatch.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/StopWatch.java index c90e2cc66125..ff55bda9a5bc 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/StopWatch.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/StopWatch.java @@ -62,13 +62,12 @@ public class StopWatch { String message = myOperation + " took " + (System.currentTimeMillis() - myStartTime) + " ms"; if (myDurationPerRoot.size() > 1) { message += "\n" + StringUtil.join(myDurationPerRoot.entrySet(), new Function, String>() { - @Override - public String fun(Map.Entry entry) { - return " " + entry.getKey().getName() + ": " + entry.getValue() + " ms"; - } - }, "\n"); + @Override + public String fun(Map.Entry entry) { + return " " + entry.getKey().getName() + ": " + entry.getValue() + " ms"; + } + }, "\n"); } LOG.debug(message); } - } diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java index 031479719a01..5f1928521ba4 100644 --- a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java +++ b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java @@ -201,7 +201,12 @@ public class VcsLogRefresherTest extends VcsLogPlatformTest { } private VcsLogRefresherImpl createLoader(Consumer dataPackConsumer) { - myDataManager = new VcsLogDataManager(myProject, myLogProviders); + myDataManager = new VcsLogDataManager(myProject, myLogProviders, new Consumer() { + @Override + public void consume(Exception e) { + LOG.error(e); + } + }); Disposer.register(myProject, myDataManager); return new VcsLogRefresherImpl(myProject, myDataManager.getHashMap(), myLogProviders, myDataManager.getUserRegistry(), myTopDetailsCache, dataPackConsumer, FAILING_EXCEPTION_HANDLER, RECENT_COMMITS_COUNT) { diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VisiblePackBuilderTest.kt b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VisiblePackBuilderTest.kt index d1914114063b..80668da1ffc3 100644 --- a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VisiblePackBuilderTest.kt +++ b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VisiblePackBuilderTest.kt @@ -117,7 +117,7 @@ class VisiblePackBuilderTest { assertDoesNotContain(visibleGraph, 1) } - private fun GraphCommit.toVcsCommit(map: VcsLogHashMap) = TimedVcsCommitImpl(map.getCommitId(this.id).hash, map.getHashes(this.parents), 1) + private fun GraphCommit.toVcsCommit(map: VcsLogHashMap) = TimedVcsCommitImpl(map.getCommitId(this.id)!!.hash, map.getHashes(this.parents), 1) fun assertDoesNotContain(graph: VisibleGraph, id: Int) { assertTrue(null == (1..graph.visibleCommitCount).firstOrNull { graph.getRowInfo(it - 1).commit == id }) @@ -135,12 +135,12 @@ class VisiblePackBuilderTest { fun build(filters: VcsLogFilterCollection): VisiblePack { val refs = refs.mapTo(HashSet(), { - VcsRefImpl(hashMap.getCommitId(it.commit).hash, it.name, BRANCH_TYPE, root) + VcsRefImpl(hashMap.getCommitId(it.commit)!!.hash, it.name, BRANCH_TYPE, root) }) val dataPack = DataPack.build(commits, mapOf(root to refs), providers, hashMap, true) val detailsCache = data.entries.map { - val hash = hashMap.getCommitId(it.key.id).hash + val hash = hashMap.getCommitId(it.key.id)!!.hash val metadata = if (it.value.user == null) null else VcsCommitMetadataImpl(hash, hashMap.getHashes(it.key.parents), 1L, root, it.value.subject, @@ -175,7 +175,7 @@ class VisiblePackBuilderTest { } - fun VcsLogHashMap.getHashes(ids: List) = ids.map { getCommitId(it).hash } + fun VcsLogHashMap.getHashes(ids: List) = ids.map { getCommitId(it)!!.hash } fun noFilters(): VcsLogFilterCollection = VcsLogFilterCollectionImpl(null, null, null, null, null, null, null) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java index e1aa69cc08cc..0bd309f8b87c 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -24,6 +24,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpointHandler; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.frame.XStackFrame; +import com.intellij.xdebugger.frame.XSuspendContext; import com.intellij.xdebugger.frame.XValueMarkerProvider; import com.intellij.xdebugger.stepping.XSmartStepIntoHandler; import com.intellij.xdebugger.ui.XDebugTabLayouter; @@ -92,7 +93,13 @@ public abstract class XDebugProcess { * when next line in current method/function is reached. * Do not call this method directly. Use {@link XDebugSession#stepOver} instead */ - public abstract void startStepOver(); + public void startStepOver() { + throw new AbstractMethodError(); + } + + public void startStepOver(@Nullable XSuspendContext context) { + startStepOver(); + } /** * Steps into suppressed call @@ -104,19 +111,36 @@ public abstract class XDebugProcess { public void startForceStepInto(){ startStepInto(); } + + public void startForceStepInto(@Nullable XSuspendContext context) { + startForceStepInto(); + } + /** * Resume execution and call {@link XDebugSession#positionReached} * when next line is reached. * Do not call this method directly. Use {@link XDebugSession#stepInto} instead */ - public abstract void startStepInto(); + public void startStepInto() { + throw new AbstractMethodError(); + } + + public void startStepInto(@Nullable XSuspendContext context) { + startStepInto(); + } /** * Resume execution and call {@link XDebugSession#positionReached} * after returning from current method/function. * Do not call this method directly. Use {@link XDebugSession#stepOut} instead */ - public abstract void startStepOut(); + public void startStepOut() { + throw new AbstractMethodError(); + } + + public void startStepOut(@Nullable XSuspendContext context) { + startStepOut(); + } /** * Implement {@link com.intellij.xdebugger.stepping.XSmartStepIntoHandler} and return its instance from this method to enable Smart Step Into action @@ -145,7 +169,13 @@ public abstract class XDebugProcess { * Resume execution. * Do not call this method directly. Use {@link XDebugSession#resume} instead */ - public abstract void resume(); + public void resume() { + throw new AbstractMethodError(); + } + + public void resume(@Nullable XSuspendContext context) { + resume(); + } /** * Resume execution and call {@link XDebugSession#positionReached(com.intellij.xdebugger.frame.XSuspendContext)} @@ -153,7 +183,13 @@ public abstract class XDebugProcess { * Do not call this method directly. Use {@link XDebugSession#runToPosition} instead * @param position position in source code */ - public abstract void runToPosition(@NotNull XSourcePosition position); + public void runToPosition(@NotNull XSourcePosition position) { + throw new AbstractMethodError(); + } + + public void runToPosition(@NotNull XSourcePosition position, @Nullable XSuspendContext context) { + runToPosition(position); + } /** * Check is it is possible to perform commands such as resume, step etc. And notify user if necessary diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java b/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java index 56b098de99f0..f0643b776c3f 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/stepping/XSmartStepIntoHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -16,7 +16,9 @@ package com.intellij.xdebugger.stepping; import com.intellij.xdebugger.XSourcePosition; +import com.intellij.xdebugger.frame.XSuspendContext; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -40,7 +42,13 @@ public abstract class XSmartStepIntoHandlervariant function/method is reached * @param variant selected variant */ - public abstract void startStepInto(@NotNull Variant variant); + public void startStepInto(@NotNull Variant variant) { + throw new AbstractMethodError(); + } + + public void startStepInto(@NotNull Variant variant, @Nullable XSuspendContext context) { + startStepInto(variant); + } /** * @return title for popup which will be shown to select method/function diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index 0500a4400f83..33fd6d1ddb37 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -476,24 +476,21 @@ public class XDebugSessionImpl implements XDebugSession { if (ignoreBreakpoints) { disableBreakpoints(); } - doResume(); - myDebugProcess.startStepOver(); + myDebugProcess.startStepOver(doResume()); } @Override public void stepInto() { if (!myDebugProcess.checkCanPerformCommands()) return; - doResume(); - myDebugProcess.startStepInto(); + myDebugProcess.startStepInto(doResume()); } @Override public void stepOut() { if (!myDebugProcess.checkCanPerformCommands()) return; - doResume(); - myDebugProcess.startStepOut(); + myDebugProcess.startStepOut(doResume()); } @Override @@ -508,8 +505,7 @@ public class XDebugSessionImpl implements XDebugSession { public void forceStepInto() { if (!myDebugProcess.checkCanPerformCommands()) return; - doResume(); - myDebugProcess.startForceStepInto(); + myDebugProcess.startForceStepInto(doResume()); } @Override @@ -519,8 +515,7 @@ public class XDebugSessionImpl implements XDebugSession { if (ignoreBreakpoints) { disableBreakpoints(); } - doResume(); - myDebugProcess.runToPosition(position); + myDebugProcess.runToPosition(position, doResume()); } @Override @@ -545,14 +540,17 @@ public class XDebugSessionImpl implements XDebugSession { public void resume() { if (!myDebugProcess.checkCanPerformCommands()) return; - doResume(); - myDebugProcess.resume(); + myDebugProcess.resume(doResume()); } - public void doResume() { - if (!myPaused.getAndSet(false)) return; + @Nullable + private XSuspendContext doResume() { + if (!myPaused.getAndSet(false)) { + return null; + } myDispatcher.getMulticaster().beforeSessionResume(); + XSuspendContext context = mySuspendContext; mySuspendContext = null; myCurrentExecutionStack = null; myCurrentStackFrame = null; @@ -565,6 +563,7 @@ public class XDebugSessionImpl implements XDebugSession { } }); myDispatcher.getMulticaster().sessionResumed(); + return context; } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NullArgumentToVariableArgMethodInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NullArgumentToVariableArgMethodInspection.java index 22b7f87f6673..fed0b16e503a 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NullArgumentToVariableArgMethodInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NullArgumentToVariableArgMethodInspection.java @@ -121,7 +121,7 @@ public class NullArgumentToVariableArgMethodInspection extends BaseInspection { final PsiEllipsisType ellipsisType = (PsiEllipsisType)type1; final PsiType arrayType = ellipsisType.toArrayType(); if (checkArray) { - if (arrayType.equals(type) || !arrayType.isAssignableFrom(type)) { + if (type.isAssignableFrom(arrayType) || !arrayType.isAssignableFrom(type)) { return; } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/InnerClassVariableHidesOuterClassVariableInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/InnerClassVariableHidesOuterClassVariableInspectionBase.java index d9329a0a1b79..f1ee4bd802a0 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/InnerClassVariableHidesOuterClassVariableInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/InnerClassVariableHidesOuterClassVariableInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2016 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. @@ -28,8 +28,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; -public class InnerClassVariableHidesOuterClassVariableInspectionBase - extends BaseInspection { +public class InnerClassVariableHidesOuterClassVariableInspectionBase extends BaseInspection { /** * @noinspection PublicField @@ -73,8 +72,7 @@ public class InnerClassVariableHidesOuterClassVariableInspectionBase return new InnerClassVariableHidesOuterClassVariableVisitor(); } - private class InnerClassVariableHidesOuterClassVariableVisitor - extends BaseInspectionVisitor { + private class InnerClassVariableHidesOuterClassVariableVisitor extends BaseInspectionVisitor { @Override public void visitField(@NotNull PsiField field) { @@ -86,22 +84,18 @@ public class InnerClassVariableHidesOuterClassVariableInspectionBase if (HardcodedMethodConstants.SERIAL_VERSION_UID.equals(fieldName)) { return; //special case } - boolean reportStaticsOnly = false; - if (aClass.hasModifierProperty(PsiModifier.STATIC)) { - reportStaticsOnly = true; - } - PsiClass ancestorClass = - ClassUtils.getContainingClass(aClass); + boolean reportStaticsOnly = aClass.hasModifierProperty(PsiModifier.STATIC); + PsiClass ancestorClass = ClassUtils.getContainingClass(aClass); while (ancestorClass != null) { - final PsiField ancestorField = - ancestorClass.findFieldByName(fieldName, false); + final PsiField ancestorField = ancestorClass.findFieldByName(fieldName, false); if (ancestorField != null) { - if (!m_ignoreInvisibleFields || - !reportStaticsOnly || - field.hasModifierProperty(PsiModifier.STATIC)) { + if (!m_ignoreInvisibleFields || !reportStaticsOnly || ancestorField.hasModifierProperty(PsiModifier.STATIC)) { registerFieldError(field); } } + if (ancestorClass.hasModifierProperty(PsiModifier.STATIC)) { + reportStaticsOnly = true; + } ancestorClass = ClassUtils.getContainingClass(ancestorClass); } } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCallInLoopCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCallInLoopCondition.html index ce1409fc4026..557814dfd46b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCallInLoopCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCallInLoopCondition.html @@ -5,9 +5,11 @@ Applying the results of this inspection without consideration might have negativ

Reports method calls in the condition part of a loop statement. In highly resource constrained environments, such calls may -have adverse performance implications +have adverse performance implications.

+Use the checkbox below to ignore method calls to common java iteration methods like Iterator.hasNext(). +

\ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/null_argument_to_variable_arg_method/NullArgumentToVariableArgMethod.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/null_argument_to_variable_arg_method/NullArgumentToVariableArgMethod.java index 43e63a73704c..0c22ea0c4291 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/null_argument_to_variable_arg_method/NullArgumentToVariableArgMethod.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/null_argument_to_variable_arg_method/NullArgumentToVariableArgMethod.java @@ -6,5 +6,13 @@ public class NullArgumentToVariableArgMethod { String.format("%s", null); String.format("%d", 1); String.format("%s", ss); + + CompletableFuture[] futures = {}; + CompletableFuture.allOf(futures); + } +} +class CompletableFuture { + public static CompletableFuture allOf(CompletableFuture... cfs) { + return null; } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/InnerClassVariableHidesOuterClassVariableInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/InnerClassVariableHidesOuterClassVariableInspection.java deleted file mode 100644 index ae86f11df061..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/InnerClassVariableHidesOuterClassVariableInspection.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.siyeh.igtest.visibility; - -import java.util.Set; -import java.util.HashSet; - -public class InnerClassVariableHidesOuterClassVariableInspection -{ - private int m_barangus = -1; - - public void foo() - { - System.out.println(m_barangus); - } - - private static class InnerClass - { - private int m_barangus = 3; - - public void foo() - { - System.out.println(m_barangus); - } - - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/inner_class_variable_hides_outer_class_variable/InnerClassVariableHidesOuterClassVariable.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/inner_class_variable_hides_outer_class_variable/InnerClassVariableHidesOuterClassVariable.java new file mode 100644 index 000000000000..3e604cc86901 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/inner_class_variable_hides_outer_class_variable/InnerClassVariableHidesOuterClassVariable.java @@ -0,0 +1,34 @@ +class InnerClassVariableHidesOuter { + + private static final int serialVersionUID = -1; + private int a = 1; + private static final char B = '1'; + + private static class Inner1 { + private int a = 2; + private char B = '2'; + private static final int serialVersionUID = -1; + } + private class Inner2 { + private int a = 3; + private char B = '3'; + private static final int serialVersionUID = -1; + } + private class Inner3 { + private static final char B = '4'; + private static final int a = 4; + private static final int serialVersionUID = -1; + } +} +class Test { + + Object field; + + private static class InnerStaticClass { + + private class InnerClass { + + Object field; + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/InnerClassVariableHidesOuterClassVariableInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/InnerClassVariableHidesOuterClassVariableInspectionTest.java new file mode 100644 index 000000000000..4a58abbc3c21 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/InnerClassVariableHidesOuterClassVariableInspectionTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2016 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.visibility; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; + +/** + * @author Bas Leijdekkers + */ +public class InnerClassVariableHidesOuterClassVariableInspectionTest extends LightInspectionTestCase { + + public void testInnerClassVariableHidesOuterClassVariable() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new InnerClassVariableHidesOuterClassVariableInspection(); + } +} \ No newline at end of file diff --git a/plugins/devkit/resources/META-INF/plugin.xml b/plugins/devkit/resources/META-INF/plugin.xml index 37ea1f01e544..cce061ba9670 100644 --- a/plugins/devkit/resources/META-INF/plugin.xml +++ b/plugins/devkit/resources/META-INF/plugin.xml @@ -76,7 +76,7 @@ level="WARNING" implementationClass="org.jetbrains.idea.devkit.inspections.PostfixTemplateDescriptionNotFoundInspection"/> @@ -133,7 +133,7 @@ implementationClass="org.jetbrains.idea.devkit.inspections.internal.UseVirtualFileEqualsInspection"/> + implementationClass="org.jetbrains.idea.devkit.inspections.internal.UnsafeReturnStatementVisitorInspection"/> + diff --git a/plugins/devkit/resources/inspectionDescriptions/QuickFixGetFamilyNameViolation.html b/plugins/devkit/resources/inspectionDescriptions/QuickFixGetFamilyNameViolation.html new file mode 100644 index 000000000000..8c9c1911784c --- /dev/null +++ b/plugins/devkit/resources/inspectionDescriptions/QuickFixGetFamilyNameViolation.html @@ -0,0 +1,6 @@ + + +Inspection reports cases when QuickFix#getFamilyName() +implementation uses non-static fields, methods, containing method local variables variables etc. + + \ No newline at end of file diff --git a/plugins/devkit/src/inspections/ComponentNotRegisteredInspection.java b/plugins/devkit/src/inspections/ComponentNotRegisteredInspection.java index 63a6de641a04..936bbcfbed08 100644 --- a/plugins/devkit/src/inspections/ComponentNotRegisteredInspection.java +++ b/plugins/devkit/src/inspections/ComponentNotRegisteredInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -27,7 +27,6 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.devkit.DevKitBundle; @@ -45,21 +44,6 @@ public class ComponentNotRegisteredInspection extends DevKitInspectionBase { public boolean IGNORE_NON_PUBLIC = true; private static final Logger LOG = Logger.getInstance("org.jetbrains.idea.devkit.inspections.ComponentNotRegisteredInspection"); - @NotNull - public String getDisplayName() { - return DevKitBundle.message("inspections.component.not.registered.name"); - } - - @NotNull - @NonNls - public String getShortName() { - return "ComponentNotRegistered"; - } - - public boolean isEnabledByDefault() { - return true; - } - @Nullable public JComponent createOptionsPanel() { JPanel jPanel = new JPanel(); diff --git a/plugins/devkit/src/inspections/InspectionDescriptionNotFoundInspection.java b/plugins/devkit/src/inspections/InspectionDescriptionNotFoundInspection.java index 1271f0a9bdcc..6ad17808f88d 100644 --- a/plugins/devkit/src/inspections/InspectionDescriptionNotFoundInspection.java +++ b/plugins/devkit/src/inspections/InspectionDescriptionNotFoundInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -25,7 +25,6 @@ import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; -import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -90,19 +89,9 @@ public class InspectionDescriptionNotFoundInspection extends DevKitInspectionBas return isLastMethodDefinitionIn(methodName, classFQN, psiClass.getSuperClass()); } - @Nls - @NotNull - public String getDisplayName() { - return "Inspection Description Checker"; - } - @NotNull public String getShortName() { return "InspectionDescriptionNotFoundInspection"; } - @Override - public boolean isEnabledByDefault() { - return true; - } } diff --git a/plugins/devkit/src/inspections/InspectionMappingConsistencyInspection.java b/plugins/devkit/src/inspections/InspectionMappingConsistencyInspection.java index df7e0b24515f..c0ff4f45d101 100644 --- a/plugins/devkit/src/inspections/InspectionMappingConsistencyInspection.java +++ b/plugins/devkit/src/inspections/InspectionMappingConsistencyInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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,7 +31,6 @@ import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.DomUtil; -import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.devkit.dom.Extension; import org.jetbrains.idea.devkit.dom.ExtensionPoint; @@ -50,13 +49,14 @@ public class InspectionMappingConsistencyInspection extends DevKitInspectionBase public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session) { - return new XmlElementVisitor() { + return new XmlElementVisitor() { @Override public void visitXmlTag(XmlTag tag) { DomElement element = DomUtil.getDomElement(tag); if (element instanceof Extension) { ExtensionPoint extensionPoint = ((Extension)element).getExtensionPoint(); - if (extensionPoint != null && InheritanceUtil.isInheritor(extensionPoint.getBeanClass().getValue(), "com.intellij.codeInspection.InspectionEP")) { + if (extensionPoint != null && + InheritanceUtil.isInheritor(extensionPoint.getBeanClass().getValue(), "com.intellij.codeInspection.InspectionEP")) { boolean key = tag.getAttribute("key") != null; boolean groupKey = tag.getAttribute("groupKey") != null; if (key) { @@ -89,7 +89,7 @@ public class InspectionMappingConsistencyInspection extends DevKitInspectionBase } private static void registerProblem(DomElement element, ProblemsHolder holder, String message, String... createAttrs) { - final Pair range = DomUtil.getProblemRange(element.getXmlTag()); + final Pair range = DomUtil.getProblemRange(element.getXmlTag()); holder.registerProblem(range.second, range.first, message, ContainerUtil.map(createAttrs, new Function() { @Override public LocalQuickFix fun(final String s) { @@ -103,17 +103,4 @@ public class InspectionMappingConsistencyInspection extends DevKitInspectionBase } }, new LocalQuickFix[createAttrs.length])); } - - @Nls - @NotNull - @Override - public String getDisplayName() { - return " tag consistency"; - } - - @NotNull - @Override - public String getShortName() { - return "InspectionMappingConsistency"; - } } diff --git a/plugins/devkit/src/inspections/IntentionDescriptionNotFoundInspection.java b/plugins/devkit/src/inspections/IntentionDescriptionNotFoundInspection.java index 209c5720ce48..19fcab3e15c9 100644 --- a/plugins/devkit/src/inspections/IntentionDescriptionNotFoundInspection.java +++ b/plugins/devkit/src/inspections/IntentionDescriptionNotFoundInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -43,12 +43,6 @@ public class IntentionDescriptionNotFoundInspection extends DescriptionNotFoundI return "Intention must have 'before.*.template' and 'after.*.template' beside 'description.html'"; } - @Nls - @NotNull - public String getDisplayName() { - return "Intention Description Checker"; - } - @NotNull public String getShortName() { return "IntentionDescriptionNotFoundInspection"; diff --git a/plugins/devkit/src/inspections/PluginXmlDomInspection.java b/plugins/devkit/src/inspections/PluginXmlDomInspection.java index bd784704c053..7be52e2413dd 100644 --- a/plugins/devkit/src/inspections/PluginXmlDomInspection.java +++ b/plugins/devkit/src/inspections/PluginXmlDomInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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,9 +35,7 @@ import com.intellij.util.xml.*; import com.intellij.util.xml.highlighting.*; import com.intellij.util.xml.reflect.DomAttributeChildDescription; import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.idea.devkit.DevKitBundle; import org.jetbrains.idea.devkit.dom.*; import org.jetbrains.idea.devkit.util.PsiUtil; import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; @@ -54,19 +52,6 @@ public class PluginXmlDomInspection extends BasicDomElementsInspection referenceIterator = + PsiTreeUtil.findChildrenOfType(body, PsiJavaCodeReferenceElement.class); + for (PsiJavaCodeReferenceElement reference : referenceIterator) { + + final PsiElement resolved = reference.resolve(); + if (resolved instanceof PsiVariable) { + if ((resolved instanceof PsiLocalVariable || resolved instanceof PsiParameter) && !PsiTreeUtil.isAncestor(body, resolved, false)) { + return true; + } + if (resolved instanceof PsiField && !((PsiField)resolved).hasModifierProperty(PsiModifier.STATIC)) { + return true; + } + } + + if (resolved instanceof PsiMethod && !((PsiMethod)resolved).hasModifierProperty(PsiModifier.STATIC)) { + final PsiClass resolvedContainingClass = ((PsiMethod)resolved).getContainingClass(); + final PsiClass methodContainingClass = method.getContainingClass(); + if (resolvedContainingClass != null && + methodContainingClass != null && + (methodContainingClass == resolvedContainingClass || + methodContainingClass.isInheritor(resolvedContainingClass, true))) { + if (doesMethodViolate((PsiMethod)resolved)) { + return true; + } + } + } + } + return false; + } +} diff --git a/plugins/devkit/src/inspections/RegistrationProblemsInspection.java b/plugins/devkit/src/inspections/RegistrationProblemsInspection.java index f3dd68209b8e..bda16163953a 100644 --- a/plugins/devkit/src/inspections/RegistrationProblemsInspection.java +++ b/plugins/devkit/src/inspections/RegistrationProblemsInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -15,7 +15,6 @@ */ package org.jetbrains.idea.devkit.inspections; -import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.codeInsight.intention.QuickFixFactory; import com.intellij.codeInspection.InspectionManager; import com.intellij.codeInspection.LocalQuickFix; @@ -54,20 +53,6 @@ public class RegistrationProblemsInspection extends DevKitInspectionBase { public boolean CHECK_JAVA_CODE = true; public boolean CHECK_ACTIONS = true; - @NotNull - public HighlightDisplayLevel getDefaultLevel() { - return HighlightDisplayLevel.ERROR; - } - - public boolean isEnabledByDefault() { - return true; - } - - @NotNull - public String getDisplayName() { - return DevKitBundle.message("inspections.registration.problems.name"); - } - @NotNull @NonNls public String getShortName() { diff --git a/plugins/devkit/src/inspections/UseGrayInspection.java b/plugins/devkit/src/inspections/UseGrayInspection.java index 18326f0b124d..19613f49ce7a 100644 --- a/plugins/devkit/src/inspections/UseGrayInspection.java +++ b/plugins/devkit/src/inspections/UseGrayInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -25,7 +25,6 @@ import com.intellij.psi.*; import com.intellij.psi.impl.JavaConstantExpressionEvaluator; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.ui.Gray; -import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.devkit.inspections.quickfix.ConvertToGrayQuickFix; @@ -63,7 +62,7 @@ public class UseGrayInspection extends DevKitInspectionBase { final PsiExpression r = expressions[0]; final PsiExpression g = expressions[1]; final PsiExpression b = expressions[2]; - if (r instanceof PsiLiteralExpression + if (r instanceof PsiLiteralExpression && g instanceof PsiLiteralExpression && b instanceof PsiLiteralExpression) { final Object red = JavaConstantExpressionEvaluator.computeConstantExpression(r, false); @@ -99,13 +98,6 @@ public class UseGrayInspection extends DevKitInspectionBase { return null; } - @Nls - @NotNull - @Override - public String getDisplayName() { - return "Using new Color(a,a,a)"; - } - @NotNull @Override public String getShortName() { diff --git a/plugins/devkit/src/inspections/internal/DontUseNewPairInspection.java b/plugins/devkit/src/inspections/internal/DontUseNewPairInspection.java index 9e6fea3f6071..0edb17bbc9d6 100644 --- a/plugins/devkit/src/inspections/internal/DontUseNewPairInspection.java +++ b/plugins/devkit/src/inspections/internal/DontUseNewPairInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -54,13 +54,6 @@ public class DontUseNewPairInspection extends InternalInspection { }; } - @Nls - @NotNull - @Override - public String getDisplayName() { - return "Don't use Pair constructor"; - } - @NotNull @Override public String getShortName() { diff --git a/plugins/devkit/src/inspections/internal/HighlightVisitorInternalInspection.java b/plugins/devkit/src/inspections/internal/HighlightVisitorInternalInspection.java index 57616bdb5fae..aa1fb99e50b2 100644 --- a/plugins/devkit/src/inspections/internal/HighlightVisitorInternalInspection.java +++ b/plugins/devkit/src/inspections/internal/HighlightVisitorInternalInspection.java @@ -1,4 +1,3 @@ - /* * Copyright 2000-2016 JetBrains s.r.o. * @@ -28,9 +27,10 @@ import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; -import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -49,24 +49,6 @@ public class HighlightVisitorInternalInspection extends BaseJavaBatchLocalInspec return GroupNames.BUGS_GROUP_NAME; } - @Nls - @NotNull - @Override - public String getDisplayName() { - return "Highlight Visitor Internal"; - } - - @Override - public boolean isEnabledByDefault() { - return false; - } - - @NotNull - @Override - public String getShortName() { - return "HighlightVisitorInternal"; - } - @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { diff --git a/plugins/devkit/src/inspections/internal/UseCoupleInspection.java b/plugins/devkit/src/inspections/internal/UseCoupleInspection.java index 8d5873f3be35..a79a85c30954 100644 --- a/plugins/devkit/src/inspections/internal/UseCoupleInspection.java +++ b/plugins/devkit/src/inspections/internal/UseCoupleInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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,7 +19,6 @@ import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.devkit.inspections.quickfix.UseCoupleQuickFix; @@ -77,16 +76,4 @@ public class UseCoupleInspection extends InternalInspection { }; } - @Nls - @NotNull - @Override - public String getDisplayName() { - return "Use Couple instead of Pair"; - } - - @NotNull - @Override - public String getShortName() { - return "UseCouple"; - } } diff --git a/plugins/devkit/src/inspections/internal/UseJBColorInspection.java b/plugins/devkit/src/inspections/internal/UseJBColorInspection.java index 6c378d56ba26..68e1830fefe6 100644 --- a/plugins/devkit/src/inspections/internal/UseJBColorInspection.java +++ b/plugins/devkit/src/inspections/internal/UseJBColorInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -24,7 +24,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.ui.JBColor; -import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.devkit.inspections.quickfix.ConvertToJBColorConstantQuickFix; @@ -103,16 +102,4 @@ public class UseJBColorInspection extends InternalInspection { return null; } - @Nls - @NotNull - @Override - public String getDisplayName() { - return "Use Darcula aware JBColor"; - } - - @NotNull - @Override - public String getShortName() { - return "UseJBColor"; - } } diff --git a/plugins/devkit/src/inspections/quickfix/ImplementOrExtendFix.java b/plugins/devkit/src/inspections/quickfix/ImplementOrExtendFix.java index 1acf58c51320..18c123a08108 100644 --- a/plugins/devkit/src/inspections/quickfix/ImplementOrExtendFix.java +++ b/plugins/devkit/src/inspections/quickfix/ImplementOrExtendFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -53,7 +53,7 @@ public class ImplementOrExtendFix extends BaseFix { else if (extendsList.getReferenceElements().length == 1) { // check for explicit "extends Object" case PsiClassType javaLangObject = PsiType.getJavaLangObject(checkedClass.getManager(), - checkedClass.getResolveScope()); + checkedClass.getResolveScope()); if (extendsList.getReferencedTypes()[0].equals(javaLangObject)) { fix = new ImplementOrExtendFix(compClass, checkedClass, onTheFly); } @@ -75,7 +75,7 @@ public class ImplementOrExtendFix extends BaseFix { @NotNull public String getFamilyName() { - return getName(); + return "Implement/Extend required base class"; } protected void doFix(Project project, ProblemDescriptor descriptor, boolean external) throws IncorrectOperationException { diff --git a/plugins/devkit/testData/inspections/getFamilyNameViolation/NotViolatedGetNameMethod.java b/plugins/devkit/testData/inspections/getFamilyNameViolation/NotViolatedGetNameMethod.java new file mode 100644 index 000000000000..1e64ea58b989 --- /dev/null +++ b/plugins/devkit/testData/inspections/getFamilyNameViolation/NotViolatedGetNameMethod.java @@ -0,0 +1,14 @@ +import com.intellij.codeInspection.QuickFix; + +class MyQuickFix implements QuickFix { + + public String getName() { + return "that fix do some fix"; + }; + + public String getFamilyName() { + return getName(); + }; + + +} \ No newline at end of file diff --git a/plugins/devkit/testData/inspections/getFamilyNameViolation/NotViolatedStaticField.java b/plugins/devkit/testData/inspections/getFamilyNameViolation/NotViolatedStaticField.java new file mode 100644 index 000000000000..62ceb6aeb255 --- /dev/null +++ b/plugins/devkit/testData/inspections/getFamilyNameViolation/NotViolatedStaticField.java @@ -0,0 +1,16 @@ +import com.intellij.codeInspection.QuickFix; + +class MyQuickFix implements QuickFix { + + static String someField = "Hello"; + + public String getName() { + return "some name"; + }; + + public String getFamilyName() { + return someField + getName() + "123"; + }; + + +} \ No newline at end of file diff --git a/plugins/devkit/testData/inspections/getFamilyNameViolation/NotViolatedStaticMethod.java b/plugins/devkit/testData/inspections/getFamilyNameViolation/NotViolatedStaticMethod.java new file mode 100644 index 000000000000..13aecff4781d --- /dev/null +++ b/plugins/devkit/testData/inspections/getFamilyNameViolation/NotViolatedStaticMethod.java @@ -0,0 +1,20 @@ +import com.intellij.codeInspection.QuickFix; + +class MyQuickFix implements QuickFix { + + String someField; + + public String getName() { + return someField; + }; + + public String getFamilyName() { + return getNameStatic() + "123"; + }; + + static String getNameStatic() { + return "Static"; + } + + +} \ No newline at end of file diff --git a/plugins/devkit/testData/inspections/getFamilyNameViolation/ViolationByExternalParameter.java b/plugins/devkit/testData/inspections/getFamilyNameViolation/ViolationByExternalParameter.java new file mode 100644 index 000000000000..dc4014552931 --- /dev/null +++ b/plugins/devkit/testData/inspections/getFamilyNameViolation/ViolationByExternalParameter.java @@ -0,0 +1,17 @@ +import com.intellij.codeInspection.QuickFix; + +class A { + + QuickFix getFix(final String someParameter) { + return new QuickFix() { + public String getName() { + return "some name"; + }; + + public String getFamilyName() { + return someParameter + "123"; + }; + }; + } + +} diff --git a/plugins/devkit/testData/inspections/getFamilyNameViolation/ViolationByField.java b/plugins/devkit/testData/inspections/getFamilyNameViolation/ViolationByField.java new file mode 100644 index 000000000000..c948ae538462 --- /dev/null +++ b/plugins/devkit/testData/inspections/getFamilyNameViolation/ViolationByField.java @@ -0,0 +1,16 @@ +import com.intellij.codeInspection.QuickFix; + +class MyQuickFix implements QuickFix { + + String someField; + + public String getName() { + return "some name"; + }; + + public String getFamilyName() { + return someField + getName() + "123"; + }; + + +} \ No newline at end of file diff --git a/plugins/devkit/testData/inspections/getFamilyNameViolation/ViolationByGetName.java b/plugins/devkit/testData/inspections/getFamilyNameViolation/ViolationByGetName.java new file mode 100644 index 000000000000..35a461b33a20 --- /dev/null +++ b/plugins/devkit/testData/inspections/getFamilyNameViolation/ViolationByGetName.java @@ -0,0 +1,16 @@ +import com.intellij.codeInspection.QuickFix; + +class MyQuickFix implements QuickFix { + + String someField; + + public String getName() { + return someField; + }; + + public String getFamilyName() { + return getName() + "123"; + }; + + +} \ No newline at end of file diff --git a/plugins/devkit/testSources/inspections/QuickFixGetFamilyNameViolationInspectionTest.java b/plugins/devkit/testSources/inspections/QuickFixGetFamilyNameViolationInspectionTest.java new file mode 100644 index 000000000000..10d4d984aa20 --- /dev/null +++ b/plugins/devkit/testSources/inspections/QuickFixGetFamilyNameViolationInspectionTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2016 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.devkit.inspections; + +import com.intellij.openapi.application.PluginPathManager; +import com.intellij.testFramework.TestDataPath; +import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; + +/** + * @author Dmitry Batkovich + */ +@TestDataPath("$CONTENT_ROOT/testData/inspections/getFamilyNameViolation") +public class QuickFixGetFamilyNameViolationInspectionTest extends JavaCodeInsightFixtureTestCase { + + @Override + protected String getBasePath() { + return PluginPathManager.getPluginHomePathRelative("devkit") + "/testData/inspections/getFamilyNameViolation"; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + myFixture.enableInspections(QuickFixGetFamilyNameViolationInspection.class); + myFixture.addClass("package com.intellij.codeInspection;" + + "public interface QuickFix {" + + " String getName();" + + " String getFamilyName();" + + "}"); + } + + public void testViolationByField() { + myFixture.testHighlighting(getTestName(false) + ".java"); + } + + public void testViolationByGetName() { + myFixture.testHighlighting(getTestName(false) + ".java"); + } + + public void testViolationByExternalParameter() { + myFixture.testHighlighting(getTestName(false) + ".java"); + } + + public void testNotViolatedStaticField() { + myFixture.testHighlighting(getTestName(false) + ".java"); + } + + public void testNotViolatedStaticMethod() { + myFixture.testHighlighting(getTestName(false) + ".java"); + } + + public void testNotViolatedGetNameMethod() { + myFixture.testHighlighting(getTestName(false) + ".java"); + } +} diff --git a/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java b/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java index 5cd24b30ad75..348360c624be 100644 --- a/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java +++ b/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java @@ -184,7 +184,8 @@ public class GitMergeProvider implements MergeProvider2 { String m = e.getMessage().trim(); if (m.startsWith("fatal: ambiguous argument ") || (m.startsWith("fatal: Path '") && m.contains("' exists on disk, but not in '")) - || (m.contains("is in the index, but not at stage "))) { + || (m.contains("is in the index, but not at stage ") + || (m.contains("bad revision")))) { return ArrayUtil.EMPTY_BYTE_ARRAY; } else { diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java index 0f8c026513f7..017d47c2889c 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java @@ -15,6 +15,7 @@ */ package git4idea.repo; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; @@ -29,13 +30,13 @@ import java.util.Arrays; import java.util.Collection; import static com.intellij.openapi.vfs.VfsUtilCore.virtualToIoFile; -import static com.intellij.psi.impl.SyntheticFileSystemItem.LOG; /** * Stores paths to Git service files (from .git/ directory) that are used by IDEA, and provides test-methods to check if a file * matches once of them. */ public class GitRepositoryFiles { + private static final Logger LOG = Logger.getInstance("#git4idea.repo.GitRepositoryFiles"); private static final String CHERRY_PICK_HEAD = "CHERRY_PICK_HEAD"; private static final String COMMIT_EDITMSG = "COMMIT_EDITMSG"; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java index 5f00e43f6568..9c8eca1dac2f 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -72,9 +72,6 @@ public class GradleArtifactsContributor implements GradleMethodContextContributo return; } GrArgumentList args = call.getArgumentList(); - if (args == null) { - return; - } int argsCount = GradleResolverUtil.getGrMethodArumentsCount(args); argsCount++; // Configuration name is delivered as an argument. diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java index cbe6a60279c0..fabb172ce30d 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -150,9 +150,6 @@ public class GradleResolverUtil { return; } GrArgumentList args = call.getArgumentList(); - if (args == null) { - return; - } int argsCount = getGrMethodArumentsCount(args); argsCount++; // Configuration name is delivered as an argument. diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java index bd9e24819514..77e734a8b09f 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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 @@ public class GradleTaskContributor implements GradleMethodContextContributor { if (psiElement instanceof GrMethodCallExpression) { GrMethodCallExpression callExpression = (GrMethodCallExpression)psiElement; GrArgumentList argumentList = callExpression.getArgumentList(); - if (argumentList != null && argumentList.getAllArguments().length > 0) { + if (argumentList.getAllArguments().length > 0) { for (GroovyPsiElement argument : argumentList.getAllArguments()) { if (argument instanceof GrNamedArgument) { GrNamedArgument namedArgument = (GrNamedArgument)argument; @@ -139,9 +139,6 @@ public class GradleTaskContributor implements GradleMethodContextContributor { return; } GrArgumentList args = call.getArgumentList(); - if (args == null) { - return; - } int argsCount = GradleResolverUtil.getGrMethodArumentsCount(args); argsCount++; // Configuration name is delivered as an argument. diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/CallInfoBase.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/CallInfoBase.java index 6abbcd2e4232..bdff73991153 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/CallInfoBase.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/CallInfoBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -15,6 +15,7 @@ */ package org.jetbrains.plugins.groovy.codeInspection.assignment; +import com.intellij.openapi.util.NullableLazyValue; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,11 +31,16 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres */ public abstract class CallInfoBase implements CallInfo { private final T myCall; - private final PsiType[] myArgTypes; + private final NullableLazyValue myArgTypes = new NullableLazyValue() { + @Nullable + @Override + protected PsiType[] compute() { + return inferArgTypes(); + } + }; protected CallInfoBase(T call) { myCall = call; - myArgTypes = inferArgTypes(); } @Nullable @@ -49,7 +55,7 @@ public abstract class CallInfoBase implements CallInfo { @Nullable @Override public PsiType[] getArgumentTypes() { - return myArgTypes; + return myArgTypes.getValue(); } @NotNull diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/control/GroovyConditionalCanBeConditionalCallInspection.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/control/GroovyConditionalCanBeConditionalCallInspection.java index 54732edc2808..224e01c9c9e9 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/control/GroovyConditionalCanBeConditionalCallInspection.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/control/GroovyConditionalCanBeConditionalCallInspection.java @@ -80,9 +80,6 @@ public class GroovyConditionalCanBeConditionalCallInspection extends BaseInspect final GrExpression qualifier = methodExpression.getQualifierExpression(); final String methodName = methodExpression.getReferenceName(); final GrArgumentList argumentList = call.getArgumentList(); - if (argumentList == null) { - return; - } replaceExpression(expression, qualifier.getText() + "?." + methodName + argumentList.getText()); } } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java index 875799171d53..e837798fb9b5 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java @@ -84,7 +84,6 @@ public class GroovyListGetCanBeKeyedAccessInspection extends BaseInspection { final GrReferenceExpression invokedExpression = (GrReferenceExpression) referenceName.getParent(); final GrMethodCallExpression callExpression = (GrMethodCallExpression) invokedExpression.getParent(); final GrArgumentList args = callExpression.getArgumentList(); - assert args != null; final GrExpression arg = args.getExpressionArguments()[0]; replaceExpression(callExpression, invokedExpression.getQualifierExpression().getText() + '[' + arg.getText() + ']'); } @@ -95,9 +94,6 @@ public class GroovyListGetCanBeKeyedAccessInspection extends BaseInspection { public void visitMethodCallExpression(GrMethodCallExpression grMethodCallExpression) { super.visitMethodCallExpression(grMethodCallExpression); final GrArgumentList args = grMethodCallExpression.getArgumentList(); - if (args == null) { - return; - } if (args.getExpressionArguments().length != 1) { return; } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java index 71840254a02c..acae298d64ac 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java @@ -84,7 +84,6 @@ public class GroovyListSetCanBeKeyedAccessInspection extends BaseInspection { final GrReferenceExpression invokedExpression = (GrReferenceExpression) referenceName.getParent(); final GrMethodCallExpression callExpression = (GrMethodCallExpression) invokedExpression.getParent(); final GrArgumentList argumentList = callExpression.getArgumentList(); - assert argumentList != null; final GrExpression[] args = argumentList.getExpressionArguments(); replaceExpression(callExpression, invokedExpression.getQualifierExpression().getText() + '[' + args[0].getText() + "]=" + args[1].getText()); @@ -96,9 +95,6 @@ public class GroovyListSetCanBeKeyedAccessInspection extends BaseInspection { public void visitMethodCallExpression(GrMethodCallExpression grMethodCallExpression) { super.visitMethodCallExpression(grMethodCallExpression); final GrArgumentList args = grMethodCallExpression.getArgumentList(); - if (args == null) { - return; - } if (args.getExpressionArguments().length != 2) { return; } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java index 621dfe82693a..e5e4acef6249 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java @@ -84,7 +84,6 @@ public class GroovyMapGetCanBeKeyedAccessInspection extends BaseInspection { final GrReferenceExpression invokedExpression = (GrReferenceExpression) referenceName.getParent(); final GrMethodCallExpression callExpression = (GrMethodCallExpression) invokedExpression.getParent(); final GrArgumentList args = callExpression.getArgumentList(); - assert args != null; final GrExpression arg = args.getExpressionArguments()[0]; replaceExpression(callExpression, invokedExpression.getQualifierExpression().getText() + '[' + arg.getText() + ']'); } @@ -95,9 +94,6 @@ public class GroovyMapGetCanBeKeyedAccessInspection extends BaseInspection { public void visitMethodCallExpression(GrMethodCallExpression grMethodCallExpression) { super.visitMethodCallExpression(grMethodCallExpression); final GrArgumentList args = grMethodCallExpression.getArgumentList(); - if (args == null) { - return; - } if (args.getExpressionArguments().length != 1) { return; } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java index afaa3ff66548..d67b2ee98380 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java @@ -85,7 +85,6 @@ public class GroovyMapPutCanBeKeyedAccessInspection extends BaseInspection { final GrReferenceExpression invokedExpression = (GrReferenceExpression) referenceName.getParent(); final GrMethodCallExpression callExpression = (GrMethodCallExpression) invokedExpression.getParent(); final GrArgumentList argumentList = callExpression.getArgumentList(); - assert argumentList != null; final GrExpression[] args = argumentList.getExpressionArguments(); replaceExpression(callExpression, invokedExpression.getQualifierExpression().getText() + '[' + args[0].getText() + "]=" + args[1].getText()); @@ -97,9 +96,6 @@ public class GroovyMapPutCanBeKeyedAccessInspection extends BaseInspection { public void visitMethodCallExpression(GrMethodCallExpression grMethodCallExpression) { super.visitMethodCallExpression(grMethodCallExpression); final GrArgumentList args = grMethodCallExpression.getArgumentList(); - if (args == null) { - return; - } if (args.getExpressionArguments().length != 2) { return; } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java index 558f0d7ce189..03deb3411eb9 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java @@ -151,13 +151,7 @@ public class EquivalenceChecker { } final GrArgumentList argumentList1 = statement1.getArgumentList(); - if (argumentList1 == null) { - return false; - } final GrArgumentList argumentList2 = statement2.getArgumentList(); - if (argumentList2 == null) { - return false; - } final GrExpression[] args1 = argumentList1.getExpressionArguments(); final GrExpression[] args2 = argumentList2.getExpressionArguments(); if (!expressionListsAreEquivalent(args1, args2)) { diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/utils/JavaStylePropertiesUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/utils/JavaStylePropertiesUtil.java index 89d33540048d..2d6d58a64c42 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/utils/JavaStylePropertiesUtil.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/utils/JavaStylePropertiesUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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,10 +28,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyNamesUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyNamesUtil; /** * @author Max Medvedev @@ -116,7 +116,7 @@ public class JavaStylePropertiesUtil { } GrArgumentList args = call.getArgumentList(); - if (args == null || args.getExpressionArguments().length != 1 || PsiImplUtil.hasNamedArguments(args)) { + if (args.getExpressionArguments().length != 1 || PsiImplUtil.hasNamedArguments(args)) { return false; } @@ -146,7 +146,7 @@ public class JavaStylePropertiesUtil { } GrArgumentList args = call.getArgumentList(); - if (args == null || args.getAllArguments().length != 0) { + if (args.getAllArguments().length != 0) { return false; } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrNamedArgumentSearchVisitor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrNamedArgumentSearchVisitor.java index 6a368781fcca..2cd087dd41c0 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrNamedArgumentSearchVisitor.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrNamedArgumentSearchVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; @@ -53,7 +54,7 @@ public class GrNamedArgumentSearchVisitor extends GroovyRecursiveElementVisitor return myResult; } - private void extractArguments(GrArgumentList argumentList) { + private void extractArguments(@NotNull GrArgumentList argumentList) { GrExpression[] expr = argumentList.getExpressionArguments(); if (expr.length == 1 && expr[0] instanceof GrLiteral) { diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrApplicationStatement.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrApplicationStatement.java index b70bd7046967..a530cf8c8cc2 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrApplicationStatement.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrApplicationStatement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; /** @@ -23,6 +24,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; */ public interface GrApplicationStatement extends GrStatement, GrMethodCall { + @NotNull @Override GrCommandArgumentList getArgumentList(); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/typedef/members/GrEnumConstant.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/typedef/members/GrEnumConstant.java index e3f6c2cba2b9..66df925958a3 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/typedef/members/GrEnumConstant.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/typedef/members/GrEnumConstant.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -43,6 +43,7 @@ public interface GrEnumConstant extends GrField, GrConstructorCall, PsiEnumConst @Nullable GrEnumConstantInitializer getInitializingClass(); + @Nullable @Override GrArgumentList getArgumentList(); } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java index 2b88b4ddb550..30c7a20b5eb8 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -180,7 +180,7 @@ public class GroovyExpectedTypesProvider { } final GrClosableBlock[] closureArgs = methodCall.getClosureArguments(); - if (ArrayUtil.contains(myExpression, closureArgs)) { + if (ArrayUtil.contains(myExpression, (Object[])closureArgs)) { final GrArgumentList argumentList = methodCall.getArgumentList(); final GrNamedArgument[] namedArgs = argumentList.getNamedArguments(); final GrExpression[] expressionArgs = argumentList.getExpressionArguments(); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/ApplicationStatementUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/ApplicationStatementUtil.java index 231cfc4ba08e..289b7e14d2ea 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/ApplicationStatementUtil.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/ApplicationStatementUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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,6 @@ public class ApplicationStatementUtil { final GrMethodCallExpression prototype = (GrMethodCallExpression)factory.createExpressionFromText("foo()"); prototype.getInvokedExpression().replace(app.getInvokedExpression()); final GrArgumentList pList = prototype.getArgumentList(); - LOG.assertTrue(pList != null); final PsiElement anchor = pList.getRightParen(); for (GroovyPsiElement arg : list.getAllArguments()) { diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java index bda8fe28be07..9180933083e4 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -25,6 +25,7 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; @@ -140,4 +141,10 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) { return multiResolve(true); } + + @NotNull + @Override + public GrArgumentList getArgumentList() { + return findNotNullChildByClass(GrArgumentList.class); + } } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrApplicationStatementImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrApplicationStatementImpl.java index 7bb5d316a4db..87de91e4b1aa 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrApplicationStatementImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrApplicationStatementImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -41,15 +41,14 @@ public class GrApplicationStatementImpl extends GrMethodCallImpl implements GrAp return "Call expression"; } + @NotNull @Override public GrCommandArgumentList getArgumentList() { - return findChildByClass(GrCommandArgumentList.class); + return findNotNullChildByClass(GrCommandArgumentList.class); } @Override public GrNamedArgument addNamedArgument(final GrNamedArgument namedArgument) throws IncorrectOperationException { - GrCommandArgumentList list = getArgumentList(); - assert list != null; - return list.addNamedArgument(namedArgument); + return getArgumentList().addNamedArgument(namedArgument); } } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrCallImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrCallImpl.java index dcb93bef2597..a09288fbca5f 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrCallImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrCallImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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,9 +17,9 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions; import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; @@ -36,12 +36,10 @@ public abstract class GrCallImpl extends GroovyPsiElementImpl implements GrCall super(node); } + @Nullable @Override public GrArgumentList getArgumentList() { - for (PsiElement cur = this.getFirstChild(); cur != null; cur = cur.getNextSibling()) { - if (cur instanceof GrArgumentList) return (GrArgumentList)cur; - } - return null; + return findChildByClass(GrArgumentList.class); } @Override diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrMethodCallImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrMethodCallImpl.java index ff864c730546..da0673c63a90 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrMethodCallImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrMethodCallImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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 com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; @@ -131,4 +132,10 @@ public abstract class GrMethodCallImpl extends GrCallExpressionImpl implements G public ItemPresentation getPresentation() { return ItemPresentationProviders.getItemPresentation(this); } + + @NotNull + @Override + public GrArgumentList getArgumentList() { + return findNotNullChildByClass(GrArgumentList.class); + } } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java index e579dfb96964..e29428255b0c 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrNewExpressionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -136,6 +136,7 @@ public class GrNewExpressionImpl extends GrCallExpressionImpl implements GrNewEx return super.addNamedArgument(namedArgument); } + @Nullable @Override public GrArgumentList getArgumentList() { final GrAnonymousClassDefinition anonymous = getAnonymousClassDefinition(); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java index e4959147e3fe..3988f9ea06ec 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/DefaultCallExpressionTypeCalculator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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,17 +177,15 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal } else if ("ncurry".equals(resolved.getName())) { final GrArgumentList argList = callExpression.getArgumentList(); - if (argList != null) { - final GrExpression[] arguments = argList.getExpressionArguments(); - if (arguments.length > 0) { - final GrExpression first = arguments[0]; - if (first instanceof GrLiteral) { - final Object value = ((GrLiteral)first).getValue(); - if (value instanceof Integer) { - final PsiType[] argTypes = PsiUtil.getArgumentTypes(refExpr, false); - if (argTypes != null) { - return ((GrClosureType)qType).curry(ArrayUtil.remove(argTypes, 0), (Integer)value, callExpression); - } + final GrExpression[] arguments = argList.getExpressionArguments(); + if (arguments.length > 0) { + final GrExpression first = arguments[0]; + if (first instanceof GrLiteral) { + final Object value = ((GrLiteral)first).getValue(); + if (value instanceof Integer) { + final PsiType[] argTypes = PsiUtil.getArgumentTypes(refExpr, false); + if (argTypes != null) { + return ((GrClosureType)qType).curry(ArrayUtil.remove(argTypes, 0), (Integer)value, callExpression); } } } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java index 14b1a985c452..c5da5cc7b688 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -61,7 +61,6 @@ public class GrMethodCallExpressionImpl extends GrMethodCallImpl implements GrMe final GrClosableBlock[] closureArguments = getClosureArguments(); final int i = ArrayUtil.find(closureArguments, closure); GrArgumentList argList = getArgumentList(); - assert argList!=null; if (argList.getText().isEmpty()) { argList = (GrArgumentList)argList.replace(GroovyPsiElementFactory.getInstance(getProject()).createArgumentList()); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/util/GroovyStdTypeCalculators.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/util/GroovyStdTypeCalculators.java index 7097cf10bb1e..49fa07b3520a 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/util/GroovyStdTypeCalculators.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/util/GroovyStdTypeCalculators.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -70,8 +70,6 @@ public class GroovyStdTypeCalculators { @Override public PsiType fun(GrMethodCall methodCall, PsiMethod method) { GrArgumentList argumentList = methodCall.getArgumentList(); - if (argumentList == null) return null; - GrExpression[] arguments = argumentList.getExpressionArguments(); if (arguments.length == 0) return null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GroovyLineMarkerProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GroovyLineMarkerProvider.java index f5e1a04c79df..67be1dca51be 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GroovyLineMarkerProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GroovyLineMarkerProvider.java @@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.codeInsight; import com.intellij.codeHighlighting.Pass; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings; import com.intellij.codeInsight.daemon.LineMarkerInfo; -import com.intellij.codeInsight.daemon.LineMarkerProvider; import com.intellij.codeInsight.daemon.impl.JavaLineMarkerProvider; import com.intellij.codeInsight.daemon.impl.MarkerType; import com.intellij.icons.AllIcons; @@ -67,13 +66,10 @@ import java.util.*; * @author ilyas * Same logic as for Java LMP */ -public class GroovyLineMarkerProvider implements LineMarkerProvider { - private final DaemonCodeAnalyzerSettings myDaemonSettings; - private final EditorColorsManager myColorsManager; +public class GroovyLineMarkerProvider extends JavaLineMarkerProvider { public GroovyLineMarkerProvider(DaemonCodeAnalyzerSettings daemonSettings, EditorColorsManager colorsManager) { - myDaemonSettings = daemonSettings; - myColorsManager = colorsManager; + super(daemonSettings, colorsManager); } @Override @@ -207,7 +203,7 @@ public class GroovyLineMarkerProvider implements LineMarkerProvider { } } else if (element instanceof PsiClass && !(element instanceof PsiTypeParameter)) { - JavaLineMarkerProvider.collectInheritingClasses((PsiClass)element, result, subClassCache); + collectInheritingClasses((PsiClass)element, result, subClassCache); } } collectOverridingMethods(methods, result); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/EachToForIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/EachToForIntention.java index 0c71f2c0f93e..51f5630b9d01 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/EachToForIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/EachToForIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -238,10 +238,8 @@ public class EachToForIntention extends Intention { GrReferenceExpression referenceExpression = (GrReferenceExpression)invokedExpression; if ("each".equals(referenceExpression.getReferenceName())) { final GrArgumentList argumentList = expression.getArgumentList(); - if (argumentList != null) { - if (PsiImplUtil.hasExpressionArguments(argumentList)) return false; - if (PsiImplUtil.hasNamedArguments(argumentList)) return false; - } + if (PsiImplUtil.hasExpressionArguments(argumentList)) return false; + if (PsiImplUtil.hasNamedArguments(argumentList)) return false; final GrClosableBlock[] closureArguments = expression.getClosureArguments(); if (closureArguments.length != 1) return false; final GrParameter[] parameters = closureArguments[0].getParameterList().getParameters(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallExplicitIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallExplicitIntention.java index 60b4d0b280ab..a2479e4033fd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallExplicitIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallExplicitIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -48,9 +48,7 @@ public class MakeClosureCallExplicitIntention extends Intention { final StringBuilder newExpression = new StringBuilder(); newExpression.append(invokedExpression.getText()); newExpression.append(".call"); - if (argList != null) { - newExpression.append(argList.getText()); - } + newExpression.append(argList.getText()); for (GrClosableBlock closureArg : closureArgs) { newExpression.append(closureArg.getText()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallImplicitIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallImplicitIntention.java index ec57d1824a79..c768b31327c3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallImplicitIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/closure/MakeClosureCallImplicitIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -49,9 +49,7 @@ public class MakeClosureCallImplicitIntention extends Intention { final GrClosableBlock[] closureArgs = expression.getClosureArguments(); final StringBuilder newExpression = new StringBuilder(); newExpression.append(qualifier.getText()); - if (argList != null) { - newExpression.append(argList.getText()); - } + newExpression.append(argList.getText()); for (GrClosableBlock closureArg : closureArgs) { newExpression.append(closureArg.getText()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertJunitAssertionToAssertStatementIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertJunitAssertionToAssertStatementIntention.java index a509cecb2e0b..5e7b74bb427e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertJunitAssertionToAssertStatementIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertJunitAssertionToAssertStatementIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -71,7 +71,6 @@ public class ConvertJunitAssertionToAssertStatementIntention extends Intention i if (replacementStatements == null) return null; GrArgumentList argumentList = methodCall.getArgumentList(); - if (argumentList == null) return null; if (argumentList.getNamedArguments().length > 0) return null; @@ -87,7 +86,6 @@ public class ConvertJunitAssertionToAssertStatementIntention extends Intention i String replacementStatement = getReplacementStatement(method, methodCall); if (replacementStatement == null) return null; - @SuppressWarnings("ConstantConditions") final GrExpression[] arguments = methodCall.getArgumentList().getExpressionArguments(); GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(method.getProject()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexingMethodConversionPredicate.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexingMethodConversionPredicate.java index cf893f353b15..431c72ac62a2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexingMethodConversionPredicate.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/IndexingMethodConversionPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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,13 +20,13 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiType; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.InheritanceUtil; -import org.jetbrains.plugins.groovy.lang.psi.util.ErrorUtil; import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.ErrorUtil; class IndexingMethodConversionPredicate implements PsiElementPredicate { @@ -41,9 +41,6 @@ class IndexingMethodConversionPredicate implements PsiElementPredicate { } final GrMethodCallExpression callExpression = (GrMethodCallExpression) element; final GrArgumentList argList = callExpression.getArgumentList(); - if (argList == null) { - return false; - } final GrExpression[] arguments = argList.getExpressionArguments(); final GrExpression invokedExpression = callExpression.getInvokedExpression(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodCallIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodCallIntention.java index 066f13fa6e0c..eef2285c1908 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodCallIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodCallIntention.java @@ -47,13 +47,11 @@ public class RemoveParenthesesFromMethodCallIntention extends Intention { final StringBuilder newStatementText = new StringBuilder(); newStatementText.append(expression.getInvokedExpression().getText()).append(' '); final GrArgumentList argumentList = expression.getArgumentList(); - if (argumentList != null) { - final PsiElement leftParen = argumentList.getLeftParen(); - final PsiElement rightParen = argumentList.getRightParen(); - if (leftParen != null) leftParen.delete(); - if (rightParen != null) rightParen.delete(); - newStatementText.append(argumentList.getText()); - } + final PsiElement leftParen = argumentList.getLeftParen(); + final PsiElement rightParen = argumentList.getRightParen(); + if (leftParen != null) leftParen.delete(); + if (rightParen != null) rightParen.delete(); + newStatementText.append(argumentList.getText()); final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject()); final GrStatement newStatement = factory.createStatementFromText(newStatementText.toString()); expression.replaceWithStatement(newStatement); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodPredicate.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodPredicate.java index 4a777797b2f0..8bda83edd176 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodPredicate.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/RemoveParenthesesFromMethodPredicate.java @@ -43,16 +43,14 @@ class RemoveParenthesesFromMethodPredicate implements PsiElementPredicate { newStatementText.append(expression.getInvokedExpression().getText()).append(' '); GrArgumentList argumentList = expression.getArgumentList(); - final GroovyPsiElement[] allArguments = argumentList != null ? argumentList.getAllArguments() : GroovyPsiElement.EMPTY_ARRAY; + final GroovyPsiElement[] allArguments = argumentList.getAllArguments(); - if (argumentList != null) { - argumentList = (GrArgumentList)argumentList.copy(); - final PsiElement leftParen = argumentList.getLeftParen(); - final PsiElement rightParen = argumentList.getRightParen(); - if (leftParen != null) leftParen.delete(); - if (rightParen != null) rightParen.delete(); - newStatementText.append(argumentList.getText()); - } + argumentList = (GrArgumentList)argumentList.copy(); + final PsiElement leftParen = argumentList.getLeftParen(); + final PsiElement rightParen = argumentList.getRightParen(); + if (leftParen != null) leftParen.delete(); + if (rightParen != null) rightParen.delete(); + newStatementText.append(argumentList.getText()); final GrStatement newStatement; try { newStatement = GroovyPsiElementFactory.getInstance(element.getProject()).createStatementFromText(newStatementText.toString()); @@ -62,8 +60,7 @@ class RemoveParenthesesFromMethodPredicate implements PsiElementPredicate { } if (newStatement instanceof GrApplicationStatement) { final GrCommandArgumentList newArgList = ((GrApplicationStatement)newStatement).getArgumentList(); - if (newArgList == null && argumentList == null || - newArgList != null && newArgList.getAllArguments().length == allArguments.length) { + if (newArgList.getAllArguments().length == allArguments.length) { return true; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java index 038aeaa07b8f..6cc55d2038dc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -110,15 +110,17 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc @Override public boolean processPrimaryMethod(ChangeInfo changeInfo) { - if (!(changeInfo instanceof GrChangeInfoImpl)) return false; + if (!(changeInfo instanceof JavaChangeInfo)) return false; - GrChangeInfoImpl grInfo = (GrChangeInfoImpl)changeInfo; - GrMethod method = grInfo.getMethod(); - if (grInfo.isGenerateDelegate()) { - return generateDelegate(grInfo); + JavaChangeInfo info = (JavaChangeInfo)changeInfo; + PsiMethod method = info.getMethod(); + if (!(method instanceof GrMethod)) return false; + + if (info.isGenerateDelegate()) { + return generateDelegate(info); } - return processPrimaryMethodInner(grInfo, method, null); + return processPrimaryMethodInner(info, ((GrMethod)method), null); } @Override @@ -183,8 +185,8 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc UsageInfo[] usages, ChangeInfo changeInfo) { } - private static boolean generateDelegate(GrChangeInfoImpl grInfo) { - final GrMethod method = grInfo.getMethod(); + private static boolean generateDelegate(JavaChangeInfo grInfo) { + final GrMethod method = (GrMethod)grInfo.getMethod(); final PsiClass psiClass = method.getContainingClass(); GrMethod newMethod = (GrMethod)method.copy(); newMethod = (GrMethod)psiClass.addAfter(newMethod, method); @@ -210,7 +212,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc return processPrimaryMethodInner(grInfo, method, null); } - private static void generateParametersForDelegateCall(GrChangeInfoImpl grInfo, GrMethod method, StringBuilder buffer) { + private static void generateParametersForDelegateCall(JavaChangeInfo grInfo, GrMethod method, StringBuilder buffer) { buffer.append("("); final GrParameter[] oldParameters = method.getParameterList().getParameters(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java index f315160a946c..602c2ddcffe5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -455,7 +455,6 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess if (argList.getAllArguments().length == 0 && PsiImplUtil.hasClosureArguments(callExpression)) { final GrArgumentList emptyArgList = ((GrMethodCallExpression)factory.createExpressionFromText("foo{}")).getArgumentList(); - LOG.assertTrue(emptyArgList != null); argList.replace(emptyArgList); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java index 8fd552bc6fd6..7e74883dfad6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -148,7 +148,6 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP if (argList.getAllArguments().length == 0 && PsiImplUtil.hasClosureArguments(callExpression)) { final GrArgumentList emptyArgList = ((GrMethodCallExpression)factory.createExpressionFromText("foo{}")).getArgumentList(); - LOG.assertTrue(emptyArgList != null); argList.replace(emptyArgList); } return false; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureForJavaTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureForJavaTest.groovy similarity index 51% rename from plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureForJavaTest.java rename to plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureForJavaTest.groovy index bcd2e765743e..991d7312e246 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureForJavaTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/changeSignature/ChangeSignatureForJavaTest.groovy @@ -1,80 +1,85 @@ -package org.jetbrains.plugins.groovy.refactoring.changeSignature; +/* + * Copyright 2000-2016 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.refactoring.changeSignature -import com.intellij.codeInsight.TargetElementUtil; -import com.intellij.psi.*; -import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; -import com.intellij.refactoring.changeSignature.JavaThrownExceptionInfo; -import com.intellij.refactoring.changeSignature.ParameterInfoImpl; -import com.intellij.refactoring.changeSignature.ThrownExceptionInfo; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.util.TestUtils; +import com.intellij.codeInsight.TargetElementUtil +import com.intellij.psi.* +import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor +import com.intellij.refactoring.changeSignature.JavaThrownExceptionInfo +import com.intellij.refactoring.changeSignature.ParameterInfoImpl +import com.intellij.refactoring.changeSignature.ThrownExceptionInfo +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import com.intellij.util.IncorrectOperationException +import groovy.transform.CompileStatic +import org.jetbrains.annotations.NonNls +import org.jetbrains.annotations.Nullable +import org.jetbrains.plugins.groovy.util.TestUtils /** * @author Maxim.Medvedev */ +@CompileStatic public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase { + + final String basePath = TestUtils.testDataPath + "/refactoring/changeSignatureForJava/" + public void testSimple() throws Exception { - doTest(null, null, null, new ParameterInfoImpl[0], new ThrownExceptionInfo[0], false); + doTest null, null, null, [], [], false } public void testParameterReorder() throws Exception { - doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(1), new ParameterInfoImpl(0)}, false); + doTest null, [new ParameterInfoImpl(1), new ParameterInfoImpl(0)], false } public void testGenericTypes() throws Exception { - doTest(null, null, "T", new GenParams() { - @Override - public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); - return new ParameterInfoImpl[]{ - new ParameterInfoImpl(-1, "x", factory.createTypeFromText("T", method.getParameterList()), "null"), - new ParameterInfoImpl(-1, "y", factory.createTypeFromText("C", method.getParameterList()), "null") - }; - } - }, false); + doTest null, null, "T", { PsiMethod method -> + final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); + return [ + new ParameterInfoImpl(-1, "x", factory.createTypeFromText("T", method.getParameterList()), "null"), + new ParameterInfoImpl(-1, "y", factory.createTypeFromText("C", method.getParameterList()), "null") + ] + }, false } public void testGenericTypesInOldParameters() throws Exception { - doTest(null, null, null, new GenParams() { - @Override - public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); - return new ParameterInfoImpl[] { - new ParameterInfoImpl(0, "t", factory.createTypeFromText("T", method), null) - }; - } - }, false); + doTest null, null, null, { PsiMethod method -> + final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); + return [ + new ParameterInfoImpl(0, "t", factory.createTypeFromText("T", method), null) + ] + }, false } public void testTypeParametersInMethod() throws Exception { - doTest(null, null, null, new GenParams() { - @Override - public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); - return new ParameterInfoImpl[]{ - new ParameterInfoImpl(-1, "t", factory.createTypeFromText("T", method.getParameterList()), "null"), - new ParameterInfoImpl(-1, "u", factory.createTypeFromText("U", method.getParameterList()), "null"), - new ParameterInfoImpl(-1, "cu", factory.createTypeFromText("C", method.getParameterList()), "null") - }; - } - }, false); + doTest null, null, null, { PsiMethod method -> + final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); + return [ + new ParameterInfoImpl(-1, "t", factory.createTypeFromText("T", method.getParameterList()), "null"), + new ParameterInfoImpl(-1, "u", factory.createTypeFromText("U", method.getParameterList()), "null"), + new ParameterInfoImpl(-1, "cu", factory.createTypeFromText("C", method.getParameterList()), "null") + ] + }, false } public void testDefaultConstructor() throws Exception { - doTest(null, - new ParameterInfoImpl[] { - new ParameterInfoImpl(-1, "j", PsiType.INT, "27") - }, false); + doTest null, [new ParameterInfoImpl(-1, "j", PsiType.INT, "27")], false } public void testGenerateDelegate() throws Exception { - doTest(null, - new ParameterInfoImpl[] { - new ParameterInfoImpl(-1, "i", PsiType.INT, "27") - }, true); + doTest null, [new ParameterInfoImpl(-1, "i", PsiType.INT, "27")], true } /*public void testGenerateDelegateForAbstract() throws Exception { @@ -106,9 +111,7 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase */ public void testGenerateDelegateDefaultConstructor() throws Exception { - doTest(null, new ParameterInfoImpl[] { - new ParameterInfoImpl(-1, "i", PsiType.INT, "27") - }, true); + doTest null, [new ParameterInfoImpl(-1, "i", PsiType.INT, "27")], true } /* @@ -151,22 +154,20 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase }, false); } */ - + public void testVarargs1() throws Exception { - doTest(null, new ParameterInfoImpl[] { + doTest null, [ new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN, "true"), new ParameterInfoImpl(0) - }, false); + ], false } public void testCovariantReturnType() throws Exception { - doTest(CommonClassNames.JAVA_LANG_RUNNABLE, new ParameterInfoImpl[0], false); + doTest CommonClassNames.JAVA_LANG_RUNNABLE, [], false } public void testReorderExceptions() throws Exception { - doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]), - new SimpleExceptionsGen(new ThrownExceptionInfo[]{new JavaThrownExceptionInfo(1), new JavaThrownExceptionInfo(0)}), - false); + doTest null, null, null, [], [new JavaThrownExceptionInfo(1), new JavaThrownExceptionInfo(0)], false } /* @@ -197,16 +198,12 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase */ public void testAddException() throws Exception { - doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]), - new GenExceptions() { - @Override - public ThrownExceptionInfo[] genExceptions(PsiMethod method) { - return new ThrownExceptionInfo[] { - new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createTypeByFQClassName("java.lang.Exception", method.getResolveScope())) - }; - } - }, - false); + doTest null, null, null, new SimpleParameterGen(), { PsiMethod method -> + return [ + new JavaThrownExceptionInfo(-1, JavaPsiFacade.getInstance(method.getProject()).getElementFactory(). + createTypeByFQClassName("java.lang.Exception", method.getResolveScope())) + ] + }, false } /* @@ -220,83 +217,105 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase } */ - private void doTest(@Nullable String newReturnType, ParameterInfoImpl[] parameterInfos, final boolean generateDelegate) throws Exception { - doTest(null, null, newReturnType, parameterInfos, new ThrownExceptionInfo[0], generateDelegate); + void testAddConstructorParameter() { + myFixture.configureByFile getTestName(false) + ".groovy" + myFixture.configureByFile getTestName(false) + ".java" + myFixture.launchAction myFixture.findSingleIntention("Add 'int' as 2nd parameter") + myFixture.checkResultByFile getTestName(false) + ".groovy", getTestName(false) + "_after.groovy", true + } + + void testAddMethodParameter() { + myFixture.configureByFile getTestName(false) + ".groovy" + myFixture.configureByFile getTestName(false) + ".java" + myFixture.launchAction myFixture.findSingleIntention("Add 'int' as 2nd parameter") + myFixture.checkResultByFile getTestName(false) + ".groovy", getTestName(false) + "_after.groovy", true + } + + private void doTest(@Nullable String newReturnType, List parameterInfos, final boolean generateDelegate) { + doTest null, null, newReturnType, parameterInfos, [], generateDelegate } private void doTest(@Nullable @PsiModifier.ModifierConstant String newVisibility, @Nullable String newName, @Nullable String newReturnType, - ParameterInfoImpl[] parameterInfo, - ThrownExceptionInfo[] exceptionInfo, - final boolean generateDelegate) throws Exception { - doTest(newVisibility, newName, newReturnType, new SimpleParameterGen(parameterInfo), new SimpleExceptionsGen(exceptionInfo), generateDelegate); + List parameterInfo, + List exceptionInfo, + final boolean generateDelegate) { + doTest newVisibility, newName, newReturnType, + new SimpleParameterGen(parameterInfo), + new SimpleExceptionsGen(exceptionInfo), + generateDelegate } - private void doTest(@Nullable @PsiModifier.ModifierConstant String newVisibility, @Nullable String newName, @Nullable @NonNls String newReturnType, GenParams gen, final boolean generateDelegate) throws Exception { + private void doTest( + @Nullable @PsiModifier.ModifierConstant String newVisibility, + @Nullable String newName, + @Nullable @NonNls String newReturnType, + GenParams gen, + final boolean generateDelegate) { doTest(newVisibility, newName, newReturnType, gen, new SimpleExceptionsGen(), generateDelegate); } - private void doTest(@Nullable @PsiModifier.ModifierConstant String newVisibility, @Nullable String newName, @Nullable String newReturnType, GenParams genParams, GenExceptions genExceptions, final boolean generateDelegate) throws Exception { - myFixture.configureByFile(getTestName(false) +".groovy"); + private void doTest( + @Nullable @PsiModifier.ModifierConstant String newVisibility, + @Nullable String newName, + @Nullable String newReturnType, + GenParams genParams, + GenExceptions genExceptions, + final boolean generateDelegate) throws Exception { + myFixture.configureByFile(getTestName(false) + ".groovy"); myFixture.configureByFile(getTestName(false) + ".java"); final PsiElement targetElement = TargetElementUtil.findTargetElement(myFixture.getEditor(), TargetElementUtil.ELEMENT_NAME_ACCEPTED); assertTrue(" is not on method name", targetElement instanceof PsiMethod); - PsiMethod method = (PsiMethod) targetElement; + PsiMethod method = (PsiMethod)targetElement; final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); PsiType newType = newReturnType != null ? factory.createTypeFromText(newReturnType, method) : method.getReturnType(); - new ChangeSignatureProcessor(getProject(), method, generateDelegate, newVisibility, - newName != null ? newName : method.getName(), - newType, genParams.genParams(method), genExceptions.genExceptions(method)).run(); + new ChangeSignatureProcessor( + getProject(), + method, + generateDelegate, + newVisibility, + newName != null ? newName : method.getName(), + newType, + genParams.genParams(method) as ParameterInfoImpl[], + genExceptions.genExceptions(method) as ThrownExceptionInfo[] + ).run(); myFixture.checkResultByFile(getTestName(false) + ".groovy", getTestName(false) + "_after.groovy", true); } private interface GenParams { - ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException; + List genParams(PsiMethod method) throws IncorrectOperationException; } private static class SimpleParameterGen implements GenParams { - private final ParameterInfoImpl[] myInfos; + private final List myInfos; - private SimpleParameterGen(ParameterInfoImpl[] infos) { + public SimpleParameterGen(List infos = []) { myInfos = infos; } @Override - public ParameterInfoImpl[] genParams(PsiMethod method) { - for (ParameterInfoImpl info : myInfos) { - info.updateFromMethod(method); - } - return myInfos; + public List genParams(PsiMethod method) { + myInfos*.updateFromMethod method + myInfos } } private interface GenExceptions { - ThrownExceptionInfo[] genExceptions(PsiMethod method) throws IncorrectOperationException; + List genExceptions(PsiMethod method) throws IncorrectOperationException; } private static class SimpleExceptionsGen implements GenExceptions { - private final ThrownExceptionInfo[] myInfos; + private final List myInfos; - public SimpleExceptionsGen() { - myInfos = new ThrownExceptionInfo[0]; - } - - private SimpleExceptionsGen(ThrownExceptionInfo[] infos) { + public SimpleExceptionsGen(List infos = []) { myInfos = infos; } @Override - public ThrownExceptionInfo[] genExceptions(PsiMethod method) { - for (ThrownExceptionInfo info : myInfos) { - info.updateFromMethod(method); - } - return myInfos; + public List genExceptions(PsiMethod method) { + myInfos*.updateFromMethod method + myInfos } } - - @Override - protected String getBasePath() { - return TestUtils.getTestDataPath() + "/refactoring/changeSignatureForJava/"; - } } diff --git a/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddConstructorParameter.groovy b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddConstructorParameter.groovy new file mode 100644 index 000000000000..040877cfd76d --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddConstructorParameter.groovy @@ -0,0 +1,7 @@ +class GroovyClass { + private final String someValue + + GroovyClass(String someValue) { + this.someValue = someValue + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddConstructorParameter.java b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddConstructorParameter.java new file mode 100644 index 000000000000..63aa6cd9faf9 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddConstructorParameter.java @@ -0,0 +1,6 @@ +public class Main { + + public static void main(String[] args) { + System.out.println(new GroovyClass("any", 666)); + } +} diff --git a/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddConstructorParameter_after.groovy b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddConstructorParameter_after.groovy new file mode 100644 index 000000000000..f298b570a837 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddConstructorParameter_after.groovy @@ -0,0 +1,7 @@ +class GroovyClass { + private final String someValue + + GroovyClass(String someValue, int i) { + this.someValue = someValue + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddMethodParameter.groovy b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddMethodParameter.groovy new file mode 100644 index 000000000000..2071067d6c93 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddMethodParameter.groovy @@ -0,0 +1,3 @@ +class GroovyClass { + static foo(String a) {} +} \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddMethodParameter.java b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddMethodParameter.java new file mode 100644 index 000000000000..bf6f631e2b6b --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddMethodParameter.java @@ -0,0 +1,5 @@ +public class Main { + public static void main(String[] args) { + GroovyClass.foo("bar", 2); + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddMethodParameter_after.groovy b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddMethodParameter_after.groovy new file mode 100644 index 000000000000..dd9b090f4db9 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/changeSignatureForJava/AddMethodParameter_after.groovy @@ -0,0 +1,3 @@ +class GroovyClass { + static foo(String a, int i) {} +} \ No newline at end of file diff --git a/plugins/hg4idea/src/META-INF/plugin.xml b/plugins/hg4idea/src/META-INF/plugin.xml index 7dfaba1bae03..ad4c5b7b2e5a 100644 --- a/plugins/hg4idea/src/META-INF/plugin.xml +++ b/plugins/hg4idea/src/META-INF/plugin.xml @@ -44,13 +44,6 @@ serviceImplementation="org.zmlx.hg4idea.HgRootsHandler"/> - - - org.zmlx.hg4idea.HgRepositoryWatcher - org.zmlx.hg4idea.HgRepositoryWatcher - - - diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgRepositoryWatcher.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgRepositoryWatcher.java deleted file mode 100644 index bd14218970a0..000000000000 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgRepositoryWatcher.java +++ /dev/null @@ -1,145 +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.zmlx.hg4idea; - -import com.intellij.openapi.components.AbstractProjectComponent; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vcs.AbstractVcs; -import com.intellij.openapi.vcs.ProjectLevelVcsManager; -import com.intellij.openapi.vcs.VcsListener; -import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.openapi.vfs.newvfs.BulkFileListener; -import com.intellij.openapi.vfs.newvfs.events.VFileEvent; -import com.intellij.util.messages.MessageBus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Collection; -import java.util.HashSet; -import java.util.List; - -/** - * Watches for events inside .hg directory of all registered roots. - * - * @author Kirill Likhodedov - */ -public class HgRepositoryWatcher extends AbstractProjectComponent implements BulkFileListener, VcsListener { - - private final Collection myWatchRequests = new HashSet(); - private final Collection myRoots = new HashSet(); - - private VcsDirtyScopeManager myDirtyScopeManager; - private ProjectLevelVcsManager myVcsManager; - private AbstractVcs myVcs; - - protected HgRepositoryWatcher(@NotNull Project project) { - super(project); - } - - @Override - public void initComponent() { - MessageBus messageBus = myProject.getMessageBus(); - messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, this); - messageBus.connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this); - myDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); - myVcsManager = ProjectLevelVcsManager.getInstance(myProject); - myVcs = HgVcs.getInstance(myProject); - } - - @Override - public void disposeComponent() { - LocalFileSystem.getInstance().removeWatchedRoots(myWatchRequests); - myWatchRequests.clear(); - myRoots.clear(); - } - - @Override - public void before(@NotNull List events) { - } - - @Override - public void after(@NotNull List events) { - for (VFileEvent event : events) { - VirtualFile file = event.getFile(); - VirtualFile root = getRootForIndexFile(file); - if (root != null) { - myDirtyScopeManager.dirDirtyRecursively(root); - } - root = getRootForChangeBranch(file); - if (root != null) { - myProject.getMessageBus().syncPublisher(HgVcs.REMOTE_TOPIC).update(myProject, root); - } - } - } - - @Nullable - private VirtualFile getRootForIndexFile(@Nullable VirtualFile file) { - if (file == null) { - return null; - } - for (VirtualFile root : myRoots) { - if (isDirstateFile(file, root) || isUndoDirstateFile(file, root)) { // hg rollback doesn't modify dirstate, only undo.dirstate - return root; - } - } - return null; - } - - private static boolean isDirstateFile(VirtualFile file, VirtualFile root) { - return FileUtil.pathsEqual(root.getPath() + "/.hg/dirstate", file.getPath()); - } - - private static boolean isUndoDirstateFile(VirtualFile file, VirtualFile root) { - return FileUtil.pathsEqual(root.getPath() + "/.hg/undo.dirstate", file.getPath()); - } - - @Nullable - private VirtualFile getRootForChangeBranch(@Nullable VirtualFile file) { - if (file == null) { - return null; - } - for (VirtualFile root : myRoots) { - if (isChangeBranchFile(file, root) || isUndoChangeBranchFile(file, root)) { - return root; - } - } - return null; - } - - private static boolean isChangeBranchFile(VirtualFile file, VirtualFile root) { - return FileUtil.pathsEqual(root.getPath() + "/.hg/branch", file.getPath()); - } - - private static boolean isUndoChangeBranchFile(VirtualFile file, VirtualFile root) { - return FileUtil.pathsEqual(root.getPath() + "/.hg/undo.branch", file.getPath()); - } - - private void registerRoot(@NotNull VirtualFile root) { - myWatchRequests.add(LocalFileSystem.getInstance().addRootToWatch(root.getPath(), true)); - myRoots.add(root); - } - - @Override - public void directoryMappingChanged() { - for (VirtualFile root : myVcsManager.getRootsUnderVcs(myVcs)) { - registerRoot(root); - } - } -} diff --git a/plugins/java-decompiler/engine/java-decompiler-engine.iml b/plugins/java-decompiler/engine/java-decompiler-engine.iml index 5880ebffc0b5..f5977f474afe 100644 --- a/plugins/java-decompiler/engine/java-decompiler-engine.iml +++ b/plugins/java-decompiler/engine/java-decompiler-engine.iml @@ -1,6 +1,6 @@ - + diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java index b55f29d7578f..dc0f3fcaa32b 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -98,7 +98,7 @@ public class ClassWriter { } else { // reference to a static method - buffer.append(ExprProcessor.getCastTypeName(new VarType(node.lambdaInformation.content_class_name, false))); + buffer.append(ExprProcessor.getCastTypeName(new VarType(node.lambdaInformation.content_class_name, true))); } buffer.append("::"); diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java index 0704efd84bdb..b5ac0fb34d9b 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -115,7 +115,9 @@ public class LambdaProcessor { node_lambda.parent = node; clProcessor.getMapRootClasses().put(node_lambda.simpleName, node_lambda); - mapMethodsLambda.put(node_lambda.lambdaInformation.content_method_key, node_lambda.simpleName); + if (!node_lambda.lambdaInformation.is_method_reference) { + mapMethodsLambda.put(node_lambda.lambdaInformation.content_method_key, node_lambda.simpleName); + } } } } diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java index 74ef0a2975f1..90d27327489e 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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,15 @@ package org.jetbrains.java.decompiler.modules.decompiler; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.modules.decompiler.exps.*; +import org.jetbrains.java.decompiler.struct.consts.PooledConstant; +import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Set; public class ConcatenationHelper { @@ -52,6 +56,12 @@ public class ConcatenationHelper { exprTmp = iex.getInstance(); } } + else if ("makeConcatWithConstants".equals(iex.getName())) { // java 9 style + List parameters = extractParameters(iex.getBootstrapArguments(), iex); + if (parameters.size() >= 2) { + return createConcatExprent(parameters, expr.bytecode); + } + } } if (exprTmp == null) { @@ -125,20 +135,69 @@ public class ConcatenationHelper { lstOperands.set(i, rep); } } + return createConcatExprent(lstOperands, expr.bytecode); + } + private static Exprent createConcatExprent(List lstOperands, Set bytecode) { // build exprent to return Exprent func = lstOperands.get(0); for (int i = 1; i < lstOperands.size(); i++) { - List lstTmp = new ArrayList(); - lstTmp.add(func); - lstTmp.add(lstOperands.get(i)); - func = new FunctionExprent(FunctionExprent.FUNCTION_STR_CONCAT, lstTmp, expr.bytecode); + func = new FunctionExprent(FunctionExprent.FUNCTION_STR_CONCAT, Arrays.asList(func, lstOperands.get(i)), bytecode); } return func; } + // See StringConcatFactory in jdk sources + private static final char TAG_ARG = '\u0001'; + private static final char TAG_CONST = '\u0002'; + + private static List extractParameters(List bootstrapArguments, InvocationExprent expr) { + List parameters = expr.getLstParameters(); + if (bootstrapArguments != null) { + PooledConstant constant = bootstrapArguments.get(0); + if (constant.type == CodeConstants.CONSTANT_String) { + String recipe = ((PrimitiveConstant)constant).getString(); + + List res = new ArrayList(); + StringBuilder acc = new StringBuilder(); + int parameterId = 0; + for (int i = 0; i < recipe.length(); i++) { + char c = recipe.charAt(i); + + if (c == TAG_CONST || c == TAG_ARG) { + // Detected a special tag, flush all accumulated characters + // as a constant first: + if (acc.length() > 0) { + res.add(new ConstExprent(VarType.VARTYPE_STRING, acc.toString(), expr.bytecode)); + acc.setLength(0); + } + if (c == TAG_CONST) { + // skip for now + } + if (c == TAG_ARG) { + res.add(parameters.get(parameterId++)); + } + } + else { + // Not a special characters, this is a constant embedded into + // the recipe itself. + acc.append(c); + } + } + + // Flush the remaining characters as constant: + if (acc.length() > 0) { + res.add(new ConstExprent(VarType.VARTYPE_STRING, acc.toString(), expr.bytecode)); + } + + return res; + } + } + return new ArrayList(parameters); + } + private static boolean isAppendConcat(InvocationExprent expr, VarType cltype) { if ("append".equals(expr.getName())) { diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index cbc66c78c63a..008d0bb794ab 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -567,21 +567,14 @@ public class ExprProcessor implements CodeConstants { case opc_invokeinterface: case opc_invokedynamic: if (instr.opcode != opc_invokedynamic || instr.bytecode_version >= CodeConstants.BYTECODE_JAVA_7) { - LinkConstant invoke_constant = pool.getLinkConstant(instr.getOperand(0)); - int dynamic_invokation_type = -1; + List bootstrap_arguments = null; if (instr.opcode == opc_invokedynamic && bootstrap != null) { - List bootstrap_arguments = bootstrap.getMethodArguments(invoke_constant.index1); - if (bootstrap_arguments.size() > 1) { // INVOKEDYNAMIC is used not only for lambdas - PooledConstant link = bootstrap_arguments.get(1); - if (link instanceof LinkConstant) { - dynamic_invokation_type = ((LinkConstant)link).index1; - } - } + bootstrap_arguments = bootstrap.getMethodArguments(invoke_constant.index1); } - InvocationExprent exprinv = new InvocationExprent(instr.opcode, invoke_constant, stack, dynamic_invokation_type, bytecode_offsets); + InvocationExprent exprinv = new InvocationExprent(instr.opcode, invoke_constant, bootstrap_arguments, stack, bytecode_offsets); if (exprinv.getDescriptor().ret.type == CodeConstants.TYPE_VOID) { exprlist.add(exprinv); } diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index 294a115207d3..3ceb99cafc60 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -15,13 +15,6 @@ */ package org.jetbrains.java.decompiler.modules.decompiler.exps; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Collections; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; - import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; @@ -36,6 +29,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.consts.LinkConstant; +import org.jetbrains.java.decompiler.struct.consts.PooledConstant; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.match.MatchEngine; @@ -45,6 +39,9 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.ListStack; import org.jetbrains.java.decompiler.util.TextUtil; +import java.util.*; +import java.util.Map.Entry; + public class InvocationExprent extends Exprent { public static final int INVOKE_SPECIAL = 1; @@ -69,16 +66,22 @@ public class InvocationExprent extends Exprent { private String invokeDynamicClassSuffix; private int invocationTyp = INVOKE_VIRTUAL; private List lstParameters = new ArrayList(); + private List bootstrapArguments; public InvocationExprent() { super(EXPRENT_INVOCATION); } - public InvocationExprent(int opcode, LinkConstant cn, ListStack stack, int dynamicInvocationType, Set bytecodeOffsets) { + public InvocationExprent(int opcode, + LinkConstant cn, + List bootstrapArguments, + ListStack stack, + Set bytecodeOffsets) { this(); name = cn.elementname; classname = cn.classname; + this.bootstrapArguments = bootstrapArguments; switch (opcode) { case CodeConstants.opc_invokestatic: @@ -115,6 +118,15 @@ public class InvocationExprent extends Exprent { } if (opcode == CodeConstants.opc_invokedynamic) { + int dynamicInvocationType = -1; + if (bootstrapArguments != null) { + if (bootstrapArguments.size() > 1) { // INVOKEDYNAMIC is used not only for lambdas + PooledConstant link = bootstrapArguments.get(1); + if (link instanceof LinkConstant) { + dynamicInvocationType = ((LinkConstant)link).index1; + } + } + } if (dynamicInvocationType == CodeConstants.CONSTANT_MethodHandle_REF_invokeStatic) { isStatic = true; } @@ -154,6 +166,7 @@ public class InvocationExprent extends Exprent { ExprProcessor.copyEntries(lstParameters); addBytecodeOffsets(expr.bytecode); + bootstrapArguments = expr.getBootstrapArguments(); } @Override @@ -492,6 +505,10 @@ public class InvocationExprent extends Exprent { return invokeDynamicClassSuffix; } + public List getBootstrapArguments() { + return bootstrapArguments; + } + // ***************************************************************************** // IMatchable implementation // ***************************************************************************** diff --git a/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 1ab4ea2f3244..e3a6f56a7979 100644 --- a/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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,6 +77,10 @@ public class SingleClassesTest { @Test public void testInnerSignature() { doTest("pkg/TestInnerSignature"); } @Test public void testParameterizedTypes() { doTest("pkg/TestParameterizedTypes"); } @Test public void testShadowing() { doTest("pkg/TestShadowing", "pkg/Shadow", "ext/Shadow"); } + @Test public void testStringConcat() { doTest("pkg/TestStringConcat"); } + @Test public void testJava9StringConcat() { doTest("java9/TestJava9StringConcat"); } + @Test public void testMethodReferenceSameName() { doTest("pkg/TestMethodReferenceSameName"); } + @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/plugins/java-decompiler/engine/testData/classes/java9/TestJava9StringConcat.class b/plugins/java-decompiler/engine/testData/classes/java9/TestJava9StringConcat.class new file mode 100644 index 000000000000..721a0ed9499e Binary files /dev/null and b/plugins/java-decompiler/engine/testData/classes/java9/TestJava9StringConcat.class differ diff --git a/plugins/java-decompiler/engine/testData/classes/pkg/R.class b/plugins/java-decompiler/engine/testData/classes/pkg/R.class new file mode 100644 index 000000000000..7c9c9e22c83c Binary files /dev/null and b/plugins/java-decompiler/engine/testData/classes/pkg/R.class differ diff --git a/plugins/java-decompiler/engine/testData/classes/pkg/TestMethodReferenceLetterClass.class b/plugins/java-decompiler/engine/testData/classes/pkg/TestMethodReferenceLetterClass.class new file mode 100644 index 000000000000..74bb32df8d43 Binary files /dev/null and b/plugins/java-decompiler/engine/testData/classes/pkg/TestMethodReferenceLetterClass.class differ diff --git a/plugins/java-decompiler/engine/testData/classes/pkg/TestMethodReferenceSameName$R1.class b/plugins/java-decompiler/engine/testData/classes/pkg/TestMethodReferenceSameName$R1.class new file mode 100644 index 000000000000..895110b36fa6 Binary files /dev/null and b/plugins/java-decompiler/engine/testData/classes/pkg/TestMethodReferenceSameName$R1.class differ diff --git a/plugins/java-decompiler/engine/testData/classes/pkg/TestMethodReferenceSameName.class b/plugins/java-decompiler/engine/testData/classes/pkg/TestMethodReferenceSameName.class new file mode 100644 index 000000000000..600e5518dce1 Binary files /dev/null and b/plugins/java-decompiler/engine/testData/classes/pkg/TestMethodReferenceSameName.class differ diff --git a/plugins/java-decompiler/engine/testData/classes/pkg/TestStringConcat.class b/plugins/java-decompiler/engine/testData/classes/pkg/TestStringConcat.class new file mode 100644 index 000000000000..029207376cef Binary files /dev/null and b/plugins/java-decompiler/engine/testData/classes/pkg/TestStringConcat.class differ diff --git a/plugins/java-decompiler/engine/testData/results/TestJava9StringConcat.dec b/plugins/java-decompiler/engine/testData/results/TestJava9StringConcat.dec new file mode 100644 index 000000000000..389bb85905dd --- /dev/null +++ b/plugins/java-decompiler/engine/testData/results/TestJava9StringConcat.dec @@ -0,0 +1,27 @@ +package java9; + +public class TestJava9StringConcat { + public String test1(String var1, int var2) { + return var1 + var2;// 20 + } + + public String test2(String var1, int var2, Object var3) { + return "(" + var1 + "-" + var2 + "---" + var3 + ")";// 24 + } +} + +class 'java9/TestJava9StringConcat' { + method 'test1 (Ljava/lang/String;I)Ljava/lang/String;' { + 2 4 + 7 4 + } + + method 'test2 (Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/String;' { + 3 8 + 8 8 + } +} + +Lines mapping: +20 <-> 5 +24 <-> 9 diff --git a/plugins/java-decompiler/engine/testData/results/TestMethodReferenceLetterClass.dec b/plugins/java-decompiler/engine/testData/results/TestMethodReferenceLetterClass.dec new file mode 100644 index 000000000000..0491efa3edf5 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/results/TestMethodReferenceLetterClass.dec @@ -0,0 +1,18 @@ +import java.util.function.Consumer; + +public class TestMethodReferenceLetterClass { + void boo() { + Consumer var1 = R::foo;// 21 + }// 22 +} + +class 'TestMethodReferenceLetterClass' { + method 'boo ()V' { + 5 4 + 6 5 + } +} + +Lines mapping: +21 <-> 5 +22 <-> 6 diff --git a/plugins/java-decompiler/engine/testData/results/TestMethodReferenceSameName.dec b/plugins/java-decompiler/engine/testData/results/TestMethodReferenceSameName.dec new file mode 100644 index 000000000000..3449a8cfc9c1 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/results/TestMethodReferenceSameName.dec @@ -0,0 +1,34 @@ +public class TestMethodReferenceSameName { + TestMethodReferenceSameName.R1 r; + + private void foo() { + TestMethodReferenceSameName.R1 var10000 = this.r;// 5 + this.r.getClass(); + (var10000::foo).run(); + }// 6 + + class R1 { + void foo() { + }// 9 + } +} + +class 'TestMethodReferenceSameName' { + method 'foo ()V' { + 1 4 + 5 5 + e 6 + 13 7 + } +} + +class 'TestMethodReferenceSameName$R1' { + method 'foo ()V' { + 0 11 + } +} + +Lines mapping: +5 <-> 5 +6 <-> 8 +9 <-> 12 diff --git a/plugins/java-decompiler/engine/testData/results/TestStringConcat.dec b/plugins/java-decompiler/engine/testData/results/TestStringConcat.dec new file mode 100644 index 000000000000..b3fc99579d32 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/results/TestStringConcat.dec @@ -0,0 +1,31 @@ +package pkg; + +public class TestStringConcat { + public String test1(String var1, int var2) { + return var1 + var2;// 20 + } + + public String test2(String var1, int var2, Object var3) { + return "(" + var1 + "-" + var2 + "---" + var3 + ")";// 24 + } +} + +class 'pkg/TestStringConcat' { + method 'test1 (Ljava/lang/String;I)Ljava/lang/String;' { + f 4 + 12 4 + } + + method 'test2 (Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/String;' { + 7 8 + 10 8 + 19 8 + 22 8 + 27 8 + 2a 8 + } +} + +Lines mapping: +20 <-> 5 +24 <-> 9 diff --git a/plugins/java-decompiler/engine/testData/src/java9/TestJava9StringConcat.java b/plugins/java-decompiler/engine/testData/src/java9/TestJava9StringConcat.java new file mode 100644 index 000000000000..9e1959649e53 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/src/java9/TestJava9StringConcat.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package java9; + +public class TestJava9StringConcat { + public String test1(String prefix, int a) { + return prefix + a; + } + + public String test2(String var, int b, Object c) { + return "(" + var + "-" + b + "---" + c + ")"; + } +} \ No newline at end of file diff --git a/plugins/java-decompiler/engine/testData/src/pkg/TestMethodReferenceLetterClass.java b/plugins/java-decompiler/engine/testData/src/pkg/TestMethodReferenceLetterClass.java new file mode 100644 index 000000000000..5f290d8ae94c --- /dev/null +++ b/plugins/java-decompiler/engine/testData/src/pkg/TestMethodReferenceLetterClass.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2016 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. + */ + +import java.util.function.Consumer; + +public class TestMethodReferenceLetterClass { + void boo() { + Consumer foo = R::foo; + } +} + +class R { + void foo() {} +} \ No newline at end of file diff --git a/plugins/java-decompiler/engine/testData/src/pkg/TestMethodReferenceSameName.java b/plugins/java-decompiler/engine/testData/src/pkg/TestMethodReferenceSameName.java new file mode 100644 index 000000000000..58d18d354cc8 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/src/pkg/TestMethodReferenceSameName.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2016 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. + */ +public class TestMethodReferenceSameName { + R1 r; + + private void foo() { + ((Runnable)r::foo).run(); + } + + class R1 { + void foo() {} + } +} diff --git a/plugins/java-decompiler/engine/testData/src/pkg/TestStringConcat.java b/plugins/java-decompiler/engine/testData/src/pkg/TestStringConcat.java new file mode 100644 index 000000000000..1a77677ad523 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/src/pkg/TestStringConcat.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pkg; + +public class TestStringConcat { + public String test1(String prefix, int a) { + return prefix + a; + } + + public String test2(String var, int b, Object c) { + return "(" + var + "-" + b + "---" + c + ")"; + } +} \ No newline at end of file diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/AbstractJavaFXQuickFixTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/AbstractJavaFXQuickFixTest.java index feaaf1ec1336..88a468abc7d4 100644 --- a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/AbstractJavaFXQuickFixTest.java +++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/AbstractJavaFXQuickFixTest.java @@ -16,6 +16,9 @@ package org.jetbrains.plugins.javaFX.fxml; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.testFramework.fixtures.CodeInsightTestUtil; + +import java.util.List; /** * User: anna @@ -34,7 +37,8 @@ public abstract class AbstractJavaFXQuickFixTest extends AbstractJavaFXTestCase protected void checkQuickFixNotAvailable(String tagName) throws Exception { myFixture.configureByFiles(getTestName(true) + ".fxml"); - final IntentionAction intention = myFixture.getAvailableIntention(getHint(tagName)); + final List intentions = myFixture.getAvailableIntentions(); + final IntentionAction intention = CodeInsightTestUtil.findIntentionByText(intentions, getHint(tagName)); assertNull(intention); } } diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxGenerateDefaultPropertyValuesScript.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxGenerateDefaultPropertyValuesScript.java new file mode 100644 index 000000000000..7a68e1756e5c --- /dev/null +++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxGenerateDefaultPropertyValuesScript.java @@ -0,0 +1,533 @@ +package org.jetbrains.plugins.javaFX.fxml; + +import javafx.application.Application; +import javafx.application.Platform; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.layout.StackPane; +import javafx.stage.Stage; +import org.jetbrains.annotations.NotNull; + +import java.beans.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.*; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * This is not a test, this is a config generator for JavaFxRedundantPropertyValueInspection + *

+ * When launched without arguments it produces default values for JavaFX classes having default constructor and their superclasses, including some (but not all) abstract classes + *

+ * When launched with -fromSource argument it attempts to extract default property values from the sources (JavaDoc and declarations), + * the results can be used for updating the contents of {@link #ourFromSource} map, which contains manually edited properties + * + * @author Pavel.Dolgov + */ +public class JavaFxGenerateDefaultPropertyValuesScript extends Application { + public static final String BINARIES_PATH = "/usr/lib/jvm/java-8-oracle/jre/lib/ext/jfxrt.jar"; + public static final String SOURCE_PATH = "/usr/lib/jvm/java-8-oracle/javafx-src.zip"; + + public static void main(String[] args) { + if (args.length == 1 && "-fromSource".equals(args[0])) { + scanSource(); + } + else { + launch(args); + } + } + + @Override + public void start(Stage primaryStage) throws Exception { + Button b = new Button(); + b.setText("Generate"); + b.setOnAction(event -> generate()); + + StackPane pane = new StackPane(); + pane.getChildren().add(b); + primaryStage.setScene(new Scene(pane, 300, 200)); + primaryStage.show(); + + Platform.runLater(() -> { + generate(); + primaryStage.close(); + }); + } + + private static final Map ourToBoxed = new HashMap<>(); + + static { + ourToBoxed.put(Boolean.TYPE, Boolean.class); + ourToBoxed.put(Character.TYPE, Character.class); + ourToBoxed.put(Byte.TYPE, Byte.class); + ourToBoxed.put(Short.TYPE, Short.class); + ourToBoxed.put(Integer.TYPE, Integer.class); + ourToBoxed.put(Long.TYPE, Long.class); + ourToBoxed.put(Float.TYPE, Float.class); + ourToBoxed.put(Double.TYPE, Double.class); + } + + private static final Map ourFromSource = new TreeMap<>(); + + static { + ourFromSource.put("javafx.concurrent.ScheduledService#maximumFailureCount", "Integer=2147483647"); + ourFromSource.put("javafx.concurrent.ScheduledService#restartOnFailure", "Boolean=true"); + ourFromSource.put("javafx.scene.Node#accessibleRole", "Enum=NODE"); + ourFromSource.put("javafx.scene.Node#focusTraversable", "Boolean=false"); + ourFromSource.put("javafx.scene.Node#nodeOrientation", "Enum=INHERIT"); + ourFromSource.put("javafx.scene.Node#pickOnBounds", "Boolean=false"); + ourFromSource.put("javafx.scene.SubScene#height", "Double=0.0"); + ourFromSource.put("javafx.scene.SubScene#width", "Double=0.0"); + ourFromSource.put("javafx.scene.chart.AreaChart#createSymbols", "Boolean=true"); + ourFromSource.put("javafx.scene.chart.Axis#label", "String="); + ourFromSource.put("javafx.scene.chart.BarChart#barGap", "Double=4.0"); + ourFromSource.put("javafx.scene.chart.BarChart#categoryGap", "Double=10.0"); + ourFromSource.put("javafx.scene.chart.Chart#title", "String="); + ourFromSource.put("javafx.scene.chart.LineChart#axisSortingPolicy", "Enum=X_AXIS"); + ourFromSource.put("javafx.scene.chart.LineChart#createSymbols", "Boolean=true"); + ourFromSource.put("javafx.scene.chart.StackedAreaChart#createSymbols", "Boolean=true"); + ourFromSource.put("javafx.scene.chart.StackedBarChart#categoryGap", "Double=10.0"); + ourFromSource.put("javafx.scene.chart.XYChart#alternativeColumnFillVisible", "Boolean=false"); + ourFromSource.put("javafx.scene.chart.XYChart#alternativeRowFillVisible", "Boolean=true"); + ourFromSource.put("javafx.scene.chart.XYChart#horizontalGridLinesVisible", "Boolean=true"); + ourFromSource.put("javafx.scene.chart.XYChart#horizontalZeroLineVisible", "Boolean=true"); + ourFromSource.put("javafx.scene.chart.XYChart#verticalGridLinesVisible", "Boolean=true"); + ourFromSource.put("javafx.scene.chart.XYChart#verticalZeroLineVisible", "Boolean=true"); + ourFromSource.put("javafx.scene.control.ComboBoxBase#editable", "Boolean=false"); + ourFromSource.put("javafx.scene.control.CustomMenuItem#hideOnClick", "Boolean=true"); + ourFromSource.put("javafx.scene.control.Labeled#alignment", "Enum=CENTER_LEFT"); + ourFromSource.put("javafx.scene.control.Labeled#mnemonicParsing", "Boolean=false"); + ourFromSource.put("javafx.scene.control.SpinnerValueFactory#wrapAround", "Boolean=false"); + ourFromSource.put("javafx.scene.control.TableSelectionModel#cellSelectionEnabled", "Boolean=false"); + ourFromSource.put("javafx.scene.media.AudioClip#balance", "Double=0.0"); + ourFromSource.put("javafx.scene.media.AudioClip#cycleCount", "Integer=1"); + ourFromSource.put("javafx.scene.media.AudioClip#pan", "Double=0.0"); + ourFromSource.put("javafx.scene.media.AudioClip#priority", "Integer=0"); + ourFromSource.put("javafx.scene.media.AudioClip#rate", "Double=1.0"); + ourFromSource.put("javafx.scene.media.AudioClip#volume", "Double=1.0"); + ourFromSource.put("javafx.scene.media.AudioEqualizer#enabled", "Boolean=false"); + ourFromSource.put("javafx.scene.media.MediaPlayer#audioSpectrumInterval", "Double=0.1"); + ourFromSource.put("javafx.scene.media.MediaPlayer#audioSpectrumNumBands", "Integer=128"); + ourFromSource.put("javafx.scene.media.MediaPlayer#audioSpectrumThreshold", "Integer=-60"); + ourFromSource.put("javafx.scene.media.MediaPlayer#autoPlay", "Boolean=false"); + ourFromSource.put("javafx.scene.media.MediaPlayer#balance", "Double=0.0"); + ourFromSource.put("javafx.scene.media.MediaPlayer#cycleCount", "Integer=1"); + ourFromSource.put("javafx.scene.media.MediaPlayer#mute", "Boolean=false"); + ourFromSource.put("javafx.scene.media.MediaPlayer#rate", "Double=1.0"); + ourFromSource.put("javafx.scene.media.MediaPlayer#volume", "Double=1.0"); + ourFromSource.put("javafx.stage.PopupWindow#anchorLocation", "Enum=WINDOW_TOP_LEFT"); + ourFromSource.put("javafx.stage.PopupWindow#autoHide", "Boolean=false"); + ourFromSource.put("javafx.stage.PopupWindow#consumeAutoHidingEvents", "Boolean=true"); + } + + private static final Set ourSkippedProperties = new HashSet<>( + Arrays.asList("javafx.scene.web.HTMLEditor#htmlText", + "javafx.scene.web.WebEngine#userAgent", + "javafx.scene.control.ButtonBar#buttonOrder")); + + static class TypedValue { + + private final String kind; + private final String value; + + TypedValue(@NotNull String kind, @NotNull String value) { + this.kind = kind; + this.value = value; + } + + public String getKind() { + return kind; + } + + public String getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TypedValue)) return false; + + TypedValue that = (TypedValue)o; + return kind.equals(that.kind) && value.equals(that.value); + } + + @Override + public int hashCode() { + return kind.hashCode() ^ value.hashCode(); + } + + @Override + public String toString() { + return kind + ':' + value; + } + } + + static class ContainedValue extends TypedValue { + private final String declaringClass; + + public ContainedValue(@NotNull String kind, @NotNull String value, @NotNull String declaringClass) { + super(kind, value); + this.declaringClass = declaringClass; + } + + public String getDeclaringClass() { + return declaringClass; + } + } + + /** + * Attempt to instantiate JavaFX classes on the FX thread, obtain default property values from instantiated objects. + */ + private static void generate() { + System.out.println("--- JavaFX default property values ---"); + + final Map> containedProperties = new TreeMap<>(); + final Map> declaredProperties = new TreeMap<>(); + final Map>> overriddenProperties = new TreeMap<>(); + final Map superClasses = new TreeMap<>(); + try (final ZipInputStream zip = new ZipInputStream(new FileInputStream(new File(BINARIES_PATH)))) { + for (ZipEntry ze = zip.getNextEntry(); ze != null; ze = zip.getNextEntry()) { + final String entryName = ze.getName(); + if (!ze.isDirectory() && entryName.endsWith(".class") && entryName.startsWith("javafx")) { + final String className = entryName.substring(0, entryName.lastIndexOf('.')).replace('/', '.'); + Class currentClass = Class.forName(className); + if (!Modifier.isPublic(currentClass.getModifiers()) && !Modifier.isProtected(currentClass.getModifiers())) continue; + if (currentClass.getName().startsWith("javafx.beans")) continue; + if (currentClass.getName().matches(".*\\$\\d+$")) continue; + BeanInfo info = Introspector.getBeanInfo(currentClass); + if (currentClass.getSuperclass() != null) { + superClasses.put(currentClass.getName(), currentClass.getSuperclass().getName()); + } + + Set bindings = new TreeSet<>(); + for (MethodDescriptor methodDesc : info.getMethodDescriptors()) { + if (methodDesc.getName().endsWith("Property") && + !methodDesc.getMethod().getGenericReturnType().toString().contains("ReadOnly")) { + bindings.add(methodDesc.getName()); + } + } + + Object obj = null; + for (PropertyDescriptor desc : info.getPropertyDescriptors()) { + final String propName = desc.getName(); + final String propQualifiedName = currentClass.getName() + "#" + propName; + if (ourSkippedProperties.contains(propQualifiedName)) continue; + final Method setter = desc.getWriteMethod(); + final boolean hasBinding = bindings.contains(propName + "Property"); + if (setter == null || !hasBinding) continue; + final Type type = setter.getGenericParameterTypes()[0]; + + if (type instanceof Class) { + final Class paramCls = (Class)type; + final String kind = kind(paramCls); + if (kind != null) { + if (obj == null) { + obj = instantiate(currentClass); + if (obj == null) break; + } + final Object value; + final Method getter = desc.getReadMethod(); + try { + value = getter.invoke(obj); + } + catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException("Can't invoke " + getter + " on " + currentClass, e); + } + if (value != null) { + if (!value.equals(validate(paramCls, value))) { + throw new RuntimeException("Invalid " + currentClass + "#" + propName + ":" + paramCls + "=" + value); + } + final Class declaringClass = getter.getDeclaringClass(); + final ContainedValue newValue = new ContainedValue(kind, String.valueOf(value), declaringClass.getName()); + if (declaringClass.getName().startsWith("javafx")) { + containedProperties + .computeIfAbsent(currentClass.getName(), unused -> new TreeMap<>()) + .put(propName, newValue); + } + + final Map shareableProperties = + declaredProperties.computeIfAbsent(declaringClass.getName(), unused -> new TreeMap<>()); + final TypedValue sharedValue = shareableProperties.get(propName); + + if (sharedValue == null) { + shareableProperties.put(propName, newValue); + } + else if (!sharedValue.equals(newValue)) { + final Set multipleValues = overriddenProperties + .computeIfAbsent(declaringClass.getName(), unused -> new TreeMap<>()) + .computeIfAbsent(propName, unused -> new TreeSet<>()); + multipleValues.add(sharedValue.getValue()); + multipleValues.add(newValue.getValue()); + } + } + } + } + } + } + } + } + catch (IOException | ClassNotFoundException | IntrospectionException e) { + e.printStackTrace(); + } + + System.out.println("-------- Collected from sources ---------"); + ourFromSource.forEach((k, v) -> System.out.println(k + ":" + v)); + + System.out.println("-------- Shared (not overridden) ---------"); + declaredProperties.forEach( + (className, propertyMap) -> { + final Map> multipleValues = overriddenProperties.getOrDefault(className, Collections.emptyMap()); + propertyMap.forEach((propName, typedValue) -> { + if (!multipleValues.containsKey(propName)) { + System.out.println(className + "#" + propName + ":" + typedValue.getKind() + "=" + typedValue.getValue()); + } + }); + }); + System.out.println("-------- Overridden in subclass ---------"); + final Map> fromSource = new TreeMap<>(); + ourFromSource.forEach((classAndPropName, kindAndValue) -> { + final int p1 = classAndPropName.indexOf('#'); + if (p1 > 0 && p1 < classAndPropName.length()) { + final String className = classAndPropName.substring(0, p1); + final String propName = classAndPropName.substring(p1 + 1); + final int p3 = kindAndValue.indexOf('='); + if (p3 > 0 && p3 < kindAndValue.length()) { + final String kind = kindAndValue.substring(0, p3); + final String value = kindAndValue.substring(p3 + 1); + final Map propMap = fromSource.computeIfAbsent(className, unused -> new TreeMap<>()); + if (!propMap.containsKey(propName)) { + final ContainedValue valueFromSource = new ContainedValue(kind, value, className); + propMap.put(propName, valueFromSource); + } + } + } + }); + containedProperties.forEach( + (className, propertyMap) -> propertyMap.forEach( + (propName, propValue) -> { + final ContainedValue sourceValue = fromSource.getOrDefault(className, Collections.emptyMap()).get(propName); + if (sourceValue != null && + sourceValue.equals(propValue)) { + return; + } + final Map> multipleValues = overriddenProperties.get(propValue.getDeclaringClass()); + if (multipleValues != null && multipleValues.get(propName) != null) { + boolean sameValueInSuperClass = false; + for (String scName = superClasses.get(className); scName != null; scName = superClasses.get(scName)) { + final Map superPropMap = containedProperties.getOrDefault(scName, fromSource.get(scName)); + if (superPropMap != null) { + ContainedValue superValue = superPropMap.get(propName); + if (superValue != null) { + sameValueInSuperClass = superValue.equals(propValue); + break; + } + } + } + if (!sameValueInSuperClass) { + System.out.println(className + "#" + propName + ":" + propValue.getKind() + "=" + propValue.getValue()); + } + } + })); + + System.out.println("-------- Overridden properties' values ---------"); + overriddenProperties + .forEach((className, propertyValues) -> propertyValues.entrySet() + .forEach(e -> System.out.println("-- " + className + "#" + e.getKey() + e.getValue()))); + System.out.println("-------- Skipped properties ---------"); + ourSkippedProperties.forEach(propName -> System.out.println("-- " + propName)); + } + + private static String kind(Class aCls) { + String kind = null; + if (aCls.isPrimitive()) { + kind = ourToBoxed.get(aCls).getSimpleName(); + } + else if (aCls.isEnum()) { + kind = "Enum"; + } + else if (Number.class.isAssignableFrom(aCls) || Boolean.class.isAssignableFrom(aCls) || Character.class.isAssignableFrom(aCls)) { + kind = aCls.getSimpleName(); + } + else if (CharSequence.class.isAssignableFrom(aCls)) { + kind = "String"; + } + return kind; + } + + private static Object validate(Class aCls, Object val) { + try { + if (aCls.isPrimitive()) { + aCls = ourToBoxed.get(aCls); + Method valueOf = aCls.getDeclaredMethod("valueOf", String.class); + return valueOf.invoke(null, String.valueOf(val)); + } + if (Number.class.isAssignableFrom(aCls) || Boolean.class.isAssignableFrom(aCls) || Character.class.isAssignableFrom(aCls)) { + Method valueOf = aCls.getDeclaredMethod("valueOf", String.class); + return valueOf.invoke(null, String.valueOf(val)); + } + if (CharSequence.class.isAssignableFrom(aCls)) { + return val; + } + if (aCls.isEnum()) { + Method valueOf = aCls.getDeclaredMethod("valueOf", String.class); + return valueOf.invoke(null, String.valueOf(val)); + } + throw new IllegalStateException("Cannot cast " + val + " to unsupported class " + aCls); + } + catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + throw new IllegalStateException("Cannot cast " + val + " to " + aCls, e); + } + } + + private static Object instantiate(Class aClass) { + try { + if (Modifier.isAbstract(aClass.getModifiers())) return null; + + final Constructor constructor; + try { + constructor = aClass.getConstructor(); + } + catch (NoSuchMethodException e) { + return null; + } + constructor.setAccessible(true); + return constructor.newInstance(); + } + catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + System.err.println("Not instantiated " + aClass + " " + e); + return null; + } + } + + private static final Set ourSourceClasses = new TreeSet<>(); + + static { + ourSourceClasses.add("javafx.animation.Animation"); + ourSourceClasses.add("javafx.concurrent.ScheduledService"); + ourSourceClasses.add("javafx.print.JobSettings"); + ourSourceClasses.add("javafx.scene.Camera"); + ourSourceClasses.add("javafx.scene.LightBase"); + ourSourceClasses.add("javafx.scene.Node"); + ourSourceClasses.add("javafx.scene.Scene"); + ourSourceClasses.add("javafx.scene.SubScene"); + ourSourceClasses.add("javafx.scene.canvas.GraphicsContext"); + ourSourceClasses.add("javafx.scene.chart.AreaChart"); + ourSourceClasses.add("javafx.scene.chart.Axis"); + ourSourceClasses.add("javafx.scene.chart.BarChart"); + ourSourceClasses.add("javafx.scene.chart.Chart"); + ourSourceClasses.add("javafx.scene.chart.LineChart"); + ourSourceClasses.add("javafx.scene.chart.PieChart"); + ourSourceClasses.add("javafx.scene.chart.StackedAreaChart"); + ourSourceClasses.add("javafx.scene.chart.StackedBarChart"); + ourSourceClasses.add("javafx.scene.chart.ValueAxis"); + ourSourceClasses.add("javafx.scene.chart.XYChart"); + ourSourceClasses.add("javafx.scene.control.Alert"); + ourSourceClasses.add("javafx.scene.control.ComboBoxBase"); + ourSourceClasses.add("javafx.scene.control.Labeled"); + ourSourceClasses.add("javafx.scene.control.MultipleSelectionModel"); + ourSourceClasses.add("javafx.scene.control.SpinnerValueFactory"); + ourSourceClasses.add("javafx.scene.control.SpinnerValueFactory"); + ourSourceClasses.add("javafx.scene.control.SpinnerValueFactory"); + ourSourceClasses.add("javafx.scene.control.TableColumnBase"); + ourSourceClasses.add("javafx.scene.control.TableSelectionModel"); + ourSourceClasses.add("javafx.scene.control.TextFormatter"); + ourSourceClasses.add("javafx.scene.control.TextInputControl"); + ourSourceClasses.add("javafx.scene.control.Toggle"); + ourSourceClasses.add("javafx.scene.input.DragEvent"); + ourSourceClasses.add("javafx.scene.input.Dragboard"); + ourSourceClasses.add("javafx.scene.input.MouseEvent"); + ourSourceClasses.add("javafx.scene.media.AudioClip"); + ourSourceClasses.add("javafx.scene.media.AudioEqualizer"); + ourSourceClasses.add("javafx.scene.media.MediaPlayer"); + ourSourceClasses.add("javafx.scene.shape.PathElement"); + ourSourceClasses.add("javafx.scene.shape.Shape"); + ourSourceClasses.add("javafx.scene.shape.Shape3D"); + ourSourceClasses.add("javafx.scene.web.WebHistory"); + ourSourceClasses.add("javafx.stage.PopupWindow"); + ourSourceClasses.add("javafx.stage.Window"); + } + + private static void scanSource() { + + Pattern defaultValueJavaDoc = Pattern.compile("^.*\\*\\s*@defaultValue\\s*(.+)\\s*$"); + Pattern fieldDecl = Pattern.compile("^.*\\s(\\w+)\\s*(=.*|;)\\s*$"); + Pattern methodDecl = Pattern.compile("^.*\\s(\\w+)\\s*\\(\\).*$"); + Pattern propertyDecl = Pattern.compile("^.*Property\\S*\\s+(\\w+)\\s*=\\s*(.+)[;{].*$"); + + Map props = new TreeMap<>(); + try (final ZipInputStream zip = new ZipInputStream(new FileInputStream(new File(SOURCE_PATH)))) { + byte[] buffer = new byte[1 << 16]; + for (ZipEntry ze = zip.getNextEntry(); ze != null; ze = zip.getNextEntry()) { + final String eName = ze.getName(); + if (!ze.isDirectory() && eName.endsWith(".java") && eName.startsWith("javafx")) { + String className = eName.substring(0, eName.lastIndexOf('.')).replace('/', '.'); + if (ourSourceClasses.contains(className)) { + StringBuilder text = new StringBuilder(); + int len; + while ((len = zip.read(buffer)) > 0) { + String str = new String(buffer, 0, len); + text.append(str); + } + String[] lines = text.toString().split("\n"); + int state = 0; + String name = null; + String value = null; + for (String s : lines) { + Matcher m; + m = propertyDecl.matcher(s); + if (m.matches()) { + name = m.group(1); + value = m.group(2); + if (!"null".equals(value)) { + props.put(className + "#" + name, value); + } + } + switch (state) { + case 0: + m = defaultValueJavaDoc.matcher(s); + if (m.matches()) { + state = 1; + value = m.group(1); + } + break; + case 1: + if (s.contains("*/")) state = 2; + break; + case 2: + if (!s.trim().isEmpty()) { + state = 0; + m = fieldDecl.matcher(s); + if (m.matches()) { + name = m.group(1); + } + else { + m = methodDecl.matcher(s); + if (m.matches()) { + name = m.group(1); + } + } + if (name != null && value != null && !"null".equals(value)) { + props.put(className + "#" + name, value); + } + name = value = null; + } + break; + } + } + } + } + } + } + catch (IOException e) { + System.err.println("Failed to read sources " + e); + } + System.out.println("--- Default values collected from JavaDoc and declarations. To be reviewed and manually edited ---"); + props.forEach((n, v) -> System.out.println(n + "=" + v)); + } +} diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxRedundantValueTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxRedundantValueTest.java new file mode 100644 index 000000000000..aab4ee8d5d7f --- /dev/null +++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxRedundantValueTest.java @@ -0,0 +1,66 @@ +package org.jetbrains.plugins.javaFX.fxml; + +import com.intellij.openapi.application.PluginPathManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.javaFX.fxml.codeInsight.inspections.JavaFxRedundantPropertyValueInspection; + +/** + * @author Pavel.Dolgov + */ +public class JavaFxRedundantValueTest extends AbstractJavaFXQuickFixTest { + @Override + protected void enableInspections() { + myFixture.enableInspections(new JavaFxRedundantPropertyValueInspection()); + } + + public void testModifiedAttribute() throws Exception { + checkQuickFixNotAvailable("alignment"); + } + + public void testImmediateAttribute() throws Exception { + doLaunchQuickfixTest("alignment"); + } + + public void testInheritedAttribute() throws Exception { + doLaunchQuickfixTest("maxHeight"); + } + + public void testModifiedTag() throws Exception { + checkQuickFixNotAvailable("alignment"); + } + + public void testImmediateTag() throws Exception { + doLaunchQuickfixTest("alignment"); + } + + public void testInheritedTag() throws Exception { + doLaunchQuickfixTest("maxHeight"); + } + + public void testAttributeHighlighting() throws Exception { + doTestHighlighting(); + } + + public void testTagHighlighting() throws Exception { + doTestHighlighting(); + } + + private void doTestHighlighting() { + myFixture.configureByFiles(getTestName(true) + ".fxml"); + myFixture.checkHighlighting(); + } + + @NotNull + @Override + protected String getTestDataPath() { + return PluginPathManager.getPluginHomePath("javaFX") + "/testData/inspections/redundantValue/"; + } + + @Override + protected String getHint(String tagName) { + if (getTestName(false).endsWith("Attribute")) { + return "Remove attribute " + tagName; + } + return "Remove tag '" + tagName + "'"; + } +} diff --git a/plugins/javaFX/resources/inspectionDescriptions/JavaFxRedundantPropertyValue.html b/plugins/javaFX/resources/inspectionDescriptions/JavaFxRedundantPropertyValue.html new file mode 100644 index 000000000000..c03a1326c547 --- /dev/null +++ b/plugins/javaFX/resources/inspectionDescriptions/JavaFxRedundantPropertyValue.html @@ -0,0 +1,6 @@ + + +This inspection reports properties in .fxml files (both attributes and tags) having default values and therefore redundant. + + + \ No newline at end of file diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml index 84ca5e512a1d..ca16653de0a9 100644 --- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml +++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml @@ -22,6 +22,8 @@ enabledByDefault="true" level="WARNING" groupName="JavaFX"/> + diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxRedundantPropertyValueInspection.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxRedundantPropertyValueInspection.java new file mode 100644 index 000000000000..fbd642fa8d74 --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxRedundantPropertyValueInspection.java @@ -0,0 +1,239 @@ +package org.jetbrains.plugins.javaFX.fxml.codeInsight.inspections; + +import com.intellij.codeInsight.daemon.impl.analysis.RemoveAttributeIntentionFix; +import com.intellij.codeInspection.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.reference.SoftReference; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import gnu.trove.THashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.javaFX.fxml.FxmlConstants; +import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory; +import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxClassBackedElementDescriptor; +import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxPropertyAttributeDescriptor; +import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxPropertyElementDescriptor; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.ref.Reference; +import java.net.URL; +import java.util.LinkedHashSet; +import java.util.Map; + +/** + * @author Pavel.Dolgov + */ +public class JavaFxRedundantPropertyValueInspection extends XmlSuppressableInspectionTool { + private static final Logger LOG = Logger.getInstance("#" + JavaFxRedundantPropertyValueInspection.class.getName()); + + private static Reference>> ourDefaultPropertyValues; + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new XmlElementVisitor() { + @Override + public void visitXmlFile(XmlFile file) { + if (!JavaFxFileTypeFactory.isFxml(file)) return; + super.visitXmlFile(file); + } + + @Override + public void visitXmlAttribute(XmlAttribute attribute) { + super.visitXmlAttribute(attribute); + final XmlAttributeDescriptor descriptor = attribute.getDescriptor(); + if (!(descriptor instanceof JavaFxPropertyAttributeDescriptor)) return; + final String attributeName = attribute.getName(); + final String attributeValue = attribute.getValue(); + if (attributeValue == null || + attributeValue.startsWith("$") || + attributeValue.startsWith("#") || + attributeValue.startsWith("%") || + FxmlConstants.FX_ID.equals(attributeName) || + FxmlConstants.FX_CONTROLLER.equals(attributeName)) { + return; + } + + final Object defaultValue = getDefaultValue(attributeName, attribute.getParent()); + if (defaultValue == null) return; + + if (isEqualValue(attributeValue, defaultValue)) { + holder.registerProblem(attribute, "Attribute is redundant because it contains default value", + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + new RemoveAttributeIntentionFix(attributeName, attribute)); + } + } + + @Override + public void visitXmlTag(XmlTag tag) { + super.visitXmlTag(tag); + final XmlElementDescriptor descriptor = tag.getDescriptor(); + if (!(descriptor instanceof JavaFxPropertyElementDescriptor) && + !(descriptor instanceof JavaFxClassBackedElementDescriptor)) { + return; + } + if (tag.getSubTags().length != 0) return; + final String tagText = tag.getValue().getText().trim(); + if (tagText.startsWith("$") || + tagText.startsWith("#") || + tagText.startsWith("%")) { + return; + } + + final Object defaultValue = getDefaultValue(tag.getName(), tag.getParentTag()); + if (defaultValue == null) return; + + if (isEqualValue(tagText, defaultValue)) { + holder.registerProblem(tag, "Tag is redundant because it contains default value", + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + new RemoveTagFix(tag.getName())); + } + } + }; + } + + @Nullable + private static Object getDefaultValue(@NotNull String propertyName, @Nullable XmlTag enclosingTag) { + if (enclosingTag != null) { + final XmlElementDescriptor descriptor = enclosingTag.getDescriptor(); + if (descriptor != null) { + final PsiElement declaration = descriptor.getDeclaration(); + if (declaration instanceof PsiClass) { + PsiClass containingClass = ((PsiClass)declaration); + { + final Object defaultValue = getDefaultPropertyValue(containingClass.getQualifiedName(), propertyName); + if (defaultValue != null) return defaultValue; + } + final LinkedHashSet superClasses = InheritanceUtil.getSuperClasses(containingClass); + for (PsiClass superClass : superClasses) { + final Object defaultValue = getDefaultPropertyValue(superClass.getQualifiedName(), propertyName); + if (defaultValue != null) return defaultValue; + } + } + } + } + return null; + } + + private static boolean isEqualValue(@NotNull String attributeValue, @NotNull Object defaultValue) { + if (defaultValue instanceof String && defaultValue.equals(attributeValue)) return true; + if (defaultValue instanceof Boolean) return defaultValue == Boolean.valueOf(attributeValue); + if (defaultValue instanceof Double) { + try { + return Double.compare((Double)defaultValue, Double.valueOf(attributeValue)) == 0; + } + catch (NumberFormatException ignored) { + return false; + } + } + if (defaultValue instanceof Integer) { + try { + return Integer.compare((Integer)defaultValue, Integer.valueOf(attributeValue)) == 0; + } + catch (NumberFormatException ignored) { + return false; + } + } + return false; + } + + private static Object getDefaultPropertyValue(String classQualifiedName, String propertyName) { + final Map values = getDefaultPropertyValues(classQualifiedName); + return values != null ? values.get(propertyName) : null; + } + + /** + * Load property values config. The config is produced with the script JavaFxGenerateDefaultPropertyValuesScript (can be found in tests) + */ + private static Map getDefaultPropertyValues(String classQualifiedName) { + if (ourDefaultPropertyValues == null) { + ourDefaultPropertyValues = loadDefaultPropertyValues(JavaFxRedundantPropertyValueInspection.class.getSimpleName() + "8.txt"); + } + Map> values = SoftReference.dereference(ourDefaultPropertyValues); + return values != null ? values.get(classQualifiedName) : null; + } + + /** + * The file format is ClassName#propertyName:type=value per line, line with leading double dash (--) is commented out + */ + private static Reference>> loadDefaultPropertyValues(String resourceName) { + final URL resource = JavaFxRedundantPropertyValueInspection.class.getResource(resourceName); + if (resource == null) { + LOG.warn("Resource not found: " + resourceName); + return null; + } + + final Map> result = new THashMap<>(200); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.openStream(), CharsetToolkit.UTF8_CHARSET))) { + for (String line : FileUtil.loadLines(reader)) { + if (line.isEmpty() || line.startsWith("--")) continue; + boolean lineParsed = false; + final int p1 = line.indexOf('#'); + if (p1 > 0 && p1 < line.length()) { + final String className = line.substring(0, p1); + final int p2 = line.indexOf(':', p1); + if (p2 > p1 && p2 < line.length()) { + final String propertyName = line.substring(p1 + 1, p2); + final int p3 = line.indexOf('=', p2 + 1); + if (p3 > 0 && p3 < line.length()) { + final String type = line.substring(p2 + 1, p3); + final String text = line.substring(p3 + 1); + final Object value = parseValue(type, text); + if (value != null) { + lineParsed = true; + final Map properties = result.computeIfAbsent(className, ignored -> new THashMap()); + if (properties.put(propertyName, value) != null) { + LOG.warn("Duplicate default property value " + line); + } + } + } + } + } + if (!lineParsed) { + LOG.warn("Can't parse default property value " + line); + } + } + } + catch (IOException e) { + LOG.warn("Cannot read resource: " + resourceName, e); + return null; + } + + return new SoftReference>>(result); + } + + @Nullable + private static Object parseValue(String type, String text) { + try { + switch (type) { + case "Boolean": + return Boolean.valueOf(text); + case "Integer": + return Integer.valueOf(text); + case "Double": + return Double.valueOf(text); + case "String": + case "Enum": + return text; + default: + LOG.warn("Unsupported value type " + type + " for '" + text + "'"); + return null; + } + } + catch (NumberFormatException ignored) { + LOG.warn("Invalid format of " + type + ": '" + text + "'"); + return null; + } + } +} + diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxRedundantPropertyValueInspection8.txt b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxRedundantPropertyValueInspection8.txt new file mode 100644 index 000000000000..5fae741200b7 --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxRedundantPropertyValueInspection8.txt @@ -0,0 +1,677 @@ +--- JavaFX default property values --- +-------- Collected from sources --------- +javafx.concurrent.ScheduledService#maximumFailureCount:Integer=2147483647 +javafx.concurrent.ScheduledService#restartOnFailure:Boolean=true +javafx.scene.Node#accessibleRole:Enum=NODE +javafx.scene.Node#focusTraversable:Boolean=false +javafx.scene.Node#nodeOrientation:Enum=INHERIT +javafx.scene.Node#pickOnBounds:Boolean=false +javafx.scene.SubScene#height:Double=0.0 +javafx.scene.SubScene#width:Double=0.0 +javafx.scene.chart.AreaChart#createSymbols:Boolean=true +javafx.scene.chart.Axis#label:String= +javafx.scene.chart.BarChart#barGap:Double=4.0 +javafx.scene.chart.BarChart#categoryGap:Double=10.0 +javafx.scene.chart.Chart#title:String= +javafx.scene.chart.LineChart#axisSortingPolicy:Enum=X_AXIS +javafx.scene.chart.LineChart#createSymbols:Boolean=true +javafx.scene.chart.StackedAreaChart#createSymbols:Boolean=true +javafx.scene.chart.StackedBarChart#categoryGap:Double=10.0 +javafx.scene.chart.XYChart#alternativeColumnFillVisible:Boolean=false +javafx.scene.chart.XYChart#alternativeRowFillVisible:Boolean=true +javafx.scene.chart.XYChart#horizontalGridLinesVisible:Boolean=true +javafx.scene.chart.XYChart#horizontalZeroLineVisible:Boolean=true +javafx.scene.chart.XYChart#verticalGridLinesVisible:Boolean=true +javafx.scene.chart.XYChart#verticalZeroLineVisible:Boolean=true +javafx.scene.control.ComboBoxBase#editable:Boolean=false +javafx.scene.control.CustomMenuItem#hideOnClick:Boolean=true +javafx.scene.control.Labeled#alignment:Enum=CENTER_LEFT +javafx.scene.control.Labeled#mnemonicParsing:Boolean=false +javafx.scene.control.SpinnerValueFactory#wrapAround:Boolean=false +javafx.scene.control.TableSelectionModel#cellSelectionEnabled:Boolean=false +javafx.scene.media.AudioClip#balance:Double=0.0 +javafx.scene.media.AudioClip#cycleCount:Integer=1 +javafx.scene.media.AudioClip#pan:Double=0.0 +javafx.scene.media.AudioClip#priority:Integer=0 +javafx.scene.media.AudioClip#rate:Double=1.0 +javafx.scene.media.AudioClip#volume:Double=1.0 +javafx.scene.media.AudioEqualizer#enabled:Boolean=false +javafx.scene.media.MediaPlayer#audioSpectrumInterval:Double=0.1 +javafx.scene.media.MediaPlayer#audioSpectrumNumBands:Integer=128 +javafx.scene.media.MediaPlayer#audioSpectrumThreshold:Integer=-60 +javafx.scene.media.MediaPlayer#autoPlay:Boolean=false +javafx.scene.media.MediaPlayer#balance:Double=0.0 +javafx.scene.media.MediaPlayer#cycleCount:Integer=1 +javafx.scene.media.MediaPlayer#mute:Boolean=false +javafx.scene.media.MediaPlayer#rate:Double=1.0 +javafx.scene.media.MediaPlayer#volume:Double=1.0 +javafx.stage.PopupWindow#anchorLocation:Enum=WINDOW_TOP_LEFT +javafx.stage.PopupWindow#autoHide:Boolean=false +javafx.stage.PopupWindow#consumeAutoHidingEvents:Boolean=true +-------- Shared (not overridden) --------- +javafx.animation.Animation#autoReverse:Boolean=false +javafx.animation.Animation#cycleCount:Integer=1 +javafx.animation.Animation#rate:Double=1.0 +javafx.animation.FadeTransition#byValue:Double=0.0 +javafx.animation.FadeTransition#fromValue:Double=NaN +javafx.animation.FadeTransition#toValue:Double=NaN +javafx.animation.PathTransition#orientation:Enum=NONE +javafx.animation.RotateTransition#byAngle:Double=0.0 +javafx.animation.RotateTransition#fromAngle:Double=NaN +javafx.animation.RotateTransition#toAngle:Double=NaN +javafx.animation.ScaleTransition#byX:Double=0.0 +javafx.animation.ScaleTransition#byY:Double=0.0 +javafx.animation.ScaleTransition#byZ:Double=0.0 +javafx.animation.ScaleTransition#fromX:Double=NaN +javafx.animation.ScaleTransition#fromY:Double=NaN +javafx.animation.ScaleTransition#fromZ:Double=NaN +javafx.animation.ScaleTransition#toX:Double=NaN +javafx.animation.ScaleTransition#toY:Double=NaN +javafx.animation.ScaleTransition#toZ:Double=NaN +javafx.animation.TranslateTransition#byX:Double=0.0 +javafx.animation.TranslateTransition#byY:Double=0.0 +javafx.animation.TranslateTransition#byZ:Double=0.0 +javafx.animation.TranslateTransition#fromX:Double=NaN +javafx.animation.TranslateTransition#fromY:Double=NaN +javafx.animation.TranslateTransition#fromZ:Double=NaN +javafx.animation.TranslateTransition#toX:Double=NaN +javafx.animation.TranslateTransition#toY:Double=NaN +javafx.animation.TranslateTransition#toZ:Double=NaN +javafx.scene.Camera#farClip:Double=100.0 +javafx.scene.Camera#nearClip:Double=0.1 +javafx.scene.Group#autoSizeChildren:Boolean=true +javafx.scene.LightBase#lightOn:Boolean=true +javafx.scene.Node#cache:Boolean=false +javafx.scene.Node#cacheHint:Enum=DEFAULT +javafx.scene.Node#depthTest:Enum=INHERIT +javafx.scene.Node#disable:Boolean=false +javafx.scene.Node#layoutX:Double=0.0 +javafx.scene.Node#layoutY:Double=0.0 +javafx.scene.Node#managed:Boolean=true +javafx.scene.Node#mouseTransparent:Boolean=false +javafx.scene.Node#opacity:Double=1.0 +javafx.scene.Node#rotate:Double=0.0 +javafx.scene.Node#scaleX:Double=1.0 +javafx.scene.Node#scaleY:Double=1.0 +javafx.scene.Node#scaleZ:Double=1.0 +javafx.scene.Node#style:String= +javafx.scene.Node#translateX:Double=0.0 +javafx.scene.Node#translateY:Double=0.0 +javafx.scene.Node#translateZ:Double=0.0 +javafx.scene.Node#visible:Boolean=true +javafx.scene.PerspectiveCamera#fieldOfView:Double=30.0 +javafx.scene.PerspectiveCamera#verticalFieldOfView:Boolean=true +javafx.scene.canvas.Canvas#height:Double=0.0 +javafx.scene.canvas.Canvas#width:Double=0.0 +javafx.scene.chart.Axis#animated:Boolean=true +javafx.scene.chart.Axis#autoRanging:Boolean=true +javafx.scene.chart.Axis#tickLabelGap:Double=3.0 +javafx.scene.chart.Axis#tickLabelRotation:Double=0.0 +javafx.scene.chart.Axis#tickLabelsVisible:Boolean=true +javafx.scene.chart.Axis#tickLength:Double=8.0 +javafx.scene.chart.Axis#tickMarkVisible:Boolean=true +javafx.scene.chart.Axis$TickMark#position:Double=0.0 +javafx.scene.chart.CategoryAxis#endMargin:Double=5.0 +javafx.scene.chart.CategoryAxis#gapStartAndEnd:Boolean=true +javafx.scene.chart.CategoryAxis#startMargin:Double=5.0 +javafx.scene.chart.Chart#animated:Boolean=true +javafx.scene.chart.Chart#legendSide:Enum=BOTTOM +javafx.scene.chart.Chart#legendVisible:Boolean=true +javafx.scene.chart.Chart#titleSide:Enum=TOP +javafx.scene.chart.NumberAxis#forceZeroInRange:Boolean=true +javafx.scene.chart.NumberAxis#tickUnit:Double=5.0 +javafx.scene.chart.PieChart#clockwise:Boolean=true +javafx.scene.chart.PieChart#labelLineLength:Double=20.0 +javafx.scene.chart.PieChart#labelsVisible:Boolean=true +javafx.scene.chart.PieChart#startAngle:Double=0.0 +javafx.scene.chart.ValueAxis#lowerBound:Double=0.0 +javafx.scene.chart.ValueAxis#minorTickCount:Integer=5 +javafx.scene.chart.ValueAxis#minorTickLength:Double=5.0 +javafx.scene.chart.ValueAxis#minorTickVisible:Boolean=true +javafx.scene.chart.ValueAxis#upperBound:Double=100.0 +javafx.scene.control.Button#cancelButton:Boolean=false +javafx.scene.control.Button#defaultButton:Boolean=false +javafx.scene.control.ButtonBar#buttonMinWidth:Double=85.0 +javafx.scene.control.Cell#editable:Boolean=true +javafx.scene.control.CheckBox#allowIndeterminate:Boolean=false +javafx.scene.control.CheckBox#indeterminate:Boolean=false +javafx.scene.control.CheckBox#selected:Boolean=false +javafx.scene.control.CheckBoxTreeItem#independent:Boolean=false +javafx.scene.control.CheckBoxTreeItem#indeterminate:Boolean=false +javafx.scene.control.CheckBoxTreeItem#selected:Boolean=false +javafx.scene.control.CheckMenuItem#selected:Boolean=false +javafx.scene.control.ComboBox#visibleRowCount:Integer=10 +javafx.scene.control.ComboBoxBase#promptText:String= +javafx.scene.control.ContextMenu#impl_showRelativeToWindow:Boolean=false +javafx.scene.control.DatePicker#showWeekNumbers:Boolean=false +javafx.scene.control.Dialog#headerText:String=Confirmation +javafx.scene.control.Dialog#resizable:Boolean=false +javafx.scene.control.Dialog#title:String=Confirmation +javafx.scene.control.DialogPane#expanded:Boolean=false +javafx.scene.control.Hyperlink#visited:Boolean=false +javafx.scene.control.Labeled#contentDisplay:Enum=LEFT +javafx.scene.control.Labeled#ellipsisString:String=... +javafx.scene.control.Labeled#graphicTextGap:Double=4.0 +javafx.scene.control.Labeled#lineSpacing:Double=0.0 +javafx.scene.control.Labeled#text:String= +javafx.scene.control.Labeled#textAlignment:Enum=LEFT +javafx.scene.control.Labeled#textOverrun:Enum=ELLIPSIS +javafx.scene.control.Labeled#underline:Boolean=false +javafx.scene.control.Labeled#wrapText:Boolean=false +javafx.scene.control.ListView#editable:Boolean=false +javafx.scene.control.ListView#fixedCellSize:Double=-1.0 +javafx.scene.control.ListView#orientation:Enum=VERTICAL +javafx.scene.control.MenuBar#useSystemMenuBar:Boolean=false +javafx.scene.control.MenuButton#popupSide:Enum=BOTTOM +javafx.scene.control.MenuItem#disable:Boolean=false +javafx.scene.control.MenuItem#mnemonicParsing:Boolean=true +javafx.scene.control.MenuItem#text:String= +javafx.scene.control.MenuItem#visible:Boolean=true +javafx.scene.control.Pagination#currentPageIndex:Integer=0 +javafx.scene.control.Pagination#maxPageIndicatorCount:Integer=10 +javafx.scene.control.Pagination#pageCount:Integer=2147483647 +javafx.scene.control.PopupControl#maxHeight:Double=-1.0 +javafx.scene.control.PopupControl#maxWidth:Double=-1.0 +javafx.scene.control.PopupControl#minHeight:Double=-1.0 +javafx.scene.control.PopupControl#minWidth:Double=-1.0 +javafx.scene.control.PopupControl#prefHeight:Double=-1.0 +javafx.scene.control.PopupControl#prefWidth:Double=-1.0 +javafx.scene.control.PopupControl#style:String= +javafx.scene.control.ProgressIndicator#progress:Double=-1.0 +javafx.scene.control.RadioMenuItem#selected:Boolean=false +javafx.scene.control.ScrollBar#blockIncrement:Double=10.0 +javafx.scene.control.ScrollBar#max:Double=100.0 +javafx.scene.control.ScrollBar#min:Double=0.0 +javafx.scene.control.ScrollBar#orientation:Enum=HORIZONTAL +javafx.scene.control.ScrollBar#unitIncrement:Double=1.0 +javafx.scene.control.ScrollBar#value:Double=0.0 +javafx.scene.control.ScrollBar#visibleAmount:Double=15.0 +javafx.scene.control.ScrollPane#fitToHeight:Boolean=false +javafx.scene.control.ScrollPane#fitToWidth:Boolean=false +javafx.scene.control.ScrollPane#hbarPolicy:Enum=AS_NEEDED +javafx.scene.control.ScrollPane#hmax:Double=1.0 +javafx.scene.control.ScrollPane#hmin:Double=0.0 +javafx.scene.control.ScrollPane#hvalue:Double=0.0 +javafx.scene.control.ScrollPane#minViewportHeight:Double=0.0 +javafx.scene.control.ScrollPane#minViewportWidth:Double=0.0 +javafx.scene.control.ScrollPane#pannable:Boolean=false +javafx.scene.control.ScrollPane#prefViewportHeight:Double=0.0 +javafx.scene.control.ScrollPane#prefViewportWidth:Double=0.0 +javafx.scene.control.ScrollPane#vbarPolicy:Enum=AS_NEEDED +javafx.scene.control.ScrollPane#vmax:Double=1.0 +javafx.scene.control.ScrollPane#vmin:Double=0.0 +javafx.scene.control.ScrollPane#vvalue:Double=0.0 +javafx.scene.control.Separator#halignment:Enum=CENTER +javafx.scene.control.Separator#orientation:Enum=HORIZONTAL +javafx.scene.control.Separator#valignment:Enum=CENTER +javafx.scene.control.Slider#blockIncrement:Double=10.0 +javafx.scene.control.Slider#majorTickUnit:Double=25.0 +javafx.scene.control.Slider#max:Double=100.0 +javafx.scene.control.Slider#min:Double=0.0 +javafx.scene.control.Slider#minorTickCount:Integer=3 +javafx.scene.control.Slider#orientation:Enum=HORIZONTAL +javafx.scene.control.Slider#showTickLabels:Boolean=false +javafx.scene.control.Slider#showTickMarks:Boolean=false +javafx.scene.control.Slider#snapToTicks:Boolean=false +javafx.scene.control.Slider#value:Double=0.0 +javafx.scene.control.Slider#valueChanging:Boolean=false +javafx.scene.control.Spinner#editable:Boolean=false +javafx.scene.control.SplitPane#orientation:Enum=HORIZONTAL +javafx.scene.control.SplitPane$Divider#position:Double=0.5 +javafx.scene.control.Tab#closable:Boolean=true +javafx.scene.control.Tab#disable:Boolean=false +javafx.scene.control.TabPane#rotateGraphic:Boolean=false +javafx.scene.control.TabPane#side:Enum=TOP +javafx.scene.control.TabPane#tabClosingPolicy:Enum=SELECTED_TAB +javafx.scene.control.TabPane#tabMaxHeight:Double=1.7976931348623157E308 +javafx.scene.control.TabPane#tabMaxWidth:Double=1.7976931348623157E308 +javafx.scene.control.TabPane#tabMinHeight:Double=0.0 +javafx.scene.control.TabPane#tabMinWidth:Double=0.0 +javafx.scene.control.TableColumn#sortType:Enum=ASCENDING +javafx.scene.control.TableColumnBase#editable:Boolean=true +javafx.scene.control.TableColumnBase#maxWidth:Double=5000.0 +javafx.scene.control.TableColumnBase#minWidth:Double=10.0 +javafx.scene.control.TableColumnBase#prefWidth:Double=80.0 +javafx.scene.control.TableColumnBase#resizable:Boolean=true +javafx.scene.control.TableColumnBase#sortable:Boolean=true +javafx.scene.control.TableColumnBase#style:String= +javafx.scene.control.TableColumnBase#text:String= +javafx.scene.control.TableColumnBase#visible:Boolean=true +javafx.scene.control.TableView#editable:Boolean=false +javafx.scene.control.TableView#fixedCellSize:Double=-1.0 +javafx.scene.control.TableView#tableMenuButtonVisible:Boolean=false +javafx.scene.control.TextArea#prefColumnCount:Integer=40 +javafx.scene.control.TextArea#prefRowCount:Integer=10 +javafx.scene.control.TextArea#scrollLeft:Double=0.0 +javafx.scene.control.TextArea#scrollTop:Double=0.0 +javafx.scene.control.TextArea#wrapText:Boolean=false +javafx.scene.control.TextField#alignment:Enum=CENTER_LEFT +javafx.scene.control.TextField#prefColumnCount:Integer=12 +javafx.scene.control.TextInputControl#editable:Boolean=true +javafx.scene.control.TextInputControl#promptText:String= +javafx.scene.control.TextInputControl#text:String= +javafx.scene.control.TitledPane#animated:Boolean=true +javafx.scene.control.TitledPane#collapsible:Boolean=true +javafx.scene.control.TitledPane#expanded:Boolean=true +javafx.scene.control.ToggleButton#selected:Boolean=false +javafx.scene.control.ToolBar#orientation:Enum=HORIZONTAL +javafx.scene.control.Tooltip#contentDisplay:Enum=LEFT +javafx.scene.control.Tooltip#graphicTextGap:Double=4.0 +javafx.scene.control.Tooltip#text:String= +javafx.scene.control.Tooltip#textAlignment:Enum=LEFT +javafx.scene.control.Tooltip#textOverrun:Enum=ELLIPSIS +javafx.scene.control.Tooltip#wrapText:Boolean=false +javafx.scene.control.TreeItem#expanded:Boolean=false +javafx.scene.control.TreeTableColumn#sortType:Enum=ASCENDING +javafx.scene.control.TreeTableView#editable:Boolean=false +javafx.scene.control.TreeTableView#fixedCellSize:Double=-1.0 +javafx.scene.control.TreeTableView#showRoot:Boolean=true +javafx.scene.control.TreeTableView#sortMode:Enum=ALL_DESCENDANTS +javafx.scene.control.TreeTableView#tableMenuButtonVisible:Boolean=false +javafx.scene.control.TreeView#editable:Boolean=false +javafx.scene.control.TreeView#fixedCellSize:Double=-1.0 +javafx.scene.control.TreeView#showRoot:Boolean=true +javafx.scene.control.cell.ComboBoxListCell#comboBoxEditable:Boolean=false +javafx.scene.control.cell.ComboBoxTableCell#comboBoxEditable:Boolean=false +javafx.scene.control.cell.ComboBoxTreeCell#comboBoxEditable:Boolean=false +javafx.scene.control.cell.ComboBoxTreeTableCell#comboBoxEditable:Boolean=false +javafx.scene.effect.Blend#mode:Enum=SRC_OVER +javafx.scene.effect.Blend#opacity:Double=1.0 +javafx.scene.effect.Bloom#threshold:Double=0.3 +javafx.scene.effect.BoxBlur#height:Double=5.0 +javafx.scene.effect.BoxBlur#iterations:Integer=1 +javafx.scene.effect.BoxBlur#width:Double=5.0 +javafx.scene.effect.ColorAdjust#brightness:Double=0.0 +javafx.scene.effect.ColorAdjust#contrast:Double=0.0 +javafx.scene.effect.ColorAdjust#hue:Double=0.0 +javafx.scene.effect.ColorAdjust#saturation:Double=0.0 +javafx.scene.effect.ColorInput#height:Double=0.0 +javafx.scene.effect.ColorInput#width:Double=0.0 +javafx.scene.effect.ColorInput#x:Double=0.0 +javafx.scene.effect.ColorInput#y:Double=0.0 +javafx.scene.effect.DisplacementMap#offsetX:Double=0.0 +javafx.scene.effect.DisplacementMap#offsetY:Double=0.0 +javafx.scene.effect.DisplacementMap#scaleX:Double=1.0 +javafx.scene.effect.DisplacementMap#scaleY:Double=1.0 +javafx.scene.effect.DisplacementMap#wrap:Boolean=false +javafx.scene.effect.DropShadow#blurType:Enum=THREE_PASS_BOX +javafx.scene.effect.DropShadow#height:Double=21.0 +javafx.scene.effect.DropShadow#offsetX:Double=0.0 +javafx.scene.effect.DropShadow#offsetY:Double=0.0 +javafx.scene.effect.DropShadow#radius:Double=10.0 +javafx.scene.effect.DropShadow#spread:Double=0.0 +javafx.scene.effect.DropShadow#width:Double=21.0 +javafx.scene.effect.FloatMap#height:Integer=1 +javafx.scene.effect.FloatMap#width:Integer=1 +javafx.scene.effect.GaussianBlur#radius:Double=10.0 +javafx.scene.effect.Glow#level:Double=0.3 +javafx.scene.effect.ImageInput#x:Double=0.0 +javafx.scene.effect.ImageInput#y:Double=0.0 +javafx.scene.effect.InnerShadow#blurType:Enum=THREE_PASS_BOX +javafx.scene.effect.InnerShadow#choke:Double=0.0 +javafx.scene.effect.InnerShadow#height:Double=21.0 +javafx.scene.effect.InnerShadow#offsetX:Double=0.0 +javafx.scene.effect.InnerShadow#offsetY:Double=0.0 +javafx.scene.effect.InnerShadow#radius:Double=10.0 +javafx.scene.effect.InnerShadow#width:Double=21.0 +javafx.scene.effect.Light$Distant#azimuth:Double=45.0 +javafx.scene.effect.Light$Distant#elevation:Double=45.0 +javafx.scene.effect.Light$Point#x:Double=0.0 +javafx.scene.effect.Light$Point#y:Double=0.0 +javafx.scene.effect.Light$Point#z:Double=0.0 +javafx.scene.effect.Light$Spot#pointsAtX:Double=0.0 +javafx.scene.effect.Light$Spot#pointsAtY:Double=0.0 +javafx.scene.effect.Light$Spot#pointsAtZ:Double=0.0 +javafx.scene.effect.Light$Spot#specularExponent:Double=1.0 +javafx.scene.effect.Lighting#diffuseConstant:Double=1.0 +javafx.scene.effect.Lighting#specularConstant:Double=0.3 +javafx.scene.effect.Lighting#specularExponent:Double=20.0 +javafx.scene.effect.Lighting#surfaceScale:Double=1.5 +javafx.scene.effect.MotionBlur#angle:Double=0.0 +javafx.scene.effect.MotionBlur#radius:Double=10.0 +javafx.scene.effect.PerspectiveTransform#llx:Double=0.0 +javafx.scene.effect.PerspectiveTransform#lly:Double=0.0 +javafx.scene.effect.PerspectiveTransform#lrx:Double=0.0 +javafx.scene.effect.PerspectiveTransform#lry:Double=0.0 +javafx.scene.effect.PerspectiveTransform#ulx:Double=0.0 +javafx.scene.effect.PerspectiveTransform#uly:Double=0.0 +javafx.scene.effect.PerspectiveTransform#urx:Double=0.0 +javafx.scene.effect.PerspectiveTransform#ury:Double=0.0 +javafx.scene.effect.Reflection#bottomOpacity:Double=0.0 +javafx.scene.effect.Reflection#fraction:Double=0.75 +javafx.scene.effect.Reflection#topOffset:Double=0.0 +javafx.scene.effect.Reflection#topOpacity:Double=0.5 +javafx.scene.effect.SepiaTone#level:Double=1.0 +javafx.scene.effect.Shadow#blurType:Enum=THREE_PASS_BOX +javafx.scene.effect.Shadow#height:Double=21.0 +javafx.scene.effect.Shadow#radius:Double=10.0 +javafx.scene.effect.Shadow#width:Double=21.0 +javafx.scene.image.ImageView#fitHeight:Double=0.0 +javafx.scene.image.ImageView#fitWidth:Double=0.0 +javafx.scene.image.ImageView#preserveRatio:Boolean=false +javafx.scene.image.ImageView#smooth:Boolean=true +javafx.scene.image.ImageView#x:Double=0.0 +javafx.scene.image.ImageView#y:Double=0.0 +javafx.scene.layout.ColumnConstraints#fillWidth:Boolean=true +javafx.scene.layout.ColumnConstraints#maxWidth:Double=-1.0 +javafx.scene.layout.ColumnConstraints#minWidth:Double=-1.0 +javafx.scene.layout.ColumnConstraints#percentWidth:Double=-1.0 +javafx.scene.layout.ColumnConstraints#prefWidth:Double=-1.0 +javafx.scene.layout.FlowPane#alignment:Enum=TOP_LEFT +javafx.scene.layout.FlowPane#columnHalignment:Enum=LEFT +javafx.scene.layout.FlowPane#hgap:Double=0.0 +javafx.scene.layout.FlowPane#orientation:Enum=HORIZONTAL +javafx.scene.layout.FlowPane#prefWrapLength:Double=400.0 +javafx.scene.layout.FlowPane#rowValignment:Enum=CENTER +javafx.scene.layout.FlowPane#vgap:Double=0.0 +javafx.scene.layout.GridPane#alignment:Enum=TOP_LEFT +javafx.scene.layout.GridPane#gridLinesVisible:Boolean=false +javafx.scene.layout.GridPane#hgap:Double=0.0 +javafx.scene.layout.GridPane#vgap:Double=0.0 +javafx.scene.layout.HBox#alignment:Enum=TOP_LEFT +javafx.scene.layout.HBox#fillHeight:Boolean=true +javafx.scene.layout.HBox#spacing:Double=0.0 +javafx.scene.layout.Region#cacheShape:Boolean=true +javafx.scene.layout.Region#centerShape:Boolean=true +javafx.scene.layout.Region#maxHeight:Double=-1.0 +javafx.scene.layout.Region#maxWidth:Double=-1.0 +javafx.scene.layout.Region#minHeight:Double=-1.0 +javafx.scene.layout.Region#minWidth:Double=-1.0 +javafx.scene.layout.Region#prefHeight:Double=-1.0 +javafx.scene.layout.Region#prefWidth:Double=-1.0 +javafx.scene.layout.Region#scaleShape:Boolean=true +javafx.scene.layout.Region#snapToPixel:Boolean=true +javafx.scene.layout.RowConstraints#fillHeight:Boolean=true +javafx.scene.layout.RowConstraints#maxHeight:Double=-1.0 +javafx.scene.layout.RowConstraints#minHeight:Double=-1.0 +javafx.scene.layout.RowConstraints#percentHeight:Double=-1.0 +javafx.scene.layout.RowConstraints#prefHeight:Double=-1.0 +javafx.scene.layout.StackPane#alignment:Enum=CENTER +javafx.scene.layout.TilePane#alignment:Enum=TOP_LEFT +javafx.scene.layout.TilePane#hgap:Double=0.0 +javafx.scene.layout.TilePane#orientation:Enum=HORIZONTAL +javafx.scene.layout.TilePane#prefColumns:Integer=5 +javafx.scene.layout.TilePane#prefRows:Integer=5 +javafx.scene.layout.TilePane#prefTileHeight:Double=-1.0 +javafx.scene.layout.TilePane#prefTileWidth:Double=-1.0 +javafx.scene.layout.TilePane#tileAlignment:Enum=CENTER +javafx.scene.layout.TilePane#vgap:Double=0.0 +javafx.scene.layout.VBox#alignment:Enum=TOP_LEFT +javafx.scene.layout.VBox#fillWidth:Boolean=true +javafx.scene.layout.VBox#spacing:Double=0.0 +javafx.scene.media.EqualizerBand#bandwidth:Double=0.0 +javafx.scene.media.EqualizerBand#centerFrequency:Double=0.0 +javafx.scene.media.EqualizerBand#gain:Double=0.0 +javafx.scene.media.MediaView#fitHeight:Double=0.0 +javafx.scene.media.MediaView#fitWidth:Double=0.0 +javafx.scene.media.MediaView#preserveRatio:Boolean=true +javafx.scene.media.MediaView#smooth:Boolean=true +javafx.scene.media.MediaView#x:Double=0.0 +javafx.scene.media.MediaView#y:Double=0.0 +javafx.scene.paint.PhongMaterial#specularPower:Double=32.0 +javafx.scene.shape.Arc#centerX:Double=0.0 +javafx.scene.shape.Arc#centerY:Double=0.0 +javafx.scene.shape.Arc#length:Double=0.0 +javafx.scene.shape.Arc#radiusX:Double=0.0 +javafx.scene.shape.Arc#radiusY:Double=0.0 +javafx.scene.shape.Arc#startAngle:Double=0.0 +javafx.scene.shape.Arc#type:Enum=OPEN +javafx.scene.shape.ArcTo#XAxisRotation:Double=0.0 +javafx.scene.shape.ArcTo#largeArcFlag:Boolean=false +javafx.scene.shape.ArcTo#radiusX:Double=0.0 +javafx.scene.shape.ArcTo#radiusY:Double=0.0 +javafx.scene.shape.ArcTo#sweepFlag:Boolean=false +javafx.scene.shape.ArcTo#x:Double=0.0 +javafx.scene.shape.ArcTo#y:Double=0.0 +javafx.scene.shape.Box#depth:Double=2.0 +javafx.scene.shape.Box#height:Double=2.0 +javafx.scene.shape.Box#width:Double=2.0 +javafx.scene.shape.Circle#centerX:Double=0.0 +javafx.scene.shape.Circle#centerY:Double=0.0 +javafx.scene.shape.Circle#radius:Double=0.0 +javafx.scene.shape.CubicCurve#controlX1:Double=0.0 +javafx.scene.shape.CubicCurve#controlX2:Double=0.0 +javafx.scene.shape.CubicCurve#controlY1:Double=0.0 +javafx.scene.shape.CubicCurve#controlY2:Double=0.0 +javafx.scene.shape.CubicCurve#endX:Double=0.0 +javafx.scene.shape.CubicCurve#endY:Double=0.0 +javafx.scene.shape.CubicCurve#startX:Double=0.0 +javafx.scene.shape.CubicCurve#startY:Double=0.0 +javafx.scene.shape.CubicCurveTo#controlX1:Double=0.0 +javafx.scene.shape.CubicCurveTo#controlX2:Double=0.0 +javafx.scene.shape.CubicCurveTo#controlY1:Double=0.0 +javafx.scene.shape.CubicCurveTo#controlY2:Double=0.0 +javafx.scene.shape.CubicCurveTo#x:Double=0.0 +javafx.scene.shape.CubicCurveTo#y:Double=0.0 +javafx.scene.shape.Cylinder#height:Double=2.0 +javafx.scene.shape.Cylinder#radius:Double=1.0 +javafx.scene.shape.Ellipse#centerX:Double=0.0 +javafx.scene.shape.Ellipse#centerY:Double=0.0 +javafx.scene.shape.Ellipse#radiusX:Double=0.0 +javafx.scene.shape.Ellipse#radiusY:Double=0.0 +javafx.scene.shape.HLineTo#x:Double=0.0 +javafx.scene.shape.Line#endX:Double=0.0 +javafx.scene.shape.Line#endY:Double=0.0 +javafx.scene.shape.Line#startX:Double=0.0 +javafx.scene.shape.Line#startY:Double=0.0 +javafx.scene.shape.LineTo#x:Double=0.0 +javafx.scene.shape.LineTo#y:Double=0.0 +javafx.scene.shape.MoveTo#x:Double=0.0 +javafx.scene.shape.MoveTo#y:Double=0.0 +javafx.scene.shape.Path#fillRule:Enum=NON_ZERO +javafx.scene.shape.PathElement#absolute:Boolean=true +javafx.scene.shape.QuadCurve#controlX:Double=0.0 +javafx.scene.shape.QuadCurve#controlY:Double=0.0 +javafx.scene.shape.QuadCurve#endX:Double=0.0 +javafx.scene.shape.QuadCurve#endY:Double=0.0 +javafx.scene.shape.QuadCurve#startX:Double=0.0 +javafx.scene.shape.QuadCurve#startY:Double=0.0 +javafx.scene.shape.QuadCurveTo#controlX:Double=0.0 +javafx.scene.shape.QuadCurveTo#controlY:Double=0.0 +javafx.scene.shape.QuadCurveTo#x:Double=0.0 +javafx.scene.shape.QuadCurveTo#y:Double=0.0 +javafx.scene.shape.Rectangle#arcHeight:Double=0.0 +javafx.scene.shape.Rectangle#arcWidth:Double=0.0 +javafx.scene.shape.Rectangle#height:Double=0.0 +javafx.scene.shape.Rectangle#width:Double=0.0 +javafx.scene.shape.Rectangle#x:Double=0.0 +javafx.scene.shape.Rectangle#y:Double=0.0 +javafx.scene.shape.SVGPath#content:String= +javafx.scene.shape.SVGPath#fillRule:Enum=NON_ZERO +javafx.scene.shape.Shape#smooth:Boolean=true +javafx.scene.shape.Shape#strokeDashOffset:Double=0.0 +javafx.scene.shape.Shape#strokeLineCap:Enum=SQUARE +javafx.scene.shape.Shape#strokeLineJoin:Enum=MITER +javafx.scene.shape.Shape#strokeMiterLimit:Double=10.0 +javafx.scene.shape.Shape#strokeType:Enum=CENTERED +javafx.scene.shape.Shape#strokeWidth:Double=1.0 +javafx.scene.shape.Shape3D#cullFace:Enum=BACK +javafx.scene.shape.Shape3D#drawMode:Enum=FILL +javafx.scene.shape.Sphere#radius:Double=1.0 +javafx.scene.shape.VLineTo#y:Double=0.0 +javafx.scene.text.Text#boundsType:Enum=LOGICAL +javafx.scene.text.Text#fontSmoothingType:Enum=GRAY +javafx.scene.text.Text#impl_caretBias:Boolean=true +javafx.scene.text.Text#impl_caretPosition:Integer=-1 +javafx.scene.text.Text#impl_selectionEnd:Integer=-1 +javafx.scene.text.Text#impl_selectionStart:Integer=-1 +javafx.scene.text.Text#lineSpacing:Double=0.0 +javafx.scene.text.Text#strikethrough:Boolean=false +javafx.scene.text.Text#text:String= +javafx.scene.text.Text#textAlignment:Enum=LEFT +javafx.scene.text.Text#textOrigin:Enum=BASELINE +javafx.scene.text.Text#underline:Boolean=false +javafx.scene.text.Text#wrappingWidth:Double=0.0 +javafx.scene.text.Text#x:Double=0.0 +javafx.scene.text.Text#y:Double=0.0 +javafx.scene.text.TextFlow#lineSpacing:Double=0.0 +javafx.scene.text.TextFlow#textAlignment:Enum=LEFT +javafx.scene.transform.Affine#mxx:Double=1.0 +javafx.scene.transform.Affine#mxy:Double=0.0 +javafx.scene.transform.Affine#mxz:Double=0.0 +javafx.scene.transform.Affine#myx:Double=0.0 +javafx.scene.transform.Affine#myy:Double=1.0 +javafx.scene.transform.Affine#myz:Double=0.0 +javafx.scene.transform.Affine#mzx:Double=0.0 +javafx.scene.transform.Affine#mzy:Double=0.0 +javafx.scene.transform.Affine#mzz:Double=1.0 +javafx.scene.transform.Affine#tx:Double=0.0 +javafx.scene.transform.Affine#ty:Double=0.0 +javafx.scene.transform.Affine#tz:Double=0.0 +javafx.scene.transform.Rotate#angle:Double=0.0 +javafx.scene.transform.Rotate#pivotX:Double=0.0 +javafx.scene.transform.Rotate#pivotY:Double=0.0 +javafx.scene.transform.Rotate#pivotZ:Double=0.0 +javafx.scene.transform.Scale#pivotX:Double=0.0 +javafx.scene.transform.Scale#pivotY:Double=0.0 +javafx.scene.transform.Scale#pivotZ:Double=0.0 +javafx.scene.transform.Scale#x:Double=1.0 +javafx.scene.transform.Scale#y:Double=1.0 +javafx.scene.transform.Scale#z:Double=1.0 +javafx.scene.transform.Shear#pivotX:Double=0.0 +javafx.scene.transform.Shear#pivotY:Double=0.0 +javafx.scene.transform.Shear#x:Double=0.0 +javafx.scene.transform.Shear#y:Double=0.0 +javafx.scene.transform.Translate#x:Double=0.0 +javafx.scene.transform.Translate#y:Double=0.0 +javafx.scene.transform.Translate#z:Double=0.0 +javafx.scene.web.WebEngine#javaScriptEnabled:Boolean=true +javafx.scene.web.WebView#contextMenuEnabled:Boolean=true +javafx.scene.web.WebView#fontScale:Double=1.0 +javafx.scene.web.WebView#fontSmoothingType:Enum=LCD +javafx.scene.web.WebView#maxHeight:Double=1.7976931348623157E308 +javafx.scene.web.WebView#maxWidth:Double=1.7976931348623157E308 +javafx.scene.web.WebView#minHeight:Double=0.0 +javafx.scene.web.WebView#minWidth:Double=0.0 +javafx.scene.web.WebView#prefHeight:Double=600.0 +javafx.scene.web.WebView#prefWidth:Double=800.0 +javafx.scene.web.WebView#zoom:Double=1.0 +javafx.stage.PopupWindow#autoFix:Boolean=true +javafx.stage.PopupWindow#hideOnEscape:Boolean=true +javafx.stage.Stage#maxHeight:Double=1.7976931348623157E308 +javafx.stage.Stage#maxWidth:Double=1.7976931348623157E308 +javafx.stage.Stage#minHeight:Double=0.0 +javafx.stage.Stage#minWidth:Double=0.0 +javafx.stage.Stage#resizable:Boolean=true +javafx.stage.Window#opacity:Double=1.0 +-------- Overridden in subclass --------- +javafx.embed.swing.SwingNode#focusTraversable:Boolean=true +javafx.scene.Group#accessibleRole:Enum=PARENT +javafx.scene.canvas.Canvas#nodeOrientation:Enum=LEFT_TO_RIGHT +javafx.scene.control.Button#accessibleRole:Enum=BUTTON +javafx.scene.control.Button#focusTraversable:Boolean=true +javafx.scene.control.Button#mnemonicParsing:Boolean=true +javafx.scene.control.CheckBox#accessibleRole:Enum=CHECK_BOX +javafx.scene.control.CheckBox#focusTraversable:Boolean=true +javafx.scene.control.CheckBox#mnemonicParsing:Boolean=true +javafx.scene.control.ChoiceBox#accessibleRole:Enum=COMBO_BOX +javafx.scene.control.ChoiceBox#focusTraversable:Boolean=true +javafx.scene.control.ColorPicker#focusTraversable:Boolean=true +javafx.scene.control.ComboBox#accessibleRole:Enum=COMBO_BOX +javafx.scene.control.ComboBox#focusTraversable:Boolean=true +javafx.scene.control.ContextMenu#autoHide:Boolean=true +javafx.scene.control.ContextMenu#consumeAutoHidingEvents:Boolean=false +javafx.scene.control.DatePicker#accessibleRole:Enum=DATE_PICKER +javafx.scene.control.DatePicker#editable:Boolean=true +javafx.scene.control.DatePicker#focusTraversable:Boolean=true +javafx.scene.control.Hyperlink#accessibleRole:Enum=HYPERLINK +javafx.scene.control.Hyperlink#focusTraversable:Boolean=true +javafx.scene.control.Label#accessibleRole:Enum=TEXT +javafx.scene.control.ListCell#accessibleRole:Enum=LIST_ITEM +javafx.scene.control.ListView#accessibleRole:Enum=LIST_VIEW +javafx.scene.control.ListView#focusTraversable:Boolean=true +javafx.scene.control.MenuBar#accessibleRole:Enum=MENU_BAR +javafx.scene.control.MenuButton#accessibleRole:Enum=MENU_BUTTON +javafx.scene.control.MenuButton#focusTraversable:Boolean=true +javafx.scene.control.MenuButton#mnemonicParsing:Boolean=true +javafx.scene.control.Pagination#accessibleRole:Enum=PAGINATION +javafx.scene.control.Pagination#focusTraversable:Boolean=true +javafx.scene.control.PasswordField#accessibleRole:Enum=PASSWORD_FIELD +javafx.scene.control.PopupControl#anchorLocation:Enum=CONTENT_TOP_LEFT +javafx.scene.control.ProgressIndicator#accessibleRole:Enum=PROGRESS_INDICATOR +javafx.scene.control.RadioButton#accessibleRole:Enum=RADIO_BUTTON +javafx.scene.control.RadioButton#alignment:Enum=CENTER_LEFT +javafx.scene.control.ScrollBar#accessibleRole:Enum=SCROLL_BAR +javafx.scene.control.ScrollPane#accessibleRole:Enum=SCROLL_PANE +javafx.scene.control.SeparatorMenuItem#hideOnClick:Boolean=false +javafx.scene.control.Slider#accessibleRole:Enum=SLIDER +javafx.scene.control.Slider#focusTraversable:Boolean=true +javafx.scene.control.Spinner#accessibleRole:Enum=SPINNER +javafx.scene.control.Spinner#focusTraversable:Boolean=true +javafx.scene.control.SplitMenuButton#accessibleRole:Enum=SPLIT_MENU_BUTTON +javafx.scene.control.TabPane#accessibleRole:Enum=TAB_PANE +javafx.scene.control.TabPane#focusTraversable:Boolean=true +javafx.scene.control.TableCell#accessibleRole:Enum=TABLE_CELL +javafx.scene.control.TableRow#accessibleRole:Enum=TABLE_ROW +javafx.scene.control.TableView#accessibleRole:Enum=TABLE_VIEW +javafx.scene.control.TableView#focusTraversable:Boolean=true +javafx.scene.control.TextArea#accessibleRole:Enum=TEXT_AREA +javafx.scene.control.TextArea#focusTraversable:Boolean=true +javafx.scene.control.TextField#accessibleRole:Enum=TEXT_FIELD +javafx.scene.control.TextField#focusTraversable:Boolean=true +javafx.scene.control.TitledPane#accessibleRole:Enum=TITLED_PANE +javafx.scene.control.TitledPane#focusTraversable:Boolean=true +javafx.scene.control.ToggleButton#accessibleRole:Enum=TOGGLE_BUTTON +javafx.scene.control.ToggleButton#alignment:Enum=CENTER +javafx.scene.control.ToggleButton#focusTraversable:Boolean=true +javafx.scene.control.ToggleButton#mnemonicParsing:Boolean=true +javafx.scene.control.ToolBar#accessibleRole:Enum=TOOL_BAR +javafx.scene.control.TreeCell#accessibleRole:Enum=TREE_ITEM +javafx.scene.control.TreeTableCell#accessibleRole:Enum=TREE_TABLE_CELL +javafx.scene.control.TreeTableRow#accessibleRole:Enum=TREE_TABLE_ROW +javafx.scene.control.TreeTableView#accessibleRole:Enum=TREE_TABLE_VIEW +javafx.scene.control.TreeTableView#focusTraversable:Boolean=true +javafx.scene.control.TreeView#accessibleRole:Enum=TREE_VIEW +javafx.scene.control.TreeView#focusTraversable:Boolean=true +javafx.scene.control.cell.CheckBoxTreeCell#accessibleRole:Enum=TREE_ITEM +javafx.scene.control.cell.CheckBoxTreeCell#alignment:Enum=CENTER_LEFT +javafx.scene.control.cell.CheckBoxTreeCell#focusTraversable:Boolean=false +javafx.scene.control.cell.CheckBoxTreeCell#mnemonicParsing:Boolean=false +javafx.scene.control.cell.CheckBoxTreeCell#nodeOrientation:Enum=INHERIT +javafx.scene.control.cell.CheckBoxTreeCell#pickOnBounds:Boolean=true +javafx.scene.control.cell.ChoiceBoxTreeCell#accessibleRole:Enum=TREE_ITEM +javafx.scene.control.cell.ChoiceBoxTreeCell#alignment:Enum=CENTER_LEFT +javafx.scene.control.cell.ChoiceBoxTreeCell#focusTraversable:Boolean=false +javafx.scene.control.cell.ChoiceBoxTreeCell#mnemonicParsing:Boolean=false +javafx.scene.control.cell.ChoiceBoxTreeCell#nodeOrientation:Enum=INHERIT +javafx.scene.control.cell.ChoiceBoxTreeCell#pickOnBounds:Boolean=true +javafx.scene.control.cell.ComboBoxTreeCell#accessibleRole:Enum=TREE_ITEM +javafx.scene.control.cell.ComboBoxTreeCell#alignment:Enum=CENTER_LEFT +javafx.scene.control.cell.ComboBoxTreeCell#focusTraversable:Boolean=false +javafx.scene.control.cell.ComboBoxTreeCell#mnemonicParsing:Boolean=false +javafx.scene.control.cell.ComboBoxTreeCell#nodeOrientation:Enum=INHERIT +javafx.scene.control.cell.ComboBoxTreeCell#pickOnBounds:Boolean=true +javafx.scene.control.cell.TextFieldTreeCell#accessibleRole:Enum=TREE_ITEM +javafx.scene.control.cell.TextFieldTreeCell#alignment:Enum=CENTER_LEFT +javafx.scene.control.cell.TextFieldTreeCell#focusTraversable:Boolean=false +javafx.scene.control.cell.TextFieldTreeCell#mnemonicParsing:Boolean=false +javafx.scene.control.cell.TextFieldTreeCell#nodeOrientation:Enum=INHERIT +javafx.scene.control.cell.TextFieldTreeCell#pickOnBounds:Boolean=true +javafx.scene.image.ImageView#accessibleRole:Enum=IMAGE_VIEW +javafx.scene.image.ImageView#nodeOrientation:Enum=LEFT_TO_RIGHT +javafx.scene.layout.Region#accessibleRole:Enum=PARENT +javafx.scene.layout.Region#pickOnBounds:Boolean=true +javafx.scene.media.MediaView#nodeOrientation:Enum=LEFT_TO_RIGHT +javafx.scene.text.Text#accessibleRole:Enum=TEXT +javafx.scene.text.Text#pickOnBounds:Boolean=true +javafx.scene.text.TextFlow#accessibleRole:Enum=TEXT +javafx.scene.web.HTMLEditor#focusTraversable:Boolean=true +javafx.scene.web.WebView#accessibleRole:Enum=PARENT +javafx.scene.web.WebView#focusTraversable:Boolean=true +javafx.scene.web.WebView#nodeOrientation:Enum=LEFT_TO_RIGHT +-------- Overridden properties' values --------- +-- javafx.scene.Node#accessibleRole[BUTTON, CHECK_BOX, COMBO_BOX, DATE_PICKER, HYPERLINK, IMAGE_VIEW, LIST_ITEM, LIST_VIEW, MENU_BAR, MENU_BUTTON, NODE, PAGINATION, PARENT, PASSWORD_FIELD, PROGRESS_INDICATOR, RADIO_BUTTON, SCROLL_BAR, SCROLL_PANE, SLIDER, SPINNER, SPLIT_MENU_BUTTON, TABLE_CELL, TABLE_ROW, TABLE_VIEW, TAB_PANE, TEXT, TEXT_AREA, TEXT_FIELD, TITLED_PANE, TOGGLE_BUTTON, TOOL_BAR, TREE_ITEM, TREE_TABLE_CELL, TREE_TABLE_ROW, TREE_TABLE_VIEW, TREE_VIEW] +-- javafx.scene.Node#focusTraversable[false, true] +-- javafx.scene.Node#nodeOrientation[INHERIT, LEFT_TO_RIGHT] +-- javafx.scene.Node#pickOnBounds[false, true] +-- javafx.scene.control.ComboBoxBase#editable[false, true] +-- javafx.scene.control.CustomMenuItem#hideOnClick[false, true] +-- javafx.scene.control.Labeled#alignment[CENTER, CENTER_LEFT] +-- javafx.scene.control.Labeled#mnemonicParsing[false, true] +-- javafx.stage.PopupWindow#anchorLocation[CONTENT_TOP_LEFT, WINDOW_TOP_LEFT] +-- javafx.stage.PopupWindow#autoHide[false, true] +-- javafx.stage.PopupWindow#consumeAutoHidingEvents[false, true] +-------- Skipped properties --------- +-- javafx.scene.web.WebEngine#userAgent +-- javafx.scene.web.HTMLEditor#htmlText +-- javafx.scene.control.ButtonBar#buttonOrder diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/RemoveTagFix.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/RemoveTagFix.java new file mode 100644 index 000000000000..0e97afd08bc7 --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/RemoveTagFix.java @@ -0,0 +1,61 @@ +package org.jetbrains.plugins.javaFX.fxml.codeInsight.inspections; + +import com.intellij.codeInsight.FileModificationService; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlTag; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory; + +/** + * @author Pavel.Dolgov + */ +public class RemoveTagFix implements LocalQuickFix { + private static final Logger LOG = Logger.getInstance("#" + RemoveTagFix.class.getName()); + + private final String myTagName; + + public RemoveTagFix(String name) { + myTagName = name; + } + + @Nls + @NotNull + @Override + public String getName() { + return "Remove tag '" + myTagName + "'"; + } + + @Nls + @NotNull + @Override + public String getFamilyName() { + return "Remove tag"; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (element != null) { + final PsiFile containingFile = element.getContainingFile(); + LOG.assertTrue(containingFile != null && JavaFxFileTypeFactory.isFxml(containingFile), + containingFile == null ? "no containing file found" : "containing file: " + containingFile.getName()); + final XmlTag xmlTag = PsiTreeUtil.getParentOfType(element, XmlTag.class, false); + if (xmlTag != null) { + final XmlTag parentTag = xmlTag.getParentTag(); + if (!FileModificationService.getInstance().preparePsiElementsForWrite(element)) return; + xmlTag.delete(); + if (parentTag != null) { + CodeStyleManager.getInstance(project).reformat(parentTag); + } + } + } + } +} diff --git a/plugins/javaFX/testData/inspections/redundantValue/attributeHighlighting.fxml b/plugins/javaFX/testData/inspections/redundantValue/attributeHighlighting.fxml new file mode 100644 index 000000000000..0b1bc41452ad --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/attributeHighlighting.fxml @@ -0,0 +1,11 @@ + + +maxHeight="-1" + maxWidth="500" + vgap="0" + hgap="1" + cache="false" + opacity="0.99"> + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/immediateAttribute.fxml b/plugins/javaFX/testData/inspections/redundantValue/immediateAttribute.fxml new file mode 100644 index 000000000000..d0590a9eb58c --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/immediateAttribute.fxml @@ -0,0 +1,8 @@ + +ent="TOP_LEFT" + prefHeight="400.0" + prefWidth="600.0"> + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/immediateAttribute_after.fxml b/plugins/javaFX/testData/inspections/redundantValue/immediateAttribute_after.fxml new file mode 100644 index 000000000000..d2064eb21f78 --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/immediateAttribute_after.fxml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/immediateTag.fxml b/plugins/javaFX/testData/inspections/redundantValue/immediateTag.fxml new file mode 100644 index 000000000000..05fce217fa21 --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/immediateTag.fxml @@ -0,0 +1,12 @@ + + + + ent>TOP_LEFT + + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/immediateTag_after.fxml b/plugins/javaFX/testData/inspections/redundantValue/immediateTag_after.fxml new file mode 100644 index 000000000000..da5fe05a55bc --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/immediateTag_after.fxml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/inheritedAttribute.fxml b/plugins/javaFX/testData/inspections/redundantValue/inheritedAttribute.fxml new file mode 100644 index 000000000000..6f07a3d0b651 --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/inheritedAttribute.fxml @@ -0,0 +1,9 @@ + + +ght="-1" + minHeight="-Infinity" + alignment="TOP_LEFT" + prefHeight="400.0" + prefWidth="600.0"> + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/inheritedAttribute_after.fxml b/plugins/javaFX/testData/inspections/redundantValue/inheritedAttribute_after.fxml new file mode 100644 index 000000000000..39056fe8dabf --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/inheritedAttribute_after.fxml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/inheritedTag.fxml b/plugins/javaFX/testData/inspections/redundantValue/inheritedTag.fxml new file mode 100644 index 000000000000..353c3a6adf33 --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/inheritedTag.fxml @@ -0,0 +1,15 @@ + + + 1 + 0 + + 100 + + + -1 + + 500 + ight>-1 + 0.99 + false + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/inheritedTag_after.fxml b/plugins/javaFX/testData/inspections/redundantValue/inheritedTag_after.fxml new file mode 100644 index 000000000000..5502aa35c848 --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/inheritedTag_after.fxml @@ -0,0 +1,14 @@ + + + 1 + 0 + + 100 + + + -1 + + 500 + 0.99 + false + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/modifiedAttribute.fxml b/plugins/javaFX/testData/inspections/redundantValue/modifiedAttribute.fxml new file mode 100644 index 000000000000..e748266cb151 --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/modifiedAttribute.fxml @@ -0,0 +1,8 @@ + +ent="CENTER" + prefHeight="400.0" + prefWidth="600.0"> + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/modifiedTag.fxml b/plugins/javaFX/testData/inspections/redundantValue/modifiedTag.fxml new file mode 100644 index 000000000000..d85785304456 --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/modifiedTag.fxml @@ -0,0 +1,12 @@ + + + + ent>CENTER + + \ No newline at end of file diff --git a/plugins/javaFX/testData/inspections/redundantValue/tagHighlighting.fxml b/plugins/javaFX/testData/inspections/redundantValue/tagHighlighting.fxml new file mode 100644 index 000000000000..66d15f708c8c --- /dev/null +++ b/plugins/javaFX/testData/inspections/redundantValue/tagHighlighting.fxml @@ -0,0 +1,19 @@ + + + + + 100 + + + -1 + + 500 + -1 + 1 + 0 + 0.99 + false + + \ No newline at end of file diff --git a/plugins/maven/maven-server-api/maven-server-api.iml b/plugins/maven/maven-server-api/maven-server-api.iml index 514b6f54ad85..7b767e9d8a0a 100644 --- a/plugins/maven/maven-server-api/maven-server-api.iml +++ b/plugins/maven/maven-server-api/maven-server-api.iml @@ -1,11 +1,11 @@ - + - + @@ -19,5 +19,4 @@ - - + \ No newline at end of file diff --git a/plugins/maven/maven2-server-impl/maven2-server-impl.iml b/plugins/maven/maven2-server-impl/maven2-server-impl.iml index c763f18e6cc2..152302312191 100644 --- a/plugins/maven/maven2-server-impl/maven2-server-impl.iml +++ b/plugins/maven/maven2-server-impl/maven2-server-impl.iml @@ -1,12 +1,12 @@ - + - + diff --git a/plugins/maven/maven3-server-common/maven3-server-common.iml b/plugins/maven/maven3-server-common/maven3-server-common.iml index 80778cfde700..cc58c726cd59 100644 --- a/plugins/maven/maven3-server-common/maven3-server-common.iml +++ b/plugins/maven/maven3-server-common/maven3-server-common.iml @@ -1,11 +1,11 @@ - + - + diff --git a/plugins/maven/maven30-server-impl/maven30-server-impl.iml b/plugins/maven/maven30-server-impl/maven30-server-impl.iml index f5efd505c00e..7c5fd16b6372 100644 --- a/plugins/maven/maven30-server-impl/maven30-server-impl.iml +++ b/plugins/maven/maven30-server-impl/maven30-server-impl.iml @@ -1,11 +1,11 @@ - + - + diff --git a/plugins/maven/maven32-server-impl/maven32-server-impl.iml b/plugins/maven/maven32-server-impl/maven32-server-impl.iml index 7d11ef040a60..1b362d0a45b7 100644 --- a/plugins/maven/maven32-server-impl/maven32-server-impl.iml +++ b/plugins/maven/maven32-server-impl/maven32-server-impl.iml @@ -1,11 +1,11 @@ - + - + diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java index 9bed388e0d08..c91ece90deab 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java @@ -25,13 +25,17 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.NotNullFactory; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.VcsBundle; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.actions.VcsContextFactory; import com.intellij.openapi.vcs.changes.*; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.EventDispatcher; +import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NotNull; @@ -44,7 +48,6 @@ import org.jetbrains.idea.svn.status.Status; import org.jetbrains.idea.svn.status.StatusType; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; -import org.tmatesoft.svn.core.internal.util.SVNPathUtil; import org.tmatesoft.svn.core.wc.ISVNStatusFileProvider; import java.io.File; @@ -208,7 +211,7 @@ public class SvnChangeProvider implements ChangeProvider { @Nullable VcsDirtyScope dirtyScope) throws SVNException { boolean foundRename = false; final Status copiedStatus = copiedFile.getStatus(); - final String copyFromURL = copiedFile.getCopyFromURL(); + final String copyFromURL = ObjectUtils.assertNotNull(copiedFile.getCopyFromURL()); final Set deletedToDelete = new HashSet(); for (SvnChangedFile deletedFile : context.getDeletedFiles()) { @@ -246,22 +249,25 @@ public class SvnChangeProvider implements ChangeProvider { // handle the case when the deleted file wasn't included in the dirty scope - try searching for the local copy // by building a relative url if (!foundRename && copiedStatus.getURL() != null) { - File wcPath = guessWorkingCopyPath(copiedStatus.getFile(), copiedStatus.getURL(), copyFromURL); - Status status; - try { - status = myVcs.getFactory(wcPath).createStatusClient().doStatus(wcPath, false); - } - catch(SvnBindException ex) { - LOG.info(ex); - status = null; - } - if (status != null && status.is(StatusType.STATUS_DELETED)) { - final FilePath filePath = myFactory.createFilePathOnDeleted(wcPath, false); - final SvnContentRevision beforeRevision = SvnContentRevision.createBaseRevision(myVcs, filePath, status.getRevision()); - final ContentRevision afterRevision = CurrentContentRevision.create(copiedFile.getFilePath()); - context.getBuilder().processChangeInList(context.createMovedChange(beforeRevision, afterRevision, copiedStatus, status), - SvnUtil.getChangelistName(status), SvnVcs.getKey()); - foundRename = true; + File wcPath = myVcs.getSvnFileUrlMapping().getLocalPath(copyFromURL); + + if (wcPath != null) { + Status status; + try { + status = myVcs.getFactory(wcPath).createStatusClient().doStatus(wcPath, false); + } + catch (SvnBindException ex) { + LOG.info(ex); + status = null; + } + if (status != null && status.is(StatusType.STATUS_DELETED)) { + final FilePath filePath = myFactory.createFilePathOnDeleted(wcPath, false); + final SvnContentRevision beforeRevision = SvnContentRevision.createBaseRevision(myVcs, filePath, status.getRevision()); + final ContentRevision afterRevision = CurrentContentRevision.create(copiedFile.getFilePath()); + context.getBuilder().processChangeInList(context.createMovedChange(beforeRevision, afterRevision, copiedStatus, status), + SvnUtil.getChangelistName(status), SvnVcs.getKey()); + foundRename = true; + } } } @@ -305,30 +311,6 @@ public class SvnChangeProvider implements ChangeProvider { status.getRevision()); } - @NotNull - private static File guessWorkingCopyPath(@NotNull File file, @NotNull SVNURL url, @NotNull String copyFromURL) throws SVNException { - String copiedPath = url.getPath(); - String copyFromPath = SVNURL.parseURIEncoded(copyFromURL).getPath(); - String commonPathAncestor = SVNPathUtil.getCommonPathAncestor(copiedPath, copyFromPath); - int pathSegmentCount = SVNPathUtil.getSegmentsCount(copiedPath); - int ancestorSegmentCount = SVNPathUtil.getSegmentsCount(commonPathAncestor); - boolean startsWithSlash = file.getAbsolutePath().startsWith("/"); - List segments = StringUtil.split(file.getPath(), File.separator); - List copyFromPathSegments = StringUtil.split(copyFromPath, "/"); - List resultSegments = new ArrayList(); - final int keepSegments = segments.size() - pathSegmentCount + ancestorSegmentCount; - for(int i=0; i< keepSegments; i++) { - resultSegments.add(segments.get(i)); - } - for(int i=ancestorSegmentCount; i|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true; -} - -function isTopScope(context) { - for (;;) { - if (!context || context.type == "top") return true; - if (context.type == "}" && context.prev.type != "namespace") return false; - context = context.prev; - } -} - -CodeMirror.defineMode("clike", function(config, parserConfig) { - var indentUnit = config.indentUnit, - statementIndentUnit = parserConfig.statementIndentUnit || indentUnit, - dontAlignCalls = parserConfig.dontAlignCalls, - keywords = parserConfig.keywords || {}, - types = parserConfig.types || {}, - builtin = parserConfig.builtin || {}, - blockKeywords = parserConfig.blockKeywords || {}, - defKeywords = parserConfig.defKeywords || {}, - atoms = parserConfig.atoms || {}, - hooks = parserConfig.hooks || {}, - multiLineStrings = parserConfig.multiLineStrings, - indentStatements = parserConfig.indentStatements !== false, - indentSwitch = parserConfig.indentSwitch !== false, - namespaceSeparator = parserConfig.namespaceSeparator, - isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/, - numberStart = parserConfig.numberStart || /[\d\.]/, - number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i, - isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/, - endStatement = parserConfig.endStatement || /^[;:,]$/; - - var curPunc, isDefKeyword; - - function tokenBase(stream, state) { - var ch = stream.next(); - if (hooks[ch]) { - var result = hooks[ch](stream, state); - if (result !== false) return result; - } - if (ch == '"' || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } - if (isPunctuationChar.test(ch)) { - curPunc = ch; - return null; - } - if (numberStart.test(ch)) { - stream.backUp(1) - if (stream.match(number)) return "number" - stream.next() - } - if (ch == "/") { - if (stream.eat("*")) { - state.tokenize = tokenComment; - return tokenComment(stream, state); - } - if (stream.eat("/")) { - stream.skipToEnd(); - return "comment"; - } - } - if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return "operator"; - } - stream.eatWhile(/[\w\$_\xa1-\uffff]/); - if (namespaceSeparator) while (stream.match(namespaceSeparator)) - stream.eatWhile(/[\w\$_\xa1-\uffff]/); - - var cur = stream.current(); - if (contains(keywords, cur)) { - if (contains(blockKeywords, cur)) curPunc = "newstatement"; - if (contains(defKeywords, cur)) isDefKeyword = true; - return "keyword"; - } - if (contains(types, cur)) return "variable-3"; - if (contains(builtin, cur)) { - if (contains(blockKeywords, cur)) curPunc = "newstatement"; - return "builtin"; - } - if (contains(atoms, cur)) return "atom"; - return "variable"; - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, next, end = false; - while ((next = stream.next()) != null) { - if (next == quote && !escaped) {end = true; break;} - escaped = !escaped && next == "\\"; - } - if (end || !(escaped || multiLineStrings)) - state.tokenize = null; - return "string"; - }; - } - - function tokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "/" && maybeEnd) { - state.tokenize = null; - break; - } - maybeEnd = (ch == "*"); - } - return "comment"; - } - - // Interface - - return { - startState: function(basecolumn) { - return { - tokenize: null, - context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), - indented: 0, - startOfLine: true, - prevToken: null - }; - }, - - token: function(stream, state) { - var ctx = state.context; - if (stream.sol()) { - if (ctx.align == null) ctx.align = false; - state.indented = stream.indentation(); - state.startOfLine = true; - } - if (stream.eatSpace()) return null; - curPunc = isDefKeyword = null; - var style = (state.tokenize || tokenBase)(stream, state); - if (style == "comment" || style == "meta") return style; - if (ctx.align == null) ctx.align = true; - - if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state); - else if (curPunc == "{") pushContext(state, stream.column(), "}"); - else if (curPunc == "[") pushContext(state, stream.column(), "]"); - else if (curPunc == "(") pushContext(state, stream.column(), ")"); - else if (curPunc == "}") { - while (isStatement(ctx.type)) ctx = popContext(state); - if (ctx.type == "}") ctx = popContext(state); - while (isStatement(ctx.type)) ctx = popContext(state); - } - else if (curPunc == ctx.type) popContext(state); - else if (indentStatements && - (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") || - (isStatement(ctx.type) && curPunc == "newstatement"))) { - var type = "statement"; - if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch") - type = "switchstatement"; - else if (style == "keyword" && stream.current() == "namespace") - type = "namespace"; - pushContext(state, stream.column(), type); - } - - if (style == "variable" && - ((state.prevToken == "def" || - (parserConfig.typeFirstDefinitions && typeBefore(stream, state) && - isTopScope(state.context) && stream.match(/^\s*\(/, false))))) - style = "def"; - - if (hooks.token) { - var result = hooks.token(stream, state, style); - if (result !== undefined) style = result; - } - - if (style == "def" && parserConfig.styleDefs === false) style = "variable"; - - state.startOfLine = false; - state.prevToken = isDefKeyword ? "def" : style || curPunc; - return style; - }, - - indent: function(state, textAfter) { - if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass; - var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); - if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev; - if (hooks.indent) { - var hook = hooks.indent(state, ctx, textAfter); - if (typeof hook == "number") return hook - } - var closing = firstChar == ctx.type; - var switchBlock = ctx.prev && ctx.prev.type == "switchstatement"; - if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) { - while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev - return ctx.indented - } - if (isStatement(ctx.type)) - return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit); - if (ctx.align && (!dontAlignCalls || ctx.type != ")")) - return ctx.column + (closing ? 0 : 1); - if (ctx.type == ")" && !closing) - return ctx.indented + statementIndentUnit; - - return ctx.indented + (closing ? 0 : indentUnit) + - (!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0); - }, - - electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/, - blockCommentStart: "/*", - blockCommentEnd: "*/", - lineComment: "//", - fold: "brace" - }; -}); - - function words(str) { - var obj = {}, words = str.split(" "); - for (var i = 0; i < words.length; ++i) obj[words[i]] = true; - return obj; - } - function contains(words, word) { - if (typeof words === "function") { - return words(word); - } else { - return words.propertyIsEnumerable(word); - } - } - var cKeywords = "auto if break case register continue return default do sizeof " + - "static else struct switch extern typedef union for goto while enum const volatile"; - var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t"; - - function cppHook(stream, state) { - if (!state.startOfLine) return false - for (var ch, next = null; ch = stream.peek();) { - if (ch == "\\" && stream.match(/^.$/)) { - next = cppHook - break - } else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) { - break - } - stream.next() - } - state.tokenize = next - return "meta" - } - - function pointerHook(_stream, state) { - if (state.prevToken == "variable-3") return "variable-3"; - return false; - } - - function cpp14Literal(stream) { - stream.eatWhile(/[\w\.']/); - return "number"; - } - - function cpp11StringHook(stream, state) { - stream.backUp(1); - // Raw strings. - if (stream.match(/(R|u8R|uR|UR|LR)/)) { - var match = stream.match(/"([^\s\\()]{0,16})\(/); - if (!match) { - return false; - } - state.cpp11RawStringDelim = match[1]; - state.tokenize = tokenRawString; - return tokenRawString(stream, state); - } - // Unicode strings/chars. - if (stream.match(/(u8|u|U|L)/)) { - if (stream.match(/["']/, /* eat */ false)) { - return "string"; - } - return false; - } - // Ignore this hook. - stream.next(); - return false; - } - - function cppLooksLikeConstructor(word) { - var lastTwo = /(\w+)::(\w+)$/.exec(word); - return lastTwo && lastTwo[1] == lastTwo[2]; - } - - // C#-style strings where "" escapes a quote. - function tokenAtString(stream, state) { - var next; - while ((next = stream.next()) != null) { - if (next == '"' && !stream.eat('"')) { - state.tokenize = null; - break; - } - } - return "string"; - } - - // C++11 raw string literal is "( anything )", where - // can be a string up to 16 characters long. - function tokenRawString(stream, state) { - // Escape characters that have special regex meanings. - var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&'); - var match = stream.match(new RegExp(".*?\\)" + delim + '"')); - if (match) - state.tokenize = null; - else - stream.skipToEnd(); - return "string"; - } - - function def(mimes, mode) { - if (typeof mimes == "string") mimes = [mimes]; - var words = []; - function add(obj) { - if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop)) - words.push(prop); - } - add(mode.keywords); - add(mode.types); - add(mode.builtin); - add(mode.atoms); - if (words.length) { - mode.helperType = mimes[0]; - CodeMirror.registerHelper("hintWords", mimes[0], words); - } - - for (var i = 0; i < mimes.length; ++i) - CodeMirror.defineMIME(mimes[i], mode); - } - - def(["text/x-csrc", "text/x-c", "text/x-chdr"], { - name: "clike", - keywords: words(cKeywords), - types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " + - "int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " + - "uint32_t uint64_t"), - blockKeywords: words("case do else for if switch while struct"), - defKeywords: words("struct"), - typeFirstDefinitions: true, - atoms: words("null true false"), - hooks: {"#": cppHook, "*": pointerHook}, - modeProps: {fold: ["brace", "include"]} - }); - - def(["text/x-c++src", "text/x-c++hdr"], { - name: "clike", - keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " + - "static_cast typeid catch operator template typename class friend private " + - "this using const_cast inline public throw virtual delete mutable protected " + - "alignas alignof constexpr decltype nullptr noexcept thread_local final " + - "static_assert override"), - types: words(cTypes + " bool wchar_t"), - blockKeywords: words("catch class do else finally for if struct switch try while"), - defKeywords: words("class namespace struct enum union"), - typeFirstDefinitions: true, - atoms: words("true false null"), - hooks: { - "#": cppHook, - "*": pointerHook, - "u": cpp11StringHook, - "U": cpp11StringHook, - "L": cpp11StringHook, - "R": cpp11StringHook, - "0": cpp14Literal, - "1": cpp14Literal, - "2": cpp14Literal, - "3": cpp14Literal, - "4": cpp14Literal, - "5": cpp14Literal, - "6": cpp14Literal, - "7": cpp14Literal, - "8": cpp14Literal, - "9": cpp14Literal, - token: function(stream, state, style) { - if (style == "variable" && stream.peek() == "(" && - (state.prevToken == ";" || state.prevToken == null || - state.prevToken == "}") && - cppLooksLikeConstructor(stream.current())) - return "def"; - } - }, - namespaceSeparator: "::", - modeProps: {fold: ["brace", "include"]} - }); - - def("text/x-java", { - name: "clike", - keywords: words("abstract assert break case catch class const continue default " + - "do else enum extends final finally float for goto if implements import " + - "instanceof interface native new package private protected public " + - "return static strictfp super switch synchronized this throw throws transient " + - "try volatile while"), - types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " + - "Integer Long Number Object Short String StringBuffer StringBuilder Void"), - blockKeywords: words("catch class do else finally for if switch try while"), - defKeywords: words("class interface package enum"), - typeFirstDefinitions: true, - atoms: words("true false null"), - endStatement: /^[;:]$/, - hooks: { - "@": function(stream) { - stream.eatWhile(/[\w\$_]/); - return "meta"; - } - }, - modeProps: {fold: ["brace", "import"]} - }); - - def("text/x-csharp", { - name: "clike", - keywords: words("abstract as async await base break case catch checked class const continue" + - " default delegate do else enum event explicit extern finally fixed for" + - " foreach goto if implicit in interface internal is lock namespace new" + - " operator out override params private protected public readonly ref return sealed" + - " sizeof stackalloc static struct switch this throw try typeof unchecked" + - " unsafe using virtual void volatile while add alias ascending descending dynamic from get" + - " global group into join let orderby partial remove select set value var yield"), - types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" + - " Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" + - " UInt64 bool byte char decimal double short int long object" + - " sbyte float string ushort uint ulong"), - blockKeywords: words("catch class do else finally for foreach if struct switch try while"), - defKeywords: words("class interface namespace struct var"), - typeFirstDefinitions: true, - atoms: words("true false null"), - hooks: { - "@": function(stream, state) { - if (stream.eat('"')) { - state.tokenize = tokenAtString; - return tokenAtString(stream, state); - } - stream.eatWhile(/[\w\$_]/); - return "meta"; - } - } - }); - - function tokenTripleString(stream, state) { - var escaped = false; - while (!stream.eol()) { - if (!escaped && stream.match('"""')) { - state.tokenize = null; - break; - } - escaped = stream.next() == "\\" && !escaped; - } - return "string"; - } - - def("text/x-scala", { - name: "clike", - keywords: words( - - /* scala */ - "abstract case catch class def do else extends final finally for forSome if " + - "implicit import lazy match new null object override package private protected return " + - "sealed super this throw trait try type val var while with yield _ : = => <- <: " + - "<% >: # @ " + - - /* package scala */ - "assert assume require print println printf readLine readBoolean readByte readShort " + - "readChar readInt readLong readFloat readDouble " + - - ":: #:: " - ), - types: words( - "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " + - "Enumeration Equiv Error Exception Fractional Function IndexedSeq Int Integral Iterable " + - "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " + - "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " + - "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " + - - /* package java.lang */ - "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + - "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + - "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + - "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" - ), - multiLineStrings: true, - blockKeywords: words("catch class do else finally for forSome if match switch try while"), - defKeywords: words("class def object package trait type val var"), - atoms: words("true false null"), - indentStatements: false, - indentSwitch: false, - hooks: { - "@": function(stream) { - stream.eatWhile(/[\w\$_]/); - return "meta"; - }, - '"': function(stream, state) { - if (!stream.match('""')) return false; - state.tokenize = tokenTripleString; - return state.tokenize(stream, state); - }, - "'": function(stream) { - stream.eatWhile(/[\w\$_\xa1-\uffff]/); - return "atom"; - }, - "=": function(stream, state) { - var cx = state.context - if (cx.type == "}" && cx.align && stream.eat(">")) { - state.context = new Context(cx.indented, cx.column, cx.type, null, cx.prev) - return "operator" - } else { - return false - } - } - }, - modeProps: {closeBrackets: {triples: '"'}} - }); - - function tokenKotlinString(tripleString){ - return function (stream, state) { - var escaped = false, next, end = false; - while (!stream.eol()) { - if (!tripleString && !escaped && stream.match('"') ) {end = true; break;} - if (tripleString && stream.match('"""')) {end = true; break;} - next = stream.next(); - if(!escaped && next == "$" && stream.match('{')) - stream.skipTo("}"); - escaped = !escaped && next == "\\" && !tripleString; - } - if (end || !tripleString) - state.tokenize = null; - return "string"; - } - } - - def("text/x-kotlin", { - name: "clike", - keywords: words( - /*keywords*/ - "package as typealias class interface this super val " + - "var fun for is in This throw return " + - "break continue object if else while do try when !in !is as? " + - - /*soft keywords*/ - "file import where by get set abstract enum open inner override private public internal " + - "protected catch finally out final vararg reified dynamic companion constructor init " + - "sealed field property receiver param sparam lateinit data inline noinline tailrec " + - "external annotation crossinline const operator infix" - ), - types: words( - /* package java.lang */ - "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + - "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + - "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + - "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" - ), - intendSwitch: false, - indentStatements: false, - multiLineStrings: true, - blockKeywords: words("catch class do else finally for if where try while enum"), - defKeywords: words("class val var object package interface fun"), - atoms: words("true false null this"), - hooks: { - '"': function(stream, state) { - state.tokenize = tokenKotlinString(stream.match('""')); - return state.tokenize(stream, state); - } - }, - modeProps: {closeBrackets: {triples: '"'}} - }); - - def(["x-shader/x-vertex", "x-shader/x-fragment"], { - name: "clike", - keywords: words("sampler1D sampler2D sampler3D samplerCube " + - "sampler1DShadow sampler2DShadow " + - "const attribute uniform varying " + - "break continue discard return " + - "for while do if else struct " + - "in out inout"), - types: words("float int bool void " + - "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " + - "mat2 mat3 mat4"), - blockKeywords: words("for while do if else struct"), - builtin: words("radians degrees sin cos tan asin acos atan " + - "pow exp log exp2 sqrt inversesqrt " + - "abs sign floor ceil fract mod min max clamp mix step smoothstep " + - "length distance dot cross normalize ftransform faceforward " + - "reflect refract matrixCompMult " + - "lessThan lessThanEqual greaterThan greaterThanEqual " + - "equal notEqual any all not " + - "texture1D texture1DProj texture1DLod texture1DProjLod " + - "texture2D texture2DProj texture2DLod texture2DProjLod " + - "texture3D texture3DProj texture3DLod texture3DProjLod " + - "textureCube textureCubeLod " + - "shadow1D shadow2D shadow1DProj shadow2DProj " + - "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " + - "dFdx dFdy fwidth " + - "noise1 noise2 noise3 noise4"), - atoms: words("true false " + - "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " + - "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " + - "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " + - "gl_FogCoord gl_PointCoord " + - "gl_Position gl_PointSize gl_ClipVertex " + - "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " + - "gl_TexCoord gl_FogFragCoord " + - "gl_FragCoord gl_FrontFacing " + - "gl_FragData gl_FragDepth " + - "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " + - "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " + - "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " + - "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " + - "gl_ProjectionMatrixInverseTranspose " + - "gl_ModelViewProjectionMatrixInverseTranspose " + - "gl_TextureMatrixInverseTranspose " + - "gl_NormalScale gl_DepthRange gl_ClipPlane " + - "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " + - "gl_FrontLightModelProduct gl_BackLightModelProduct " + - "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " + - "gl_FogParameters " + - "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " + - "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " + - "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " + - "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " + - "gl_MaxDrawBuffers"), - indentSwitch: false, - hooks: {"#": cppHook}, - modeProps: {fold: ["brace", "include"]} - }); - - def("text/x-nesc", { - name: "clike", - keywords: words(cKeywords + "as atomic async call command component components configuration event generic " + - "implementation includes interface module new norace nx_struct nx_union post provides " + - "signal task uses abstract extends"), - types: words(cTypes), - blockKeywords: words("case do else for if switch while struct"), - atoms: words("null true false"), - hooks: {"#": cppHook}, - modeProps: {fold: ["brace", "include"]} - }); - - def("text/x-objectivec", { - name: "clike", - keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " + - "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"), - types: words(cTypes), - atoms: words("YES NO NULL NILL ON OFF true false"), - hooks: { - "@": function(stream) { - stream.eatWhile(/[\w\$]/); - return "keyword"; - }, - "#": cppHook, - indent: function(_state, ctx, textAfter) { - if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented - } - }, - modeProps: {fold: "brace"} - }); - - def("text/x-squirrel", { - name: "clike", - keywords: words("base break clone continue const default delete enum extends function in class" + - " foreach local resume return this throw typeof yield constructor instanceof static"), - types: words(cTypes), - blockKeywords: words("case catch class else for foreach if switch try while"), - defKeywords: words("function local class"), - typeFirstDefinitions: true, - atoms: words("true false null"), - hooks: {"#": cppHook}, - modeProps: {fold: ["brace", "include"]} - }); - - // Ceylon Strings need to deal with interpolation - var stringTokenizer = null; - function tokenCeylonString(type) { - return function(stream, state) { - var escaped = false, next, end = false; - while (!stream.eol()) { - if (!escaped && stream.match('"') && - (type == "single" || stream.match('""'))) { - end = true; - break; - } - if (!escaped && stream.match('``')) { - stringTokenizer = tokenCeylonString(type); - end = true; - break; - } - next = stream.next(); - escaped = type == "single" && !escaped && next == "\\"; - } - if (end) - state.tokenize = null; - return "string"; - } - } - - def("text/x-ceylon", { - name: "clike", - keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" + - " exists extends finally for function given if import in interface is let module new" + - " nonempty object of out outer package return satisfies super switch then this throw" + - " try value void while"), - types: function(word) { - // In Ceylon all identifiers that start with an uppercase are types - var first = word.charAt(0); - return (first === first.toUpperCase() && first !== first.toLowerCase()); - }, - blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"), - defKeywords: words("class dynamic function interface module object package value"), - builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" + - " native optional sealed see serializable shared suppressWarnings tagged throws variable"), - isPunctuationChar: /[\[\]{}\(\),;\:\.`]/, - isOperatorChar: /[+\-*&%=<>!?|^~:\/]/, - numberStart: /[\d#$]/, - number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i, - multiLineStrings: true, - typeFirstDefinitions: true, - atoms: words("true false null larger smaller equal empty finished"), - indentSwitch: false, - styleDefs: false, - hooks: { - "@": function(stream) { - stream.eatWhile(/[\w\$_]/); - return "meta"; - }, - '"': function(stream, state) { - state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single"); - return state.tokenize(stream, state); - }, - '`': function(stream, state) { - if (!stringTokenizer || !stream.match('`')) return false; - state.tokenize = stringTokenizer; - stringTokenizer = null; - return state.tokenize(stream, state); - }, - "'": function(stream) { - stream.eatWhile(/[\w\$_\xa1-\uffff]/); - return "atom"; - }, - token: function(_stream, state, style) { - if ((style == "variable" || style == "variable-3") && - state.prevToken == ".") { - return "variable-2"; - } - } - }, - modeProps: { - fold: ["brace", "import"], - closeBrackets: {triples: '"'} - } - }); - -}); diff --git a/python/educational-core/student/resources/code-mirror/template.html b/python/educational-core/student/resources/code-mirror/template.html index 11ced417926c..ff4e21866b8c 100644 --- a/python/educational-core/student/resources/code-mirror/template.html +++ b/python/educational-core/student/resources/code-mirror/template.html @@ -18,7 +18,7 @@ - +