From fcd90cfbda9a763e8ba4dc12fb1448df308b50c3 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Mon, 24 Mar 2014 16:34:18 +0400 Subject: [PATCH 01/69] Injection cache extracted from Concatenation injector for using in Groovy injector as well --- .../inject/java/ConcatenationInjector.java | 73 ++--------- .../inject/java/InjectionCache.java | 113 ++++++++++++++++++ .../src/META-INF/intellilang-java-support.xml | 4 + 3 files changed, 126 insertions(+), 64 deletions(-) create mode 100644 plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/InjectionCache.java diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java index 32378d0bc46c..65c6d88bfc6d 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,26 +19,20 @@ import com.intellij.lang.Language; import com.intellij.lang.injection.ConcatenationAwareInjector; import com.intellij.lang.injection.MultiHostRegistrar; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.ProperTextRange; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.patterns.ElementPattern; import com.intellij.psi.*; -import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.injection.ReferenceInjector; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.util.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; -import com.intellij.util.PatternValuesIndex; import com.intellij.util.Processor; -import com.intellij.util.containers.ContainerUtil; -import gnu.trove.THashMap; import gnu.trove.THashSet; import org.intellij.plugins.intelliLang.Configuration; import org.intellij.plugins.intelliLang.inject.InjectedLanguage; @@ -46,7 +40,6 @@ import org.intellij.plugins.intelliLang.inject.InjectorUtils; import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; -import org.intellij.plugins.intelliLang.inject.config.InjectionPlace; import org.intellij.plugins.intelliLang.util.AnnotationUtilEx; import org.intellij.plugins.intelliLang.util.ContextComputationProcessor; import org.intellij.plugins.intelliLang.util.PsiUtilEx; @@ -61,8 +54,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { private final Configuration myConfiguration; private final Project myProject; private final TemporaryPlacesRegistry myTemporaryPlacesRegistry; - private final CachedValue> myAnnoIndex; - private final CachedValue> myXmlIndex; + private final LanguageInjectionSupport mySupport; @@ -71,54 +63,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { myProject = project; myTemporaryPlacesRegistry = temporaryPlacesRegistry; mySupport = InjectorUtils.findNotNullInjectionSupport(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID); - myXmlIndex = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider>() { - public Result> compute() { - final Map, BaseInjection> map = new THashMap, BaseInjection>(); - for (BaseInjection injection : myConfiguration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) { - for (InjectionPlace place : injection.getInjectionPlaces()) { - if (!place.isEnabled() || place.getElementPattern() == null) continue; - map.put(place.getElementPattern(), injection); - } - } - final Set stringSet = PatternValuesIndex.buildStringIndex(map.keySet()); - return new Result>(stringSet, myConfiguration); - } - }, false); - myAnnoIndex = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider>() { - public Result> compute() { - final String annotationClass = myConfiguration.getAdvancedConfiguration().getLanguageAnnotationClass(); - final Collection result = new THashSet(); - final ArrayList annoClasses = new ArrayList(3); - annoClasses.add(StringUtil.getShortName(annotationClass)); - for (int cursor = 0; cursor < annoClasses.size(); cursor++) { - final String annoClass = annoClasses.get(cursor); - for (PsiAnnotation annotation : JavaAnnotationIndex.getInstance().get(annoClass, myProject, GlobalSearchScope.allScope(myProject))) { - final PsiElement modList = annotation.getParent(); - if (!(modList instanceof PsiModifierList)) continue; - final PsiElement element = modList.getParent(); - if (element instanceof PsiParameter) { - final PsiElement scope = ((PsiParameter)element).getDeclarationScope(); - if (scope instanceof PsiNamedElement) { - ContainerUtil.addIfNotNull(((PsiNamedElement)scope).getName(), result); - } - else { - ContainerUtil.addIfNotNull(((PsiNamedElement)element).getName(), result); - } - } - else if (element instanceof PsiNamedElement) { - if (element instanceof PsiClass && ((PsiClass)element).isAnnotationType()) { - final String s = ((PsiClass)element).getName(); - if (!annoClasses.contains(s)) annoClasses.add(s); - } - else { - ContainerUtil.addIfNotNull(((PsiNamedElement)element).getName(), result); - } - } - } - } - return new Result>(result, PsiModificationTracker.MODIFICATION_COUNT, myConfiguration); - } - }, false); + } public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull PsiElement... operands) { @@ -418,7 +363,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { else { if (!(curHost instanceof PsiLiteralExpression)) { TextRange textRange = ElementManipulators.getManipulator(curHost).getRangeInElement(curHost); - ProperTextRange.assertProperRange(textRange, injection); + TextRange.assertProperRange(textRange, injection); result.add(Trinity.create(curHost, InjectedLanguage.create(injection.getInjectedLanguageId(), curPrefix, curSuffix, true), textRange)); } @@ -426,7 +371,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { final List injectedArea = injection.getInjectedArea(curHost); for (int j = 0, injectedAreaSize = injectedArea.size(); j < injectedAreaSize; j++) { TextRange textRange = injectedArea.get(j); - ProperTextRange.assertProperRange(textRange, injection); + TextRange.assertProperRange(textRange, injection); result.add(Trinity.create( curHost, InjectedLanguage.create(injection.getInjectedLanguageId(), (separateFiles || j == 0 ? curPrefix : ""), @@ -477,10 +422,10 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { public Collection getAnnotatedElementsValue() { // note: external annotations not supported - return myAnnoIndex.getValue(); + return InjectionCache.getInstance(myProject).getAnnoIndex(); } private Collection getXmlAnnotatedElementsValue() { - return myXmlIndex.getValue(); + return InjectionCache.getInstance(myProject).getXmlIndex(); } } diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/InjectionCache.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/InjectionCache.java new file mode 100644 index 000000000000..56e3cdc956f2 --- /dev/null +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/InjectionCache.java @@ -0,0 +1,113 @@ +/* + * 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 org.intellij.plugins.intelliLang.inject.java; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.patterns.ElementPattern; +import com.intellij.psi.*; +import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.PsiModificationTracker; +import com.intellij.util.PatternValuesIndex; +import com.intellij.util.containers.ContainerUtil; +import gnu.trove.THashMap; +import gnu.trove.THashSet; +import org.intellij.plugins.intelliLang.Configuration; +import org.intellij.plugins.intelliLang.inject.config.BaseInjection; +import org.intellij.plugins.intelliLang.inject.config.InjectionPlace; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +/** + * Created by Max Medvedev on 22/03/14 + */ +public class InjectionCache { + private final CachedValue> myAnnoIndex; + private final CachedValue> myXmlIndex; + + public InjectionCache(final Project project, final Configuration configuration) { + + myXmlIndex = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider>() { + public Result> compute() { + final Map, BaseInjection> map = new THashMap, BaseInjection>(); + for (BaseInjection injection : configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) { + for (InjectionPlace place : injection.getInjectionPlaces()) { + if (!place.isEnabled() || place.getElementPattern() == null) continue; + map.put(place.getElementPattern(), injection); + } + } + final Set stringSet = PatternValuesIndex.buildStringIndex(map.keySet()); + return new Result>(stringSet, configuration); + } + }, false); + + myAnnoIndex = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider>() { + public Result> compute() { + final String annotationClass = configuration.getAdvancedConfiguration().getLanguageAnnotationClass(); + final Collection result = new THashSet(); + final ArrayList annoClasses = new ArrayList(3); + annoClasses.add(StringUtil.getShortName(annotationClass)); + for (int cursor = 0; cursor < annoClasses.size(); cursor++) { + final String annoClass = annoClasses.get(cursor); + for (PsiAnnotation annotation : JavaAnnotationIndex.getInstance().get(annoClass, project, GlobalSearchScope.allScope(project))) { + final PsiElement modList = annotation.getParent(); + if (!(modList instanceof PsiModifierList)) continue; + final PsiElement element = modList.getParent(); + if (element instanceof PsiParameter) { + final PsiElement scope = ((PsiParameter)element).getDeclarationScope(); + if (scope instanceof PsiNamedElement) { + ContainerUtil.addIfNotNull(((PsiNamedElement)scope).getName(), result); + } + else { + ContainerUtil.addIfNotNull(((PsiNamedElement)element).getName(), result); + } + } + else if (element instanceof PsiNamedElement) { + if (element instanceof PsiClass && ((PsiClass)element).isAnnotationType()) { + final String s = ((PsiClass)element).getName(); + if (!annoClasses.contains(s)) annoClasses.add(s); + } + else { + ContainerUtil.addIfNotNull(((PsiNamedElement)element).getName(), result); + } + } + } + } + return new Result>(result, PsiModificationTracker.MODIFICATION_COUNT, configuration); + } + }, false); + } + + public static InjectionCache getInstance(Project project) { + return ServiceManager.getService(project, InjectionCache.class); + } + + public Collection getAnnoIndex() { + return myAnnoIndex.getValue(); + } + + public Collection getXmlIndex() { + return myXmlIndex.getValue(); + } +} diff --git a/plugins/IntelliLang/src/META-INF/intellilang-java-support.xml b/plugins/IntelliLang/src/META-INF/intellilang-java-support.xml index f5d9305e6d9b..2821e74ae71b 100644 --- a/plugins/IntelliLang/src/META-INF/intellilang-java-support.xml +++ b/plugins/IntelliLang/src/META-INF/intellilang-java-support.xml @@ -26,6 +26,8 @@ + @@ -36,6 +38,8 @@ + + \ No newline at end of file From 894430be9b591fdd1e9e004f8b4de3c8c0d202b7 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Mon, 24 Mar 2014 16:35:02 +0400 Subject: [PATCH 02/69] optimize method call checks for Groovy Injector using Injection cache --- .../groovy/GrConcatenationAwareInjector.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationAwareInjector.java b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationAwareInjector.java index 6d141a665882..ab3d4ea1e4c6 100644 --- a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationAwareInjector.java +++ b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationAwareInjector.java @@ -38,6 +38,7 @@ import org.intellij.plugins.intelliLang.inject.InjectorUtils; import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; +import org.intellij.plugins.intelliLang.inject.java.InjectionCache; import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport; import org.intellij.plugins.intelliLang.util.AnnotationUtilEx; import org.jetbrains.annotations.NotNull; @@ -54,6 +55,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; +import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -63,10 +65,12 @@ import java.util.List; public class GrConcatenationAwareInjector implements ConcatenationAwareInjector { private final LanguageInjectionSupport mySupport; private final Configuration myConfiguration; + private final Project myProject; @SuppressWarnings("UnusedParameters") public GrConcatenationAwareInjector(Configuration configuration, Project project, TemporaryPlacesRegistry temporaryPlacesRegistry) { myConfiguration = configuration; + myProject = project; mySupport = InjectorUtils.findNotNullInjectionSupport(GroovyLanguageInjectionSupport.GROOVY_SUPPORT_ID); } @@ -88,6 +92,18 @@ public class GrConcatenationAwareInjector implements ConcatenationAwareInjector InjectorUtils.registerSupport(mySupport, settingsAvailable, registrar); InjectorUtils.putInjectedFileUserData(registrar, InjectedLanguageUtil.FRANKENSTEIN_INJECTION, unparsable); } + + @Override + protected boolean areThereInjectionsWithName(String methodName, boolean annoOnly) { + if (getAnnotatedElementsValue().contains(methodName)) { + return true; + } + if (!annoOnly && getXmlAnnotatedElementsValue().contains(methodName)) { + return true; + } + return false; + } + }.processInjections(); } @@ -384,4 +400,12 @@ public class GrConcatenationAwareInjector implements ConcatenationAwareInjector } } + public Collection getAnnotatedElementsValue() { + // note: external annotations not supported + return InjectionCache.getInstance(myProject).getAnnoIndex(); + } + + private Collection getXmlAnnotatedElementsValue() { + return InjectionCache.getInstance(myProject).getXmlIndex(); + } } From bdd42a7aa75b1770006e98f9cb262c37ba513a73 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Mon, 24 Mar 2014 20:17:01 +0400 Subject: [PATCH 03/69] resolve annotations inside injected fragments --- .../types/GrCodeReferenceElementImpl.java | 3 +-- .../completion/InjectedGroovyTest.groovy | 27 ++++++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java index a29c26862687..3608405db27c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java @@ -24,7 +24,6 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.impl.source.resolve.FileContextUtil; import com.intellij.psi.impl.source.resolve.ResolveCache; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; @@ -516,7 +515,7 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl0) assert InjectedLanguageUtil.findInjectedPsiNoCommit(psiFile, psiFile.getText().indexOf('injected') + 1) } + public void testResolveAnnotationsInInjectedCode() { + myFixture.addClass("package foo; @interface Bar{}") + + myFixture.addClass("package groovy.lang; public class GroovyShell { public void evaluate(String s) { }}"); + final PsiFile psiFile = myFixture.configureByText("script.groovy", """ +new groovy.lang.GroovyShell().evaluate(''' +import foo.Bar + +@Bar +def abc = null +''') +"""); + assertNotNull(psiFile); + PsiReference ref = psiFile.findReferenceAt(myFixture.editor.caretModel.offset) + assert ref.resolve() instanceof PsiClass + assert ref.resolve().qualifiedName == 'foo.Bar' + + } + } From 4e1ade32f5676a28f2daa2f37f146fea3c83c84d Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Tue, 25 Mar 2014 12:50:22 +0400 Subject: [PATCH 04/69] IDEA-122707 @BaseScript initial support @BaseScript highlighted by annotator if it is not applicable Methods of a script using @BaseScript resolved --- plugins/groovy/src/META-INF/plugin.xml | 1 + .../plugins/groovy/GroovyBundle.properties | 2 + .../BaseScriptAnnotationChecker.java | 60 +++++++++ .../psi/impl/synthetic/GroovyScriptClass.java | 116 +++++++++++++++--- .../lang/psi/util/GroovyCommonClassNames.java | 1 + .../lang/resolve/GroovyResolveTestCase.groovy | 6 +- .../lang/resolve/ResolveMethodTest.groovy | 19 +++ 7 files changed, 188 insertions(+), 17 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index e31fc8ad575d..39f8de6ce81a 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -205,6 +205,7 @@ + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index c3b8164e4d94..ac51fc9f3d61 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -372,3 +372,5 @@ mixing.private.and.public.protected.methods.of.the.same.name=Mixing private and explicit.constructors.are.not.allowed.in.immutable.class=Explicit constructors are not allowed for @Immutable class repetitive.method.name.0=Repetitive method name ''{0}'' assign.expected='=' expected +declared.type.0.have.to.extend.script=Declared type ''{0}'' does not extend 'groovy.lang.Script' class +base.script.annotation.is.allowed.only.inside.scripts=Annotation @BaseScript can only be used within a script diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java new file mode 100644 index 000000000000..22e79abac6ee --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java @@ -0,0 +1,60 @@ +/* + * 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 org.jetbrains.plugins.groovy.annotator; + +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.psi.CommonClassNames; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiType; +import com.intellij.psi.util.InheritanceUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.GroovyBundle; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; + +/** + * Created by Max Medvedev on 25/03/14 + */ +public class BaseScriptAnnotationChecker extends CustomAnnotationChecker { + @Override + public boolean checkApplicability(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) { + if (GroovyCommonClassNames.GROOVY_TRANSFORM_BASE_SCRIPT.equals(annotation.getQualifiedName())) { + PsiFile file = annotation.getContainingFile(); + if (file instanceof GroovyFile && !(((GroovyFile)file).isScript())) { + holder.createErrorAnnotation(annotation, GroovyBundle.message("base.script.annotation.is.allowed.only.inside.scripts")); + return false; + } + + PsiElement pparent = annotation.getParent().getParent(); + if (pparent instanceof GrVariableDeclaration) { + GrTypeElement typeElement = ((GrVariableDeclaration)pparent).getTypeElementGroovy(); + PsiType type = typeElement != null ? typeElement.getType() : null; + + if (!InheritanceUtil.isInheritor(type, GroovyCommonClassNames.GROOVY_LANG_SCRIPT)) { + String typeText = type != null ? type.getCanonicalText() : CommonClassNames.JAVA_LANG_OBJECT; + holder.createErrorAnnotation(annotation, GroovyBundle.message("declared.type.0.have.to.extend.script", typeText)); + return false; + } + } + } + + return true; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java index 5108e852e11e..ab4b8402b578 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java @@ -16,7 +16,9 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.synthetic; import com.intellij.navigation.ItemPresentation; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; @@ -38,6 +40,11 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; @@ -157,12 +164,68 @@ public class GroovyScriptClass extends LightElement implements PsiClass, Synthet @NotNull public PsiClassType[] getExtendsListTypes() { + PsiClassType type = getSuperClassTypeFromBaseScriptAnnotatedVariable(); + if (type != null) { + return new PsiClassType[]{type}; + } + final PsiClassType superClassFromDSL = GroovyDslFileIndex.pocessScriptSuperClasses(myFile); - PsiClassType superClass = superClassFromDSL != null ? superClassFromDSL - : TypesUtil.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_LANG_SCRIPT, this); + if (superClassFromDSL != null) { + return new PsiClassType[]{superClassFromDSL}; + } + + PsiClassType superClass = TypesUtil.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_LANG_SCRIPT, this); return new PsiClassType[]{superClass}; } + @Nullable + private PsiClassType getSuperClassTypeFromBaseScriptAnnotatedVariable() { + return CachedValuesManager.getCachedValue(myFile, new CachedValueProvider() { + @Nullable + @Override + public Result compute() { + GrVariableDeclaration declaration = findDeclaration(); + if (declaration != null) { + GrModifierList modifierList = declaration.getModifierList(); + if (modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_BASE_SCRIPT) != null) { + GrTypeElement typeElement = declaration.getTypeElementGroovy(); + if (typeElement != null) { + PsiType type = typeElement.getType(); + if (type instanceof PsiClassType) { + return Result.create(((PsiClassType)type), myFile); + } + } + } + } + + return Result.create(null, myFile); + } + }); + } + + @Nullable + private GrVariableDeclaration findDeclaration() { + final Ref ref = Ref.create(); + myFile.accept(new GroovyRecursiveElementVisitor() { + @Override + public void visitVariableDeclaration(GrVariableDeclaration variableDeclaration) { + super.visitVariableDeclaration(variableDeclaration); + if (variableDeclaration.getModifierList().findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_BASE_SCRIPT) != null) { + ref.set(variableDeclaration); + } + } + + @Override + public void visitElement(GroovyPsiElement element) { + if (ref.isNull()) { + super.visitElement(element); + } + } + }); + + return ref.get(); + } + @NotNull public PsiClassType[] getImplementsListTypes() { return PsiClassType.EMPTY_ARRAY; @@ -212,26 +275,47 @@ public class GroovyScriptClass extends LightElement implements PsiClass, Synthet PsiMethod[] methods = myFile.getMethods(); - byte hasMain = 1; - byte hasRun = 1; - for (PsiMethod method : methods) { - if (method.isEquivalentTo(myMainMethod)) { - hasMain = 0; - } - else if (method.isEquivalentTo(myRunMethod)) hasRun = 0; - } - if (hasMain + hasRun == 0) return Result.create(methods, myFile); - - PsiMethod[] result = new PsiMethod[methods.length + hasMain + hasRun]; - if (hasMain == 1) result[0] = myMainMethod; - if (hasRun == 1) result[hasMain] = myRunMethod; - System.arraycopy(methods, 0, result, hasMain + hasRun, methods.length); + int addMain = hasMain(methods) ? 0 : 1; + int addRun = hasRun(methods) ? 0 : 1; + PsiMethod[] result = initMethods(methods, addMain, addRun); return Result.create(result, myFile); } }); } + private PsiMethod[] initMethods(PsiMethod[] methods, int addMain, int addRun) { + if (addMain + addRun == 0) { + return methods; + } + + PsiMethod[] result = new PsiMethod[methods.length + addMain + addRun]; + if (addMain == 1) result[0] = myMainMethod; + if (addRun == 1) result[addMain] = myRunMethod; + System.arraycopy(methods, 0, result, addMain + addRun, methods.length); + return result; + } + + private boolean hasMain(@NotNull PsiMethod[] methods) { + assert myMainMethod != null; + return ContainerUtil.find(methods, new Condition() { + @Override + public boolean value(PsiMethod method) { + return method.isEquivalentTo(myMainMethod); + } + }) != null; + } + + private boolean hasRun(@NotNull PsiMethod[] methods) { + assert myRunMethod != null; + return ContainerUtil.find(methods, new Condition() { + @Override + public boolean value(PsiMethod method) { + return method.isEquivalentTo(myRunMethod); + } + }) != null; + } + private synchronized void initMethods() { if (myInitialized) return; myMainMethod = new LightMethodBuilder(getManager(), GroovyFileType.GROOVY_LANGUAGE, "main"). diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java index 0cf18709c585..996a523a15b2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java @@ -69,6 +69,7 @@ public final class GroovyCommonClassNames { @NonNls public static final String GROOVY_LANG_DELEGATES_TO_TARGET = "groovy.lang.DelegatesTo.Target"; @NonNls public static final String GROOVY_TRANSFORM_COMPILE_DYNAMIC = "groovy.transform.CompileDynamic"; @NonNls public static final String GROOVY_TRANSFORM_STC_CLOSURE_PARAMS = "groovy.transform.stc.ClosureParams"; + @NonNls public static final String GROOVY_TRANSFORM_BASE_SCRIPT = "groovy.transform.BaseScript"; public static final Set GROOVY_EXTENSION_CLASSES = Collections.unmodifiableSet(ContainerUtil.newLinkedHashSet( "org.codehaus.groovy.runtime.DateGroovyMethods", diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy index 5c7a25b73755..4c590e705480 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy @@ -20,6 +20,7 @@ package org.jetbrains.plugins.groovy.lang.resolve; import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiReference import org.intellij.lang.annotations.Language @@ -92,7 +93,7 @@ public abstract class GroovyResolveTestCase extends LightGroovyTestCase { } @Nullable - protected T resolveByText(String text, Class type = null) { + protected T resolveByText(@Language("Groovy") String text, Class type = null) { final ref = configureByText(text) assertNotNull(ref) final resolved = ref.resolve() @@ -107,4 +108,7 @@ public abstract class GroovyResolveTestCase extends LightGroovyTestCase { return ((GrReferenceExpression)ref).advancedResolve(); } + protected PsiClass addBaseScript() { + myFixture.addClass("package groovy.transform; public @interface BaseScript {}") + } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy index ebfcf790745e..c03e13ab9bee 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy @@ -1903,4 +1903,23 @@ new Foo().foo(new File('')) assertTrue(resolved.hasModifierProperty(PsiModifier.STATIC)) } + + void testBaseScript() { + addBaseScript() + + myFixture.addClass ''' +class CustomScript extends Script { + void foo() {} +}''' + + resolveByText(''' +import groovy.transform.BaseScript + +@BaseScript +CustomScript myScript; + +foo() +''', PsiMethod) + } + } From 530e8251a0dae7647f840235a73272ce13d7d774 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Tue, 25 Mar 2014 12:50:22 +0400 Subject: [PATCH 05/69] base script checker --- .../groovy/annotator/BaseScriptAnnotationChecker.java | 6 +++--- .../psi/impl/types/GrCodeReferenceElementImpl.java | 11 ++++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java index 22e79abac6ee..5c49f9499fd5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java @@ -39,7 +39,7 @@ public class BaseScriptAnnotationChecker extends CustomAnnotationChecker { PsiFile file = annotation.getContainingFile(); if (file instanceof GroovyFile && !(((GroovyFile)file).isScript())) { holder.createErrorAnnotation(annotation, GroovyBundle.message("base.script.annotation.is.allowed.only.inside.scripts")); - return false; + return true; } PsiElement pparent = annotation.getParent().getParent(); @@ -50,11 +50,11 @@ public class BaseScriptAnnotationChecker extends CustomAnnotationChecker { if (!InheritanceUtil.isInheritor(type, GroovyCommonClassNames.GROOVY_LANG_SCRIPT)) { String typeText = type != null ? type.getCanonicalText() : CommonClassNames.JAVA_LANG_OBJECT; holder.createErrorAnnotation(annotation, GroovyBundle.message("declared.type.0.have.to.extend.script", typeText)); - return false; + return true; } } } - return true; + return false; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java index 3608405db27c..80a41de9d3e4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java @@ -515,7 +515,7 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl Date: Tue, 25 Mar 2014 11:06:04 +0100 Subject: [PATCH 06/69] IDEA-122833 SearchEverywhere: renderer is broken in Jr. IDEs --- .../src/com/intellij/ide/actions/SearchEverywhereAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index bda015f19206..244d76978759 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -994,8 +994,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } Color bg = cmp.getBackground(); - cmp.setBackground(UIUtil.getListBackground(isSelected)); if (bg == null) { + cmp.setBackground(UIUtil.getListBackground(isSelected)); bg = cmp.getBackground(); } myMainPanel.setBorder(new CustomLineBorder(bg, 0, 0, 2, 0)); From 2c67c8874f212da6570309e45b1745c850ea9558 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 25 Mar 2014 11:38:42 +0100 Subject: [PATCH 07/69] IDEA-122837 Add UI click counters to toolwindow buttons --- .../src/com/intellij/openapi/wm/impl/StripeButton.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java index f9625958aec7..b37e9c4af446 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.wm.impl; +import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.actions.ActivateToolWindowAction; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.actionSystem.ActionGroup; @@ -289,6 +290,7 @@ public final class StripeButton extends AnchoredButton implements ActionListener myDecorator.fireActivated(); } myPressedWhenSelected = false; + FeatureUsageTracker.getInstance().triggerFeatureUsed("toolwindow.clickstat." + myDecorator.getToolWindow().getId()); } public void apply(@NotNull WindowInfoImpl info) { From e949ad5a528936fd2ea0ffb4fa13f78358af0afe Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Mar 2014 11:05:33 +0100 Subject: [PATCH 08/69] remove finishExecution form platform --- .../console/BaseConsoleExecuteActionHandler.java | 9 --------- .../python/console/PydevConsoleExecuteActionHandler.java | 1 - 2 files changed, 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/BaseConsoleExecuteActionHandler.java b/platform/lang-impl/src/com/intellij/execution/console/BaseConsoleExecuteActionHandler.java index 1ab34812695e..2f4ae7d41735 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/BaseConsoleExecuteActionHandler.java +++ b/platform/lang-impl/src/com/intellij/execution/console/BaseConsoleExecuteActionHandler.java @@ -60,15 +60,6 @@ public abstract class BaseConsoleExecuteActionHandler extends ConsoleExecuteActi throw new AbstractMethodError(); } - @Deprecated - /** - * @deprecated to remove in IDEA 14 - * - * Never used. It is Python specific implementation. - */ - public void finishExecution() { - } - public String getEmptyExecuteAction() { return ConsoleExecuteAction.CONSOLE_EXECUTE_ACTION_ID; } diff --git a/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java b/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java index 45f8298d2083..596dfa3c7c47 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java +++ b/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java @@ -322,7 +322,6 @@ public class PydevConsoleExecuteActionHandler extends ProcessBackedConsoleExecut setCurrentIndentSize(1); } - @SuppressWarnings({"override", "deprecation"}) public void finishExecution() { final LanguageConsoleImpl console = myConsoleView.getConsole(); final Editor currentEditor = console.getConsoleEditor(); From b7b7efe2ef1bc7a95aa29d3900c80d80bab0eacb Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 25 Mar 2014 14:51:42 +0400 Subject: [PATCH 09/69] IDEA-122152 Retain 'the oldest' caret in editor on Esc press --- .../openapi/editor/actions/EscapeAction.java | 12 ++++++++-- .../editor/multiCaret/EditorEscape-after.txt | 4 ++-- .../openapi/editor/EditorMultiCaretTest.java | 24 +++++++++++++++++++ .../SelectUnselectOccurrenceActionsTest.java | 9 +++++++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java index bc3b85bfce95..788ff8e9271b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java @@ -17,12 +17,14 @@ package com.intellij.openapi.editor.actions; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.editor.ex.EditorEx; +import org.jetbrains.annotations.Nullable; /** * @author max @@ -35,17 +37,23 @@ public class EscapeAction extends EditorAction { private static class Handler extends EditorActionHandler { @Override - public void execute(Editor editor, DataContext dataContext) { + public void doExecute(Editor editor, @Nullable Caret caret, DataContext dataContext) { if (editor instanceof EditorEx) { EditorEx editorEx = (EditorEx)editor; if (editorEx.isStickySelection()) { editorEx.setStickySelection(false); } } - editor.getCaretModel().removeSecondaryCarets(); + retainOldestCaret(editor.getCaretModel()); editor.getSelectionModel().removeSelection(); } + private static void retainOldestCaret(CaretModel caretModel) { + while(caretModel.getCaretCount() > 1) { + caretModel.removeCaret(caretModel.getPrimaryCaret()); + } + } + @Override public boolean isEnabled(Editor editor, DataContext dataContext) { SelectionModel selectionModel = editor.getSelectionModel(); diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorEscape-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorEscape-after.txt index 4c0106054912..5ab09c21d06e 100644 --- a/platform/platform-tests/testData/editor/multiCaret/EditorEscape-after.txt +++ b/platform/platform-tests/testData/editor/multiCaret/EditorEscape-after.txt @@ -1,2 +1,2 @@ -some text -some other text \ No newline at end of file +some text +some other text \ No newline at end of file diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java index caec0af4de9c..34835b20f92e 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java @@ -242,4 +242,28 @@ public class EditorMultiCaretTest extends AbstractEditorTest { "five eightsix \n" + "seven"); } + + public void testEscapeAfterDragDown() throws Exception { + init("line1\n" + + "line2", + TestFileType.TEXT); + setEditorVisibleSize(1000, 1000); + + mouse().alt().clickAt(0, 1).dragTo(1, 2).release(); + executeAction("EditorEscape"); + checkResultByText("line1\n" + + "line2"); + } + + public void testEscapeAfterDragUp() throws Exception { + init("line1\n" + + "line2", + TestFileType.TEXT); + setEditorVisibleSize(1000, 1000); + + mouse().alt().clickAt(1, 1).dragTo(0, 2).release(); + executeAction("EditorEscape"); + checkResultByText("line1\n" + + "line2"); + } } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java index 8e8dc7b24d9b..d8a740c49a7a 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java @@ -185,6 +185,15 @@ public class SelectUnselectOccurrenceActionsTest extends LightPlatformCodeInsigh checkResult("text text text"); } + public void testEscapeReturnsToInitialPosition() throws Exception { + init("line\n" + + "another line"); + executeAction(); + myFixture.performEditorAction("EditorEscape"); + checkResult("line\n" + + "another line"); + } + private void init(String text) { myFixture.configureByText(FileTypes.PLAIN_TEXT, text); } From d822760bdd49220adef8762184acf0cdf06d88f3 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 24 Mar 2014 15:30:26 +0100 Subject: [PATCH 10/69] no expensive groovy runnable icon calculation in dumb mode --- .../lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java index 1c20805c3463..2c325d1be901 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java @@ -19,6 +19,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef; import com.intellij.lang.ASTNode; import com.intellij.navigation.ItemPresentation; import com.intellij.navigation.ItemPresentationProviders; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -572,7 +573,7 @@ public abstract class GrTypeDefinitionImpl extends GrStubElementBase Date: Tue, 25 Mar 2014 11:34:37 +0100 Subject: [PATCH 11/69] lazy DirectoryInfo order entries calculation --- .../openapi/roots/impl/RootIndex.java | 225 +++++++++++------- .../openapi/roots/impl/DirectoryInfo.java | 20 +- 2 files changed, 139 insertions(+), 106 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java index 960f8e8c6c06..cea7f6be00d0 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootIndex.java @@ -56,21 +56,24 @@ class RootIndex { private final Map myInfoCache = ContainerUtil.newConcurrentMap(); private final List> myRootTypes = ContainerUtil.newArrayList(); private final TObjectIntHashMap> myRootTypeId = new TObjectIntHashMap>(); + @NotNull private final Project myProject; + private volatile Map myOrderEntries; RootIndex(@NotNull final Project project) { + myProject = project; final RootInfo info = buildRootInfo(project); Set allRoots = info.getAllRoots(); for (VirtualFile root : allRoots) { List hierarchy = getHierarchy(root, allRoots, info); - Pair pair = hierarchy == null ? new Pair(null, null) : info.calcDirectoryInfo(root, hierarchy); + Pair pair = hierarchy == null ? new Pair(null, null) : calcDirectoryInfo(root, hierarchy, info); cacheInfos(root, root, pair.first); myPackagePrefixRoots.putValue(pair.second, root); if (info.shouldMarkAsProjectExcluded(root, hierarchy)) { myProjectExcludedRoots.add(root); } } - + myModuleExcludedRoots = info.excludedFromModule.keySet(); } @@ -78,17 +81,14 @@ class RootIndex { final RootInfo info = new RootInfo(); for (final Module module : ModuleManager.getInstance(project).getModules()) { final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); - final OrderEntry[] orderEntries = moduleRootManager.getOrderEntries(); - final ContentEntry[] contentEntries = moduleRootManager.getContentEntries(); - final VirtualFile[] contentRoots = moduleRootManager.getContentRoots(); - for (final VirtualFile contentRoot : contentRoots) { + for (final VirtualFile contentRoot : moduleRootManager.getContentRoots()) { if (!info.contentRootOf.containsKey(contentRoot)) { info.contentRootOf.put(contentRoot, module); } } - for (ContentEntry contentEntry : contentEntries) { + for (ContentEntry contentEntry : moduleRootManager.getContentEntries()) { for (VirtualFile excludeRoot : contentEntry.getExcludeFolderFiles()) { info.excludedFromModule.put(excludeRoot, module); } @@ -105,21 +105,8 @@ class RootIndex { } } - for (OrderEntry orderEntry : orderEntries) { - // init ordered entries - if (orderEntry instanceof ModuleOrderEntry) { - final Module depModule = ((ModuleOrderEntry)orderEntry).getModule(); - if (depModule != null) { - VirtualFile[] importedClassRoots = OrderEnumerator.orderEntries(depModule).exportedOnly().recursively().classes().usingCache().getRoots(); - for (VirtualFile importedClassRoot : importedClassRoots) { - info.depEntries.putValue(importedClassRoot, orderEntry); - } - } - for (VirtualFile sourceRoot : orderEntry.getFiles(OrderRootType.SOURCES)) { - info.depEntries.putValue(sourceRoot, orderEntry); - } - } - else if (orderEntry instanceof LibraryOrSdkOrderEntry) { + for (OrderEntry orderEntry : moduleRootManager.getOrderEntries()) { + if (orderEntry instanceof LibraryOrSdkOrderEntry) { final LibraryOrSdkOrderEntry entry = (LibraryOrSdkOrderEntry)orderEntry; final VirtualFile[] sourceRoots = entry.getRootFiles(OrderRootType.SOURCES); final VirtualFile[] classRoots = entry.getRootFiles(OrderRootType.CLASSES); @@ -127,14 +114,14 @@ class RootIndex { // Init library sources for (final VirtualFile sourceRoot : sourceRoots) { info.classAndSourceRoots.add(sourceRoot); - info.libSourceRootEntries.putValue(sourceRoot, orderEntry); + info.libraryOrSdkSources.add(sourceRoot); info.packagePrefix.put(sourceRoot, ""); } // init library classes for (final VirtualFile classRoot : classRoots) { info.classAndSourceRoots.add(classRoot); - info.libClassRootEntries.putValue(classRoot, orderEntry); + info.libraryOrSdkClasses.add(classRoot); info.packagePrefix.put(classRoot, ""); } @@ -163,6 +150,77 @@ class RootIndex { return info; } + private Map getOrderEntries() { + Map result = myOrderEntries; + if (result != null) return result; + + MultiMap libClassRootEntries = MultiMap.createSmartList(); + MultiMap libSourceRootEntries = MultiMap.createSmartList(); + MultiMap depEntries = MultiMap.createSmartList(); + + for (final Module module : ModuleManager.getInstance(myProject).getModules()) { + final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + for (OrderEntry orderEntry : moduleRootManager.getOrderEntries()) { + if (orderEntry instanceof ModuleOrderEntry) { + final Module depModule = ((ModuleOrderEntry)orderEntry).getModule(); + if (depModule != null) { + VirtualFile[] importedClassRoots = OrderEnumerator.orderEntries(depModule).exportedOnly().recursively().classes().usingCache().getRoots(); + for (VirtualFile importedClassRoot : importedClassRoots) { + depEntries.putValue(importedClassRoot, orderEntry); + } + } + for (VirtualFile sourceRoot : orderEntry.getFiles(OrderRootType.SOURCES)) { + depEntries.putValue(sourceRoot, orderEntry); + } + } + else if (orderEntry instanceof LibraryOrSdkOrderEntry) { + final LibraryOrSdkOrderEntry entry = (LibraryOrSdkOrderEntry)orderEntry; + for (final VirtualFile sourceRoot : entry.getRootFiles(OrderRootType.SOURCES)) { + libSourceRootEntries.putValue(sourceRoot, orderEntry); + } + for (final VirtualFile classRoot : entry.getRootFiles(OrderRootType.CLASSES)) { + libClassRootEntries.putValue(classRoot, orderEntry); + } + } + } + } + + RootInfo rootInfo = buildRootInfo(myProject); + result = ContainerUtil.newHashMap(); + Set allRoots = rootInfo.getAllRoots(); + for (VirtualFile file : allRoots) { + List hierarchy = getHierarchy(file, allRoots, rootInfo); + result.put(file, hierarchy == null ? OrderEntry.EMPTY_ARRAY : calcOrderEntries(rootInfo, depEntries, libClassRootEntries, libSourceRootEntries, hierarchy)); + } + myOrderEntries = result; + return result; + } + + private static OrderEntry[] calcOrderEntries(RootInfo info, + MultiMap depEntries, + MultiMap libClassRootEntries, + MultiMap libSourceRootEntries, List hierarchy) { + @Nullable VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false); + @Nullable VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true); + Set orderEntries = ContainerUtil.newLinkedHashSet(); + orderEntries.addAll(info.getLibraryOrderEntries(hierarchy, libraryClassRoot, librarySourceRoot, libClassRootEntries, libSourceRootEntries)); + for (VirtualFile root : hierarchy) { + orderEntries.addAll(depEntries.get(root)); + } + VirtualFile moduleContentRoot = info.findModuleRootInfo(hierarchy); + if (moduleContentRoot != null) { + ContainerUtil.addIfNotNull(orderEntries, info.getModuleSourceEntry(hierarchy, moduleContentRoot, libClassRootEntries)); + } + if (orderEntries.isEmpty()) { + return null; + } + + OrderEntry[] array = orderEntries.toArray(new OrderEntry[orderEntries.size()]); + Arrays.sort(array, DirectoryInfo.BY_OWNER_MODULE); + return array; + } + + public void checkConsistency() { for (VirtualFile file : myProjectExcludedRoots) { assert file.exists() : file.getPath() + " does not exist"; @@ -338,19 +396,18 @@ class RootIndex { // getDirectoriesByPackageName used to be in this order, some clients might rely on that @NotNull final LinkedHashSet classAndSourceRoots = ContainerUtil.newLinkedHashSet(); + @NotNull final Set libraryOrSdkSources = ContainerUtil.newHashSet(); + @NotNull final Set libraryOrSdkClasses = ContainerUtil.newHashSet(); @NotNull final Map contentRootOf = ContainerUtil.newHashMap(); @NotNull final MultiMap sourceRootOf = MultiMap.createSet(); @NotNull final TObjectIntHashMap rootTypeId = new TObjectIntHashMap(); - @NotNull final MultiMap libClassRootEntries = MultiMap.createSmartList(); - @NotNull final MultiMap libSourceRootEntries = MultiMap.createSmartList(); - @NotNull final MultiMap depEntries = MultiMap.createSmartList(); @NotNull final MultiMap excludedFromLibraries = MultiMap.createSmartList(); @NotNull final MultiMap classOfLibraries = MultiMap.createSmartList(); @NotNull final MultiMap sourceOfLibraries = MultiMap.createSmartList(); @NotNull final Set excludedFromProject = ContainerUtil.newHashSet(); @NotNull final Map excludedFromModule = ContainerUtil.newHashMap(); @NotNull final Map packagePrefix = ContainerUtil.newHashMap(); - + Set getAllRoots() { LinkedHashSet result = ContainerUtil.newLinkedHashSet(); result.addAll(classAndSourceRoots); @@ -371,7 +428,7 @@ class RootIndex { } }) == null; } - + @Nullable private VirtualFile findModuleRootInfo(List hierarchy) { for (VirtualFile root : hierarchy) { @@ -392,10 +449,10 @@ class RootIndex { Set librariesToIgnore = ContainerUtil.newHashSet(); for (VirtualFile root : hierarchy) { librariesToIgnore.addAll(excludedFromLibraries.get(root)); - if (source && libSourceRootEntries.containsKey(root) && + if (source && libraryOrSdkSources.contains(root) && (!sourceOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(sourceOfLibraries.get(root)))) { return root; - } else if (!source && libClassRootEntries.containsKey(root) && + } else if (!source && libraryOrSdkClasses.contains(root) && (!classOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(classOfLibraries.get(root)))) { return root; } @@ -403,35 +460,6 @@ class RootIndex { return null; } - @NotNull - private Pair calcDirectoryInfo(VirtualFile root, @NotNull final List hierarchy) { - VirtualFile moduleContentRoot = findModuleRootInfo(hierarchy); - VirtualFile libraryClassRoot = findLibraryRootInfo(hierarchy, false); - VirtualFile librarySourceRoot = findLibraryRootInfo(hierarchy, true); - if (moduleContentRoot == null && libraryClassRoot == null && librarySourceRoot == null) { - return new Pair(null, null); - } - - VirtualFile sourceRoot = findPackageRootInfo(hierarchy, moduleContentRoot, null, librarySourceRoot); - - VirtualFile moduleSourceRoot = findPackageRootInfo(hierarchy, moduleContentRoot, null, null); - boolean inModuleSources = moduleSourceRoot != null; - boolean inLibrarySource = librarySourceRoot != null; - int typeId = moduleSourceRoot != null ? rootTypeId.get(moduleSourceRoot) : 0; - - OrderEntry[] entries = getOrderEntries(hierarchy, moduleContentRoot, libraryClassRoot, librarySourceRoot); - DirectoryInfo directoryInfo = new DirectoryInfo(contentRootOf.get(moduleContentRoot), - moduleContentRoot, - sourceRoot, - libraryClassRoot, - (byte)DirectoryInfo.createSourceRootTypeData(inModuleSources, inLibrarySource, typeId), - entries); - - String packagePrefix = calcPackagePrefix(root, hierarchy, moduleContentRoot, libraryClassRoot, librarySourceRoot); - - return Pair.create(directoryInfo, packagePrefix); - } - private String calcPackagePrefix(VirtualFile root, List hierarchy, VirtualFile moduleContentRoot, @@ -467,31 +495,28 @@ class RootIndex { return null; } - private void collectDependencyOrderEntries(List hierarchy, Set result) { - for (VirtualFile root : hierarchy) { - result.addAll(depEntries.get(root)); - } - } - - private void collectLibraryOrderEntries(List hierarchy, - @Nullable VirtualFile libraryClassRoot, - @Nullable VirtualFile librarySourceRoot, - Set result) { + private LinkedHashSet getLibraryOrderEntries(List hierarchy, + @Nullable VirtualFile libraryClassRoot, + @Nullable VirtualFile librarySourceRoot, + MultiMap libClassRootEntries, + MultiMap libSourceRootEntries) { + LinkedHashSet orderEntries = ContainerUtil.newLinkedHashSet(); for (VirtualFile root : hierarchy) { if (root == libraryClassRoot && !sourceRootOf.containsKey(root)) { - result.addAll(libClassRootEntries.get(root)); + orderEntries.addAll(libClassRootEntries.get(root)); } if (root == librarySourceRoot && libraryClassRoot == null) { - result.addAll(libSourceRootEntries.get(root)); + orderEntries.addAll(libSourceRootEntries.get(root)); } if (libClassRootEntries.containsKey(root) || sourceRootOf.containsKey(root) && librarySourceRoot == null) { break; } } + return orderEntries; } @Nullable - private ModuleSourceOrderEntry getModuleSourceEntry(List hierarchy, @NotNull VirtualFile moduleContentRoot) { + private ModuleSourceOrderEntry getModuleSourceEntry(List hierarchy, @NotNull VirtualFile moduleContentRoot, MultiMap libClassRootEntries) { Module module = contentRootOf.get(moduleContentRoot); for (VirtualFile root : hierarchy) { if (sourceRootOf.get(root).contains(module)) { @@ -504,24 +529,42 @@ class RootIndex { return null; } - private OrderEntry[] getOrderEntries(List hierarchy, - @Nullable VirtualFile moduleContentRoot, - @Nullable VirtualFile libraryClassRoot, - @Nullable VirtualFile librarySourceRoot) { - LinkedHashSet orderEntries = ContainerUtil.newLinkedHashSet(); - collectLibraryOrderEntries(hierarchy, libraryClassRoot, librarySourceRoot, orderEntries); - collectDependencyOrderEntries(hierarchy, orderEntries); - if (moduleContentRoot != null) { - ContainerUtil.addIfNotNull(orderEntries, getModuleSourceEntry(hierarchy, moduleContentRoot)); - } - if (orderEntries.isEmpty()) { - return null; - } - - OrderEntry[] array = orderEntries.toArray(new OrderEntry[orderEntries.size()]); - Arrays.sort(array, DirectoryInfo.BY_OWNER_MODULE); - return array; - } } + @NotNull + private Pair calcDirectoryInfo(final VirtualFile root, @NotNull final List hierarchy, RootInfo info) { + VirtualFile moduleContentRoot = info.findModuleRootInfo(hierarchy); + VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false); + VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true); + if (moduleContentRoot == null && libraryClassRoot == null && librarySourceRoot == null) { + return new Pair(null, null); + } + + VirtualFile sourceRoot = info.findPackageRootInfo(hierarchy, moduleContentRoot, null, librarySourceRoot); + + VirtualFile moduleSourceRoot = info.findPackageRootInfo(hierarchy, moduleContentRoot, null, null); + boolean inModuleSources = moduleSourceRoot != null; + boolean inLibrarySource = librarySourceRoot != null; + int typeId = moduleSourceRoot != null ? info.rootTypeId.get(moduleSourceRoot) : 0; + + DirectoryInfo directoryInfo = new DirectoryInfo(info.contentRootOf.get(moduleContentRoot), + moduleContentRoot, + sourceRoot, + libraryClassRoot, + (byte)DirectoryInfo.createSourceRootTypeData(inModuleSources, inLibrarySource, typeId), + null) { + @NotNull + @Override + public OrderEntry[] getOrderEntries() { + OrderEntry[] entries = RootIndex.this.getOrderEntries().get(root); + return entries == null ? OrderEntry.EMPTY_ARRAY : entries; + } + }; + + String packagePrefix = info.calcPackagePrefix(root, hierarchy, moduleContentRoot, libraryClassRoot, librarySourceRoot); + + return Pair.create(directoryInfo, packagePrefix); + } + + } \ No newline at end of file diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java index 4298046c8c24..550e99d82033 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java @@ -35,7 +35,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; -public final class DirectoryInfo { +public class DirectoryInfo { public static final int MAX_ROOT_TYPE_ID = (1 << (Byte.SIZE - 2)) - 1; private final Module module; // module to which content it belongs or null private final VirtualFile libraryClassRoot; // class root in library @@ -81,7 +81,7 @@ public final class DirectoryInfo { Comparing.equal(contentRoot, info.contentRoot) && Comparing.equal(libraryClassRoot, info.libraryClassRoot) && Comparing.equal(module, info.module) && - Arrays.equals(orderEntries, info.orderEntries) && + Arrays.equals(getOrderEntries(), info.getOrderEntries()) && Comparing.equal(sourceRoot, info.sourceRoot); } @@ -105,7 +105,7 @@ public final class DirectoryInfo { ", libraryClassRoot=" + getLibraryClassRoot() + ", contentRoot=" + getContentRoot() + ", sourceRoot=" + getSourceRoot() + - ", orderEntries=" + Arrays.toString(orderEntries) + + ", orderEntries=" + Arrays.toString(getOrderEntries()) + "}"; } @@ -117,10 +117,7 @@ public final class DirectoryInfo { @Nullable OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) { - OrderEntry[] entries = orderEntries; - if (entries == null) { - return null; - } + OrderEntry[] entries = getOrderEntries(); if (entries.length < 10) { for (OrderEntry entry : entries) { if (entry.getOwnerModule() == ownerModule) return entry; @@ -133,10 +130,7 @@ public final class DirectoryInfo { @NotNull List findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) { - OrderEntry[] entries = orderEntries; - if (entries == null) { - return Collections.emptyList(); - } + OrderEntry[] entries = getOrderEntries(); if (entries.length == 1) { OrderEntry entry = entries[0]; return entry.getOwnerModule() == ownerModule ? Arrays.asList(entries) : Collections.emptyList(); @@ -271,10 +265,6 @@ public final class DirectoryInfo { return sourceRoot; } - public boolean hasSourceRoot() { - return getSourceRoot() != null; - } - public VirtualFile getLibraryClassRoot() { return libraryClassRoot; } From 104f227341785d9d896633148757fae1055e130b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Mar 2014 11:46:50 +0100 Subject: [PATCH 12/69] gFileChooserDescriptor renamed to getFileChooserDescriptor --- .../src/com/intellij/openapi/ui/TextBrowseFolderListener.java | 2 +- .../src/com/intellij/openapi/ui/TextFieldWithBrowseButton.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/ui/TextBrowseFolderListener.java b/platform/platform-api/src/com/intellij/openapi/ui/TextBrowseFolderListener.java index 5bb1f74f3bcf..8064d19d8843 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/TextBrowseFolderListener.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/TextBrowseFolderListener.java @@ -35,7 +35,7 @@ public class TextBrowseFolderListener extends ComponentWithBrowseButton.BrowseFo myTextComponent = component; } - FileChooserDescriptor gFileChooserDescriptor() { + FileChooserDescriptor getFileChooserDescriptor() { return myFileChooserDescriptor; } } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/openapi/ui/TextFieldWithBrowseButton.java b/platform/platform-api/src/com/intellij/openapi/ui/TextFieldWithBrowseButton.java index bf7b6ed0796f..4c60c7f5af07 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/TextFieldWithBrowseButton.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/TextFieldWithBrowseButton.java @@ -59,7 +59,7 @@ public class TextFieldWithBrowseButton extends ComponentWithBrowseButton Date: Tue, 25 Mar 2014 14:58:45 +0400 Subject: [PATCH 13/69] IDEA-122607 "SVN Repositories" tab don't closing --- .../src/com/intellij/util/ui/FadeInFadeOut.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/util/ui/FadeInFadeOut.java b/platform/platform-api/src/com/intellij/util/ui/FadeInFadeOut.java index 14eccd0c55f1..4c9ecac18f36 100644 --- a/platform/platform-api/src/com/intellij/util/ui/FadeInFadeOut.java +++ b/platform/platform-api/src/com/intellij/util/ui/FadeInFadeOut.java @@ -16,6 +16,7 @@ package com.intellij.util.ui; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -34,7 +35,7 @@ public class FadeInFadeOut extends JComponent { private final BufferedImage myComponentImage; private Rectangle myComponentBounds; - @NotNull + @Nullable private final Component myIcon; private Rectangle myIconBounds; @@ -46,7 +47,7 @@ public class FadeInFadeOut extends JComponent { private Runnable myOnDone = null; - public FadeInFadeOut(@NotNull Component component, int timeToComplete, boolean fadeIn, @NotNull Component icon) { + public FadeInFadeOut(@NotNull Component component, int timeToComplete, boolean fadeIn, @Nullable Component icon) { setFocusable(false); myComponent = component; myFadeIn = fadeIn; @@ -81,7 +82,11 @@ public class FadeInFadeOut extends JComponent { super.reshape(x, y, w, h); if (!myTriggered) { myComponentBounds = SwingUtilities.convertRectangle(myComponent.getParent(), myComponent.getBounds(), this); - myIconBounds = SwingUtilities.convertRectangle(myIcon.getParent(), myIcon.getBounds(), this); + if (myIcon == null) { + myIconBounds = myComponentBounds; + } else { + myIconBounds = SwingUtilities.convertRectangle(myIcon.getParent(), myIcon.getBounds(), this); + } } } From cd14dd0484ef2f5c0ea52be9dd4cb49ed2fd950c Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 25 Mar 2014 11:58:10 +0100 Subject: [PATCH 14/69] IDEA-122838 Add UI click counters to the Editor context menu --- .../intellij/openapi/actionSystem/impl/ActionMenuItem.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java index 4a4322a06420..1c6fa05e4fb5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.actionSystem.impl; +import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; @@ -227,6 +228,10 @@ public class ActionMenuItem extends JCheckBoxMenuItem { public void actionPerformed(final ActionEvent e) { final IdeFocusManager fm = IdeFocusManager.findInstanceByContext(myContext); final ActionCallback typeAhead = new ActionCallback(); + final String id = ActionManager.getInstance().getId(myAction.getAction()); + if (id != null) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("context.menu.click.stats." + id.replace(' ', '.')); + } fm.typeAheadUntil(typeAhead); fm.runOnOwnContext(myContext, new Runnable() { @Override From 390da27143c38017cb752378541028073f89d6ec Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 25 Mar 2014 15:38:09 +0400 Subject: [PATCH 15/69] Bug fix: replace addListener() with removeListener() inside ToolWindowManagerImpl.removeToolWindowManagerListener() +review CR-IC --- .../src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9f35bddaac03..b1c4abddbcf3 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 @@ -575,7 +575,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements @Override public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { - myDispatcher.addListener(l); + myDispatcher.removeListener(l); } /** From 29f8c8b32dfc684c68dcaddae5c91651ef1689f7 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 25 Mar 2014 12:47:37 +0100 Subject: [PATCH 16/69] IDEA-112576 ("if statement replaceable with switch" quickfix is not equivalent for string targets) --- .../siyeh/InspectionGadgetsBundle.properties | 1 + .../ig/migration/IfCanBeSwitchInspection.java | 44 ++++--------- .../com/siyeh/ig/psiutils/SwitchUtils.java | 61 ++++++++++++++++--- .../inspectionDescriptions/IfCanBeSwitch.html | 2 + .../migration/if_switch/IfCanBeSwitch.java | 38 ++++++++++-- .../igtest/migration/if_switch/expected.xml | 14 +++++ .../IfCanBeSwitchInspectionTest.java | 5 +- 7 files changed, 118 insertions(+), 47 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index bd42445a51ae..613ddd22ec3d 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1877,6 +1877,7 @@ if.can.be.switch.quickfix=Replace with 'switch' if.can.be.switch.minimum.branch.option=Minimum number of branches: if.can.be.switch.int.option=Suggest switch on numbers if.can.be.switch.enum.option=Suggest switch on enums +if.can.be.switch.null.safe.option=Only suggest on null-safe expressions unnecessarily.qualified.inner.class.access.option=Ignore references for which an import is needed unqualified.inner.class.access.option=Ignore references to local inner classes try.with.identical.catches.quickfix=Collapse 'catch' blocks diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/IfCanBeSwitchInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/IfCanBeSwitchInspection.java index 08ea82310e0e..1a70ac3b1639 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/IfCanBeSwitchInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/IfCanBeSwitchInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 Bas Leijdekkers + * Copyright 2011-2014 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,20 +15,19 @@ */ package com.siyeh.ig.migration; -import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.ui.DocumentAdapter; +import com.intellij.util.ui.CheckBox; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.ControlFlowUtils; import com.siyeh.ig.psiutils.EquivalenceChecker; -import com.siyeh.ig.psiutils.ParenthesesUtils; import com.siyeh.ig.psiutils.SwitchUtils; import com.siyeh.ig.psiutils.SwitchUtils.IfStatementBranch; import org.jetbrains.annotations.Nls; @@ -37,8 +36,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.text.Document; import java.awt.*; @@ -58,6 +55,9 @@ public class IfCanBeSwitchInspection extends BaseInspection { @SuppressWarnings({"PublicField"}) public boolean suggestEnumSwitches = false; + @SuppressWarnings("PublicField") + public boolean onlySuggestNullSafe = true; + @Override public boolean isEnabledByDefault() { return true; @@ -121,26 +121,16 @@ public class IfCanBeSwitchInspection extends BaseInspection { constraints.gridx = 0; constraints.gridy = 1; constraints.gridwidth = 2; - final JCheckBox checkBox1 = new JCheckBox(InspectionGadgetsBundle.message("if.can.be.switch.int.option"), suggestIntSwitches); - final ButtonModel model1 = checkBox1.getModel(); - model1.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - suggestIntSwitches = model1.isSelected(); - } - }); + final CheckBox checkBox1 = new CheckBox(InspectionGadgetsBundle.message("if.can.be.switch.int.option"), this, "suggestIntSwitches"); panel.add(checkBox1, constraints); constraints.gridy = 2; - constraints.weighty = 1.0; - final JCheckBox checkBox2 = new JCheckBox(InspectionGadgetsBundle.message("if.can.be.switch.enum.option"), suggestEnumSwitches); - final ButtonModel model2 = checkBox2.getModel(); - model2.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - suggestEnumSwitches = model2.isSelected(); - } - }); + final CheckBox checkBox2 = new CheckBox(InspectionGadgetsBundle.message("if.can.be.switch.enum.option"), this, "suggestEnumSwitches"); panel.add(checkBox2, constraints); + constraints.gridy = 3; + constraints.weighty = 1.0; + final CheckBox checkBox3 = + new CheckBox(InspectionGadgetsBundle.message("if.can.be.switch.null.safe.option"), this, "onlySuggestNullSafe"); + panel.add(checkBox3, constraints); return panel; } @@ -508,18 +498,10 @@ public class IfCanBeSwitchInspection extends BaseInspection { if (parent instanceof PsiIfStatement) { return; } - final PsiExpression switchExpression = SwitchUtils.getSwitchExpression(statement, minimumBranches); + final PsiExpression switchExpression = SwitchUtils.getSwitchExpression(statement, minimumBranches, onlySuggestNullSafe); if (switchExpression == null) { return; } - final PsiExpression unwrappedExpression = ParenthesesUtils.stripParentheses(switchExpression); - if (unwrappedExpression instanceof PsiReferenceExpression) { - final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)unwrappedExpression; - final PsiElement target = referenceExpression.resolve(); - if (target instanceof PsiModifierListOwner && NullableNotNullManager.isNullable((PsiModifierListOwner)target)) { - return; - } - } final PsiType type = switchExpression.getType(); if (!suggestIntSwitches) { if (type instanceof PsiClassType) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SwitchUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SwitchUtils.java index b759773ddea5..115a38d93133 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SwitchUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/SwitchUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2014 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. @@ -15,6 +15,7 @@ */ package com.siyeh.ig.psiutils; +import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; @@ -47,16 +48,21 @@ public class SwitchUtils { @Nullable public static PsiExpression getSwitchExpression(PsiIfStatement statement, int minimumBranches) { + return getSwitchExpression(statement, minimumBranches, false); + } + + @Nullable + public static PsiExpression getSwitchExpression(PsiIfStatement statement, int minimumBranches, boolean nullSafe) { final PsiExpression condition = statement.getCondition(); final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(statement); - final PsiExpression possibleSwitchExpression = determinePossibleSwitchExpressions(condition, languageLevel); + final PsiExpression possibleSwitchExpression = determinePossibleSwitchExpressions(condition, languageLevel, nullSafe); if (!canBeSwitchExpression(possibleSwitchExpression, languageLevel)) { return null; } int branchCount = 0; while (true) { branchCount++; - if (!canBeMadeIntoCase(statement.getCondition(), possibleSwitchExpression, languageLevel)) { + if (!canBeMadeIntoCase(statement.getCondition(), possibleSwitchExpression, languageLevel, false)) { break; } final PsiStatement elseBranch = statement.getElseBranch(); @@ -74,10 +80,11 @@ public class SwitchUtils { return null; } - private static boolean canBeMadeIntoCase(PsiExpression expression, PsiExpression switchExpression, LanguageLevel languageLevel) { + private static boolean canBeMadeIntoCase(PsiExpression expression, PsiExpression switchExpression, LanguageLevel languageLevel, + boolean nullSafe) { expression = ParenthesesUtils.stripParentheses(expression); if (languageLevel.isAtLeast(LanguageLevel.JDK_1_7)) { - final PsiExpression stringSwitchExpression = determinePossibleStringSwitchExpression(expression); + final PsiExpression stringSwitchExpression = determinePossibleStringSwitchExpression(expression, nullSafe); if (EquivalenceChecker.expressionsAreEquivalent(switchExpression, stringSwitchExpression)) { return true; } @@ -90,7 +97,7 @@ public class SwitchUtils { final PsiExpression[] operands = polyadicExpression.getOperands(); if (operation.equals(JavaTokenType.OROR)) { for (PsiExpression operand : operands) { - if (!canBeMadeIntoCase(operand, switchExpression, languageLevel)) { + if (!canBeMadeIntoCase(operand, switchExpression, languageLevel, nullSafe)) { return false; } } @@ -114,6 +121,9 @@ public class SwitchUtils { return true; } else if (type instanceof PsiClassType) { + if (isAnnotatedNullable(expression)) { + return false; + } if (type.equalsToText(CommonClassNames.JAVA_LANG_CHARACTER) || type.equalsToText(CommonClassNames.JAVA_LANG_BYTE) || type.equalsToText(CommonClassNames.JAVA_LANG_SHORT) || type.equalsToText(CommonClassNames.JAVA_LANG_INTEGER)) { return true; @@ -132,13 +142,13 @@ public class SwitchUtils { return false; } - private static PsiExpression determinePossibleSwitchExpressions(PsiExpression expression, LanguageLevel languageLevel) { + private static PsiExpression determinePossibleSwitchExpressions(PsiExpression expression, LanguageLevel languageLevel, boolean nullSafe) { expression = ParenthesesUtils.stripParentheses(expression); if (expression == null) { return null; } if (languageLevel.isAtLeast(LanguageLevel.JDK_1_7)) { - final PsiExpression jdk17Expression = determinePossibleStringSwitchExpression(expression); + final PsiExpression jdk17Expression = determinePossibleStringSwitchExpression(expression, nullSafe); if (jdk17Expression != null) { return jdk17Expression; } @@ -150,7 +160,7 @@ public class SwitchUtils { final IElementType operation = polyadicExpression.getOperationTokenType(); final PsiExpression[] operands = polyadicExpression.getOperands(); if (operation.equals(JavaTokenType.OROR) && operands.length > 0) { - return determinePossibleSwitchExpressions(operands[0], languageLevel); + return determinePossibleSwitchExpressions(operands[0], languageLevel, nullSafe); } else if (operation.equals(JavaTokenType.EQEQ) && operands.length == 2) { final PsiExpression lhs = operands[0]; @@ -165,7 +175,7 @@ public class SwitchUtils { return null; } - private static PsiExpression determinePossibleStringSwitchExpression(PsiExpression expression) { + private static PsiExpression determinePossibleStringSwitchExpression(PsiExpression expression, boolean nullSafe) { if (!(expression instanceof PsiMethodCallExpression)) { return null; } @@ -194,6 +204,9 @@ public class SwitchUtils { return null; } if (PsiUtil.isConstantExpression(qualifierExpression)) { + if (nullSafe && !isAnnotatedNotNull(argument)) { + return null; + } return argument; } else if (PsiUtil.isConstantExpression(argument)) { @@ -202,6 +215,34 @@ public class SwitchUtils { return null; } + private static boolean isAnnotatedNotNull(PsiExpression expression) { + expression = ParenthesesUtils.stripParentheses(expression); + if (!(expression instanceof PsiReferenceExpression)) { + return false; + } + final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression; + final PsiElement target = referenceExpression.resolve(); + if (!(target instanceof PsiModifierListOwner)) { + return false; + } + final PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)target; + return NullableNotNullManager.isNotNull(modifierListOwner); + } + + private static boolean isAnnotatedNullable(PsiExpression expression) { + expression = ParenthesesUtils.stripParentheses(expression); + if (!(expression instanceof PsiReferenceExpression)) { + return false; + } + final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression; + final PsiElement target = referenceExpression.resolve(); + if (!(target instanceof PsiModifierListOwner)) { + return false; + } + final PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)target; + return NullableNotNullManager.isNullable(modifierListOwner); + } + private static boolean canBeCaseLabel(PsiExpression expression, LanguageLevel languageLevel) { if (expression == null) { return false; diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IfCanBeSwitch.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IfCanBeSwitch.html index 527cc6996a26..33a970a9b3e7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IfCanBeSwitch.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IfCanBeSwitch.html @@ -14,6 +14,8 @@ primitive and boxed numbers and characters. Use the second checkbox below to have this inspection suggest switch statements on enum constants.

+Use the third checkbox below to only suggest switch statements which can't introduce a NullPointerException +

New in 10.5 \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/IfCanBeSwitch.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/IfCanBeSwitch.java index 4b65e91cb8f2..7bfc8aa08ff0 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/IfCanBeSwitch.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/IfCanBeSwitch.java @@ -1,5 +1,5 @@ +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; - class IfCanBeSwitch { void m1(int i) { // ok if (i == 0) System.out.println("zero"); else if (i == 1) System.out.println("one"); else System.out.println("many"); @@ -23,10 +23,10 @@ class IfCanBeSwitch { void polyadic() { String s = null; - if ("asdf".equals(s) || "addd".equals(s) || "lkjh".equals(s)) { + if (s.equals("asdf") || s.equals("addd") || s.equals("lkjh")) { System.out.println("asdf"); - } else if ("null".equals(s)) { + } else if (s.equals("null")) { System.out.println("null"); } else { @@ -35,7 +35,7 @@ class IfCanBeSwitch { } void nullable(@Nullable String s) { - if ("a".equals(s)) { + if ("a".equals((s))) { System.out.println(1); } else if ("b".equals(s)) { System.out.println(2); @@ -45,4 +45,34 @@ class IfCanBeSwitch { System.out.println(4); } } + + void notNullSafe() { + String narf = null; + if ("foo".equals(narf)) { + // do this + } else if ("bar".equals(narf)){ + // do that + } + else { + // do something else. + } + } + + void nullSafe(String earth) { + if (earth.equals("foo")) { + } else if ("bar".equals(earth)) { + } else { + } + } + + void nullSafe2(@NotNull String narf) { + if ("foo".equals((narf))) { + // do this + } else if ("bar".equals(narf)){ + // do that + } + else { + // do something else. + } + } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/expected.xml index af78b4213567..e56ebb574747 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/if_switch/expected.xml @@ -27,4 +27,18 @@ 'if' replaceable with 'switch' <code>if</code> statement replaceable with 'switch' statement #loc + + + IfCanBeSwitch.java + 62 + 'if' replaceable with 'switch' + <code>if</code> statement replaceable with 'switch' statement #loc + + + + IfCanBeSwitch.java + 69 + 'if' replaceable with 'switch' + <code>if</code> statement replaceable with 'switch' statement #loc + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/IfCanBeSwitchInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/IfCanBeSwitchInspectionTest.java index bf9dced7682a..704748f02df4 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/IfCanBeSwitchInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/IfCanBeSwitchInspectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ public class IfCanBeSwitchInspectionTest extends IGInspectionTestCase { public void test() throws Exception { final IfCanBeSwitchInspection inspection = new IfCanBeSwitchInspection(); inspection.suggestIntSwitches = true; - doTest("com/siyeh/igtest/migration/if_switch", new LocalInspectionToolWrapper(inspection)); + inspection.onlySuggestNullSafe = true; + doTest("com/siyeh/igtest/migration/if_switch", new LocalInspectionToolWrapper(inspection)); } } From b814912aa986bb7ad3da0da5321372e07a36afd2 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 25 Mar 2014 16:01:15 +0400 Subject: [PATCH 17/69] Improove code readability. +review CR-IC-4863 --- .../annotator/MavenDomGutterAnnotator.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java index 952ae7039862..b240e899a40f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java @@ -190,33 +190,33 @@ public class MavenDomGutterAnnotator implements Annotator { private static String generateTooltip(MavenDomDependency dependency) { StringBuilder res = new StringBuilder(); - res.append("<dependency>\n"); - res.append("    <groupId>").append(dependency.getGroupId().getStringValue()).append("</groupId>\n"); - res.append("    <artifactId>").append(dependency.getArtifactId().getStringValue()).append("</artifactId>\n"); + res.append("\n"); + res.append(" ").append(dependency.getGroupId().getStringValue()).append("\n"); + res.append(" ").append(dependency.getArtifactId().getStringValue()).append("\n"); if (dependency.getType().getXmlElement() != null) { - res.append("    <type>").append(dependency.getType().getStringValue()).append("</type>\n"); + res.append(" ").append(dependency.getType().getStringValue()).append("\n"); } if (dependency.getClassifier().getXmlElement() != null) { - res.append("    <classifier>").append(dependency.getClassifier().getStringValue()).append("</classifier>\n"); + res.append(" ").append(dependency.getClassifier().getStringValue()).append("\n"); } if (dependency.getScope().getXmlElement() != null) { - res.append("    <scope>").append(dependency.getScope().getStringValue()).append("</scope>\n"); + res.append(" ").append(dependency.getScope().getStringValue()).append("\n"); } if (dependency.getOptional().getXmlElement() != null) { - res.append("    <optional>").append(dependency.getOptional().getStringValue()).append("</optional>\n"); + res.append(" ").append(dependency.getOptional().getStringValue()).append("\n"); } if (dependency.getVersion().getXmlElement() != null) { - res.append("    <version>").append(dependency.getVersion().getStringValue()).append("</version>\n"); + res.append(" ").append(dependency.getVersion().getStringValue()).append("\n"); } - res.append("</dependency>"); + res.append(""); - return res.toString(); + return StringUtil.escapeXml(res.toString()).replace(" ", " "); } private static class MyListCellRenderer extends PsiElementListCellRenderer { From 446b34c6fdac6436f6fa8419004f68623692dc5e Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Tue, 25 Mar 2014 16:21:14 +0400 Subject: [PATCH 18/69] Eliminating ugly black window with jdk7 and jdk8. --- .../intellij/ui/messages/SheetMessage.java | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java index 765d56091fb8..786613eaf430 100755 --- a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java @@ -17,7 +17,9 @@ package com.intellij.ui.messages; import com.apple.eawt.FullScreenUtilities; import com.intellij.openapi.application.impl.LaterInvocator; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.JBColor; import com.intellij.ui.mac.MacMainFrameDecorator; import com.intellij.util.ui.Animator; @@ -28,12 +30,17 @@ import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; /** * Created by Denis Fokin */ public class SheetMessage { + + private static final Logger LOG = Logger.getInstance("#com.intellij.ui.messages.SheetMessage"); + private JDialog myWindow; private Window myParent; private SheetController myController; @@ -73,19 +80,51 @@ public class SheetMessage { registerMoveResizeHandler(); myWindow.setFocusable(true); myWindow.setFocusableWindowState(true); + if (SystemInfo.isJavaVersionAtLeast("1.7")) { + myWindow.setSize(myController.SHEET_NC_WIDTH, 0); - startAnimation(true); - myWindow.setSize(myController.SHEET_NC_WIDTH, myController.SHEET_NC_HEIGHT); + setWindowOpacity(0.0f); + + myWindow.addComponentListener(new ComponentAdapter() { + @Override + public void componentShown(ComponentEvent e) { + super.componentShown(e); + setWindowOpacity(1.0f); + myWindow.setSize(myController.SHEET_NC_WIDTH, myController.SHEET_NC_HEIGHT); + startAnimation(true); + } + }); + } else { + myWindow.setModal(true); + myWindow.setSize(myController.SHEET_NC_WIDTH, myController.SHEET_NC_HEIGHT); + setPositionRelativeToParent(); + } restoreFullscreenButton = couldBeInFullScreen(); if (restoreFullscreenButton) { FullScreenUtilities.setWindowCanFullScreen(myParent, false); } - setPositionRelativeToParent(); + LaterInvocator.enterModal(myWindow); myWindow.setVisible(true); LaterInvocator.leaveModal(myWindow); } + private void setWindowOpacity(float opacity) { + try { + Method setOpacityMethod = myWindow.getClass().getMethod("setOpacity", Float.TYPE); + setOpacityMethod.invoke(myWindow, opacity); + } + catch (NoSuchMethodException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + catch (IllegalAccessException e) { + LOG.error(e); + } + } + private boolean couldBeInFullScreen() { if (myParent instanceof JFrame) { JRootPane rootPane = ((JFrame)myParent).getRootPane(); From 1896ad2c789fdbd64d77a880f43c27d585c99233 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 25 Mar 2014 16:25:15 +0400 Subject: [PATCH 19/69] IDEA-121916 Allow to select several words with multiple carets with mouse --- .../openapi/editor/impl/EditorImpl.java | 23 +++++++--- .../openapi/editor/EditorMultiCaretTest.java | 43 ++++++++++++++++++- .../fixtures/EditorMouseFixture.java | 22 ++++++++-- 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index c90c5286debb..3dbffbf59f91 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -306,6 +306,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi private LogicalPosition myLastMousePressedLocation; private VisualPosition myTargetMultiSelectionPosition; private boolean myMultiSelectionInProgress; + private boolean myLastPressCreatedCaret; private CaretImpl myPrimaryCaret; @@ -5670,22 +5671,31 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi final int oldStart = mySelectionModel.getSelectionStart(); final int oldEnd = mySelectionModel.getSelectionEnd(); + boolean toggleCaret = myCaretModel.supportsMultipleCarets() && e.getSource() != myGutterComponent && isToggleCaretEvent(e); + boolean lastPressCreatedCaret = myLastPressCreatedCaret; + if (e.getClickCount() == 1) { + myLastPressCreatedCaret = false; + } // Don't move caret on mouse press above gutter line markers area (a place where break points, 'override', 'implements' etc icons // are drawn) and annotations area. E.g. we don't want to change caret position if a user sets new break point (clicks // at 'line markers' area). if (e.getSource() != myGutterComponent || (eventArea != EditorMouseEventArea.LINE_MARKERS_AREA && eventArea != EditorMouseEventArea.ANNOTATIONS_AREA)) { - boolean toggleCaret = myCaretModel.supportsMultipleCarets() && e.getSource() != myGutterComponent && isToggleCaretEvent(e); LogicalPosition pos = getLogicalPositionForScreenPos(x, y, true); if (toggleCaret) { VisualPosition visualPosition = logicalToVisualPosition(pos); Caret caret = getCaretModel().getCaretAt(visualPosition); - if (caret == null) { - getCaretModel().addCaret(visualPosition); + if (e.getClickCount() == 1) { + if (caret == null) { + myLastPressCreatedCaret = getCaretModel().addCaret(visualPosition) != null; + } + else { + getCaretModel().removeCaret(caret); + } } - else { - getCaretModel().removeCaret(caret); + else if (e.getClickCount() == 3 && lastPressCreatedCaret) { + getCaretModel().moveToLogicalPosition(pos); } } else { @@ -5755,7 +5765,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } else { if (!e.isPopupTrigger() - && (eventArea == EditorMouseEventArea.EDITING_AREA || eventArea == EditorMouseEventArea.LINE_NUMBERS_AREA)) + && (eventArea == EditorMouseEventArea.EDITING_AREA || eventArea == EditorMouseEventArea.LINE_NUMBERS_AREA) + && (!toggleCaret || lastPressCreatedCaret)) { switch (e.getClickCount()) { case 2: diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java index 34835b20f92e..1c05f47b16ed 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java @@ -233,7 +233,8 @@ public class EditorMultiCaretTest extends AbstractEditorTest { "three four \n" + "five six \n" + "seven eight", - TestFileType.TEXT); + TestFileType.TEXT + ); executeAction("EditorCut"); executeAction("EditorLineEnd"); executeAction("EditorPaste"); @@ -246,7 +247,8 @@ public class EditorMultiCaretTest extends AbstractEditorTest { public void testEscapeAfterDragDown() throws Exception { init("line1\n" + "line2", - TestFileType.TEXT); + TestFileType.TEXT + ); setEditorVisibleSize(1000, 1000); mouse().alt().clickAt(0, 1).dragTo(1, 2).release(); @@ -266,4 +268,41 @@ public class EditorMultiCaretTest extends AbstractEditorTest { checkResultByText("line1\n" + "line2"); } + + public void testAltShiftDoubleClick() throws Exception { + init("quick brown fox", + TestFileType.TEXT); + mouse().alt().shift().doubleClickAt(0, 8); + checkResultByText("quick brown fox"); + } + + public void testAltShiftDoubleClickAtExistingCaret() throws Exception { + init("quick brown fox", + TestFileType.TEXT); + mouse().alt().shift().doubleClickAt(0, 8); + checkResultByText("quick brown fox"); + } + + public void testAltShiftTripleClick() throws Exception { + init("quick\n" + + "brown\n" + + "fox", + TestFileType.TEXT + ); + mouse().alt().shift().tripleClickAt(1, 2); + checkResultByText("quick\n" + + "brown\n" + + "fox"); + } + + public void testAltShiftTripleClickAtExistingCaret() throws Exception { + init("quick\n" + + "brown\n" + + "fox", + TestFileType.TEXT); + mouse().alt().shift().tripleClickAt(1, 2); + checkResultByText("quick\n" + + "brown\n" + + "fox"); + } } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorMouseFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorMouseFixture.java index fb86ce7b59f3..e7808af7df85 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorMouseFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorMouseFixture.java @@ -37,6 +37,10 @@ public class EditorMouseFixture { } public EditorMouseFixture pressAt(int visualLine, int visualColumn) { + return pressAt(1, visualLine, visualColumn); + } + + private EditorMouseFixture pressAt(int clickCount, int visualLine, int visualColumn) { JComponent component = myEditor.getContentComponent(); Point p = getPoint(visualLine, visualColumn); component.dispatchEvent(new MouseEvent(component, @@ -45,13 +49,17 @@ public class EditorMouseFixture { getModifiers(), myX = p.x, myY = p.y, - 1, + clickCount, false, myButton)); return this; } public EditorMouseFixture release() { + return release(1); + } + + private EditorMouseFixture release(int clickCount) { int oldLastId = myLastId; JComponent component = myEditor.getContentComponent(); component.dispatchEvent(new MouseEvent(component, @@ -60,7 +68,7 @@ public class EditorMouseFixture { getModifiers(), myX, myY, - 1, + clickCount, false, myButton)); if (oldLastId == MouseEvent.MOUSE_PRESSED) { @@ -70,7 +78,7 @@ public class EditorMouseFixture { getModifiers(), myX, myY, - 1, + clickCount, false, myButton)); } @@ -81,6 +89,14 @@ public class EditorMouseFixture { return pressAt(visualLine, visualColumn).release(); } + public EditorMouseFixture doubleClickAt(int visualLine, int visualColumn) { + return clickAt(visualLine, visualColumn).pressAt(2, visualLine, visualColumn).release(2); + } + + public EditorMouseFixture tripleClickAt(int visualLine, int visualColumn) { + return doubleClickAt(visualLine, visualColumn).pressAt(3, visualLine, visualColumn).release(3); + } + public EditorMouseFixture dragTo(int visualLine, int visualColumn) { JComponent component = myEditor.getContentComponent(); Point p = getPoint(visualLine, visualColumn); From 4c49d4f550de7ceb312e5ca1b4083249bafcd350 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 25 Mar 2014 16:05:22 +0400 Subject: [PATCH 20/69] reverted fix for IDEA-122637 --- .../debugger/ui/XBreakpointClassGroup.java | 8 ------- .../ui/XBreakpointGroupingByClassRule.java | 7 +++--- .../ui/XBreakpointGroupingByPackageRule.java | 3 +-- .../debugger/ui/XBreakpointPackageGroup.java | 17 ++------------ .../src/messages/XDebuggerBundle.properties | 1 - .../ui/XBreakpointGroupingRule.java | 2 +- .../ui/grouping/XBreakpointFileGroup.java | 23 +------------------ .../grouping/XBreakpointFileGroupingRule.java | 10 +++----- .../XBreakpointGroupingByTypeRule.java | 3 +-- .../ui/grouping/XBreakpointTypeGroup.java | 17 +------------- 10 files changed, 13 insertions(+), 78 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointClassGroup.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointClassGroup.java index 477e2d3cfca1..ca978304202e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointClassGroup.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointClassGroup.java @@ -17,7 +17,6 @@ package com.intellij.debugger.ui; import com.intellij.debugger.DebuggerBundle; import com.intellij.util.PlatformIcons; -import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,13 +25,6 @@ import javax.swing.*; public class XBreakpointClassGroup extends XBreakpointGroup { private static final String DEFAULT_PACKAGE_NAME = DebuggerBundle.message("default.package.name"); - public static final XBreakpointClassGroup UNKNOWN = new XBreakpointClassGroup("", "") { - @NotNull - @Override - public String getName() { - return XDebuggerBundle.message("xbreakpoint.group.unknown"); - } - }; private String myPackageName; private String myClassName; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java index 50c70fba17a1..fc3a179da2e8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java @@ -42,18 +42,17 @@ class XBreakpointGroupingByClassRule extends XBreakpointGroupingRule groups) { if (b instanceof XBreakpoint) { Breakpoint javaBreakpoint = BreakpointManager.findBreakpoint((XBreakpoint)b); if (javaBreakpoint == null) { - return XBreakpointClassGroup.UNKNOWN; + return null; } String className = javaBreakpoint.getShortClassName(); String packageName = javaBreakpoint.getPackageName(); if (className == null) { - return XBreakpointClassGroup.UNKNOWN; + return null; } for (XBreakpointClassGroup group : groups) { if (group.getClassName().equals(className) && group.getPackageName().equals(packageName)) { @@ -62,7 +61,7 @@ class XBreakpointGroupingByClassRule extends XBreakpointGroupingRule extends XBreakpointGroupingRule return XBreakpointsGroupingPriorities.BY_PACKAGE; } - @NotNull @Override public XBreakpointPackageGroup getGroup(@NotNull B breakpoint, @NotNull Collection groups) { String packageName = null; @@ -50,7 +49,7 @@ public class XBreakpointGroupingByPackageRule extends XBreakpointGroupingRule } } if (packageName == null) { - return XBreakpointPackageGroup.UNKNOWN; + return null; } for (XBreakpointPackageGroup group : groups) { if (StringUtil.equals(group.getPackageName(), packageName)) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointPackageGroup.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointPackageGroup.java index 470d56bfe506..0d193a20255b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointPackageGroup.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointPackageGroup.java @@ -18,30 +18,17 @@ package com.intellij.debugger.ui; import com.intellij.debugger.DebuggerBundle; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.PlatformIcons; -import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; public class XBreakpointPackageGroup extends XBreakpointGroup { private static final String DEFAULT_PACKAGE_NAME = DebuggerBundle.message("default.package.name"); - public static final XBreakpointPackageGroup UNKNOWN = new XBreakpointPackageGroup() { - @NotNull - @Override - public String getName() { - return XDebuggerBundle.message("xbreakpoint.group.unknown"); - } - }; private String myPackageName; - private XBreakpointPackageGroup() { - myPackageName = null; - } - - public XBreakpointPackageGroup(@NotNull String packageName) { + public XBreakpointPackageGroup(String packageName) { myPackageName = packageName; } @@ -57,7 +44,7 @@ public class XBreakpointPackageGroup extends XBreakpointGroup { return StringUtil.isEmpty(packageName) ? DEFAULT_PACKAGE_NAME : packageName; } - @Nullable + @NotNull public String getPackageName() { return myPackageName; } diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties index 63adccb02428..de89eaa7f3b3 100644 --- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties +++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties @@ -44,7 +44,6 @@ xbreakpoint.master.breakpoint.none= xbreakpoint.master.breakpoint.description=Disabled until selected breakpoint is hit: rule.name.group.by.file=Group by file xbreakpoint.default.display.text=Line {0} in {1} -xbreakpoint.group.unknown=Unknown xbreakpoint.reached.text=Breakpoint reached: diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java index 650e295ad087..1038747be2c0 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java @@ -53,7 +53,7 @@ public abstract class XBreakpointGroupingRule { return XBreakpointsGroupingPriorities.DEFAULT; } - @NotNull + @Nullable public abstract G getGroup(@NotNull B breakpoint, @NotNull Collection groups); @Nullable diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroup.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroup.java index c86b5e30bd28..f7ae89a202a9 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroup.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroup.java @@ -15,11 +15,9 @@ */ package com.intellij.xdebugger.impl.breakpoints.ui.grouping; -import com.intellij.icons.AllIcons; import com.intellij.ide.presentation.VirtualFilePresentation; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,26 +27,8 @@ import javax.swing.*; * @author nik */ public class XBreakpointFileGroup extends XBreakpointGroup { - public static final XBreakpointFileGroup UNKNOWN = new XBreakpointFileGroup() { - @NotNull - @Override - public String getName() { - return XDebuggerBundle.message("xbreakpoint.group.unknown"); - } - - @Nullable - @Override - public Icon getIcon(boolean isOpen) { - return AllIcons.FileTypes.Text; - } - }; - private final VirtualFile myFile; - private XBreakpointFileGroup() { - myFile = null; - } - public XBreakpointFileGroup(@NotNull VirtualFile file) { myFile = file; } @@ -63,7 +43,6 @@ public class XBreakpointFileGroup extends XBreakpointGroup { return myFile.getPresentableUrl(); } - @Nullable public VirtualFile getFile() { return myFile; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java index 44afa0fe3c88..b0b5998ef71f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java @@ -16,7 +16,6 @@ package com.intellij.xdebugger.impl.breakpoints.ui.grouping; import com.intellij.icons.AllIcons; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.XSourcePosition; @@ -42,20 +41,17 @@ public class XBreakpointFileGroupingRule extends XBreakpointGroupingRule groups) { if (!(breakpoint instanceof XLineBreakpoint)) { - return XBreakpointFileGroup.UNKNOWN; + return null; } XSourcePosition position = ((XLineBreakpoint)breakpoint).getSourcePosition(); - if (position == null) { - return XBreakpointFileGroup.UNKNOWN; - } + if (position == null) return null; VirtualFile file = position.getFile(); for (XBreakpointFileGroup group : groups) { - if (Comparing.equal(group.getFile(), file)) { + if (group.getFile().equals(file)) { return group; } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointGroupingByTypeRule.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointGroupingByTypeRule.java index 19c9018ee270..5d1301604f72 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointGroupingByTypeRule.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointGroupingByTypeRule.java @@ -45,7 +45,6 @@ public class XBreakpointGroupingByTypeRule extends XBreakpointGroupingRule groups) { if (b instanceof XBreakpoint) { @@ -57,6 +56,6 @@ public class XBreakpointGroupingByTypeRule extends XBreakpointGroupingRule Date: Tue, 25 Mar 2014 16:35:15 +0400 Subject: [PATCH 21/69] IDEA-122637 CCE at com.intellij.debugger.ui.XBreakpointGroupingByClassRule.getGroup --- .../breakpoints/ui/tree/BreakpointItemsTreeController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java index 7c90280fc0f3..656a5dab374d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java @@ -129,8 +129,7 @@ public class BreakpointItemsTreeController implements BreakpointsCheckboxTree.De private CheckedTreeNode getParentNode(final BreakpointItem breakpoint) { CheckedTreeNode parent = myRoot; for (int i = 0; i < myGroupingRules.size(); i++) { - Collection existingGroups = getGroupNodes(parent); - XBreakpointGroup group = myGroupingRules.get(i).getGroup(breakpoint.getBreakpoint(), existingGroups); + XBreakpointGroup group = myGroupingRules.get(i).getGroup(breakpoint.getBreakpoint(), Collections.emptyList()); if (group != null) { parent = getOrCreateGroupNode(parent, group, i); } From c6e39c5fdd325573f52071a34085e187efa32010 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 25 Mar 2014 13:49:46 +0100 Subject: [PATCH 22/69] IDEA-122757 IOE at com.intellij.openapi.util.io.FileUtilRt.doCreateTempFile --- .../src/com/intellij/platform/PlatformProjectOpenProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java b/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java index 0e1087592934..fe35f5067a21 100644 --- a/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java +++ b/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java @@ -111,7 +111,7 @@ public class PlatformProjectOpenProcessor extends ProjectOpenProcessor { if (baseDir == null) { // no reasonable directory -> create new temp one or use parent if (Registry.is("ide.open.file.in.temp.project.dir")) { try { - dummyProjectName = virtualFile.getPath(); + dummyProjectName = virtualFile.getName(); File directory = FileUtil.createTempDirectory(dummyProjectName, null, true); baseDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(directory); dummyProject = true; From 319a7b03c39f04e41e81a7d2206fcb62cc98d39a Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 25 Mar 2014 16:59:33 +0400 Subject: [PATCH 23/69] Bug fix: IDEA does not recognize managed dependencies usage in current pom.xml --- .../idea/maven/dom/MavenDomProjectProcessorUtils.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java index c585131b9ac9..ceebebb093e5 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java @@ -182,13 +182,11 @@ public class MavenDomProjectProcessorUtils { final Set usages = new HashSet(); Processor collectProcessor = new Processor() { public boolean process(MavenDomProjectModel mavenDomProjectModel) { - if (!model.equals(mavenDomProjectModel)) { - for (MavenDomDependency domDependency : mavenDomProjectModel.getDependencies().getDependencies()) { - if (excludes.contains(domDependency)) continue; + for (MavenDomDependency domDependency : mavenDomProjectModel.getDependencies().getDependencies()) { + if (excludes.contains(domDependency)) continue; - if (dependencyId.equals(DependencyConflictId.create(domDependency))) { - usages.add(domDependency); - } + if (dependencyId.equals(DependencyConflictId.create(domDependency))) { + usages.add(domDependency); } } return false; From a1456bf79034428e2398f37aab475792c81e7e04 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 25 Mar 2014 17:12:30 +0400 Subject: [PATCH 24/69] warn about active method breakpoints on debug session start --- .../debugger/ui/breakpoints/BreakpointManager.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java index e97814845175..c12dccea2660 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java @@ -133,6 +133,16 @@ public class BreakpointManager { @Override public void changeEvent(@NotNull DebuggerContextImpl newContext, int event) { + if (event == DebuggerSession.EVENT_ATTACHED) { + // notify about possibly slow method breakpoints + for (XLineBreakpoint breakpoint : getXBreakpointManager().getBreakpoints(JavaMethodBreakpointType.class)) { + if (breakpoint.isEnabled()) { + XDebugSessionImpl.NOTIFICATION_GROUP.createNotification("Method breakpoints may dramatically slow down debugging", MessageType.WARNING).notify( + myProject); + break; + } + } + } if (newContext.getDebuggerSession() != myPreviousSession || event == DebuggerSession.EVENT_DETACHED) { updateBreakpointsUI(); myPreviousSession = newContext.getDebuggerSession(); From 7e1ce96a3d05e6a648bb3e3c4db29e1a06e65e43 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Tue, 25 Mar 2014 17:24:34 +0400 Subject: [PATCH 25/69] Focus was broken for F12 on Windows. --- .../src/com/intellij/openapi/wm/FocusCommand.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java index dfbf3ddd486b..13269fee8c5a 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java @@ -182,8 +182,10 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable { // This change seems reasonable to me. But as far as some implementations // can ignore the "forced" parameter we can get bad focus behaviour. // So let's start from mac. - if (!myToFocus.requestFocusInWindow() && (isForced() && SystemInfo.isMac)) { - myToFocus.requestFocus(); + if (!(myToFocus.requestFocusInWindow())) { + if (!SystemInfo.isMac || isForced() ) { + myToFocus.requestFocus(); + } } } } From 5605b2e6f05c77d28b278ea6198f789d0ecdc1d2 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Mar 2014 12:40:42 +0100 Subject: [PATCH 26/69] field can be local: quick fix to register stop-annotations is added (IDEA-122836) --- .../FieldCanBeLocalInspectionBase.java | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java index 276b451276ca..f84abbb0e3d6 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java @@ -18,7 +18,12 @@ package com.intellij.codeInspection.varScopeCanBeNarrowed; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.daemon.ImplicitUsageProvider; -import com.intellij.codeInspection.*; +import com.intellij.codeInsight.daemon.QuickFixBundle; +import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool; +import com.intellij.codeInspection.InspectionsBundle; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.codeInspection.util.SpecialAnnotationsUtilBase; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.JDOMExternalizableStringList; @@ -28,15 +33,14 @@ import com.intellij.psi.*; import com.intellij.psi.controlFlow.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.util.Processor; +import com.siyeh.InspectionGadgetsBundle; import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class FieldCanBeLocalInspectionBase extends BaseJavaBatchLocalInspectionTool { @NonNls public static final String SHORT_NAME = "FieldCanBeLocal"; @@ -69,10 +73,26 @@ public class FieldCanBeLocalInspectionBase extends BaseJavaBatchLocalInspectionT if (candidates.isEmpty()) return; final ImplicitUsageProvider[] implicitUsageProviders = Extensions.getExtensions(ImplicitUsageProvider.EP_NAME); - for (PsiField field : candidates) { + for (final PsiField field : candidates) { if (usedFields.contains(field) && !hasImplicitReadOrWriteUsage(field, implicitUsageProviders)) { final String message = InspectionsBundle.message("inspection.field.can.be.local.problem.descriptor"); - holder.registerProblem(field.getNameIdentifier(), message, createFix()); + final ArrayList fixes = new ArrayList(); + SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(field, new Processor() { + @Override + public boolean process(String qualifiedName) { + final LocalQuickFix quickFix = SpecialAnnotationsUtilBase.createAddToSpecialAnnotationsListQuickFix( + InspectionGadgetsBundle.message("add.0.to.ignore.if.annotated.by.list.quickfix", qualifiedName), + QuickFixBundle.message("fix.add.special.annotation.family"), + EXCLUDE_ANNOS, qualifiedName, field); + fixes.add(quickFix); + return true; + } + }); + final LocalQuickFix fix = createFix(); + if (fix != null) { + fixes.add(fix); + } + holder.registerProblem(field.getNameIdentifier(), message, fixes.toArray(new LocalQuickFix[fixes.size()])); } } } From 9f58257359069d187791ea39e29d5af95de0c4c5 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Mar 2014 13:50:38 +0100 Subject: [PATCH 27/69] new inference: String::length should be exact (IDEA-122191) --- .../java/PsiMethodReferenceExpressionImpl.java | 2 +- .../lambda/newMethodRef/IDEA112191.java | 15 +++++++++++++++ .../lambda/NewMethodRefHighlightingTest.java | 4 ++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IDEA112191.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java index 94f6adf546de..b5b0b7729bdb 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java @@ -163,7 +163,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase if (containingClass != null) { PsiMethod[] methods = null; if (element instanceof PsiIdentifier) { - methods = containingClass.findMethodsByName(element.getText(), true); + methods = containingClass.findMethodsByName(element.getText(), !qualifierResolveResult.isReferenceTypeQualified()); } else if (isConstructor()) { final PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject()); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IDEA112191.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IDEA112191.java new file mode 100644 index 000000000000..273107e89500 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IDEA112191.java @@ -0,0 +1,15 @@ +import java.util.function.ToIntFunction; +class Test { + { + fooBar(String::length); + } + + class Foo { + Foo then() { + return null; + } + } + static Foo fooBar(ToIntFunction keyExtractor) { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java index 21536e393c4e..6bb48f2b6f7f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java @@ -209,6 +209,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIDEA112191() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } From 40b2cd30b82f00820614c3a698285acb9dce80c4 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 25 Mar 2014 17:58:51 +0400 Subject: [PATCH 28/69] IDEA-122164 Possibility to change default prompt style in LanguageConsoleImpl --- .../execution/console/LanguageConsoleImpl.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index bb646a81ee46..c2e2ec5da39c 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -92,6 +92,8 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { private String myTitle; @Nullable private String myPrompt = "> "; + private TextAttributes myPromptAttributes = ConsoleViewContentType.USER_INPUT.getAttributes(); + private final LightVirtualFile myHistoryFile; private Editor myCurrentEditor; @@ -332,6 +334,10 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { return myPrompt; } + public void setPromptAttributes(@NotNull TextAttributes textAttributes) { + myPromptAttributes = textAttributes; + } + public void setPrompt(@Nullable String prompt) { // always add space to the prompt otherwise it may look ugly myPrompt = prompt != null && !prompt.endsWith(" ") ? prompt + " " : prompt; @@ -344,7 +350,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { - myConsoleEditor.setPrefixTextAndAttributes(prompt, ConsoleViewContentType.USER_INPUT.getAttributes()); + myConsoleEditor.setPrefixTextAndAttributes(prompt, myPromptAttributes); if (myPanel.isVisible()) { queueUiUpdate(false); } @@ -540,7 +546,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { } protected void doAddPromptToHistory() { - addTextToHistory(myPrompt, ConsoleViewContentType.USER_INPUT.getAttributes()); + addTextToHistory(myPrompt, myPromptAttributes); } // returns the real (cyclic-buffer-aware) start offset of the inserted text From b1e0f63290828c1be92981af34c5de1e7fc9f472 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 25 Mar 2014 15:02:38 +0100 Subject: [PATCH 29/69] do not do resolve in dumb mode!!! --- .../com/intellij/find/impl/FindInProjectUtil.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java index d788d9c6abe9..123b3ee2c824 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java @@ -34,6 +34,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.util.ProgressWrapper; import com.intellij.openapi.progress.util.TooManyUsagesStatus; +import com.intellij.openapi.project.DumbServiceImpl; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; @@ -71,14 +72,16 @@ public class FindInProjectUtil { private FindInProjectUtil() {} public static void setDirectoryName(@NotNull FindModel model, @NotNull DataContext dataContext) { - PsiElement psiElement; - try { - psiElement = CommonDataKeys.PSI_ELEMENT.getData(dataContext); - } - catch (IndexNotReadyException e) { - psiElement = null; + PsiElement psiElement = null; + Project project = CommonDataKeys.PROJECT.getData(dataContext); + + if (project != null && !DumbServiceImpl.getInstance(project).isDumb()) { + try { + psiElement = CommonDataKeys.PSI_ELEMENT.getData(dataContext); + } catch (IndexNotReadyException ignore) {} } + String directoryName = null; if (psiElement instanceof PsiDirectory) { From a02159e89ec25e18ffad78e3cd5b1fe5184635f8 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 25 Mar 2014 15:03:09 +0100 Subject: [PATCH 30/69] IDEA-122861 IDE fails to open HTML files on a system with Turkish locale --- xml/xml-psi-impl/src/com/intellij/xml/util/HTMLControls.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/HTMLControls.java b/xml/xml-psi-impl/src/com/intellij/xml/util/HTMLControls.java index 9651de7ca137..1611b7819155 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/util/HTMLControls.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/util/HTMLControls.java @@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable; import java.io.InputStream; import java.util.Collections; +import java.util.Locale; import java.util.Set; /** @@ -91,13 +92,13 @@ public class HTMLControls { @Nullable @Override public TagState fromString(@NotNull String value) { - return TagState.valueOf(value.toUpperCase()); + return TagState.valueOf(value.toUpperCase(Locale.US)); } @NotNull @Override public String toString(@NotNull TagState state) { - return state.name().toLowerCase(); + return state.name().toLowerCase(Locale.US); } } From 4b4d83159faa2899d37df7811902bffa62c0ae2c Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 25 Mar 2014 18:04:20 +0400 Subject: [PATCH 31/69] fix regressions for copy/paste behaviour in column selection mode --- .../editor/EditorModificationUtil.java | 12 +++++++++ .../openapi/editor/impl/CaretImpl.java | 14 +++++++++- .../editor/impl/SelectionModelImpl.java | 22 +++++++++++++--- .../EditorMultiCaretColumnModeTest.java | 26 +++++++++++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java index da8e13c29852..c3db1de87059 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java @@ -178,6 +178,18 @@ public class EditorModificationUtil { if (editor.getCaretModel().supportsMultipleCarets()) { int caretCount = editor.getCaretModel().getCaretCount(); + if (caretCount == 1 && editor.isColumnMode()) { + int pastedLineCount = LineTokenizer.calcLineCount(text, true); + deleteSelectedText(editor); + Caret caret = editor.getCaretModel().getPrimaryCaret(); + for (int i = 0; i < pastedLineCount - 1; i++) { + caret = caret.clone(false); + if (caret == null) { + break; + } + } + caretCount = editor.getCaretModel().getCaretCount(); + } final Iterator segments = new ClipboardTextPerCaretSplitter().split(text, caretCount).iterator(); editor.getCaretModel().runForEachCaret(new CaretAction() { @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java index 794844bf9d8a..f8e2b867a45f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java @@ -1445,7 +1445,19 @@ public class CaretImpl extends UserDataHolderBase implements Caret { CharSequence text = myEditor.getDocument().getCharsSequence(); int selectionStart = getSelectionStart(); int selectionEnd = getSelectionEnd(); - return text.subSequence(selectionStart, selectionEnd).toString(); + String selectedText = text.subSequence(selectionStart, selectionEnd).toString(); + if (isVirtualSelectionEnabled() && myEndVirtualOffset > myStartVirtualOffset) { + int padding = myEndVirtualOffset - myStartVirtualOffset; + StringBuilder builder = new StringBuilder(selectedText.length() + padding); + builder.append(selectedText); + for (int i = 0; i < padding; i++) { + builder.append(' '); + } + return builder.toString(); + } + else { + return selectedText; + } } private void validateContext(boolean isWrite) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java index 7ee0e4d2668d..263ea77c286f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java @@ -482,8 +482,8 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi public String getSelectedText(boolean allCarets) { validateContext(false); - CharSequence text = myEditor.getDocument().getCharsSequence(); - if (hasBlockSelection() || (myEditor.getCaretModel().supportsMultipleCarets() && allCarets)) { + if (hasBlockSelection()) { + CharSequence text = myEditor.getDocument().getCharsSequence(); int[] starts = getBlockSelectionStarts(); int[] ends = getBlockSelectionEnds(); int width = myEditor.getCaretModel().supportsMultipleCarets() ? 0 : Math.abs(myBlockEnd.column - myBlockStart.column); @@ -496,8 +496,22 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi } return buf.toString(); } - - return myEditor.getCaretModel().getCurrentCaret().getSelectedText(); + else if (myEditor.getCaretModel().supportsMultipleCarets() && allCarets) { + final StringBuilder buf = new StringBuilder(); + String separator = ""; + for (Caret caret : myEditor.getCaretModel().getAllCarets()) { + buf.append(separator); + String caretSelectedText = caret.getSelectedText(); + if (caretSelectedText != null) { + buf.append(caretSelectedText); + } + separator = "\n"; + } + return buf.toString(); + } + else { + return myEditor.getCaretModel().getCurrentCaret().getSelectedText(); + } } private static void appendCharSequence(@NotNull StringBuilder buf, @NotNull CharSequence s, int srcOffset, int len) { diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java index 267b1824a9a5..425ee52ed9c1 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java @@ -271,6 +271,32 @@ public class EditorMultiCaretColumnModeTest extends AbstractEditorTest { "ccScc"); } + public void testCopyPasteOfShortLines() throws Exception { + init("a\n" + + "bbb\n" + + "ccccc"); + mouse().clickAt(0, 2).dragTo(2, 4).release(); + executeAction("EditorCopy"); + executeAction("EditorLineStart"); + executeAction("EditorPaste"); + checkResultByText(" a\n" + + "b bbb\n" + + "ccccccc"); + } + + public void testPasteOfBlockToASingleCaret() throws Exception { + init("a\n" + + "bbb\n" + + "ccccc"); + mouse().clickAt(1, 2).dragTo(2, 4).release(); + executeAction("EditorCopy"); + mouse().clickAt(0, 2); + executeAction("EditorPaste"); + checkResultByText("a b \n" + + "bbccb\n" + + "ccccc"); + } + private void init(String text) throws IOException { configureFromFileText(getTestName(false) + ".txt", text); setEditorVisibleSize(1000, 1000); From 5705d769faa486be0951d4dd2c9dab3f1d23786e Mon Sep 17 00:00:00 2001 From: Vassiliy Date: Tue, 25 Mar 2014 18:04:03 +0400 Subject: [PATCH 32/69] IDEA-122529 Wrong event log icon --- .../com/intellij/ide/actions/ActivateToolWindowAction.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ActivateToolWindowAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ActivateToolWindowAction.java index fc05f1a3c075..f832840d0ac2 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ActivateToolWindowAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ActivateToolWindowAction.java @@ -16,12 +16,14 @@ */ package com.intellij.ide.actions; +import com.intellij.icons.AllIcons; import com.intellij.ide.IdeBundle; +import com.intellij.notification.EventLog; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.SizedIcon; @@ -55,6 +57,9 @@ public class ActivateToolWindowAction extends AnAction implements DumbAware { presentation.setVisible(toolWindow!=null); if (toolWindow != null) { Icon icon = toolWindow.getIcon(); + if (EventLog.LOG_TOOL_WINDOW_ID.equals(myToolWindowId)) { + icon = AllIcons.Ide.Info_notifications; + } presentation.setIcon(icon == null ? null : new SizedIcon(icon, icon.getIconHeight(), icon.getIconHeight())); } } From d19b9b4fcf5599b2db0155e45905dd727eeb4a50 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 25 Mar 2014 18:07:30 +0400 Subject: [PATCH 33/69] svn: Make SvnVcs.isVcsBackgroundOperationsAllowed be always true if command line is configured --- plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java index 4ffca15fc590..6c636d228c7e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java @@ -51,6 +51,7 @@ import com.intellij.openapi.vcs.update.UpdateEnvironment; import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings; import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.util.Consumer; @@ -1351,7 +1352,13 @@ public class SvnVcs extends AbstractVcs { @Override public boolean isVcsBackgroundOperationsAllowed(VirtualFile root) { - return ThreeState.YES.equals(myAuthNotifier.isAuthenticatedFor(root)); + // TODO: Currently myAuthNotifier.isAuthenticatedFor directly uses SVNKit to check credentials - so assume for now that background + // TODO: operations are always allowed for command line. As sometimes this leads to errors - for instance, incoming changes are not + // TODO: displayed in "Incoming" tab - incoming changes are collected using command line but not displayed because + // TODO: SvnVcs.isVcsBackgroundOperationsAllowed is false. + ClientFactory factory = getFactory(VfsUtilCore.virtualToIoFile(root)); + + return factory == cmdClientFactory || ThreeState.YES.equals(myAuthNotifier.isAuthenticatedFor(root)); } public SvnBranchPointsCalculator getSvnBranchPointsCalculator() { From a761ae4ccdcd469caafba54e9186085ea28f95c2 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 25 Mar 2014 18:14:19 +0400 Subject: [PATCH 34/69] svn: Make CmdVersionClient utilize CommandExecutor (not to duplicate common logic) --- .../idea/svn/api/CmdVersionClient.java | 35 ++++++------------- .../idea/svn/commandLine/CommandExecutor.java | 13 +++++++ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java index 5fc4266400b0..c3acfdc7c561 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java @@ -1,15 +1,13 @@ package org.jetbrains.idea.svn.api; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.EncodingEnvironmentUtil; -import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.process.CapturingProcessHandler; import com.intellij.execution.process.ProcessOutput; import com.intellij.openapi.util.Version; import com.intellij.openapi.vcs.VcsException; -import com.intellij.openapi.vfs.CharsetToolkit; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.svn.SvnApplicationSettings; +import org.jetbrains.idea.svn.commandLine.Command; +import org.jetbrains.idea.svn.commandLine.CommandExecutor; +import org.jetbrains.idea.svn.commandLine.SvnBindException; import org.jetbrains.idea.svn.commandLine.SvnCommandName; import java.util.regex.Matcher; @@ -25,29 +23,18 @@ public class CmdVersionClient extends BaseSvnClient implements VersionClient { @NotNull @Override public Version getVersion() throws VcsException { - // TODO: Do not use common command running mechanism for now - to preserve timeout behavior. - ProcessOutput output; - - try { - output = runCommand(); - } - catch (ExecutionException e) { - throw new VcsException(e); - } - - return parseVersion(output); + return parseVersion(runCommand()); } - private static ProcessOutput runCommand() throws ExecutionException { - GeneralCommandLine commandLine = new GeneralCommandLine(); - commandLine.setExePath(SvnApplicationSettings.getInstance().getCommandLinePath()); - commandLine.addParameter(SvnCommandName.version.getName()); - commandLine.addParameter("--quiet"); + private static ProcessOutput runCommand() throws SvnBindException { + // TODO: Seems CommandRuntime should be used here when its api is more robust (to specify timeout or so). + Command command = new Command(SvnCommandName.version); + command.put("--quiet"); - EncodingEnvironmentUtil.fixDefaultEncodingIfMac(commandLine, null); + CommandExecutor executor = new CommandExecutor(SvnApplicationSettings.getInstance().getCommandLinePath(), command); + executor.run(30 * 1000); - CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset()); - return handler.runProcess(30 * 1000); + return executor.getProcessOutput(); } @NotNull diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java index ee97159b9eec..05971ec37093 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java @@ -156,6 +156,10 @@ public class CommandExecutor { return outputAdapter.getOutput().getStderr(); } + public ProcessOutput getProcessOutput() { + return outputAdapter.getOutput(); + } + @Nullable public ByteArrayOutputStream getBinaryOutput() { return myHandler instanceof BinaryOSProcessHandler ? ((BinaryOSProcessHandler)myHandler).myBinaryOutput : null; @@ -209,6 +213,15 @@ public class CommandExecutor { while (!finished); } + public void run(int timeout) throws SvnBindException { + start(); + boolean finished = waitFor(timeout); + if (!finished) { + outputAdapter.getOutput().setTimeout(); + doDestroyProcess(); + } + } + public void addListener(final LineCommandListener listener) { synchronized (myLock) { myListeners.addListener(listener); From 7a4cf37b50e57ab4d71a1c80523a828584479ff7 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 25 Mar 2014 18:09:54 +0400 Subject: [PATCH 35/69] EA-55230 github: do not use deprecated method --- .../plugins/github/tasks/GithubRepository.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java index 35c8a219fec6..3106454968a2 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java +++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java @@ -63,9 +63,20 @@ public class GithubRepository extends BaseRepositoryImpl { setUrl(GithubApiUtil.DEFAULT_GITHUB_HOST); } + @NotNull @Override - public void testConnection() throws Exception { - getIssues("", 10, 0); + public CancellableConnection createCancellableConnection() { + return new CancellableConnection() { + @Override + protected void doTest() throws Exception { + getIssues("", 10, false); + } + + @Override + public void cancel() { + // TODO + } + }; } @Override From 02a51bfbaf54bcd3f8d95bde8b50054021e8a523 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 25 Mar 2014 18:26:41 +0400 Subject: [PATCH 36/69] svn: Refactored CommandExecutor - methods extracted --- .../idea/svn/commandLine/CommandExecutor.java | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java index 05971ec37093..a5773ba19d4d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java @@ -106,8 +106,7 @@ public class CommandExecutor { checkNotStarted(); try { - EncodingEnvironmentUtil.fixDefaultEncodingIfMac(myCommandLine, null); - + beforeCreateProcess(); myProcess = createProcess(); if (LOG.isDebugEnabled()) { LOG.debug(myCommandLine.toString()); @@ -115,7 +114,8 @@ public class CommandExecutor { myHandler = createProcessHandler(); myProcessWriter = new OutputStreamWriter(myHandler.getProcessInput()); startHandlingStreams(); - } catch (ExecutionException e) { + } + catch (ExecutionException e) { // TODO: currently startFailed() is not used for some real logic in svn4idea plugin listeners().startFailed(e); throw new SvnBindException(e); @@ -123,6 +123,13 @@ public class CommandExecutor { } } + protected void cleanup() { + } + + protected void beforeCreateProcess() { + EncodingEnvironmentUtil.fixDefaultEncodingIfMac(myCommandLine, null); + } + @NotNull protected OSProcessHandler createProcessHandler() { return needsBinaryOutput() @@ -200,25 +207,35 @@ public class CommandExecutor { } public void run() throws SvnBindException { - start(); - boolean finished; - do { - finished = waitFor(500); - if (!finished && (wasError() || needsDestroy() || checkCancelled())) { - waitFor(1000); - doDestroyProcess(); - break; + try { + start(); + boolean finished; + do { + finished = waitFor(500); + if (!finished && (wasError() || needsDestroy() || checkCancelled())) { + waitFor(1000); + doDestroyProcess(); + break; + } } + while (!finished); + } + finally { + cleanup(); } - while (!finished); } public void run(int timeout) throws SvnBindException { - start(); - boolean finished = waitFor(timeout); - if (!finished) { - outputAdapter.getOutput().setTimeout(); - doDestroyProcess(); + try { + start(); + boolean finished = waitFor(timeout); + if (!finished) { + outputAdapter.getOutput().setTimeout(); + doDestroyProcess(); + } + } + finally { + cleanup(); } } From c47c4f5a809117b64e5551f33ddfce24eac58244 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 25 Mar 2014 15:25:46 +0100 Subject: [PATCH 37/69] comment about special negative timestamps and long value for milliseconds --- .../src/com/intellij/util/indexing/IndexingStamp.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java index ff9c740cbf16..5b3c01eb6d6b 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java @@ -49,7 +49,11 @@ import java.util.concurrent.ConcurrentMap; * and set its indexed state to unindexed * if we get other event we set indexed state to outdated * - * Index stamp is file timestamp of the index directory, we assume that index stamps are monotonically increasing + * Index stamp is file timestamp of the index directory, it is assumed that index stamps are monotonically increasing, but + * still << Long.MAX_VALUE: there are two negative special timestamps used for marking outdated / unindexed index state. + * The code doesn't take overflow of real file timestaps (or their coincidence to negative special timestamps) into account because + * it will happen (if time will go as forward as it does today) near year 292277094 (=new java.util.Date(Long.MAX_VALUE).getYear()). + * At that time (if this code will be still actual) we can use positive small timestamps for special cases. */ public class IndexingStamp { private static final long UNINDEXED_STAMP = -1L; // we don't store trivial "absent" state From 6495aaa4d80e54010d545c47b4c1224ab72f8772 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Tue, 25 Mar 2014 18:32:36 +0400 Subject: [PATCH 38/69] Better "do not ask" checkbox re-layout. --- .../intellij/ui/messages/SheetController.java | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java index 73dedb4e9f3d..d12e37515f65 100755 --- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java @@ -172,9 +172,7 @@ public class SheetController { } private final static int TOP_SHEET_PADDING = 15; - private final static int GAP_BETWEEN_TITLE_AND_MESSAGE = 10; - private final static int GAP_BETWEEN_MESSAGE_AND_BUTTONS = 10; - private final static int BUTTONS_PLUS_CHECKBOX = 70; + private final static int GAP_BETWEEN_LINES = 10; private final static int LEFT_SHEET_PADDING = 35; private final static int LEFT_SHEET_OFFSET = 120; @@ -254,15 +252,23 @@ public class SheetController { messageTextPane.repaint(); - SHEET_HEIGHT = TOP_SHEET_PADDING + headerLabel.getPreferredSize().height + GAP_BETWEEN_TITLE_AND_MESSAGE + messageArea.height - + GAP_BETWEEN_MESSAGE_AND_BUTTONS + BUTTONS_PLUS_CHECKBOX; + ico.setOpaque(false); ico.setSize(new Dimension(AllIcons.Logo_welcomeScreen.getIconWidth(), AllIcons.Logo_welcomeScreen.getIconHeight())); ico.setLocation(LEFT_SHEET_PADDING, TOP_SHEET_PADDING); sheetPanel.add(ico); headerLabel.setLocation(LEFT_SHEET_OFFSET, TOP_SHEET_PADDING); - messageTextPane.setLocation(LEFT_SHEET_OFFSET, TOP_SHEET_PADDING + headerLabel.getPreferredSize().height + GAP_BETWEEN_TITLE_AND_MESSAGE); + messageTextPane.setLocation(LEFT_SHEET_OFFSET, TOP_SHEET_PADDING + headerLabel.getPreferredSize().height + GAP_BETWEEN_LINES); + + SHEET_HEIGHT = TOP_SHEET_PADDING + headerLabel.getPreferredSize().height + GAP_BETWEEN_LINES + messageArea.height + + GAP_BETWEEN_LINES; + + + if (myDoNotAskOption != null) { + layoutDoNotAskCheckbox(sheetPanel); + } + layoutWithAbsoluteLayout(buttons, sheetPanel); sheetPanel.setFocusCycleRoot(true); @@ -281,11 +287,6 @@ public class SheetController { private void layoutWithAbsoluteLayout(JButton[] buttons, JPanel sheetPanel) { layoutButtons(buttons, sheetPanel); - - if (myDoNotAskOption != null) { - layoutDoNotAskCheckbox(); - sheetPanel.add(doNotAskCheckBox); - } } private void paintShadow(Graphics2D g2d) { @@ -299,6 +300,8 @@ public class SheetController { int buttonsWidth = 15; + + for (JButton button : buttons) { panel.add(button); button.repaint(); @@ -313,13 +316,15 @@ public class SheetController { Dimension size = button.getPreferredSize(); buttonShift += size.width; button.setBounds(SHEET_WIDTH - buttonShift, - SHEET_HEIGHT - 40, + SHEET_HEIGHT, size.width, size.height); buttonShift += 10; } + + SHEET_HEIGHT += buttons[0].getHeight() + GAP_BETWEEN_LINES; } - private void layoutDoNotAskCheckbox() { + private void layoutDoNotAskCheckbox(JPanel sheetPanel) { doNotAskCheckBox = new JCheckBox(myDoNotAskOption.getDoNotShowMessage()); doNotAskCheckBox.addItemListener(new ItemListener() { @Override @@ -329,7 +334,12 @@ public class SheetController { }); doNotAskCheckBox.repaint(); doNotAskCheckBox.setSize(doNotAskCheckBox.getPreferredSize()); - doNotAskCheckBox.setLocation(LEFT_SHEET_OFFSET, SHEET_HEIGHT - BUTTONS_PLUS_CHECKBOX); + + + doNotAskCheckBox.setLocation(LEFT_SHEET_OFFSET, SHEET_HEIGHT); + sheetPanel.add(doNotAskCheckBox); + + SHEET_HEIGHT += doNotAskCheckBox.getHeight() + GAP_BETWEEN_LINES; } /** From b197f0504757d8931b37c93cdb4c0e9ea14cf1dd Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Tue, 25 Mar 2014 18:00:33 +0400 Subject: [PATCH 39/69] "Line/block comment at first column" options to be taken from language-specific settings [CR-IC-4952] --- .../CodeStyleGenerationConfigurable.java | 18 ++++++++++++------ .../CommentByBlockCommentHandler.java | 6 +++--- .../CommentByLineCommentHandler.java | 3 ++- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.java b/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.java index aebfb44da1ca..7d09903487b2 100644 --- a/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.java +++ b/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.java @@ -16,6 +16,7 @@ package com.intellij.application.options; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; @@ -23,6 +24,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ToolbarDecorator; import com.intellij.ui.components.JBList; @@ -204,6 +206,7 @@ public class CodeStyleGenerationConfigurable implements Configurable { }*/ public void reset(CodeStyleSettings settings) { + CommonCodeStyleSettings javaCommonSettings = settings.getCommonSettings(JavaLanguage.INSTANCE); myCbPreferLongerNames.setSelected(settings.PREFER_LONGER_NAMES); myFieldPrefixField.setText(settings.FIELD_NAME_PREFIX); @@ -216,8 +219,8 @@ public class CodeStyleGenerationConfigurable implements Configurable { myParameterSuffixField.setText(settings.PARAMETER_NAME_SUFFIX); myLocalVariableSuffixField.setText(settings.LOCAL_VARIABLE_NAME_SUFFIX); - myCbLineCommentAtFirstColumn.setSelected(settings.LINE_COMMENT_AT_FIRST_COLUMN); - myCbBlockCommentAtFirstColumn.setSelected(settings.BLOCK_COMMENT_AT_FIRST_COLUMN); + myCbLineCommentAtFirstColumn.setSelected(javaCommonSettings.LINE_COMMENT_AT_FIRST_COLUMN); + myCbBlockCommentAtFirstColumn.setSelected(javaCommonSettings.BLOCK_COMMENT_AT_FIRST_COLUMN); myCbGenerateFinalLocals.setSelected(settings.GENERATE_FINAL_LOCALS); myCbGenerateFinalParameters.setSelected(settings.GENERATE_FINAL_PARAMETERS); @@ -233,6 +236,7 @@ public class CodeStyleGenerationConfigurable implements Configurable { } public void apply(CodeStyleSettings settings) throws ConfigurationException { + CommonCodeStyleSettings javaCommonSettings = settings.getCommonSettings(JavaLanguage.INSTANCE); settings.PREFER_LONGER_NAMES = myCbPreferLongerNames.isSelected(); settings.FIELD_NAME_PREFIX = setPrefixSuffix(myFieldPrefixField.getText(), true); @@ -245,8 +249,8 @@ public class CodeStyleGenerationConfigurable implements Configurable { settings.PARAMETER_NAME_SUFFIX = setPrefixSuffix(myParameterSuffixField.getText(), false); settings.LOCAL_VARIABLE_NAME_SUFFIX = setPrefixSuffix(myLocalVariableSuffixField.getText(), false); - settings.LINE_COMMENT_AT_FIRST_COLUMN = myCbLineCommentAtFirstColumn.isSelected(); - settings.BLOCK_COMMENT_AT_FIRST_COLUMN = myCbBlockCommentAtFirstColumn.isSelected(); + javaCommonSettings.LINE_COMMENT_AT_FIRST_COLUMN = myCbLineCommentAtFirstColumn.isSelected(); + javaCommonSettings.BLOCK_COMMENT_AT_FIRST_COLUMN = myCbBlockCommentAtFirstColumn.isSelected(); settings.GENERATE_FINAL_LOCALS = myCbGenerateFinalLocals.isSelected(); settings.GENERATE_FINAL_PARAMETERS = myCbGenerateFinalParameters.isSelected(); @@ -276,6 +280,8 @@ public class CodeStyleGenerationConfigurable implements Configurable { } public boolean isModified(CodeStyleSettings settings) { + CommonCodeStyleSettings javaCommonSettings = settings.getCommonSettings(JavaLanguage.INSTANCE); + boolean isModified = isModified(myCbPreferLongerNames, settings.PREFER_LONGER_NAMES); isModified |= isModified(myFieldPrefixField, settings.FIELD_NAME_PREFIX); @@ -288,8 +294,8 @@ public class CodeStyleGenerationConfigurable implements Configurable { isModified |= isModified(myParameterSuffixField, settings.PARAMETER_NAME_SUFFIX); isModified |= isModified(myLocalVariableSuffixField, settings.LOCAL_VARIABLE_NAME_SUFFIX); - isModified |= isModified(myCbLineCommentAtFirstColumn, settings.LINE_COMMENT_AT_FIRST_COLUMN); - isModified |= isModified(myCbBlockCommentAtFirstColumn, settings.BLOCK_COMMENT_AT_FIRST_COLUMN); + isModified |= isModified(myCbLineCommentAtFirstColumn, javaCommonSettings.LINE_COMMENT_AT_FIRST_COLUMN); + isModified |= isModified(myCbBlockCommentAtFirstColumn, javaCommonSettings.BLOCK_COMMENT_AT_FIRST_COLUMN); isModified |= isModified(myCbGenerateFinalLocals, settings.GENERATE_FINAL_LOCALS); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByBlockCommentHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByBlockCommentHandler.java index b4a3bed19422..8861cb9b9004 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByBlockCommentHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByBlockCommentHandler.java @@ -36,8 +36,8 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.codeStyle.Indent; import com.intellij.psi.templateLanguages.MultipleLangCommentProvider; import com.intellij.psi.templateLanguages.OuterLanguageElement; @@ -55,7 +55,7 @@ import java.util.List; public class CommentByBlockCommentHandler implements CodeInsightActionHandler { private Project myProject; private Editor myEditor; - private PsiFile myFile; + private @NotNull PsiFile myFile; private Document myDocument; private CommenterDataHolder mySelfManagedCommenterData; @@ -402,7 +402,7 @@ public class CommentByBlockCommentHandler implements CodeInsightActionHandler { if (startOffset == 0 || chars.charAt(startOffset - 1) == '\n') { if (endOffset == myDocument.getTextLength() || endOffset > 0 && chars.charAt(endOffset - 1) == '\n') { CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myProject); - CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myProject); + CommonCodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myProject).getCommonSettings(myFile.getLanguage()); String space; if (!settings.BLOCK_COMMENT_AT_FIRST_COLUMN) { final FileType fileType = myFile.getFileType(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java index ee07d199cb21..ba73ac14d715 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java @@ -260,7 +260,8 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler { } boolean allLineCommented = true; - boolean commentWithIndent = !CodeStyleSettingsManager.getSettings(myProject).LINE_COMMENT_AT_FIRST_COLUMN; + boolean commentWithIndent = + !CodeStyleSettingsManager.getSettings(myProject).getCommonSettings(myFile.getLanguage()).LINE_COMMENT_AT_FIRST_COLUMN; for (int line = myStartLine; line <= myEndLine; line++) { Commenter commenter = blockSuitableCommenter != null ? blockSuitableCommenter : findCommenter(line); From 80126cba2138949536a7e74c0d24db28b85cf06d Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 25 Mar 2014 18:39:34 +0400 Subject: [PATCH 40/69] IDEA-104933 IDEA-113949 Use temporary file to specify message for svn commit operation --- .../idea/svn/commandLine/CommandExecutor.java | 63 +++++++++++++++++-- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java index a5773ba19d4d..405e1c03a352 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java @@ -19,9 +19,12 @@ import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.EncodingEnvironmentUtil; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.process.*; +import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.util.EventDispatcher; import com.intellij.util.io.BaseDataReader; import com.intellij.util.io.BinaryOutputReader; @@ -30,10 +33,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.tmatesoft.svn.core.SVNCancelException; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; +import java.io.*; +import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -48,6 +49,8 @@ public class CommandExecutor { static final Logger LOG = Logger.getInstance(CommandExecutor.class.getName()); private final AtomicReference myExitCodeReference; + @Nullable private String myMessage; + @Nullable private File myMessageFile; private boolean myIsDestroyed; private boolean myNeedsDestroy; private volatile String myDestroyReason; @@ -84,10 +87,30 @@ public class CommandExecutor { myCommandLine.addParameters("--config-dir", command.getConfigDir().getPath()); } myCommandLine.addParameter(command.getName().getName()); - myCommandLine.addParameters(command.getParameters()); + myCommandLine.addParameters(prepareParameters(command)); myExitCodeReference = new AtomicReference(); } + @NotNull + private List prepareParameters(@NotNull Command command) { + List parameters = command.getParameters(); + + detectAndRemoveMessage(parameters); + + return parameters; + } + + private void detectAndRemoveMessage(@NotNull List parameters) { + int index = parameters.indexOf("-m"); + index = index < 0 ? parameters.indexOf("--message") : index; + + if (index >= 0 && index + 1 < parameters.size()) { + myMessage = parameters.get(index + 1); + parameters.remove(index + 1); + parameters.remove(index); + } + } + /** * Indicates if process was destroyed "manually" by command execution logic. * @@ -124,10 +147,38 @@ public class CommandExecutor { } protected void cleanup() { + cleanupMessageFile(); } - protected void beforeCreateProcess() { + protected void beforeCreateProcess() throws SvnBindException { EncodingEnvironmentUtil.fixDefaultEncodingIfMac(myCommandLine, null); + ensureMessageFile(); + } + + private void ensureMessageFile() throws SvnBindException { + if (myMessage != null) { + try { + File vcsFolder = new File(PathManager.getSystemPath(), "vcs"); + myMessageFile = FileUtil.createTempFile(new File(vcsFolder, "svn"), "commit-message", ".txt"); + FileUtil.writeToFile(myMessageFile, myMessage); + + myCommandLine.addParameters("-F", myMessageFile.getAbsolutePath()); + myCommandLine.addParameters("--config-option", "config:miscellany:log-encoding=" + CharsetToolkit.UTF8); + } + catch (IOException e) { + throw new SvnBindException(e); + } + } + } + + private void cleanupMessageFile() { + if (myMessageFile != null) { + boolean wasDeleted = FileUtil.delete(myMessageFile); + + if (!wasDeleted) { + LOG.info("Failed to delete temp commit message file " + myMessageFile.getAbsolutePath()); + } + } } @NotNull From ffe52682f5c94f217468e4bdecc7b55de13a7dc7 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Tue, 25 Mar 2014 18:54:41 +0400 Subject: [PATCH 41/69] IDEA-113949 Read output of svn commands with "--xml" option using UTF-8 encoding --- .../idea/svn/commandLine/CommandExecutor.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java index 405e1c03a352..5d909a5e186e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java @@ -185,7 +185,7 @@ public class CommandExecutor { protected OSProcessHandler createProcessHandler() { return needsBinaryOutput() ? new BinaryOSProcessHandler(myProcess, myCommandLine.getCommandLineString()) - : new OSProcessHandler(myProcess, myCommandLine.getCommandLineString()); + : new MyOSProcessHandler(myProcess, myCommandLine.getCommandLineString()); } private boolean needsBinaryOutput() { @@ -445,6 +445,21 @@ public class CommandExecutor { } } + private class MyOSProcessHandler extends OSProcessHandler { + + public MyOSProcessHandler(@NotNull Process process, @Nullable String commandLine) { + super(process, commandLine); + } + + @Override + protected Reader createProcessOutReader() { + if (myCommand.getParameters().contains("--xml")) { + return new InputStreamReader(myProcess.getInputStream(), CharsetToolkit.UTF8_CHARSET); + } + return super.createProcessOutReader(); + } + } + private static class BinaryOSProcessHandler extends OSProcessHandler { @NotNull private final ByteArrayOutputStream myBinaryOutput; From d9a27f7ed09339113afa40cf7c697f268de3bca6 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Tue, 25 Mar 2014 18:57:52 +0400 Subject: [PATCH 42/69] Typo --- .../src/com/intellij/ui/messages/SheetMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java index 786613eaf430..e47f16bd6937 100755 --- a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java @@ -91,7 +91,6 @@ public class SheetMessage { super.componentShown(e); setWindowOpacity(1.0f); myWindow.setSize(myController.SHEET_NC_WIDTH, myController.SHEET_NC_HEIGHT); - startAnimation(true); } }); } else { @@ -99,6 +98,7 @@ public class SheetMessage { myWindow.setSize(myController.SHEET_NC_WIDTH, myController.SHEET_NC_HEIGHT); setPositionRelativeToParent(); } + startAnimation(true); restoreFullscreenButton = couldBeInFullScreen(); if (restoreFullscreenButton) { FullScreenUtilities.setWindowCanFullScreen(myParent, false); From d134ceafa9edc0a04335022fd46814d187899182 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Tue, 25 Mar 2014 19:14:08 +0400 Subject: [PATCH 43/69] IDEA-122869 Change signature: unreadable message --- .../src/com/intellij/ui/messages/SheetController.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java index d12e37515f65..85b69ad776a6 100755 --- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java @@ -48,6 +48,8 @@ public class SheetController { private JButton myDefaultButton; private JButton myFocusedButton; + private static int RIGHT_OFFSET = 15; + public int SHADOW_BORDER = 10; // SHEET @@ -242,7 +244,9 @@ public class SheetController { messageTextPane.setContentType("text/html"); messageTextPane.setSize(250, Short.MAX_VALUE); messageTextPane.setText(message); - messageArea.setSize(250, messageTextPane.getPreferredSize().height); + messageArea.setSize(messageTextPane.getPreferredSize().width, messageTextPane.getPreferredSize().height); + + SHEET_WIDTH = Math.max(LEFT_SHEET_OFFSET + messageTextPane.getPreferredSize().width + RIGHT_OFFSET, SHEET_WIDTH); messageTextPane.setSize(messageArea); messageTextPane.setOpaque(false); @@ -298,7 +302,7 @@ public class SheetController { private void layoutButtons(final JButton[] buttons, JPanel panel) { - int buttonsWidth = 15; + int buttonsWidth = RIGHT_OFFSET; From 44818b41708113cdbb61277d7436c14d0acc2c9c Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Tue, 25 Mar 2014 19:32:28 +0400 Subject: [PATCH 44/69] IDEA-122866 'Terminate the process after disconnect' checkbox is switch off by default --- .../src/com/intellij/ui/messages/SheetController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java index 85b69ad776a6..553a23efc092 100755 --- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java @@ -329,7 +329,7 @@ public class SheetController { } private void layoutDoNotAskCheckbox(JPanel sheetPanel) { - doNotAskCheckBox = new JCheckBox(myDoNotAskOption.getDoNotShowMessage()); + doNotAskCheckBox = new JCheckBox(myDoNotAskOption.getDoNotShowMessage(), !myDoNotAskOption.isToBeShown()); doNotAskCheckBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { From 904069bc1dffd22c1805ace4ec8c0940f6a0af3f Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Tue, 25 Mar 2014 20:04:00 +0400 Subject: [PATCH 45/69] IDEA-122852 Mac Messages: underscore (broken mnemonic) on some buttons --- .../intellij/ui/messages/SheetController.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java index 553a23efc092..d10b1361d655 100755 --- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java @@ -134,13 +134,17 @@ public class SheetController { private void handleMnemonics(int i, String buttonTitle) { buttons[i].setName(buttonTitle); - - if (buttonTitle.indexOf('&') != -1) { - buttons[i].setMnemonic(buttonTitle.charAt(buttonTitle.indexOf('&') + 1)); - buttonTitle = buttonTitle.replace("&",""); - } - buttons[i].setText(buttonTitle); + setMnemonicsFromChar('&', buttons[i]); + setMnemonicsFromChar('_', buttons[i]); + } + + private static void setMnemonicsFromChar(char mnemonicChar, JButton button) { + String buttonTitle = button.getText(); + if (buttonTitle.indexOf(mnemonicChar) != -1) { + button.setMnemonic(buttonTitle.charAt(buttonTitle.indexOf(mnemonicChar) + 1)); + button.setText(buttonTitle.replace(Character.toString(mnemonicChar), "")); + } } void requestFocus() { From 6b9fcd03c216b9c398722e542b47bd78a353c2f3 Mon Sep 17 00:00:00 2001 From: Vassiliy Date: Tue, 25 Mar 2014 20:05:39 +0400 Subject: [PATCH 46/69] IDEA-122865 Settings / Editor / Color and Fonts: disable ability to edit color for inherited attributes --- platform/platform-api/src/com/intellij/ui/ColorPanel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ui/ColorPanel.java b/platform/platform-api/src/com/intellij/ui/ColorPanel.java index 49702e90ad0c..29871088f687 100644 --- a/platform/platform-api/src/com/intellij/ui/ColorPanel.java +++ b/platform/platform-api/src/com/intellij/ui/ColorPanel.java @@ -40,6 +40,7 @@ public class ColorPanel extends JComponent { addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { + if (!isEnabled() || !isEditable) return; Color color = ColorChooser.chooseColor(ColorPanel.this, UIBundle.message("color.panel.select.color.dialog.description"), myColor); if (color != null) { myColor = color; @@ -87,7 +88,7 @@ public class ColorPanel extends JComponent { return null; } StringBuilder buffer = new StringBuilder("0x").append(ColorUtil.toHex(myColor).toUpperCase()); - if (isEnabled()) { + if (isEnabled() && isEditable) { buffer.append(" (Click to customize)"); } return buffer.toString(); From 915a3d6b9181f0d8e31222d3dcc175ab728e8e60 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 25 Mar 2014 20:08:55 +0400 Subject: [PATCH 47/69] do not show Local History group in console editors --- .../ui/actions/LocalHistoryGroup.java | 17 ++++++++--------- .../integration/ui/actions/PutLabelAction.java | 6 ++++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryGroup.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryGroup.java index 550374a9541f..042b3162a60b 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryGroup.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/LocalHistoryGroup.java @@ -16,20 +16,19 @@ package com.intellij.history.integration.ui.actions; +import com.intellij.ide.actions.NonTrivialActionGroup; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.DumbAware; -public class LocalHistoryGroup extends DefaultActionGroup implements DumbAware { +public class LocalHistoryGroup extends NonTrivialActionGroup implements DumbAware { public void update(AnActionEvent event) { - Presentation p = event.getPresentation(); - boolean hasProject = event.getData(CommonDataKeys.PROJECT) != null; - - p.setVisible(hasProject); - p.setEnabled(hasProject); + if (event.getData(CommonDataKeys.PROJECT) == null) { + event.getPresentation().setEnabledAndVisible(false); + } + else { + super.update(event); + } } } diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/PutLabelAction.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/PutLabelAction.java index 5a3f6dfb0f35..86ba6ca5a3ef 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/PutLabelAction.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/actions/PutLabelAction.java @@ -17,6 +17,7 @@ package com.intellij.history.integration.ui.actions; import com.intellij.history.LocalHistory; +import com.intellij.history.core.LocalHistoryFacade; import com.intellij.history.integration.IdeaGateway; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.Project; @@ -34,4 +35,9 @@ public class PutLabelAction extends LocalHistoryActionWithDialog { if (labelName == null) return; LocalHistory.getInstance().putUserLabel(p, labelName); } + + @Override + protected boolean isEnabled(LocalHistoryFacade vcs, IdeaGateway gw, VirtualFile f, AnActionEvent e) { + return f != null && gw.isVersioned(f); + } } \ No newline at end of file From f072cf4d7b265827eb7f61c50d5b250059dbaec1 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Mar 2014 16:58:59 +0100 Subject: [PATCH 48/69] don't assume that *.txt is mapped to Plain Text (IDEA-122775) --- .../src/com/intellij/find/impl/FindDialog.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index e7c4aac7cafe..9b5ae4ba3952 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -30,6 +30,7 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.FileTypes; +import com.intellij.openapi.fileTypes.PlainTextFileType; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; @@ -56,7 +57,6 @@ import com.intellij.ui.components.labels.LinkListener; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -668,15 +668,17 @@ public class FindDialog extends DialogWrapper { final Component editorComponent = inputComboBox.getEditor().getEditorComponent(); if (editorComponent instanceof EditorTextField) { - boolean selected = myCbRegularExpressions.isSelectedWhenSelectable(); - @NonNls final String s = selected ? "*.regexp" : "*.txt"; - FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(s); - - if (selected && fileType == FileTypes.UNKNOWN) { - fileType = FileTypeManager.getInstance().getFileTypeByFileName("*.txt"); // RegExp plugin is not installed + boolean isRegexp = myCbRegularExpressions.isSelectedWhenSelectable(); + FileType fileType = PlainTextFileType.INSTANCE; + if (isRegexp) { + FileType regexpFileType = FileTypeManager.getInstance().getFileTypeByFileName("a.regexp"); + if (regexpFileType != FileTypes.UNKNOWN) { // RegExp plugin might not be installed + fileType = regexpFileType; + } } - final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(s, fileType, ((EditorTextField)editorComponent).getText(), -1, true); + String fileName = isRegexp ? "a.regexp" : "a.txt"; + final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(fileName, fileType, ((EditorTextField)editorComponent).getText(), -1, true); ((EditorTextField)editorComponent).setNewDocumentAndFileType(fileType, PsiDocumentManager.getInstance(myProject).getDocument(file)); } From 86e73625e9b70a961e4427789a592d495615792f Mon Sep 17 00:00:00 2001 From: Vassiliy Date: Tue, 25 Mar 2014 20:28:59 +0400 Subject: [PATCH 49/69] IDEA-122863 Settings / TODO: the user-defined color is shown incorrectly after making changes --- platform/platform-api/src/com/intellij/ui/ColorPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/ui/ColorPanel.java b/platform/platform-api/src/com/intellij/ui/ColorPanel.java index 29871088f687..48732d310880 100644 --- a/platform/platform-api/src/com/intellij/ui/ColorPanel.java +++ b/platform/platform-api/src/com/intellij/ui/ColorPanel.java @@ -43,7 +43,7 @@ public class ColorPanel extends JComponent { if (!isEnabled() || !isEditable) return; Color color = ColorChooser.chooseColor(ColorPanel.this, UIBundle.message("color.panel.select.color.dialog.description"), myColor); if (color != null) { - myColor = color; + setSelectedColor(color); fireActionEvent(); } } From 0db54408e48ad61116cd486fa0d3805229ac96bb Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Tue, 25 Mar 2014 20:35:40 +0400 Subject: [PATCH 50/69] Better approach for IDEA-122869 Change signature: unreadable message --- .../intellij/ui/messages/SheetController.java | 19 +++++++++++++++---- .../intellij/ui/messages/SheetMessage.java | 5 +++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java index d10b1361d655..d530410c55c5 100755 --- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java @@ -246,11 +246,22 @@ public class SheetController { messageTextPane.setEditable(false); messageTextPane.setContentType("text/html"); - messageTextPane.setSize(250, Short.MAX_VALUE); - messageTextPane.setText(message); - messageArea.setSize(messageTextPane.getPreferredSize().width, messageTextPane.getPreferredSize().height); - SHEET_WIDTH = Math.max(LEFT_SHEET_OFFSET + messageTextPane.getPreferredSize().width + RIGHT_OFFSET, SHEET_WIDTH); + FontMetrics fontMetrics = mySheetMessage.getFontMetrics(regularFont); + + int widestWordWidth = 250; + + String [] words = message.split(" "); + + for (String word : words) { + widestWordWidth = Math.max(fontMetrics.stringWidth(word), widestWordWidth); + } + + messageTextPane.setSize(widestWordWidth, Short.MAX_VALUE); + messageTextPane.setText(message); + messageArea.setSize(widestWordWidth, messageTextPane.getPreferredSize().height); + + SHEET_WIDTH = Math.max(LEFT_SHEET_OFFSET + widestWordWidth + RIGHT_OFFSET, SHEET_WIDTH); messageTextPane.setSize(messageArea); messageTextPane.setOpaque(false); diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java index e47f16bd6937..523fd6d4c311 100755 --- a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java @@ -228,6 +228,11 @@ public class SheetMessage { } }); } + + FontMetrics getFontMetrics(Font f) { + return myParent.getGraphics().getFontMetrics(f); + } + } From ea818c84878b0d22c4feb94650e2c2c4b04dd802 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 25 Mar 2014 20:45:06 +0400 Subject: [PATCH 51/69] PY-12332 "Generate stubs for binary module" in IronPython with non-Camelcase names not available or presented (Env test added) --- .../src/com/intellij/openapi/wm/impl/TestWindowManager.java | 2 +- .../python/inspections/quickfix/GenerateBinaryStubsFix.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/TestWindowManager.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/TestWindowManager.java index cce1a675fd00..413386bb9daa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/TestWindowManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/TestWindowManager.java @@ -266,7 +266,7 @@ public final class TestWindowManager extends WindowManagerEx implements Applicat @Override public IdeFrame findFrameFor(@Nullable Project project) { - throw new UnsupportedOperationException(); + return null; } @NotNull diff --git a/python/src/com/jetbrains/python/inspections/quickfix/GenerateBinaryStubsFix.java b/python/src/com/jetbrains/python/inspections/quickfix/GenerateBinaryStubsFix.java index a351b5c36b6e..6381710aecef 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/GenerateBinaryStubsFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/GenerateBinaryStubsFix.java @@ -86,19 +86,22 @@ public class GenerateBinaryStubsFix implements LocalQuickFix { return elementText; } + @Override @NotNull public String getName() { return "Generate stubs for binary module " + myQualifiedName; } + @Override @NotNull public String getFamilyName() { return "Generate binary stubs"; } + @Override public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) { final PsiFile file = descriptor.getPsiElement().getContainingFile(); - final String folder = file.getContainingDirectory().getVirtualFile().getPath(); + final String folder = file.getContainingDirectory().getVirtualFile().getCanonicalPath(); final Task.Backgroundable backgroundable = new Task.Backgroundable(project, "Generating skeletons for binary module", false) { From 5305823aa02e50500b880b03d4b32b9f87e9e0ea Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 25 Mar 2014 21:45:13 +0400 Subject: [PATCH 52/69] PY-12521 Wrong skeletons generated for static methods in CLR/IronPython --- .../pycharm_generator_utils/module_redeclarator.py | 4 +++- .../helpers/pycharm_generator_utils/util_methods.py | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/python/helpers/pycharm_generator_utils/module_redeclarator.py b/python/helpers/pycharm_generator_utils/module_redeclarator.py index dcae2b5471c6..4d00e1f43875 100644 --- a/python/helpers/pycharm_generator_utils/module_redeclarator.py +++ b/python/helpers/pycharm_generator_utils/module_redeclarator.py @@ -529,7 +529,9 @@ class ModuleRedeclarator(object): out(indent, "def ", spec, ": # ", sig_note) out_doc_attr(out, p_func, indent + 1, p_class) elif sys.platform == 'cli' and is_clr_type(p_class): - spec, sig_note = restore_clr(p_name, p_class) + is_static, spec, sig_note = restore_clr(p_name, p_class) + if is_static: + out(indent, "@staticmethod") if not spec: return if sig_note: out(indent, "def ", spec, ": #", sig_note) diff --git a/python/helpers/pycharm_generator_utils/util_methods.py b/python/helpers/pycharm_generator_utils/util_methods.py index 2ddbc94f4a63..d679e3385264 100644 --- a/python/helpers/pycharm_generator_utils/util_methods.py +++ b/python/helpers/pycharm_generator_utils/util_methods.py @@ -520,28 +520,32 @@ def is_clr_type(clr_type): def restore_clr(p_name, p_class): """ Restore the function signature by the CLR type signature + :return (is_static, spec, sig_note) """ clr_type = clr.GetClrType(p_class) if p_name == '__new__': methods = [c for c in clr_type.GetConstructors()] if not methods: - return p_name + '(*args)', 'cannot find CLR constructor' + return False, p_name + '(*args)', 'cannot find CLR constructor' else: methods = [m for m in clr_type.GetMethods() if m.Name == p_name] if not methods: bases = p_class.__bases__ if len(bases) == 1 and p_name in dir(bases[0]): # skip inherited methods - return None, None - return p_name + '(*args)', 'cannot find CLR method' + return False, None, None + return False, p_name + '(*args)', 'cannot find CLR method' parameter_lists = [] for m in methods: parameter_lists.append([p.Name for p in m.GetParameters()]) params = restore_parameters_for_overloads(parameter_lists) + is_static = False if not methods[0].IsStatic: params = ['self'] + params - return build_signature(p_name, params), None + else: + is_static = True + return is_static, build_signature(p_name, params), None def build_output_name(dirname, qualified_name): qualifiers = qualified_name.split(".") From 933956c5545298d7f7009849d0fcf2d411e221d0 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Tue, 25 Mar 2014 12:50:22 +0400 Subject: [PATCH 53/69] custom annotation checkers should be applied to alias annotations --- plugins/groovy/src/META-INF/plugin.xml | 18 +-- .../groovy/annotator/GroovyAnnotator.java | 48 +------ .../checkers/AliasedAnnotationHolder.java | 131 ++++++++++++++++++ .../annotator/checkers/AnnotationChecker.java | 77 ++++++++++ .../AnnotationCollectorChecker.java | 10 +- .../BaseScriptAnnotationChecker.java | 2 +- .../CustomAnnotationChecker.java | 33 +++-- .../DelegatesToAnnotationChecker.java | 4 +- .../FieldAnnotationChecker.java | 4 +- .../GrAliasAnnotationChecker.java | 59 +++----- .../{ => checkers}/GrabAnnotationChecker.java | 4 +- .../NewifyAnnotationChecker.java | 4 +- .../TypeCheckedAnnotationChecker.java | 10 +- ...ffonPropertyListenerAnnotationChecker.java | 4 +- .../lang/psi/impl/GrAnnotationUtil.java | 8 ++ .../annotation/GrAnnotationImpl.java | 5 +- .../psi/impl/synthetic/GrLightAnnotation.java | 22 ++- .../groovy/lang/resolve/ResolveUtil.java | 2 +- 18 files changed, 305 insertions(+), 140 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AliasedAnnotationHolder.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AnnotationChecker.java rename plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/{ => checkers}/AnnotationCollectorChecker.java (90%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/{ => checkers}/BaseScriptAnnotationChecker.java (97%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/{ => checkers}/CustomAnnotationChecker.java (83%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/{ => checkers}/DelegatesToAnnotationChecker.java (96%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/{ => checkers}/FieldAnnotationChecker.java (97%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/{ => checkers}/GrAliasAnnotationChecker.java (67%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/{ => checkers}/GrabAnnotationChecker.java (93%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/{ => checkers}/NewifyAnnotationChecker.java (92%) rename plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/{ => checkers}/TypeCheckedAnnotationChecker.java (85%) diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 39f8de6ce81a..896ea0b847e1 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -75,7 +75,7 @@ - + @@ -198,17 +198,17 @@ - - - - - - + + + + + + - + - + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index bb4012b325fe..37f1ccd9957c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -55,6 +55,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.GroovyFileType; +import org.jetbrains.plugins.groovy.annotator.checkers.AnnotationChecker; +import org.jetbrains.plugins.groovy.annotator.checkers.CustomAnnotationChecker; import org.jetbrains.plugins.groovy.annotator.intentions.*; import org.jetbrains.plugins.groovy.codeInspection.bugs.GrModifierFix; import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; @@ -1447,48 +1449,12 @@ public class GroovyAnnotator extends GroovyElementVisitor { @Override public void visitAnnotation(GrAnnotation annotation) { - final GrCodeReferenceElement ref = annotation.getClassReference(); - final PsiElement resolved = ref.resolve(); - - if (resolved == null) return; - assert resolved instanceof PsiClass; - - PsiClass anno = (PsiClass)resolved; - String qname = anno.getQualifiedName(); - if (!anno.isAnnotationType() && GrAnnotationCollector.findAnnotationCollector(anno) == null) { - if (qname != null) { - myHolder.createErrorAnnotation(ref, GroovyBundle.message("class.is.not.annotation", qname)); - } - return; - } - - for (CustomAnnotationChecker checker : CustomAnnotationChecker.EP_NAME.getExtensions()) { - if (checker.checkApplicability(myHolder, annotation)) return; - } - - String description = CustomAnnotationChecker.isAnnotationApplicable(annotation, annotation.getParent()); - if (description != null) { - myHolder.createErrorAnnotation(ref, description).registerFix(new GrRemoveAnnotationIntention()); - } + new AnnotationChecker(myHolder).checkApplicability(annotation, annotation.getOwner()); } @Override public void visitAnnotationArgumentList(GrAnnotationArgumentList annotationArgumentList) { - final GrAnnotation annotation = (GrAnnotation)annotationArgumentList.getParent(); - - final PsiClass anno = ResolveUtil.resolveAnnotation(annotationArgumentList); - if (anno == null) return; - - for (CustomAnnotationChecker checker : CustomAnnotationChecker.EP_NAME.getExtensions()) { - if (checker.checkArgumentList(myHolder, annotation)) return; - } - - Map errors = ContainerUtil.newHashMap(); - CustomAnnotationChecker.checkAnnotationArguments(errors, anno, annotation.getClassReference(), annotationArgumentList.getAttributes(), - true); - for (Map.Entry entry : errors.entrySet()) { - myHolder.createErrorAnnotation(entry.getKey(), entry.getValue()); - } + new AnnotationChecker(myHolder).checkAnnotationArgumentList((GrAnnotation)annotationArgumentList.getParent()); } @Override @@ -1500,11 +1466,7 @@ public class GroovyAnnotator extends GroovyElementVisitor { final PsiType type = annotationMethod.getReturnType(); - Map errors = ContainerUtil.newHashMap(); - CustomAnnotationChecker.checkAnnotationValueByType(errors, value, type, false); - for (Map.Entry entry : errors.entrySet()) { - myHolder.createErrorAnnotation(entry.getKey(), entry.getValue()); - } + CustomAnnotationChecker.checkAnnotationValueByType(myHolder, value, type, false); } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AliasedAnnotationHolder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AliasedAnnotationHolder.java new file mode 100644 index 000000000000..026131065b1e --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AliasedAnnotationHolder.java @@ -0,0 +1,131 @@ +/* + * 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 org.jetbrains.plugins.groovy.annotator.checkers; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.annotation.Annotation; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.AnnotationSession; +import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; + +/** +* Created by Max Medvedev on 25/03/14 +*/ +class AliasedAnnotationHolder implements AnnotationHolder { + private final AnnotationHolder myHolder; + private final GrAnnotation myAlias; + private final GrCodeReferenceElement myReference; + + public AliasedAnnotationHolder(@NotNull AnnotationHolder holder, @NotNull GrAnnotation alias) { + myHolder = holder; + myAlias = alias; + myReference = myAlias.getClassReference(); + } + + @NotNull + private PsiElement findCodeElement(@NotNull PsiElement elt) { + if (PsiTreeUtil.isAncestor(myAlias, elt, true)) { + return elt; + } + else { + return myReference; + } + } + + @Override + public Annotation createErrorAnnotation(@NotNull PsiElement elt, @Nullable String message) { + PsiElement codeElement = findCodeElement(elt); + return myHolder.createErrorAnnotation(codeElement, message); + } + + @Override + public Annotation createErrorAnnotation(@NotNull ASTNode node, @Nullable String message) { + return createErrorAnnotation(node.getPsi(), message); + } + + @Override + public Annotation createErrorAnnotation(@NotNull TextRange range, @Nullable String message) { + throw new UnsupportedOperationException("unsupported"); + } + + @Override + public Annotation createWarningAnnotation(@NotNull PsiElement elt, @Nullable String message) { + return myHolder.createWarningAnnotation(findCodeElement(elt), message); + } + + @Override + public Annotation createWarningAnnotation(@NotNull ASTNode node, @Nullable String message) { + return myHolder.createWarningAnnotation(node.getPsi(), message); + } + + @Override + public Annotation createWarningAnnotation(@NotNull TextRange range, @Nullable String message) { + throw new UnsupportedOperationException("unsupported"); + } + + @Override + public Annotation createWeakWarningAnnotation(@NotNull PsiElement elt, @Nullable String message) { + return myHolder.createWeakWarningAnnotation(findCodeElement(elt), message); + } + + @Override + public Annotation createWeakWarningAnnotation(@NotNull ASTNode node, @Nullable String message) { + return myHolder.createWarningAnnotation(node.getPsi(), message); + } + + @Override + public Annotation createWeakWarningAnnotation(@NotNull TextRange range, @Nullable String message) { + throw new UnsupportedOperationException("unsupported"); + } + + @Override + public Annotation createInfoAnnotation(@NotNull PsiElement elt, @Nullable String message) { + return myHolder.createInfoAnnotation(findCodeElement(elt), message); + } + + @Override + public Annotation createInfoAnnotation(@NotNull ASTNode node, @Nullable String message) { + return myHolder.createInfoAnnotation(node.getPsi(), message); + } + + @Override + public Annotation createInfoAnnotation(@NotNull TextRange range, @Nullable String message) { + throw new UnsupportedOperationException("unsupported"); + } + + @Override + public Annotation createAnnotation(@NotNull HighlightSeverity severity, @NotNull TextRange range, @Nullable String message) { + throw new UnsupportedOperationException("unsupported"); + } + + @NotNull + @Override + public AnnotationSession getCurrentAnnotationSession() { + return myHolder.getCurrentAnnotationSession(); + } + + @Override + public boolean isBatchMode() { + return myHolder.isBatchMode(); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AnnotationChecker.java new file mode 100644 index 000000000000..47ec8c9adf0f --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AnnotationChecker.java @@ -0,0 +1,77 @@ +/* + * 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 org.jetbrains.plugins.groovy.annotator.checkers; + +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.psi.PsiAnnotationOwner; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.GroovyBundle; +import org.jetbrains.plugins.groovy.annotator.GrRemoveAnnotationIntention; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers.GrAnnotationCollector; +import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; + +/** + * Created by Max Medvedev on 25/03/14 + */ +public class AnnotationChecker { + private final AnnotationHolder myHolder; + + public AnnotationChecker(@NotNull AnnotationHolder holder) { + myHolder = holder; + } + + public void checkApplicability(@NotNull GrAnnotation annotation, @Nullable PsiAnnotationOwner owner) { + final GrCodeReferenceElement ref = annotation.getClassReference(); + final PsiElement resolved = ref.resolve(); + + if (resolved == null) return; + assert resolved instanceof PsiClass; + + PsiClass anno = (PsiClass)resolved; + String qname = anno.getQualifiedName(); + if (!anno.isAnnotationType() && GrAnnotationCollector.findAnnotationCollector(anno) == null) { + if (qname != null) { + myHolder.createErrorAnnotation(ref, GroovyBundle.message("class.is.not.annotation", qname)); + } + return; + } + + for (CustomAnnotationChecker checker : CustomAnnotationChecker.EP_NAME.getExtensions()) { + if (checker.checkApplicability(myHolder, annotation)) return; + } + + String description = CustomAnnotationChecker.isAnnotationApplicable(annotation, owner); + if (description != null) { + myHolder.createErrorAnnotation(ref, description).registerFix(new GrRemoveAnnotationIntention()); + } + } + + public void checkAnnotationArgumentList(@NotNull GrAnnotation annotation) { + final PsiClass anno = ResolveUtil.resolveAnnotation(annotation); + if (anno == null) return; + + for (CustomAnnotationChecker checker : CustomAnnotationChecker.EP_NAME.getExtensions()) { + if (checker.checkArgumentList(myHolder, annotation)) return; + } + + CustomAnnotationChecker.checkAnnotationArguments(myHolder, anno, annotation.getClassReference(), annotation.getParameterList().getAttributes(), true); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/AnnotationCollectorChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AnnotationCollectorChecker.java similarity index 90% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/AnnotationCollectorChecker.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AnnotationCollectorChecker.java index e866454026d6..e25a8cae67d6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/AnnotationCollectorChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/AnnotationCollectorChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.annotator; +package org.jetbrains.plugins.groovy.annotator.checkers; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.openapi.util.Condition; @@ -26,8 +26,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation. import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; -import java.util.Map; - /** * @author Medvdedev Max */ @@ -42,12 +40,10 @@ public class AnnotationCollectorChecker extends CustomAnnotationChecker { public boolean checkArgumentList(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) { if (!isInAliasDeclaration(annotation)) return false; - Map errors = ContainerUtil.newHashMap(); final PsiClass clazz = (PsiClass)annotation.getClassReference().resolve(); if (clazz == null) return true; final GrAnnotationNameValuePair[] attributes = annotation.getParameterList().getAttributes(); - CustomAnnotationChecker.checkAnnotationArguments(errors, clazz, annotation.getClassReference(), attributes, false); - highlightErrors(holder, errors); + CustomAnnotationChecker.checkAnnotationArguments(holder, clazz, annotation.getClassReference(), attributes, false); return true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/BaseScriptAnnotationChecker.java similarity index 97% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/BaseScriptAnnotationChecker.java index 5c49f9499fd5..c3f3376dd04a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/BaseScriptAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/BaseScriptAnnotationChecker.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.annotator; +package org.jetbrains.plugins.groovy.annotator.checkers; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.psi.CommonClassNames; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/CustomAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/CustomAnnotationChecker.java similarity index 83% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/CustomAnnotationChecker.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/CustomAnnotationChecker.java index 082ec4d3fcda..d6ab1f291739 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/CustomAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/CustomAnnotationChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.annotator; +package org.jetbrains.plugins.groovy.annotator.checkers; import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.lang.annotation.AnnotationHolder; @@ -52,8 +52,9 @@ public abstract class CustomAnnotationChecker { public boolean checkApplicability(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) {return false;} @Nullable - public static String isAnnotationApplicable(@NotNull GrAnnotation annotation, final PsiElement parent) { - PsiElement ownerToUse = parent instanceof PsiModifierList ? parent.getParent() : parent; + public static String isAnnotationApplicable(@NotNull GrAnnotation annotation, @Nullable PsiAnnotationOwner owner) { + if (!(owner instanceof PsiElement)) return null; + PsiElement ownerToUse = owner instanceof PsiModifierList ? ((PsiElement)owner).getParent() : (PsiElement)owner; PsiAnnotation.TargetType[] elementTypeFields = GrAnnotationImpl.getApplicableElementTypeFields(ownerToUse); if (elementTypeFields.length != 0 && !GrAnnotationImpl.isAnnotationApplicableTo(annotation, elementTypeFields)) { String annotationTargetText = JavaErrorMessages.message("annotation.target." + elementTypeFields[0]); @@ -64,10 +65,11 @@ public abstract class CustomAnnotationChecker { return null; } - public static void checkAnnotationArguments(@NotNull Map holder, + public static void checkAnnotationArguments(@NotNull AnnotationHolder holder, @NotNull PsiClass annotation, @NotNull GrCodeReferenceElement refToHighlight, - @NotNull GrAnnotationNameValuePair[] attributes, boolean checkMissedAttributes) { + @NotNull GrAnnotationNameValuePair[] attributes, + boolean checkMissedAttributes) { Set usedAttrs = new HashSet(); if (attributes.length > 0) { @@ -99,7 +101,7 @@ public abstract class CustomAnnotationChecker { } if (checkMissedAttributes && !missedAttrs.isEmpty()) { - holder.put(refToHighlight, GroovyBundle.message("missed.attributes", StringUtil.join(missedAttrs, ", "))); + holder.createErrorAnnotation(refToHighlight, GroovyBundle.message("missed.attributes", StringUtil.join(missedAttrs, ", "))); } } @@ -108,17 +110,17 @@ public abstract class CustomAnnotationChecker { @NotNull String name, @NotNull Set usedAttrs, @Nullable GrAnnotationMemberValue value, - @NotNull Map holder) { + @NotNull AnnotationHolder holder) { if (usedAttrs.contains(name)) { - holder.put(identifierToHighlight, GroovyBundle.message("duplicate.attribute")); + holder.createErrorAnnotation(identifierToHighlight, GroovyBundle.message("duplicate.attribute")); } usedAttrs.add(name); final PsiMethod[] methods = annotation.findMethodsByName(name, false); if (methods.length == 0) { - holder.put(identifierToHighlight, - GroovyBundle.message("at.interface.0.does.not.contain.attribute", annotation.getQualifiedName(), name)); + holder.createErrorAnnotation(identifierToHighlight, + GroovyBundle.message("at.interface.0.does.not.contain.attribute", annotation.getQualifiedName(), name)); } else { final PsiMethod method = methods[0]; @@ -129,7 +131,7 @@ public abstract class CustomAnnotationChecker { } } - public static void checkAnnotationValueByType(@NotNull Map holder, + public static void checkAnnotationValueByType(@NotNull AnnotationHolder holder, @NotNull GrAnnotationMemberValue value, @Nullable PsiType ltype, boolean skipArrays) { @@ -146,7 +148,8 @@ public abstract class CustomAnnotationChecker { } if (rtype != null && !checkAnnoTypeAssignable(ltype, rtype, value, skipArrays)) { - holder.put(value, GroovyBundle.message("cannot.assign", rtype.getPresentableText(), ltype.getPresentableText())); + holder.createErrorAnnotation(value, + GroovyBundle.message("cannot.assign", rtype.getPresentableText(), ltype.getPresentableText())); } } @@ -155,7 +158,7 @@ public abstract class CustomAnnotationChecker { if (resolved instanceof PsiClass) { final PsiClassType rtype = JavaPsiFacade.getElementFactory(value.getProject()).createType((PsiClass)resolved, PsiSubstitutor.EMPTY); if (!checkAnnoTypeAssignable(ltype, rtype, value, skipArrays)) { - holder.put(value, GroovyBundle.message("cannot.assign", rtype.getPresentableText(), ltype.getPresentableText())); + holder.createErrorAnnotation(value, GroovyBundle.message("cannot.assign", rtype.getPresentableText(), ltype.getPresentableText())); } } } @@ -172,7 +175,7 @@ public abstract class CustomAnnotationChecker { else { final PsiType rtype = TypesUtil.getTupleByAnnotationArrayInitializer((GrAnnotationArrayInitializer)value); if (!checkAnnoTypeAssignable(ltype, rtype, value, skipArrays)) { - holder.put(value, GroovyBundle.message("cannot.assign", rtype.getPresentableText(), ltype.getPresentableText())); + holder.createErrorAnnotation(value, GroovyBundle.message("cannot.assign", rtype.getPresentableText(), ltype.getPresentableText())); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/DelegatesToAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/DelegatesToAnnotationChecker.java similarity index 96% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/DelegatesToAnnotationChecker.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/DelegatesToAnnotationChecker.java index fcb6d65af29a..d995b60fd18b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/DelegatesToAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/DelegatesToAnnotationChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.annotator; +package org.jetbrains.plugins.groovy.annotator.checkers; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.psi.PsiAnnotationMemberValue; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/FieldAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/FieldAnnotationChecker.java similarity index 97% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/FieldAnnotationChecker.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/FieldAnnotationChecker.java index db27997dd239..9de2ab1045dd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/FieldAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/FieldAnnotationChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.annotator; +package org.jetbrains.plugins.groovy.annotator.checkers; import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.lang.annotation.AnnotationHolder; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/GrAliasAnnotationChecker.java similarity index 67% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/GrAliasAnnotationChecker.java index d9709702eee0..532a71475eb8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/GrAliasAnnotationChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,24 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.annotator; +package org.jetbrains.plugins.groovy.annotator.checkers; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.psi.PsiAnnotation; -import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers.GrAnnotationCollector; -import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import java.util.ArrayList; -import java.util.Map; import java.util.Set; /** @@ -40,27 +36,30 @@ public class GrAliasAnnotationChecker extends CustomAnnotationChecker { @Override public boolean checkApplicability(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) { - final PsiAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation); - if (annotationCollector == null) { + final ArrayList aliasedAnnotations = getAliasedAnnotations(annotation); + if (aliasedAnnotations == null) { return false; } - final GrCodeReferenceElement ref = annotation.getClassReference(); - - final ArrayList aliasedAnnotations = ContainerUtil.newArrayList(); - GrAnnotationCollector.collectAnnotations(aliasedAnnotations, annotation, annotationCollector); - - for (GrAnnotation anno : aliasedAnnotations) { - if (GroovyCommonClassNames.GROOVY_TRANSFORM_ANNOTATION_COLLECTOR.equals(anno.getQualifiedName())) continue; - final String description = CustomAnnotationChecker.isAnnotationApplicable(anno, annotation.getParent()); - if (description != null) { - holder.createErrorAnnotation(ref, description); - } + AliasedAnnotationHolder aliasedHolder = new AliasedAnnotationHolder(holder, annotation); + AnnotationChecker checker = new AnnotationChecker(aliasedHolder); + for (GrAnnotation aliased : aliasedAnnotations) { + checker.checkApplicability(aliased, annotation.getOwner()); } return true; } + @Nullable + private static ArrayList getAliasedAnnotations(GrAnnotation annotation) { + final PsiAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation); + if (annotationCollector == null) return null; + + final ArrayList aliasedAnnotations = ContainerUtil.newArrayList(); + GrAnnotationCollector.collectAnnotations(aliasedAnnotations, annotation, annotationCollector); + return aliasedAnnotations; + } + @Override public boolean checkArgumentList(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) { final PsiAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation); @@ -71,24 +70,10 @@ public class GrAliasAnnotationChecker extends CustomAnnotationChecker { final ArrayList annotations = ContainerUtil.newArrayList(); final Set usedAttributes = GrAnnotationCollector.collectAnnotations(annotations, annotation, annotationCollector); - final GrCodeReferenceElement ref = annotation.getClassReference(); - - Map map = ContainerUtil.newHashMap(); + AliasedAnnotationHolder aliasedHolder = new AliasedAnnotationHolder(holder, annotation); + AnnotationChecker checker = new AnnotationChecker(aliasedHolder); for (GrAnnotation aliased : annotations) { - final PsiClass clazz = (PsiClass)aliased.getClassReference().resolve(); - assert clazz != null; - checkAnnotationArguments(map, clazz, ref, aliased.getParameterList().getAttributes(), true); - } - - for (Map.Entry entry : map.entrySet()) { - final PsiElement key = entry.getKey(); - final String value = entry.getValue(); - if (PsiTreeUtil.isAncestor(annotation, key, true)) { - holder.createErrorAnnotation(key, value); - } - else { - holder.createErrorAnnotation(ref, value); - } + checker.checkAnnotationArgumentList(aliased); } final GrAnnotationNameValuePair[] attributes = annotation.getParameterList().getAttributes(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrabAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/GrabAnnotationChecker.java similarity index 93% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrabAnnotationChecker.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/GrabAnnotationChecker.java index 229627d4da7e..5586fcc8a2b9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrabAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/GrabAnnotationChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.annotator; +package org.jetbrains.plugins.groovy.annotator.checkers; import com.intellij.lang.annotation.AnnotationHolder; import org.jetbrains.annotations.NotNull; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/NewifyAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/NewifyAnnotationChecker.java similarity index 92% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/NewifyAnnotationChecker.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/NewifyAnnotationChecker.java index 75e8c03cc74f..93f7d8f0e923 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/NewifyAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/NewifyAnnotationChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.annotator; +package org.jetbrains.plugins.groovy.annotator.checkers; import com.intellij.lang.annotation.AnnotationHolder; import org.jetbrains.annotations.NotNull; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/TypeCheckedAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/TypeCheckedAnnotationChecker.java similarity index 85% rename from plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/TypeCheckedAnnotationChecker.java rename to plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/TypeCheckedAnnotationChecker.java index b378d93fd1f4..ce990515bde2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/TypeCheckedAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/checkers/TypeCheckedAnnotationChecker.java @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.annotator; +package org.jetbrains.plugins.groovy.annotator.checkers; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; @@ -26,8 +25,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation. import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; -import java.util.Map; - /** * @author Max Medvedev */ @@ -46,10 +43,7 @@ public class TypeCheckedAnnotationChecker extends CustomAnnotationChecker { "2.1.0".equals(sdkVersion))) return false; GrAnnotationNameValuePair[] attributes = annotation.getParameterList().getAttributes(); - Map errorMap = ContainerUtil.newHashMap(); - CustomAnnotationChecker.checkAnnotationArguments(errorMap, (PsiClass)resolved, classReference, attributes, false); - highlightErrors(holder, errorMap); - + checkAnnotationArguments(holder, (PsiClass)resolved, classReference, attributes, false); return true; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonPropertyListenerAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonPropertyListenerAnnotationChecker.java index 56075796b6e5..31cd38b12b99 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonPropertyListenerAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonPropertyListenerAnnotationChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import com.intellij.psi.PsiAnnotationOwner; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.annotator.CustomAnnotationChecker; +import org.jetbrains.plugins.groovy.annotator.checkers.CustomAnnotationChecker; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrAnnotationUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrAnnotationUtil.java index b43ee28c1ece..cf5a9dd34c7e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrAnnotationUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrAnnotationUtil.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; @@ -102,4 +103,11 @@ public class GrAnnotationUtil { } return null; } + + public static PsiElement getActualOwner(GrAnnotation annotation) { + PsiAnnotationOwner owner = annotation.getOwner(); + if (owner instanceof PsiModifierList) return ((PsiModifierList)owner).getParent(); + + return (PsiElement)owner; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java index c672ca128c8c..234dc18f73b2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -176,7 +176,8 @@ public class GrAnnotationImpl extends GrStubElementBase implem @Nullable public PsiAnnotationOwner getOwner() { - return (PsiAnnotationOwner)getParent(); + PsiElement parent = getParent(); + return parent instanceof PsiAnnotationOwner ? (PsiAnnotationOwner)parent : null; } @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java index ebf4312775cc..4862c0bbb553 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,10 +45,13 @@ public class GrLightAnnotation extends LightElement implements GrAnnotation { private final GrLightAnnotationArgumentList myAnnotationArgList; private final String myQualifiedName; - private PsiAnnotationOwner myOwner; - private GrLightClassReferenceElement myRef; + private final PsiAnnotationOwner myOwner; + private final GrLightClassReferenceElement myRef; - public GrLightAnnotation(PsiManager manager, Language language, String qualifiedName, PsiAnnotationOwner owner) { + public GrLightAnnotation(@NotNull PsiManager manager, + @NotNull Language language, + @NotNull String qualifiedName, + @NotNull PsiAnnotationOwner owner) { super(manager, language); myQualifiedName = qualifiedName; myOwner = owner; @@ -157,12 +160,17 @@ public class GrLightAnnotation extends LightElement implements GrAnnotation { } - private static class GrLightAnnotationArgumentList extends LightElement implements GrAnnotationArgumentList { + private class GrLightAnnotationArgumentList extends LightElement implements GrAnnotationArgumentList { private List myAttributes = null; private GrAnnotationNameValuePair[] myCachedAttributes = GrAnnotationNameValuePair.EMPTY_ARRAY; - private GrLightAnnotationArgumentList(PsiManager manager, Language language) { + @Override + public PsiElement getContext() { + return GrLightAnnotation.this; + } + + private GrLightAnnotationArgumentList(@NotNull PsiManager manager, @NotNull Language language) { super(manager, language); } @@ -203,7 +211,7 @@ public class GrLightAnnotation extends LightElement implements GrAnnotation { @Override public String getText() { - if (myAttributes.isEmpty()) return ""; + if (myAttributes == null || myAttributes.isEmpty()) return ""; StringBuilder buffer = new StringBuilder(); buffer.append('('); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index 2f93cdc977ca..80e2d31de99d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -850,7 +850,7 @@ public class ResolveUtil { @Nullable public static PsiClass resolveAnnotation(PsiElement insideAnnotation) { - final GrAnnotation annotation = PsiTreeUtil.getParentOfType(insideAnnotation, GrAnnotation.class); + final GrAnnotation annotation = PsiTreeUtil.getParentOfType(insideAnnotation, GrAnnotation.class, false); if (annotation == null) return null; final GrCodeReferenceElement reference = annotation.getClassReference(); From 0b83ac9c9bdfd2f81d67b1267937ac0f76e9561c Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 25 Mar 2014 22:19:33 +0400 Subject: [PATCH 54/69] IDEA-122839 wrong ToolWindow title --- .../com/intellij/openapi/wm/ToolWindow.java | 12 ++++++++++- .../openapi/wm/ToolWindowContentUiType.java | 4 ++-- .../intellij/openapi/wm/ex/ToolWindowEx.java | 1 + .../openapi/wm/impl/StripeButton.java | 4 ++-- .../impl/ToolWindowHeadlessManagerImpl.java | 10 +++++++++ .../openapi/wm/impl/ToolWindowImpl.java | 21 +++++++++++++++---- .../wm/impl/content/ContentLayout.java | 2 +- .../wm/impl/status/ToolWindowsWidget.java | 3 +-- 8 files changed, 45 insertions(+), 12 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindow.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindow.java index 93870283c6ce..4e12f29beaa0 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindow.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindow.java @@ -123,10 +123,20 @@ public interface ToolWindow extends BusyObject { /** * Sets new window title. - * @exception IllegalStateException if tool window isn't installed. */ void setTitle(String title); + /** + * @return window stripe button text. + */ + @NotNull + String getStripeTitle(); + + /** + * Sets new window stripe button text. + */ + void setStripeTitle(@NotNull String title); + /** * @return whether the window is available or not. */ diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowContentUiType.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowContentUiType.java index 9b09923df6e5..ca7c87dae7e8 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowContentUiType.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowContentUiType.java @@ -21,8 +21,8 @@ public class ToolWindowContentUiType { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.ToolWindowContentUiType"); - public static ToolWindowContentUiType TABBED = new ToolWindowContentUiType("tabs"); - public static ToolWindowContentUiType COMBO = new ToolWindowContentUiType("combo"); + public static final ToolWindowContentUiType TABBED = new ToolWindowContentUiType("tabs"); + public static final ToolWindowContentUiType COMBO = new ToolWindowContentUiType("combo"); private final String myName; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/ex/ToolWindowEx.java b/platform/platform-impl/src/com/intellij/openapi/wm/ex/ToolWindowEx.java index 0e27dcf1146d..c9369d249b13 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/ex/ToolWindowEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/ex/ToolWindowEx.java @@ -29,6 +29,7 @@ public interface ToolWindowEx extends ToolWindow { @NonNls String PROP_AVAILABLE = "available"; @NonNls String PROP_ICON = "icon"; @NonNls String PROP_TITLE = "title"; + @NonNls String PROP_STRIPE_TITLE = "stripe-title"; /** * Removes specified property change listener. diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java index b37e9c4af446..3d89975c5820 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java @@ -325,7 +325,7 @@ public final class StripeButton extends AnchoredButton implements ActionListener * and short cut registered in the key map. */ void updateText() { - String toolWindowId = myDecorator.getToolWindow().getTitle(); + String toolWindowId = myDecorator.getToolWindow().getStripeTitle(); String text = toolWindowId; if (UISettings.getInstance().SHOW_TOOL_WINDOW_NUMBERS) { final int mnemonic = ActivateToolWindowAction.getMnemonicForToolWindow(toolWindowId); @@ -366,7 +366,7 @@ public final class StripeButton extends AnchoredButton implements ActionListener if (ToolWindowEx.PROP_AVAILABLE.equals(name)) { updateState(); } - else if (ToolWindowEx.PROP_TITLE.equals(name)) { + else if (ToolWindowEx.PROP_STRIPE_TITLE.equals(name)) { updateText(); } else if (ToolWindowEx.PROP_ICON.equals(name)) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java index 340ca8032263..d6e1d9994500 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java @@ -163,6 +163,16 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { public void setTitle(String title) { } + @NotNull + @Override + public String getStripeTitle() { + return ""; + } + + @Override + public void setStripeTitle(@NotNull String title) { + } + @Override public boolean isAvailable() { return false; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java index 084b035ede5a..ae1e5336e9fe 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java @@ -61,7 +61,7 @@ public final class ToolWindowImpl implements ToolWindowEx { private boolean myAvailable; private final ContentManager myContentManager; private Icon myIcon; - private String myTitle; + private String myStripeTitle; private static final Content EMPTY_CONTENT = new ContentImpl(new JLabel(), "", false); private final ToolWindowContentUi myContentUI; @@ -344,7 +344,13 @@ public final class ToolWindowImpl implements ToolWindowEx { public final String getTitle() { ApplicationManager.getApplication().assertIsDispatchThread(); - return ObjectUtils.notNull(myTitle, myId); + return getSelectedContent().getDisplayName(); + } + + @NotNull + public final String getStripeTitle() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return ObjectUtils.notNull(myStripeTitle, myId); } public final void setIcon(final Icon icon) { @@ -360,11 +366,18 @@ public final class ToolWindowImpl implements ToolWindowEx { public final void setTitle(String title) { ApplicationManager.getApplication().assertIsDispatchThread(); - final String oldTitle = getTitle(); - myTitle = title; + String oldTitle = getTitle(); + getSelectedContent().setDisplayName(title); myChangeSupport.firePropertyChange(PROP_TITLE, oldTitle, title); } + public final void setStripeTitle(@NotNull String stripeTitle) { + ApplicationManager.getApplication().assertIsDispatchThread(); + String oldTitle = myStripeTitle; + myStripeTitle = stripeTitle; + myChangeSupport.firePropertyChange(PROP_STRIPE_TITLE, oldTitle, stripeTitle); + } + private Content getSelectedContent() { final Content selected = getContentManager().getSelectedContent(); return selected != null ? selected : EMPTY_CONTENT; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java index fb606e577402..e4b07345bf3d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java @@ -71,7 +71,7 @@ abstract class ContentLayout { public abstract boolean shouldDrawDecorations(); protected void updateIdLabel(BaseLabel label) { - label.setText(myUi.myWindow.getTitle() + (shouldDrawDecorations() ? ":" : "")); + label.setText(myUi.myWindow.getStripeTitle() + (shouldDrawDecorations() ? ":" : "")); label.setBorder(new EmptyBorder(0, 2, 0, 8)); if (myUi.myManager.getContentCount() == 1) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java index 8fd1559c61b1..4609acf0fd4b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java @@ -30,7 +30,6 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.*; import com.intellij.openapi.wm.impl.IdeFrameImpl; -import com.intellij.openapi.wm.impl.ToolWindowImpl; import com.intellij.ui.GotItMessage; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.UIBundle; @@ -146,7 +145,7 @@ class ToolWindowsWidget extends JLabel implements CustomStatusBarWidget, StatusB @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { final ToolWindow toolWindow = (ToolWindow)value; - label.setText(toolWindow instanceof ToolWindowImpl ? ((ToolWindowImpl)toolWindow).getId() : toolWindow.getTitle()); + label.setText(toolWindow.getStripeTitle()); label.setIcon(toolWindow.getIcon()); label.setBorder(IdeBorderFactory.createEmptyBorder(4, 10, 4, 10)); label.setForeground(UIUtil.getListForeground(isSelected)); From 9449019eb1f389de599ec3feb7109ff287523955 Mon Sep 17 00:00:00 2001 From: Vassiliy Date: Tue, 25 Mar 2014 22:24:43 +0400 Subject: [PATCH 55/69] IDEA-102508 error status of run configuration is not updated after fix --- .../lang-impl/src/com/intellij/ui/DeferredIconImpl.java | 4 ++-- .../lang-impl/src/com/intellij/ui/IconDeferrerImpl.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java index d23082d8d225..2cb330c71114 100644 --- a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java @@ -218,7 +218,7 @@ public class DeferredIconImpl implements DeferredIcon { private void setDone(@NotNull Icon result) { if (myEvalListener != null) { - myEvalListener.evalDone(myParam, result); + myEvalListener.evalDone(this, myParam, result); } myDone = true; @@ -334,6 +334,6 @@ public class DeferredIconImpl implements DeferredIcon { } public interface IconListener { - void evalDone(T key, @NotNull Icon result); + void evalDone(DeferredIconImpl source, T key, @NotNull Icon result); } } diff --git a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java index 7d6f25e1365c..7f2cf33332eb 100644 --- a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java @@ -82,7 +82,7 @@ public class IconDeferrerImpl extends IconDeferrer { return deferImpl(base, param, f, true); } - private Icon deferImpl(Icon base, T param, @NotNull Function f, boolean autoupdatable) { + private Icon deferImpl(Icon base, T param, @NotNull Function f, final boolean autoupdatable) { if (myEvaluationIsInProgress.get().booleanValue()) { return f.fun(param); } @@ -93,11 +93,11 @@ public class IconDeferrerImpl extends IconDeferrer { final long started = myLastClearTimestamp; result = new DeferredIconImpl(base, param, f, new DeferredIconImpl.IconListener() { @Override - public void evalDone(T key, @NotNull Icon r) { + public void evalDone(DeferredIconImpl source, T key, @NotNull Icon r) { synchronized (LOCK) { // check if our results is not outdated yet if (started == myLastClearTimestamp) { - myIconsCache.put(key, r); + myIconsCache.put(key, autoupdatable ? source: r); } } } From 60651123dd8f94c09ea8911fe3d3e9eefaea8ea2 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Mar 2014 15:07:06 +0100 Subject: [PATCH 56/69] IDEA-122796 Call to 'printStackTrace()' should warn about overridden calls as well --- .../ThrowablePrintStackTraceInspectionBase.java | 4 ++-- .../ThrowablePrintStackTraceInspectionTest.java | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/ThrowablePrintStackTraceInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/ThrowablePrintStackTraceInspectionBase.java index 69c9e5642457..621015a685fe 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/ThrowablePrintStackTraceInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/ThrowablePrintStackTraceInspectionBase.java @@ -16,6 +16,7 @@ package com.siyeh.ig.maturity; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.HardcodedMethodConstants; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; @@ -69,8 +70,7 @@ public class ThrowablePrintStackTraceInspectionBase extends BaseInspection { if (containingClass == null) { return; } - final String name = containingClass.getQualifiedName(); - if (!CommonClassNames.JAVA_LANG_THROWABLE.equals(name)) { + if (!InheritanceUtil.isInheritor(containingClass, false, CommonClassNames.JAVA_LANG_THROWABLE)) { return; } registerMethodCallError(expression, expression); diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/maturity/ThrowablePrintStackTraceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/maturity/ThrowablePrintStackTraceInspectionTest.java index 5928bb4cc53d..5e30afe17cd2 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/maturity/ThrowablePrintStackTraceInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/maturity/ThrowablePrintStackTraceInspectionTest.java @@ -37,6 +37,16 @@ public class ThrowablePrintStackTraceInspectionTest extends LightInspectionTestC "}"); } + public void testPrintStacktraceOverridden() throws Exception { + addEnvironmentClass("public class FException extends Exception {\n" + + " @Override\n" + + " public void printStackTrace() {\n" + + " super.printStackTrace();\n" + + " }\n" + + "}\n"); + doStatementTest("new FException()./*Call to 'printStackTrace()' should probably be replaced with more robust logging*/printStackTrace/**/();"); + } + @Override protected InspectionProfileEntry getInspection() { return new ThrowablePrintStackTraceInspection(); From 0beea24a953581506ebeba3d3759a026ce9ba595 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Mar 2014 18:08:05 +0100 Subject: [PATCH 57/69] NPE during completion for lambda params --- .../completion/JavaMemberNameCompletionContributor.java | 6 ++++-- .../src/com/intellij/psi/util/PropertyUtil.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java index 542e4ad3d027..a484e4b1f4f9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java @@ -109,7 +109,9 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor { String propertyName = null; if (variableKind == VariableKind.PARAMETER) { final PsiMethod method = PsiTreeUtil.getParentOfType(var, PsiMethod.class); - propertyName = PropertyUtil.getPropertyName(method); + if (method != null) { + propertyName = PropertyUtil.getPropertyName(method); + } if (method != null && method.getName().startsWith("with")) { propertyName = StringUtil.decapitalize(method.getName().substring(4)); } @@ -133,7 +135,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor { addLookupItems(set, null, matcher, project, getOverlappedNameVersions(matcher.getPrefix(), suggestedNames, "")); } PsiElement parent = PsiTreeUtil.getParentOfType(var, PsiCodeBlock.class); - if(parent == null) parent = PsiTreeUtil.getParentOfType(var, PsiMethod.class); + if(parent == null) parent = PsiTreeUtil.getParentOfType(var, PsiMethod.class, PsiLambdaExpression.class); addLookupItems(set, suggestedNameInfo, matcher, project, getUnresolvedReferences(parent, false)); if (var instanceof PsiParameter && parent instanceof PsiMethod) { addSuggestionsInspiredByFieldNames(set, matcher, var, project, codeStyleManager); diff --git a/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java index 425b46dfef15..4edae81248b9 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java @@ -103,7 +103,7 @@ public class PropertyUtil { return Comparing.equal(PsiUtil.resolveClassInType(TypeConversionUtil.erasure(returnType)), method.getContainingClass()); } - @Nullable public static String getPropertyName(PsiMethod method) { + @Nullable public static String getPropertyName(@NotNull PsiMethod method) { if (isSimplePropertyGetter(method)) { return getPropertyNameByGetter(method); } From 7df68974f996480d6cb173620d80c00d9d9079c7 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Mar 2014 20:00:25 +0100 Subject: [PATCH 58/69] testng: allow in ui "all in project" for group, pattern, suite configurations (IDEA-122835) --- .../configuration/TestNGConfigurationEditor.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java index 551bf3476c14..5148a61adbdf 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java @@ -230,6 +230,7 @@ public class TestNGConfigurationEditor extends SettingsEditor Date: Tue, 25 Mar 2014 20:13:33 +0100 Subject: [PATCH 59/69] update: ignore errors on automatic updates (IDEA-122848) --- .../updateSettings/impl/UpdateChecker.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index 53d197e1e739..10898f5cf01e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -148,7 +148,7 @@ public final class UpdateChecker { private static void doUpdateAndShowResult(final @Nullable Project project, final boolean enableLink, - final boolean showDialog, + final boolean manualCheck, final @Nullable PluginHostsConfigurable hostsConfigurable, final UpdateSettings updateSettings, final @Nullable ProgressIndicator indicator, @@ -161,17 +161,17 @@ public final class UpdateChecker { settings.setKnownChannelIds(result.getAllChannelsIds()); } else if (result.getState() == UpdateStrategy.State.CONNECTION_ERROR) { - showErrorMessage(showDialog, project, IdeBundle.message("updates.error.connection.failed")); + showErrorMessage(manualCheck, project, IdeBundle.message("updates.error.connection.failed")); return; } boolean platformUpdate = newChannelReady(result.getChannelToPropose()) || result.getUpdatedChannel() != null; - final List updatedPlugins = platformUpdate ? null : updatePlugins(showDialog, project, hostsConfigurable, indicator); + final List updatedPlugins = platformUpdate ? null : updatePlugins(manualCheck, project, hostsConfigurable, indicator); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - showUpdateResult(project, result, updatedPlugins, enableLink, showDialog); + showUpdateResult(project, result, updatedPlugins, enableLink, manualCheck); if (callback != null) { callback.setDone(); } @@ -179,7 +179,7 @@ public final class UpdateChecker { }); } - private static List updatePlugins(boolean showDialog, + private static List updatePlugins(boolean manualCheck, @Nullable Project project, @Nullable PluginHostsConfigurable hostsConfigurable, @Nullable ProgressIndicator indicator) { @@ -250,12 +250,12 @@ public final class UpdateChecker { return null; } catch (Exception e) { - showErrorMessage(showDialog, project, e.getMessage()); + showErrorMessage(manualCheck, project, e.getMessage()); } } if (!failed.isEmpty()) { - showErrorMessage(showDialog, project, IdeBundle.message("updates.error.plugin.description.failed", StringUtil.join(failed, ","))); + showErrorMessage(manualCheck, project, IdeBundle.message("updates.error.plugin.description.failed", StringUtil.join(failed, ","))); } return downloaded.isEmpty() ? null : downloaded; @@ -278,7 +278,6 @@ public final class UpdateChecker { }); } else { - showNotification(project, message, true, null); LOG.warn(message); } } From 1b22104e1575876106318142c6dc5518d202b869 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Mar 2014 20:47:48 +0100 Subject: [PATCH 60/69] use RegExpFileType in find dialog directly (IDEA-122775) --- platform/lang-impl/lang-impl.iml | 1 + .../src/com/intellij/find/impl/FindDialog.java | 12 ++---------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/lang-impl.iml b/platform/lang-impl/lang-impl.iml index 7528850108a3..3138d88014df 100644 --- a/platform/lang-impl/lang-impl.iml +++ b/platform/lang-impl/lang-impl.iml @@ -31,6 +31,7 @@ + diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index 9b5ae4ba3952..b6a6152b678b 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -28,8 +28,6 @@ import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.FileTypeManager; -import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.fileTypes.PlainTextFileType; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.module.Module; @@ -57,6 +55,7 @@ import com.intellij.ui.components.labels.LinkListener; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import com.intellij.util.ui.UIUtil; +import org.intellij.lang.regexp.RegExpFileType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -669,14 +668,7 @@ public class FindDialog extends DialogWrapper { if (editorComponent instanceof EditorTextField) { boolean isRegexp = myCbRegularExpressions.isSelectedWhenSelectable(); - FileType fileType = PlainTextFileType.INSTANCE; - if (isRegexp) { - FileType regexpFileType = FileTypeManager.getInstance().getFileTypeByFileName("a.regexp"); - if (regexpFileType != FileTypes.UNKNOWN) { // RegExp plugin might not be installed - fileType = regexpFileType; - } - } - + FileType fileType = isRegexp ? RegExpFileType.INSTANCE : PlainTextFileType.INSTANCE; String fileName = isRegexp ? "a.regexp" : "a.txt"; final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(fileName, fileType, ((EditorTextField)editorComponent).getText(), -1, true); From 163f0ea6aa92cb095405ac09cd72bc5403908480 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 25 Mar 2014 23:54:56 +0400 Subject: [PATCH 61/69] new master password dialog icon --- platform/icons/src/general/passwordLock.png | Bin 0 -> 3003 bytes platform/icons/src/general/passwordLock@2x.png | Bin 0 -> 7643 bytes .../masterKey/PasswordComponentBase.java | 4 ++-- .../util/src/com/intellij/icons/AllIcons.java | 1 + 4 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 platform/icons/src/general/passwordLock.png create mode 100644 platform/icons/src/general/passwordLock@2x.png diff --git a/platform/icons/src/general/passwordLock.png b/platform/icons/src/general/passwordLock.png new file mode 100644 index 0000000000000000000000000000000000000000..8042c16d8547f7b815730022a03908b5b185d0ba GIT binary patch literal 3003 zcmV;s3q2ZW_EVhF+pIb zQ56SOYE=>XM4}|5q!nN*BE{haB~a1FNYD@yS~Z4BRS{~dfYS#8n7UP!r>3Dzs!GJ9 zR%HWGT0w~tl!sIy>Psm}Rq+>s>-GHI+wYuvXLr_KuK{}v8#>nU{N1^8&v$p2 zVZRha=X8;7<`8 zBjrBdGt3u?1>yTXGY^e83Fh~r$=__#hXKMifVIp8Fl-(y9pMK`9l+u8rqh7UKj>W! zhW}D57Dch82E*d zuamQ5m6wk3@=EQ3U2C%QFp7vV+tw96IY-~u@DaNJ$Yb=3ahx7Bz0bs23+P$ugZgSZ09@C*izG{) zo}>?kKMBSIO*V}^PkEUj3FlCCoFhb1IR6Biuz;>pAJkXV0pK{&Y_U0yOt$onQozXwOpjT*b2i%)qgIH5~x5911J8^(2Z31SUGyLTAEdYOl?G*gdsX zG-J5ceKi#Twkv z>Ab!6nr%aE9eS4fpuU>2Akx)0cn{`slHNwpA}J?^Nww!rJ0t?`6^yTcxVQV`rUIbr z#UrHbyTInt;5DBXK@Ac6axwH+kQorlOs5fKC15hgOc&5@%W&_S-`|n|boLD*co+M@*k*^bILU<$hpNDK z&*x6HHl!+_O58AQE5vqh&b5ss^#FkA8R_kgZy5kO_YAgx`QL%LZd2VcrEkx}-gEif zajF3j)e2D7f-(S{Lr`u&)nb!RBqr)^#?GumKpbmaZt|e zT{i^)jHl8s7Xqu30bR}=3=m0@mdinr*%KfMCsg_{+N?XeeP)_4<2V3(9009#J9*we)VPzuq(r zSh;6#J*0bxm`@q!I$+L7o(9emCtm%WaPltI%BPJWRgefBMidzvvq&`oS`bBXnG!Y) z_3dNZyARDd04w*r(FW;$2&uPwVA}V=yzd#c_tK>=yZ~UxVs3iIYXG5300B&Mgsf73 zK#M1_2tz8c#B_cM_ZA=9{>1q?H37)=r%=oGirVKa^G5Bt#^Xccg`9D6>iXXxiawr= zga{MUr)RHof@S@N(hEU9xlvQNAq`lu`;A3l_8%TC`#|b`-mdqt91C2RGpuLv z@PbGoj-I zgt!m%m6*jcVJgLTn#~!Lqp{GK=0pQl>^|&xp7&4Kdq=+D8@p!^3;@(yjB8GAb_=-* zzQBXDrJX8iDkL93{(u%!qaglQ9LHZezGJOws1HC$`ydeSV0Cv5QJ71G586T-*ywsW zJQx`N;DiW1e1}g9OCA>aCClmqU`q@>KW;;7e!pgINL+QVOq>TrWx=&UPEg8K(uTG) zw+ohfC5sEC7M`sLPqhVqKPiIu-zo<~rPIflx%_<()vYo|fWfms^E;)9FU(kIu9YjV z7l7;b0j?wOr{IJF6PI3|Cbu*|TFB%AjxHxMwJ1FE9!t=5TqZgWKYF+BGsY(f{)RyC z3X&N-je*C)W0DUvd>RDOiyg;)-9f6KDO-mKOcdAhbzSeTga7iHpX-^|^IAYqs#z|t zUS~jVjCZ&>r;OjnBi?NBB8qJWm#Dhx>?~PsB136eAPFvc zwC*!$zmyqP6-+9E;jzty38bHNOj_Td0L2tRropv+kx+}jDf9=&jfel*3LzJEu!N`D zI18k(I8LhGYmTLLh}SRA8wiE(Ofka)4}4;5S4TXQD#$>C060Pelu$!MJ%2$L>_qrcH!+ zMUUYXDyM9%$V}Cqx@1MpW1c$0MWuxJ?mbEmI&{PQuU(g6z81iZMICgc+wk zsc(MAg!g8Ecy}&*z|nf^)h)%mxH?+0F}qGy)q`EQfM4o9+Jr^`)O>(F(Ovb_A4jo)B{%UAASKD;EqZPT)maX0&(F#mk_Zb zQ{+lf&QymzH&Ym$ur45Ug?U^2jM(mD)|B?U7m5P3tL6-0GQ-_NJzYPXlZp^jwjcC; zFyq&{Unu(G&iQwUE0;%2V*-z_@NSJnioVgF+X3-o8MYb z7zEhBpPuc!p@PT_*90-ZAA_;=7-rj40S^tFN@bVMUxq!yi^r6>#I{l_Cpo?HngAFl z!0x)cjn#fCA=&m9F_s_Ql(P8h{UaOT++LN_RD6l4(JNO$qm^(sT_jBt8aoVPycNK; z&Yvf)rC&J9jYB=1zrATIL*ME@I)H(0lGj-M497zelmd2e1O`2qI>NgnQ0Zen}8Z}1Q=pRq7ercE{dY&`oHX9Y@=d&My xD5X7$alJ#UVnfe$HFSLP|Gyr;&A0yvFaQFf1uFrLHy;21002ovPDHLkV1h}Qi{1bL literal 0 HcmV?d00001 diff --git a/platform/icons/src/general/passwordLock@2x.png b/platform/icons/src/general/passwordLock@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ce15932c1df74eb37008a72e47a7a417c9e07e65 GIT binary patch literal 7643 zcmV<19VFt3P)VpYlo%|q~2MetEUtxBb0ToPFx zLLNoL#E2O20m=$ugk1!7ncbba-`Abr>DSl&-FtWD-n(<>-kI;)J=5R)p8fSXea`9A zr_T{uYpS=EyUDr`5z@_dO6T|25%+H|QUyFb- z+JN*X;3~i)_<0@5QvrOOq?7@&EHe-v^Vjh`xOXQ%18_AzvlaoPk9aO#1^6QNPxHsz zaa;0l`@@#ZIV}4qOUFsH-9Ls20p;)E{>!m{|8g2SFDniJ#QZ*r{{&`FW9$kEBy+Eh zdV7P*Mp?%D4R;NLzmK0`C`A|@;$HU-M>y%fngcB1_U@~$`LJX6B4+oDL@7j6a?clC zH~{`BO$z%`DN|}CNMYZdodN-T0aqW3@?*6K7#-xl8wkI?D&q}gTzWY#Vi`{qk$_|O z1{4zk6M!m670T^f;G1yG^(bdhe!3=rB}e|%7Xz6$Fmhw%j*)KJxhICq5dbTCU337= zg>nP{ zALDzwMLZKgBO-wIAzn0MXtN<0BEYpw1V#@KtUFj>v|F7J+yK`qT^vJN+yudJ(YTHb z#+Cq>^#iFFTMb{9$Zs~BHs3JEt34n1djLECfJb}_@Jj%X?_Yp(uLSmgR}1kfMrKeX zgU%4C43XX-Nbe9zzX3nLRujOmSpSEw243Y~804FwT*E-4(X_q45gB+&ng1XV`62Ax z*5$GPglqmBm+k;&KMqar<*Y9#=m2CuSP?*WSg4)upmWv==_6XGU0$82?Es5!@VO8Q z-L{NbzvS_|W&6wp8h$+Qhka(mC;kq_Zve5kX(Qje17E|}ntKG9XYjKcPQ+Mfn0MOu zo6*HKu2anchDHE%xpb^Q^9G&BtXom^J^^|D0W029D_;jIqQ7?*yO*QnNuqbhb_IS% zqAY3#qci*=uH8L$Z8>hr3&#AbfrKZ~3#Xfq_swP#Fp;qS2>EvdF2FYyCBhsLXbRRl z;n;d&K(hN8PTv98?umwnghgIZp6ArcThyAHqgE^D-!nM3_0!kyJXmvp#by7m1%jqS z?+==O+3Ouq7r^h8N~?f;4{YtzS| z%4wA6j2jmiLjs_4N~2Gt=t(6Zs0H1)8Yfa{+CFN}PK+|I51He5hEV*u=4;VcW~zm zoc>=e#BcdI1aBlt9ZclbngAAG30Nb%mhQW+H{o*cH*CJxYc%zi)zl3U6nPKMp zfZ;6y@;u{dU{xxK+R1&QCyfZovP2;fffGnmx0(PJUj$4Bt8B#jl^>>AWpBp!ddmS? zf&C{VfS3cgkpPPZiWI~!LJ%}V-lHg*Neo0_uU%CWz+x+b(Rf`ri|4efiou?Opt0|+}&R1?4=Z?R~Ot$Iq^ z;ay?o?UmK~SqxZ_;E=DPd*bJKW@3p6k1(@+wzo^l-H=mYxF?iwgecoAisLvRIEEsC zLeCEzK)4Zrv*%k+9;@)_Fz&YoAR_AMzo(t7Hwcw{583Hp^DH*_@Ux_yFEFA&Cv|9> zEUXD&@!3FP+xHf}VC{3nQ266IVgH>U>%@t&`{rJ$D$m3jD2rN%fs^Mto&>*Kv@MxP+I_iQZxK1pGEO2u+DudF*s58q>`hfI3l!_Nb<4 z);?D3k4#+Qy69di*9>%$N!?t`Y7Vd{-Cvizt_s1G+qrkE_G@~2jrP62bQd>b07_wH z@rbuV)dVmc`LD~ant(@wj>_nsUf8r2>AR@%jv)Ih@2Ux4IP(99prSedq=)vWXT;B} za+Bm3)f`|*BA^Szy|vSRFDzP6_vdxu0KGoHCV+nN-@WI@9zQ8i&pH5$fNt-Q9dv-6 zpI;NeAWFa>a5UdT13bSbfTPX3CoL9aT%yw9z5 zfLa2Kw*(kR5pV=CP_pai!hT#*FNPqI-pkL_=`gfi1k?nuR4m{S;4Z-34(?wB7H|dN zGl1<5&cnf}ac2P|wJ_v@>;HM)YhM23ziM6((r7ePmSx`%LfnkQyY8Dh&L8D&k zz{dyV;~W}p1K==VhHNOfX90W3hKT!-18@_1s`_9@a9?IPWB)f#LVey3czZ1Z1{~ro z;Gz@n-+1=kpb(@RSTZqd-VV;d%egr2-+VKkQw}yq$Kr*a>~8p7)Qy*!F+kMNq4)v+ zz4lBd#6S75iqP`3;ur0)$LMW-^H>~tr!s?O4fV={(c5OFS7KIhI{qyVIh_e zg~%X8@%dC9v{PTq>~$q@lso7RQREFp{4PFkmI-LC=T~s>4^Uo#Gmj?Xqt*d>M7-TD z!_QBlT%RC5ULca}i)f`!H9l||45Awg@+*cy8BGecyP}DbIJ|edMK}}c1K4>F$}fqq zc3Ia1aAXl+Bk;L~n#3;4*LR8tfmD(AK43%jSWFm!Ra3+jx-fub;YhbxMr}>S>@QgI z@HRqNk0ZBW_Zq-Oiu7g?YzQb|H^l#f$@KBtqOnuE6d#{C*>T?He_2&=^7feuka zSt2_qXca=JasjUs1Q9R~7ox~DylwJHl>`t<=Z(w+k$562>syM)oP}TC#NGwif5a2t zC=fwo#E{RX+B<=`<3bO1TDL)X7AJj(2%t(Ji5^h0|2RJIkwzjEiGg?}vG3)=Ay_zf zab7RT`${O(hgTF?;=sYkOhhN)o_|9HF2JcDmaItE1i;&Q*WHR9FE}FCac!(ULU>$; z;aOEIi1raeVEGH6fXL_*;tqHjFJ;N@dEbVV6>bHQEjiABAqc<3jBm7ra6Fl)WBPSC z^wUuwf{`GAbFbUA1<1J#4RO3hK1IlnqH=|?xk$plw}pWh6=g5kUl=P26yT$e=&&9% ztR}YWL?wE@>+Qxqpj<>zWuC)-Inbz*mIy#ROa!~}u(R;^y;Z$q#Ss9IKY=FR1%#b! zB6GGOnM1FLDE7Y$L=lWX)tCYCsDWY;z}WCvKtwtf;N-bk^B26mtfV&og>b%wrMEES zSsPBELht8NaEt<6UKBR!h%%x;GA|&Ta)3_e*uq-q*P)zC6x5YQ0MPtz#K)hR4C_RR z=qxJ{pH-}K(jifH8S0t+CO)x=>l?sUCKlB12{K&gAcU48-O7UzNmFS|5(b^x)I)(# zqzzC*A|9&-1%Qdi5`|rSYKZDJfE)3qcP`}w;*t`;xjS#Y49I$i39TWch+A0*x|H;K z5y}3N-3yAWJhtcZJ(CR}U#3%m3vFnA{zOIu5V`>(0PU0kt@TH|9g2vJzf7b~>;HQMk!{B4?*`yCK0f;umuYH*3 zu*;lbRTGHMB8`6Vp$Xx65};cJ>BB9EdllxUSWHN-8;COGoKXagD3TPZA&y3s;T~@H zli2+aoOpC)aR4Dc3s|4B{7SB$O7D*iJRvlsb~1kzdi-Q#ag8i2N}7|T!434`JaR~h z>LiVp;L&a{T-t=FTtmw0h6yxbyplePlNYTR0s!lO3y`@Z^z2L~z2CF`kno|+z!S|H zfJ5l1Cgi&uo>%Tf!@N%%YJsh5C)Z0+!!e``2?$;3`JFbS81BFgZ^n@ zqqnXGGJgQ1o)F9W80j_ubcO9xtmxTNH^Azr8cU`@o3=ZYlgNw2a+su`^OnNGMH(-Z z3twwNxiB_L>ql|@%kIARcZM2meCYlF=q>LBK2NZ6--P0|$j*cr?pZ?cv3RY1AcQZq ze+Fr=V?C9*>>W$<&%7IT;JUntmH8pPR`L1aRK*dE+^S4qVO`5Od|Ox1&dZMfowWyb+t|IuB*v3v-<{KZ)or+e}8-zRyD z-L6u@4qM|2*7l_sxxh@mr)L-)h)P--pODh)1ci%cYPdkIf^Oir!%x5sPPymWOVqOB z0KnJzfEOnYoUspI8E`lBEA4u|Z^(Q?mVrA)&AY}`CvOUB%qr?=7{v=qw&GpmBC@wugbadiy7WLLddd(UGx3X!k`VF?t z?fE{`Cg#d9y{!bRmu<1m`xwes_l6x)R7~@_5iaFeJ701<2*k}{voRs)9jD`XW;kwS-+O54CmvHAGd+8 zhm2j^>5TE$0XQwYA!`}AaFvc6I&#>oiuPGHoJgnkx!%*S{-5uCEXocR)xqgy+IoW- z`$E3==hl&Pkdc6M24ykOZ0lxjSy>Q2(Rv2{V0JJtK7`^l>YnX28uI{McSv( z!qJ~Dg^;jqrR@Gom%}LFL{Z77qC>}XIXZOvA_;E49KEMuZ02EsMgN4@m;`cjH`h?I z{?d%A!eURJx*Hh(s{97!lS@}OShtD9GfyPSmuTl!_V|V^eYlSv{(#O9a4p7YOznFYaB)k+$kM$@=}6(HQseAj zJww){>^Cnq3Ym_wip4+;T=VLSA#$?*-jUSNXBx9aFyB}?5kaNP`?_Ud2^4cta(8d? zA+PxyaXigPQKc-ki62$}2AU1eBYE~)NUdJ)Qp(x@rXS^#Q;pidV(Z`~!Nk^2WJQ@z_{+o57$YyLL0tF~^gB?&)-8 z*wz=3ShHy$52K*{D=M8qx&HG-0TQM4NO)t1DfM&XPXJmx2iQc~2VgE2TOM&?EO#KD z8kM}{T7^ZQ#v@?BG@abzRh}oqKvAf{7HEd$r^s}u}kQjgh7(tZhN$PoP2Gj%e{zz0YF&WWf2_Vbl0^7>l zL;VV88h--NZV7Z0N@qdCxy&eQ&T+z6@W2HM5#k69!UeRG{V@lS_?_wgdp~(6&!Suh z;M3MNvTR-skj^HC<4-OJ4)BPV>6EB~^DD+Yg>xT%GQveeYp!yU6 zK8HY900PK;y842oh%=MVLqX;6&$q#z<-h?R?x^`LU~4uSba=L9*WX7AF2e|Z0Wp6% za{$$*14ug))W6}!_x{56e(lOt6U})gi)@Ai8mH{QX6hpC8{e+xf; zm2Ngs_v|Csi36xUI6$0OQu&1*X0e9_e#ffG)l1TLqr(A6e>+XU>|66ov=)KhL@oofD$^(%*X27V@g!+eC5W;shz;Cy@R4MBH)a0e?g zsT1CU^#?&yt0vH>x@_EB8SommHMqFdH46;NYc=%}QOa8a7kq#DPE&_Mg?g3s)TZve z5oYr1A++7zvF8A8<3tN5r(e3ThFPjPX@u5(ZM0$dfXE~Uf4q&&>FA(oFjKVIgH`1fZFv3B3pKB5Qf;&6LY{+`MHYJ@JdD z>|A@$$Sb{-9Y@-NN;w5lwC54(gow6i;ZEMGP6VJ-GK$#zyp1+Y+(L(xQCNECO|l2? zyJJ{*8Cr;#+dpt2H_=~}Xsp%0J(z}mo3Wk=$HfBQ*)#J z8z?H^j+<+YGMCv8t(=pu4E4Orc*qZ+DsE}ePmWnf>w1y<)uE+(Hblxbx4rMY z>xPMsp~ne?{Js(2`d%&M2{s6Gf1F_LhBYQ$z|&7YV`KIT7q_2R76+uOwy?4bApq(~ z1iCF#I6vZ;ts7{XM<{*FB*poO&@PX1+YB2YOOiZ##|?L025tS8fSf+L0B>`%E!y|Q zQ)Va@CyAg=iKIG29%-}hSM2<;OM09i z$DsA}-|Af4-;45RTB{|&gIMZx=NEnQuA4Ai`=fc2I`+wCnH$U=oTbBu4pTmtFN`e$ z$*ZPT(d6n$)9a6FP^yT#V0ihr5MO`njY@ZZXvfMC0i|t#M+Ev6oHeB15kXh##=oiQ zDFdD$m4LTEYquDUX@3fNlXcDE9{r3@%hLm2|>Y?Sz0i11M3lyq*P2QlR z%mqejD>eUzf%LOb?hWDM@`CQU=Hiv3161^Zy(VFT){kpa(WJ;S0_|kK)<5TOh0NdU zm%Di#WJM`~)$Qw7p2xl70<_U%-ZZ*w@UMco_c46qg@A`cE&(%zY)#86ngE=9`~mvO z+1Pz>lvA$vW%0A$bhi0MT`@8H#iUEHja2GblZ}(aV^9Xqfj+Pcjda$ihK21(=_9%q z=-@xAzD|U_IHnkT42ZcyRmmV z*FEm_aq5`Zqev@7E6x<$kpK$Skq7`kV{-xaE<>X}I>N|*6m@*7sjJp|IwHS_S-(p) z?_ADm0`Mzr{Lsh;SWsa#&X>`kr=q+DjlFM#IQ~A==~`E}uXrzHU;pqedFffK-RdSC zc`&bd0x-!Ed=drULtL0OzmNZi&}7$P|Hat2RCvhE2T{=Vz>-Ig# z+J*R=R=gd6SJZMtWX^QTj-8owfugIv{=w6Sn~@d7-8ixuzd6o6!*&1%TOQPqz?k_S z+4YTg;n!Vw-@%H~*D++Am-(IKf8uIJddYGijhG=Q&9)U%M7hAqX8BhXDa`o#>(cW_ z3m`_*F6{4eXy0PAaiUWIrvfB8h`w|6Y`ge1Bh`pwA9-&(*f$OCV+aY383DFx&6NY0{~(M*%a~{*lqv-002ov JPDHLkV1g?6yy*Y{ literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/PasswordComponentBase.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/PasswordComponentBase.java index 1edf5bcd5eca..903811f53e72 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/PasswordComponentBase.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/PasswordComponentBase.java @@ -15,7 +15,7 @@ */ package com.intellij.ide.passwordSafe.impl.providers.masterKey; -import com.intellij.openapi.ui.Messages; +import com.intellij.icons.AllIcons; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -47,7 +47,7 @@ public abstract class PasswordComponentBase { mySafe = safe; myTitle = title; myIconLabel.setText(""); - myIconLabel.setIcon(Messages.getQuestionIcon()); // todo add some lock icon + myIconLabel.setIcon(AllIcons.General.PasswordLock); //myPromptLabel.setUI(new MultiLineLabelUI()); myPromptLabel.setFont(UIUtil.getLabelFont(UIUtil.FontSize.SMALL)); diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java index 3e8631a13fae..8784d348bde1 100644 --- a/platform/util/src/com/intellij/icons/AllIcons.java +++ b/platform/util/src/com/intellij/icons/AllIcons.java @@ -437,6 +437,7 @@ public class AllIcons { public static final Icon OverridenMethod = IconLoader.getIcon("/general/overridenMethod.png"); // 10x14 public static final Icon OverridingMethod = IconLoader.getIcon("/general/overridingMethod.png"); // 10x14 public static final Icon PackagesTab = IconLoader.getIcon("/general/packagesTab.png"); // 16x16 + public static final Icon PasswordLock = IconLoader.getIcon("/general/passwordLock.png"); // 64x64 public static final Icon PathVariables = IconLoader.getIcon("/general/pathVariables.png"); // 32x32 public static final Icon Pin_tab = IconLoader.getIcon("/general/pin_tab.png"); // 16x16 public static final Icon PluginManager = IconLoader.getIcon("/general/pluginManager.png"); // 32x32 From 824b8b0cdc734e1ba5d6332dba962351b91da94e Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Mar 2014 21:14:00 +0100 Subject: [PATCH 62/69] WEB-11399 Live Console: variables defined in the console are not autocompleted (global context) --- .../intellij/execution/console/ConsoleExecuteAction.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java index 9ed8c47266c5..878b2577b01e 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java +++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java @@ -144,7 +144,7 @@ public class ConsoleExecuteAction extends DumbAwareAction { myPreserveMarkup = preserveMarkup; } - public ConsoleHistoryModel getConsoleHistoryModel() { + public final ConsoleHistoryModel getConsoleHistoryModel() { return myCommandHistoryModel; } @@ -152,11 +152,16 @@ public class ConsoleExecuteAction extends DumbAwareAction { return true; } - public void setAddCurrentToHistory(boolean addCurrentToHistory) { + public final void setAddCurrentToHistory(boolean addCurrentToHistory) { myAddToHistory = addCurrentToHistory; } + protected void beforeExecution(@NotNull LanguageConsoleImpl console) { + } + final void runExecuteAction(@NotNull LanguageConsoleImpl console, @Nullable LanguageConsoleView consoleView) { + beforeExecution(console); + String text = console.prepareExecuteAction(myAddToHistory, myPreserveMarkup, true); ((UndoManagerImpl)UndoManager.getInstance(console.getProject())).invalidateActionsFor(DocumentReferenceManager.getInstance().create(console.getCurrentEditor().getDocument())); addToCommandHistoryAndExecute(console, consoleView, text); From 6b2fb64d553399e9f52b01505298cfcafe7356ad Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Tue, 25 Mar 2014 12:50:22 +0400 Subject: [PATCH 63/69] IDEA-122729 Rename refactoring fails on method with spaces (Groovy) --- plugins/groovy/src/META-INF/plugin.xml | 1 + .../inplace/GrMethodInplaceRenameHandler.java | 43 +++++++++++++++++++ .../inplace/GrMethodInplaceRenamer.java | 36 ++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/inplace/GrMethodInplaceRenameHandler.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/inplace/GrMethodInplaceRenamer.java diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 896ea0b847e1..dbf606cb014a 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -308,6 +308,7 @@ implementationClass="org.jetbrains.plugins.groovy.refactoring.rename.inplace.GroovyResolveSnapshotProvider"/> + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/inplace/GrMethodInplaceRenameHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/inplace/GrMethodInplaceRenameHandler.java new file mode 100644 index 000000000000..2bad31412d5a --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/inplace/GrMethodInplaceRenameHandler.java @@ -0,0 +1,43 @@ +/* + * 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 org.jetbrains.plugins.groovy.refactoring.rename.inplace; + +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiNameIdentifierOwner; +import com.intellij.refactoring.rename.inplace.MemberInplaceRenameHandler; +import com.intellij.refactoring.rename.inplace.MemberInplaceRenamer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; + +/** + * Created by Max Medvedev on 26/03/14 + */ +public class GrMethodInplaceRenameHandler extends MemberInplaceRenameHandler { + @Override + protected boolean isAvailable(PsiElement element, Editor editor, PsiFile file) { + if (!editor.getSettings().isVariableInplaceRenameEnabled()) return false; + + return element instanceof GrMethod; + } + + @NotNull + @Override + protected MemberInplaceRenamer createMemberRenamer(@NotNull PsiElement element, PsiNameIdentifierOwner elementToRename, Editor editor) { + return new GrMethodInplaceRenamer(elementToRename, element, editor); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/inplace/GrMethodInplaceRenamer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/inplace/GrMethodInplaceRenamer.java new file mode 100644 index 000000000000..f68ecd1da86a --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/inplace/GrMethodInplaceRenamer.java @@ -0,0 +1,36 @@ +/* + * 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 org.jetbrains.plugins.groovy.refactoring.rename.inplace; + +import com.intellij.lang.Language; +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; +import com.intellij.refactoring.rename.inplace.MemberInplaceRenamer; + +/** + * Created by Max Medvedev on 26/03/14 + */ +public class GrMethodInplaceRenamer extends MemberInplaceRenamer { + public GrMethodInplaceRenamer(PsiNamedElement elementToRename, PsiElement substituted, Editor editor) { + super(elementToRename, substituted, editor); + } + + @Override + protected boolean isIdentifier(String newName, Language language) { + return true; + } +} From 8b26747557182658196b12e93af5629aad63aa20 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 26 Mar 2014 08:11:01 +0100 Subject: [PATCH 64/69] fix overriding final method: com.intellij.execution.process.ConsoleHistoryModel com.intellij.execution.console.ConsoleExecuteAction$ConsoleExecuteActionHandler#getConsoleHistoryModel() (in SBT:1.5.1) --- .../com/intellij/execution/console/ConsoleExecuteAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java index 878b2577b01e..b9e504642e5e 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java +++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java @@ -144,7 +144,7 @@ public class ConsoleExecuteAction extends DumbAwareAction { myPreserveMarkup = preserveMarkup; } - public final ConsoleHistoryModel getConsoleHistoryModel() { + public ConsoleHistoryModel getConsoleHistoryModel() { return myCommandHistoryModel; } From eb997fbc035dea69872e48c3dbd95e8af8247002 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Wed, 26 Mar 2014 12:41:22 +0400 Subject: [PATCH 65/69] multi-caret typing fixes for Java files --- .../editorActions/JavaTypedHandler.java | 18 ++- .../typing/multicaretIndentLBrace_after.java | 8 + .../typing/multicaretIndentLBrace_before.java | 8 + .../typing/multicaretIndentRBrace_after.java | 10 ++ .../typing/multicaretIndentRBrace_before.java | 10 ++ .../typing/multicaretInsertGt_after.java | 10 ++ .../typing/multicaretInsertGt_before.java | 10 ++ .../typing/multicaretInsertQuote_after.java | 6 + .../typing/multicaretInsertQuote_before.java | 6 + .../typing/multicaretInsertRParen_after.java | 6 + .../typing/multicaretInsertRParen_before.java | 6 + .../typing/multicaretSkipGt_after.java | 6 + .../typing/multicaretSkipGt_before.java | 6 + .../typing/multicaretSkipQuote_after.java | 6 + .../typing/multicaretSkipQuote_before.java | 6 + .../typing/multicaretSkipRParen_after.java | 6 + .../typing/multicaretSkipRParen_before.java | 6 + .../typing/multicaretSkipSemicolon_after.java | 6 + .../multicaretSkipSemicolon_before.java | 6 + .../intellij/codeInsight/JavaTypingTest.java | 70 +++++++++ .../editorActions/TypedHandler.java | 148 ++++++++++-------- .../editor/EditorModificationUtil.java | 8 + 22 files changed, 300 insertions(+), 72 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretIndentLBrace_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretIndentLBrace_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretIndentRBrace_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretIndentRBrace_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretInsertGt_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretInsertGt_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretInsertQuote_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretInsertQuote_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretInsertRParen_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretInsertRParen_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretSkipGt_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretSkipGt_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretSkipQuote_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretSkipQuote_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretSkipRParen_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretSkipRParen_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretSkipSemicolon_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/multicaretSkipSemicolon_before.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java index ae7dfb95f2ca..ee371f8e1206 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.JavaClassReferenceCompletionContributor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtil; -import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.highlighter.HighlighterIterator; import com.intellij.openapi.fileTypes.FileType; @@ -132,7 +131,7 @@ public class JavaTypedHandler extends TypedHandlerDelegate { return Result.CONTINUE; } if (PsiTreeUtil.getParentOfType(leaf, PsiCodeBlock.class, false, PsiMember.class) != null) { - EditorModificationUtil.insertStringAtCaret(editor, "{", false, true); + EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, "{"); TypedHandler.indentOpenedBrace(project, editor); return Result.STOP; } @@ -170,8 +169,7 @@ public class JavaTypedHandler extends TypedHandlerDelegate { char charAt = editor.getDocument().getCharsSequence().charAt(offset); if (charAt != ';') return false; - editor.getCaretModel().moveToOffset(offset + 1); - editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + EditorModificationUtil.moveAllCaretsRelatively(editor, 1); return true; } @@ -211,8 +209,7 @@ public class JavaTypedHandler extends TypedHandlerDelegate { } if (balance == 0) { - editor.getCaretModel().moveToOffset(offset + 1); - editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + EditorModificationUtil.moveAllCaretsRelatively(editor, 1); return true; } @@ -251,7 +248,12 @@ public class JavaTypedHandler extends TypedHandlerDelegate { } if (balance == 1) { - editor.getDocument().insertString(offset, ">"); + if (editor.getCaretModel().supportsMultipleCarets()) { + EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, ">", 0); + } + else { + editor.getDocument().insertString(offset, ">"); + } } } diff --git a/java/java-tests/testData/codeInsight/typing/multicaretIndentLBrace_after.java b/java/java-tests/testData/codeInsight/typing/multicaretIndentLBrace_after.java new file mode 100644 index 000000000000..31d1689ea98c --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretIndentLBrace_after.java @@ -0,0 +1,8 @@ +class Foo { + void m() { + if (true) + { + if (true) + { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretIndentLBrace_before.java b/java/java-tests/testData/codeInsight/typing/multicaretIndentLBrace_before.java new file mode 100644 index 000000000000..cc7542de0f46 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretIndentLBrace_before.java @@ -0,0 +1,8 @@ +class Foo { + void m() { + if (true) + + if (true) + + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretIndentRBrace_after.java b/java/java-tests/testData/codeInsight/typing/multicaretIndentRBrace_after.java new file mode 100644 index 000000000000..dd2d47d65563 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretIndentRBrace_after.java @@ -0,0 +1,10 @@ +class Foo { + void m() { + if (true) { + System.out.println(); + } + if (true) { + System.out.println(); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretIndentRBrace_before.java b/java/java-tests/testData/codeInsight/typing/multicaretIndentRBrace_before.java new file mode 100644 index 000000000000..386e2e261916 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretIndentRBrace_before.java @@ -0,0 +1,10 @@ +class Foo { + void m() { + if (true) { + System.out.println(); + + if (true) { + System.out.println(); + + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretInsertGt_after.java b/java/java-tests/testData/codeInsight/typing/multicaretInsertGt_after.java new file mode 100644 index 000000000000..5779f885b4bd --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretInsertGt_after.java @@ -0,0 +1,10 @@ +class Foo { + void m() { + if (true) { + List<> + } + if (true) { + List<> + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretInsertGt_before.java b/java/java-tests/testData/codeInsight/typing/multicaretInsertGt_before.java new file mode 100644 index 000000000000..fa17fc84dca4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretInsertGt_before.java @@ -0,0 +1,10 @@ +class Foo { + void m() { + if (true) { + List + } + if (true) { + List + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretInsertQuote_after.java b/java/java-tests/testData/codeInsight/typing/multicaretInsertQuote_after.java new file mode 100644 index 000000000000..bef6962d2280 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretInsertQuote_after.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.out.println(""); + System.out.println(""); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretInsertQuote_before.java b/java/java-tests/testData/codeInsight/typing/multicaretInsertQuote_before.java new file mode 100644 index 000000000000..c0716b5a99b8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretInsertQuote_before.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.out.println(); + System.out.println(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretInsertRParen_after.java b/java/java-tests/testData/codeInsight/typing/multicaretInsertRParen_after.java new file mode 100644 index 000000000000..ec85a6782591 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretInsertRParen_after.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.exit() + System.exit() + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretInsertRParen_before.java b/java/java-tests/testData/codeInsight/typing/multicaretInsertRParen_before.java new file mode 100644 index 000000000000..594fa9162ca3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretInsertRParen_before.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.exit + System.exit + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretSkipGt_after.java b/java/java-tests/testData/codeInsight/typing/multicaretSkipGt_after.java new file mode 100644 index 000000000000..432129e7f48e --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretSkipGt_after.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + java.util.List l1 = new java.util.ArrayList<>(); + java.util.List l2 = new java.util.ArrayList<>(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretSkipGt_before.java b/java/java-tests/testData/codeInsight/typing/multicaretSkipGt_before.java new file mode 100644 index 000000000000..7fe0a6077934 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretSkipGt_before.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + java.util.List l1 = new java.util.ArrayList<>(); + java.util.List l2 = new java.util.ArrayList<>(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretSkipQuote_after.java b/java/java-tests/testData/codeInsight/typing/multicaretSkipQuote_after.java new file mode 100644 index 000000000000..a2ce5c51e485 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretSkipQuote_after.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.out.println(""); + System.out.println(""); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretSkipQuote_before.java b/java/java-tests/testData/codeInsight/typing/multicaretSkipQuote_before.java new file mode 100644 index 000000000000..bef6962d2280 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretSkipQuote_before.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.out.println(""); + System.out.println(""); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretSkipRParen_after.java b/java/java-tests/testData/codeInsight/typing/multicaretSkipRParen_after.java new file mode 100644 index 000000000000..45324ed65b40 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretSkipRParen_after.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.exit() + System.exit() + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretSkipRParen_before.java b/java/java-tests/testData/codeInsight/typing/multicaretSkipRParen_before.java new file mode 100644 index 000000000000..ec85a6782591 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretSkipRParen_before.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.exit() + System.exit() + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretSkipSemicolon_after.java b/java/java-tests/testData/codeInsight/typing/multicaretSkipSemicolon_after.java new file mode 100644 index 000000000000..0e0ddbaf5385 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretSkipSemicolon_after.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.out.println(); + System.out.println(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/multicaretSkipSemicolon_before.java b/java/java-tests/testData/codeInsight/typing/multicaretSkipSemicolon_before.java new file mode 100644 index 000000000000..cadfb3312bd6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/multicaretSkipSemicolon_before.java @@ -0,0 +1,6 @@ +class Foo { + void m() { + System.out.println(); + System.out.println(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java new file mode 100644 index 000000000000..8c3837fe1722 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight; + +import com.intellij.testFramework.PlatformTestUtil; +import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; + +import java.io.File; + +public class JavaTypingTest extends LightPlatformCodeInsightFixtureTestCase { + public void testMulticaretIndentLBrace() { + doTest('{'); + } + + public void testMulticaretIndentRBrace() { + doTest('}'); + } + + public void testMulticaretSkipSemicolon() { + doTest(';'); + } + + public void testMulticaretSkipGt() { + doTest('>'); + } + + public void testMulticaretInsertGt() { + doTest('<'); + } + + public void testMulticaretSkipRParen() { + doTest(')'); + } + + public void testMulticaretInsertRParen() { + doTest('('); + } + + public void testMulticaretSkipQuote() { + doTest('"'); + } + + public void testMulticaretInsertQuote() { + doTest('"'); + } + + private void doTest(char c) { + myFixture.configureByFile(getTestName(true) + "_before.java"); + myFixture.type(c); + myFixture.checkResultByFile(getTestName(true) + "_after.java"); + } + + @Override + protected String getTestDataPath() { + return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/java/java-tests/testData/codeInsight/typing"; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java index 259fe9766fb1..5bda686334ee 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java @@ -191,7 +191,7 @@ public class TypedHandler extends TypedActionHandlerBase { } } - if (!editor.getSelectionModel().hasBlockSelection() && editor.getCaretModel().getCaretCount() == 1) { + if (!editor.getSelectionModel().hasBlockSelection()) { if (')' == charTyped || ']' == charTyped || '}' == charTyped) { if (FileTypes.PLAIN_TEXT != fileType) { if (handleRParen(editor, fileType, charTyped)) return; @@ -210,7 +210,7 @@ public class TypedHandler extends TypedActionHandlerBase { if (('(' == charTyped || '[' == charTyped || '{' == charTyped) && CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET && - !editor.getSelectionModel().hasBlockSelection() && editor.getCaretModel().getCaretCount() == 1 && fileType != FileTypes.PLAIN_TEXT) { + !editor.getSelectionModel().hasBlockSelection() && fileType != FileTypes.PLAIN_TEXT) { handleAfterLParen(editor, fileType, charTyped); } else if ('}' == charTyped) { @@ -361,7 +361,12 @@ public class TypedHandler extends TypedActionHandlerBase { else { throw new AssertionError("Unknown char "+lparenChar); } - editor.getDocument().insertString(offset, text); + if (editor.getCaretModel().supportsMultipleCarets()) { + EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, text, 0); + } + else { + editor.getDocument().insertString(offset, text); + } } } @@ -417,8 +422,7 @@ public class TypedHandler extends TypedActionHandlerBase { if (!matched) return false; - editor.getCaretModel().moveToOffset(offset + 1); - editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + EditorModificationUtil.moveAllCaretsRelatively(editor, 1); return true; } @@ -436,8 +440,7 @@ public class TypedHandler extends TypedActionHandlerBase { if (offset < length && chars.charAt(offset) == quote){ if (isClosingQuote(editor, quoteHandler, offset)){ - editor.getCaretModel().moveToOffset(offset + 1); - editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + EditorModificationUtil.moveAllCaretsRelatively(editor, 1); return true; } } @@ -456,7 +459,9 @@ public class TypedHandler extends TypedActionHandlerBase { } } - myOriginalHandler.execute(editor, quote, dataContext); + if (myOriginalHandler != null) { + myOriginalHandler.execute(editor, quote, dataContext); + } offset = editor.getCaretModel().getOffset(); if (quoteHandler instanceof MultiCharQuoteHandler) { @@ -464,7 +469,12 @@ public class TypedHandler extends TypedActionHandlerBase { if (closingQuote != null && hasNonClosedLiterals(editor, quoteHandler, offset - 1)) { if (offset == document.getTextLength() || !Character.isUnicodeIdentifierPart(document.getCharsSequence().charAt(offset))) { //any better heuristic or an API? - document.insertString(offset, closingQuote); + if (editor.getCaretModel().supportsMultipleCarets()) { + EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, closingQuote.toString(), 0); + } + else { + document.insertString(offset, closingQuote); + } return true; } } @@ -473,7 +483,12 @@ public class TypedHandler extends TypedActionHandlerBase { if (isOpeningQuote(editor, quoteHandler, offset - 1) && hasNonClosedLiterals(editor, quoteHandler, offset - 1)) { if (offset == document.getTextLength() || !Character.isUnicodeIdentifierPart(document.getCharsSequence().charAt(offset))) { //any better heuristic or an API? - document.insertString(offset, String.valueOf(quote)); + if (editor.getCaretModel().supportsMultipleCarets()) { + EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, String.valueOf(quote), 0); + } + else { + document.insertString(offset, String.valueOf(quote)); + } } } @@ -558,67 +573,72 @@ public class TypedHandler extends TypedActionHandlerBase { } private static void indentBrace(@NotNull final Project project, @NotNull final Editor editor, final char braceChar) { - final int offset = editor.getCaretModel().getOffset() - 1; - final Document document = editor.getDocument(); - CharSequence chars = document.getCharsSequence(); - if (offset < 0 || chars.charAt(offset) != braceChar) return; + editor.getCaretModel().runForEachCaret(new CaretAction() { + @Override + public void perform(Caret caret) { + final int offset = editor.getCaretModel().getOffset() - 1; + final Document document = editor.getDocument(); + CharSequence chars = document.getCharsSequence(); + if (offset < 0 || chars.charAt(offset) != braceChar) return; - int spaceStart = CharArrayUtil.shiftBackward(chars, offset - 1, " \t"); - if (spaceStart < 0 || chars.charAt(spaceStart) == '\n' || chars.charAt(spaceStart) == '\r'){ - PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); - documentManager.commitDocument(document); + int spaceStart = CharArrayUtil.shiftBackward(chars, offset - 1, " \t"); + if (spaceStart < 0 || chars.charAt(spaceStart) == '\n' || chars.charAt(spaceStart) == '\r'){ + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); + documentManager.commitDocument(document); - final PsiFile file = documentManager.getPsiFile(document); - if (file == null || !file.isWritable()) return; - PsiElement element = file.findElementAt(offset); - if (element == null) return; + final PsiFile file = documentManager.getPsiFile(document); + if (file == null || !file.isWritable()) return; + PsiElement element = file.findElementAt(offset); + if (element == null) return; - EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter(); - HighlighterIterator iterator = highlighter.createIterator(offset); + EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter(); + HighlighterIterator iterator = highlighter.createIterator(offset); - final FileType fileType = file.getFileType(); - BraceMatcher braceMatcher = BraceMatchingUtil.getBraceMatcher(fileType, iterator); - boolean rBraceToken = braceMatcher.isRBraceToken(iterator, chars, fileType); - final boolean isBrace = braceMatcher.isLBraceToken(iterator, chars, fileType) || rBraceToken; - int lBraceOffset = -1; + final FileType fileType = file.getFileType(); + BraceMatcher braceMatcher = BraceMatchingUtil.getBraceMatcher(fileType, iterator); + boolean rBraceToken = braceMatcher.isRBraceToken(iterator, chars, fileType); + final boolean isBrace = braceMatcher.isLBraceToken(iterator, chars, fileType) || rBraceToken; + int lBraceOffset = -1; - if (CodeInsightSettings.getInstance().REFORMAT_BLOCK_ON_RBRACE && - rBraceToken && - braceMatcher.isStructuralBrace(iterator, chars, fileType) && offset > 0) { - lBraceOffset = BraceMatchingUtil.findLeftLParen( - highlighter.createIterator(offset - 1), - braceMatcher.getOppositeBraceTokenType(iterator.getTokenType()), - editor.getDocument().getCharsSequence(), - fileType - ); - } - if (element.getNode() != null && isBrace) { - final int finalLBraceOffset = lBraceOffset; - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run(){ - try{ - int newOffset; - if (finalLBraceOffset != -1) { - RangeMarker marker = document.createRangeMarker(offset, offset + 1); - CodeStyleManager.getInstance(project).reformatRange(file, finalLBraceOffset, offset, true); - newOffset = marker.getStartOffset(); - marker.dispose(); - } else { - newOffset = CodeStyleManager.getInstance(project).adjustLineIndent(file, offset); - } - - editor.getCaretModel().moveToOffset(newOffset + 1); - editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); - editor.getSelectionModel().removeSelection(); - } - catch(IncorrectOperationException e){ - LOG.error(e); - } + if (CodeInsightSettings.getInstance().REFORMAT_BLOCK_ON_RBRACE && + rBraceToken && + braceMatcher.isStructuralBrace(iterator, chars, fileType) && offset > 0) { + lBraceOffset = BraceMatchingUtil.findLeftLParen( + highlighter.createIterator(offset - 1), + braceMatcher.getOppositeBraceTokenType(iterator.getTokenType()), + editor.getDocument().getCharsSequence(), + fileType + ); } - }); + if (element.getNode() != null && isBrace) { + final int finalLBraceOffset = lBraceOffset; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run(){ + try{ + int newOffset; + if (finalLBraceOffset != -1) { + RangeMarker marker = document.createRangeMarker(offset, offset + 1); + CodeStyleManager.getInstance(project).reformatRange(file, finalLBraceOffset, offset, true); + newOffset = marker.getStartOffset(); + marker.dispose(); + } else { + newOffset = CodeStyleManager.getInstance(project).adjustLineIndent(file, offset); + } + + editor.getCaretModel().moveToOffset(newOffset + 1); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + } + catch(IncorrectOperationException e){ + LOG.error(e); + } + } + }); + } + } } - } + }); } } diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java index c3db1de87059..d67466ec7916 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java @@ -415,6 +415,14 @@ public class EditorModificationUtil { } } + public static void typeInStringAtCaretHonorMultipleCarets(final Editor editor, @NotNull final String str) { + typeInStringAtCaretHonorMultipleCarets(editor, str, true, str.length()); + } + + public static void typeInStringAtCaretHonorMultipleCarets(final Editor editor, @NotNull final String str, final int caretShift) { + typeInStringAtCaretHonorMultipleCarets(editor, str, true, caretShift); + } + public static void typeInStringAtCaretHonorMultipleCarets(final Editor editor, @NotNull final String str, final boolean toProcessOverwriteMode) { typeInStringAtCaretHonorMultipleCarets(editor, str, toProcessOverwriteMode, str.length()); } From e0e1939256e1ac2db62e23be86ed3eb79cfc8c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Wed, 26 Mar 2014 10:13:47 +0100 Subject: [PATCH 66/69] IDEA-122465 Spring: Alt-F1/SpringBeans... navigation doesn't work properly in mixed contexts StubAnchor equals() missing --- .../intellij/util/xml/impl/DomAnchorImpl.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomAnchorImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomAnchorImpl.java index 01c0bf7ec468..2177ad95e567 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomAnchorImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomAnchorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -377,5 +377,22 @@ public abstract class DomAnchorImpl implements DomAnchor Date: Wed, 26 Mar 2014 10:07:55 +0100 Subject: [PATCH 67/69] EP for upsource added --- .../src/com/intellij/properties/PropertiesCoreEnvironment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java b/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java index 3cd75ed07b6e..185883c1cfcd 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java @@ -17,6 +17,7 @@ public class PropertiesCoreEnvironment { appEnvironment.registerFileType(PropertiesFileType.INSTANCE, "properties"); SyntaxHighlighterFactory.LANGUAGE_FACTORY.addExplicitExtension(PropertiesLanguage.INSTANCE, new PropertiesSyntaxHighlighterFactory()); appEnvironment.addExplicitExtension(LanguageParserDefinitions.INSTANCE, PropertiesLanguage.INSTANCE, new PropertiesParserDefinition()); + SyntaxHighlighterFactory.LANGUAGE_FACTORY.addExplicitExtension(PropertiesLanguage.INSTANCE, new PropertiesSyntaxHighlighterFactory()); } } From dcc87d6d73b6bc79d6061d7fe14c6568e9e314d6 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Tue, 25 Mar 2014 15:45:16 +0400 Subject: [PATCH 68/69] comment added --- .../intellij/javaee/DefaultHtmlDoctypeInitialConfigurator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/xml/impl/src/com/intellij/javaee/DefaultHtmlDoctypeInitialConfigurator.java b/xml/impl/src/com/intellij/javaee/DefaultHtmlDoctypeInitialConfigurator.java index faeb64e30634..a7d50e3d4cfa 100644 --- a/xml/impl/src/com/intellij/javaee/DefaultHtmlDoctypeInitialConfigurator.java +++ b/xml/impl/src/com/intellij/javaee/DefaultHtmlDoctypeInitialConfigurator.java @@ -20,6 +20,7 @@ public class DefaultHtmlDoctypeInitialConfigurator { ExternalResourceManagerEx.getInstanceEx() .setDefaultHtmlDoctype(Html5SchemaProvider.getHtml5SchemaLocation(), projectManager.getDefaultProject()); } + // sometimes VFS fails to pick up updated schema contents and we need to force refresh if (propertiesComponent.getOrInitInt("DefaultHtmlDoctype.Refreshed", 0) < VERSION) { propertiesComponent.setValue("DefaultHtmlDoctype.Refreshed", Integer.toString(VERSION)); final String schemaUrl = VfsUtilCore.pathToUrl(Html5SchemaProvider.getHtml5SchemaLocation()); From a48429d8b5d503d2d0437f1a04f60ace240211ad Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Wed, 26 Mar 2014 13:25:35 +0400 Subject: [PATCH 69/69] (IDEA-122795) problem with merge during update project fixed *execution pull with update or rebase reverted to the separeted calls pull and update or rebase; *separate rebase command implemented; *annotations added; *text indicator added; --- .../org/zmlx/hg4idea/HgVcsMessages.properties | 1 + .../zmlx/hg4idea/command/HgRebaseCommand.java | 21 ++++++-- .../provider/update/HgRegularUpdater.java | 54 +++++++++---------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties b/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties index c1a2765a903a..f0be716bf856 100644 --- a/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties +++ b/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties @@ -110,6 +110,7 @@ hg4idea.progress.updatingTo=Updating to {0}... hg4idea.progress.countingHeads=Checking number of heads... hg4idea.progress.pull.with.rebase=Rebasing patches hg4idea.progress.pull.with.update=Updating repository +hg4idea.progress.rebase=Rebasing repository hg4idea.error.invalidTarget=Invalid integration target hg4idea.progress.checking.ignored=Checking for ignoring files diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java index 6eeafffd5979..ad9c137b5602 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java @@ -14,12 +14,14 @@ package org.zmlx.hg4idea.command; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.repo.HgRepository; import java.util.Arrays; +import java.util.Collections; public class HgRebaseCommand { @@ -31,15 +33,28 @@ public class HgRebaseCommand { this.repo = repo; } - public HgCommandResult continueRebase() { - HgCommandResult result = new HgCommandExecutor(project).executeInCurrentThread(repo.getRoot(), "rebase", Arrays.asList("--continue"), null); + @Nullable + public HgCommandResult startRebase() { + HgCommandResult result = + new HgCommandExecutor(project).executeInCurrentThread(repo.getRoot(), "rebase", Collections.emptyList(), null); repo.update(); project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project, null); return result; } + @Nullable + public HgCommandResult continueRebase() { + HgCommandResult result = + new HgCommandExecutor(project).executeInCurrentThread(repo.getRoot(), "rebase", Arrays.asList("--continue"), null); + repo.update(); + project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project, null); + return result; + } + + @Nullable public HgCommandResult abortRebase() { - HgCommandResult result = new HgCommandExecutor(project).executeInCurrentThread(repo.getRoot(), "rebase", Arrays.asList("--abort"), null); + HgCommandResult result = + new HgCommandExecutor(project).executeInCurrentThread(repo.getRoot(), "rebase", Arrays.asList("--abort"), null); repo.update(); project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project, null); return result; diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java index 98f6cad13ba3..391adaeaa0cb 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java @@ -12,7 +12,6 @@ // limitations under the License. package org.zmlx.hg4idea.provider.update; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; @@ -42,7 +41,6 @@ public class HgRegularUpdater implements HgUpdater { private final Project project; @NotNull private final VirtualFile repoRoot; @NotNull private final UpdateConfiguration updateConfiguration; - private static final Logger LOG = Logger.getInstance(HgRegularUpdater.class); public HgRegularUpdater(Project project, @NotNull VirtualFile repository, @NotNull UpdateConfiguration configuration) { this.project = project; @@ -50,10 +48,6 @@ public class HgRegularUpdater implements HgUpdater { this.updateConfiguration = configuration; } - private boolean shouldRebase() { - return updateConfiguration.shouldRebase(); - } - private boolean shouldMerge() { return updateConfiguration.shouldMerge(); } @@ -87,20 +81,18 @@ public class HgRegularUpdater implements HgUpdater { // throw new VcsException("working dir not at branch tip (use \"Update to...\" to check out branch tip)"); // } - HgRevisionNumber parentBeforeUpdate = new HgWorkingCopyRevisionsCommand(project).firstParent(repoRoot); - HgCommandExitCode pullResult = pull(repoRoot, indicator, shouldRebase()); + HgCommandExitCode pullResult = pull(repoRoot, indicator); if (pullResult == HgCommandExitCode.ERROR) { return false; } - if (pullResult == HgCommandExitCode.SUCCESS) { - HgRevisionNumber parentAfterUpdate = new HgWorkingCopyRevisionsCommand(project).firstParent(repoRoot); - addUpdatedFiles(repoRoot, updatedFiles, parentBeforeUpdate, parentAfterUpdate); - return true; - } - if (shouldMerge()) { + List parentsBeforeUpdate = new HgWorkingCopyRevisionsCommand(project).parents(repoRoot); + if (parentsBeforeUpdate.size() > 1) { + throw new VcsException(HgVcsMessages.message("hg4idea.update.error.uncommittedMerge", repoRoot.getPath())); + } + indicator.setText2(HgVcsMessages.message("hg4idea.progress.countingHeads")); List branchHeadsAfterPull = new HgHeadsCommand(project, repoRoot).execute(); @@ -119,11 +111,15 @@ public class HgRegularUpdater implements HgUpdater { commitOrWarnAboutConflicts(warnings, mergeResult); } } + else { + //in case of multiple heads the update will report the appropriate error + update(repoRoot, indicator, updatedFiles, warnings); + } //any kind of update could have resulted in merges and merge conflicts, so run the resolver resolvePossibleConflicts(updatedFiles); } else { - processRebase(updatedFiles); + processRebase(indicator, updatedFiles); } return true; @@ -207,22 +203,30 @@ public class HgRegularUpdater implements HgUpdater { return new HgHeadMerger(project, mergeCommand).merge(repoRoot); } - private void processRebase(final UpdatedFiles updatedFiles) throws VcsException { + private void processRebase(ProgressIndicator indicator, final UpdatedFiles updatedFiles) throws VcsException { + indicator.setText2(HgVcsMessages.message("hg4idea.progress.rebase")); HgRepository repository = HgUtil.getRepositoryManager(project).getRepositoryForRoot(repoRoot); - HgCommandResult result; - do { + if (repository == null) { + throw new VcsException("Repository not found for root " + repoRoot); + } + HgRebaseCommand rebaseCommand = new HgRebaseCommand(project, repository); + HgCommandResult result = new HgRebaseCommand(project, repository).startRebase(); + if (HgErrorUtil.isAbort(result)) { + new HgCommandResultNotifier(project).notifyError(result, "Hg Error", "Couldn't rebase repository."); + return; + } + //noinspection ConstantConditions + while (result.getExitValue() == 1) { //if result == null isAbort will be true; resolvePossibleConflicts(updatedFiles); - if (repository == null || !HgConflictResolver.findConflicts(project, repoRoot).isEmpty()) { + if (!HgConflictResolver.findConflicts(project, repoRoot).isEmpty()) { return; } - HgRebaseCommand rebaseCommand = new HgRebaseCommand(project, repository); result = rebaseCommand.continueRebase(); if (HgErrorUtil.isAbort(result)) { new HgCommandResultNotifier(project).notifyError(result, "Hg Error", "Couldn't continue rebasing"); return; } } - while (result.getExitValue() == 1); } private void abortOnLocalChanges() throws VcsException { @@ -240,18 +244,12 @@ public class HgRegularUpdater implements HgUpdater { return statusCommand.execute(repoRoot); } - private HgCommandExitCode pull(VirtualFile repo, ProgressIndicator indicator, boolean isRebase) + private HgCommandExitCode pull(VirtualFile repo, ProgressIndicator indicator) throws VcsException { indicator.setText2(HgVcsMessages.message("hg4idea.progress.pull.with.update")); HgPullCommand hgPullCommand = new HgPullCommand(project, repo); final String defaultPath = HgUtil.getRepositoryDefaultPath(project, repo); hgPullCommand.setSource(defaultPath); - if (isRebase) { - hgPullCommand.setRebase(true); - } - else { - hgPullCommand.setUpdate(true); - } return hgPullCommand.execute(); }