From cc65b6f0676060f00845201087fe6e79b4b6f450 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 29 May 2012 18:31:10 +0400 Subject: [PATCH 01/11] private inner is not visible in type param bounds (IDEA-67517) --- .../daemon/impl/analysis/HighlightClassUtil.java | 11 +++++++++-- .../advHighlighting7/InnerInTypeArguments.java | 3 +++ .../daemon/LightAdvHighlightingJdk7Test.java | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/InnerInTypeArguments.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java index a28be95d2166..08e9dc352a3f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java @@ -689,8 +689,15 @@ public class HighlightClassUtil { return null; } final PsiClass aClass = (PsiClass)grand; + final PsiClass containerClass; if (aClass instanceof PsiTypeParameter) { - return null; + final PsiTypeParameterListOwner owner = ((PsiTypeParameter)aClass).getOwner(); + if (!(owner instanceof PsiClass)) { + return null; + } + containerClass = (PsiClass)owner; + } else { + containerClass = aClass; } if (aClass.getExtendsList() != parent && aClass.getImplementsList() != parent) { return null; @@ -713,7 +720,7 @@ public class HighlightClassUtil { if (resolve instanceof PsiClass) { final PsiClass base = (PsiClass)resolve; final PsiClass baseClass = base.getContainingClass(); - if (baseClass != null && base.hasModifierProperty(PsiModifier.PRIVATE) && !PsiTreeUtil.isAncestor(baseClass, aClass, true)) { + if (baseClass != null && base.hasModifierProperty(PsiModifier.PRIVATE) && baseClass == containerClass) { String description = JavaErrorMessages.message("private.symbol", HighlightUtil.formatClass(base), HighlightUtil.formatClass(baseClass)); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/InnerInTypeArguments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/InnerInTypeArguments.java new file mode 100644 index 000000000000..594fee242c64 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/InnerInTypeArguments.java @@ -0,0 +1,3 @@ +class AA.B> { + private class B {} +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java index acb08fd82d81..2bac9bb26aba 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java @@ -87,6 +87,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { public void testDiamondNeg14() throws Exception { doTest(false, false); } public void testDiamondMisc() throws Exception { doTest(false, false); } public void testHighlightInaccessibleFromClassModifierList() throws Exception { doTest(false, false); } + public void testInnerInTypeArguments() throws Exception { doTest(false, false); } public void testDynamicallyAddIgnoredAnnotations() throws Exception { ExtensionPoint point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL); From 2faacc7488bd91e5302a8f1accc4492013881ae2 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 29 May 2012 18:33:50 +0400 Subject: [PATCH 02/11] inner classes shadowing: jls 8.5: private classes are not visible in inheritors; all non-private inner classes from superclass and superinterfaces are available (IDEA-67594) --- .../intellij/psi/impl/PsiClassImplUtil.java | 5 +- .../resolve/ClassResolverProcessor.java | 76 ++++++++++++++----- .../InnerClassesShadowing.java | 70 +++++++++++++++++ .../daemon/LightAdvHighlightingTest.java | 1 + 4 files changed, 133 insertions(+), 19 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java index d3847146e4a1..f649a2ef5d4a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java @@ -628,6 +628,7 @@ public class PsiClassImplUtil { PsiElement place, ResolveState state, boolean isRaw, PsiElementFactory factory) { + boolean resolved = false; for (final PsiClassType superType : aClass.getSuperTypes()) { final PsiClassType.ClassResolveResult superTypeResolveResult = superType.resolveGenerics(); PsiClass superClass = superTypeResolveResult.getElement(); @@ -635,10 +636,10 @@ public class PsiClassImplUtil { PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(superClass, superTypeResolveResult.getSubstitutor(), aClass, state.get(PsiSubstitutor.KEY), place, factory); if (!processDeclarationsInClass(superClass, processor, state.put(PsiSubstitutor.KEY, finalSubstitutor), visited, last, place, isRaw)) { - return false; + resolved = true; } } - return true; + return !resolved; } @Nullable diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java index d1bcc1f39828..8d75323420f6 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java @@ -15,17 +15,15 @@ */ package com.intellij.psi.impl.source.resolve; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.ClassCandidateInfo; -import com.intellij.psi.scope.BaseScopeProcessor; -import com.intellij.psi.scope.ElementClassHint; -import com.intellij.psi.scope.JavaScopeProcessorEvent; -import com.intellij.psi.scope.NameHint; -import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.scope.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.SmartList; import java.util.Iterator; @@ -49,15 +47,21 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi if (((JavaCodeFragment)file).getVisibilityChecker() != null) place = null; } myPlace = place; - if (place instanceof PsiReferenceExpression) { - final PsiReferenceExpression expression = (PsiReferenceExpression)place; - final PsiExpression qualifierExpression = expression.getQualifierExpression(); - if (qualifierExpression != null) { - final PsiType type = qualifierExpression.getType(); + if (place instanceof PsiJavaCodeReferenceElement) { + final PsiJavaCodeReferenceElement expression = (PsiJavaCodeReferenceElement)place; + final PsiElement qualifierExpression = expression.getQualifier(); + if (qualifierExpression instanceof PsiExpression) { + final PsiType type = ((PsiExpression)qualifierExpression).getType(); if (type instanceof PsiClassType) { myAccessClass = ((PsiClassType)type).resolve(); } } + else if (qualifierExpression instanceof PsiJavaCodeReferenceElement) { + final PsiElement resolve = ((PsiJavaCodeReferenceElement)qualifierExpression).resolve(); + if (resolve instanceof PsiClass) { + myAccessClass = (PsiClass)resolve; + } + } } } @@ -132,13 +136,23 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi final PsiClass containingClass1 = aClass.getContainingClass(); final PsiClass containingClass2 = otherClass.getContainingClass(); - if (containingClass1 != null && containingClass2 != null && containingClass2.isInheritor(containingClass1, true) && - !isImported(myCurrentFileContext)) { - // shadowing - return Domination.DOMINATED_BY; + if (myAccessClass != null && !Comparing.equal(containingClass1, containingClass2)) { + if (myAccessClass.equals(containingClass1)) return Domination.DOMINATES; + if (myAccessClass.equals(containingClass2)) return Domination.DOMINATED_BY; } - boolean infoAccessible = info.isAccessible(); + //JLS 8.5: + //A class may inherit two or more type declarations with the same name, either from two interfaces or from its superclass and an interface. + //It is a compile-time error to attempt to refer to any ambiguously inherited class or interface by its simple name. + if (containingClass1 != null && containingClass2 != null && containingClass2.isInheritor(containingClass1, true) && + !isImported(myCurrentFileContext)) { + if (!isAmbiguousInherited(containingClass1)) { + // shadowing + return Domination.DOMINATED_BY; + } + } + + boolean infoAccessible = info.isAccessible() && !otherClass.hasModifierProperty(PsiModifier.PRIVATE); if (infoAccessible && !accessible) { return Domination.DOMINATED_BY; } @@ -169,6 +183,17 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi return Domination.EQUAL; } + private boolean isAmbiguousInherited(PsiClass containingClass1) { + PsiClass psiClass = PsiTreeUtil.getParentOfType(myPlace, PsiClass.class); + while (psiClass != null) { + if (psiClass.isInheritor(containingClass1, false)) { + return true; + } + psiClass = psiClass.getContainingClass(); + } + return false; + } + @Override public boolean execute(PsiElement element, ResolveState state) { if (!(element instanceof PsiClass)) return true; @@ -187,7 +212,7 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi for (int i = myCandidates.size()-1; i>=0; i--) { ClassCandidateInfo info = myCandidates.get(i); - Domination domination = dominates(aClass, accessible, fqName, info); + Domination domination = dominates(aClass, accessible && !aClass.hasModifierProperty(PsiModifier.PRIVATE), fqName, info); if (domination == Domination.DOMINATED_BY) { return true; } @@ -202,7 +227,7 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi myHasInaccessibleCandidate |= !accessible; myCandidates.add(new ClassCandidateInfo(aClass, state.get(PsiSubstitutor.KEY), !accessible, myCurrentFileContext)); myResult = null; - if (!accessible) return true; + if (!accessible || aClass.hasModifierProperty(PsiModifier.PRIVATE)) return true; return myCurrentFileContext instanceof PsiImportStatementBase; } @@ -219,6 +244,23 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi } } + /* if (myPlace instanceof PsiJavaCodeReferenceElement) { + final PsiElement element = + PsiTreeUtil.skipParentsOfType(myPlace, PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiReferenceParameterList.class); + if (element instanceof PsiReferenceList) { + final PsiElement pparent = element.getParent(); + if (pparent instanceof PsiClass) { + final PsiClass parentClass = (PsiClass)pparent; + if (element.equals(parentClass.getExtendsList()) || element.equals(parentClass.getImplementsList())) { + final PsiClass containingClass = aClass.getContainingClass(); + if (containingClass != null && !PsiTreeUtil.isAncestor(containingClass, parentClass, false)) { + final PsiElement qualifier = ((PsiJavaCodeReferenceElement)myPlace).getQualifier(); + if (qualifier instanceof PsiReference && parentClass == ((PsiReference)qualifier).resolve()) return false; + } + } + } + } + }*/ boolean accessible = true; if (aClass instanceof PsiTypeParameter) { accessible = !myStaticContext; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java new file mode 100644 index 000000000000..825d9d62f4cf --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java @@ -0,0 +1,70 @@ +public class Main { + static interface A + { + interface B { } + } + + static class D implements A + { + private interface B { } + } + + + static class C extends D implements A + { + interface E extends B { } + interface E1 extends D.B { } + interface E2 extends A.B { } + } + +} + + + +class Main1 { + static interface A + { + interface B { } + } + + static class D implements A + { + interface B { } + } + + + static class C extends D implements A + { + interface E extends B { } + interface E1 extends D.B { + } + interface E2 extends A.B { } + } + +} + + +interface A +{ + interface B { } + interface B1 { } +} + +class D implements A +{ + private interface B { } + interface B1 { } +} + + +class C extends D implements A +{ + interface E extends B { } + interface E1 extends D.B { } + interface E2 extends A.B { } + + interface F extends B1 { } + interface F1 extends D.B1 { } + interface F2 extends A.B1 { } + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java index 2524776bddac..509b1cd13a31 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java @@ -194,6 +194,7 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase { public void testDefaultPackageClassInStaticImport() throws Exception { doTest(false, false); } public void testUnusedParamsOfPublicMethod() throws Exception { doTest(true, false); } + public void testInnerClassesShadowing() throws Exception { doTest(false, false); } public void testUnusedParamsOfPublicMethodDisabled() throws Exception { myUnusedSymbolLocalInspection.REPORT_PARAMETER_FOR_PUBLIC_METHODS = false; From 85232f8731c81928baebb74cc47812f6413d500a Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Tue, 29 May 2012 18:38:51 +0400 Subject: [PATCH 03/11] Improvements in dumper (compile-server). --- .../dependencyView/IntIntMultiMaplet.java | 17 ++++++++++++++--- .../dependencyView/IntObjectMultiMaplet.java | 19 ++++++++++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/IntIntMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntMultiMaplet.java index 3224d28371ce..92e4b38e0fa6 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/IntIntMultiMaplet.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntMultiMaplet.java @@ -20,6 +20,9 @@ import gnu.trove.TIntObjectProcedure; import gnu.trove.TIntProcedure; import java.io.PrintStream; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; /** * Created by IntelliJ IDEA. @@ -63,15 +66,23 @@ abstract class IntIntMultiMaplet implements Streamable { stream.println(context.getValue(a)); stream.println(" Values:"); + final List list = new LinkedList(); + b.forEach(new TIntProcedure() { @Override public boolean execute(final int value) { - stream.print(" "); - stream.println(context.getValue(value)); - + list.add(context.getValue(value)); return true; } }); + + Collections.sort(list); + + for (final String l : list) { + stream.print(" "); + stream.println(l); + } + stream.println(" End Of Values"); return true; } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectMultiMaplet.java index e8811f160393..1f2ad2b02dfa 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectMultiMaplet.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectMultiMaplet.java @@ -17,8 +17,12 @@ package org.jetbrains.ether.dependencyView; import gnu.trove.TIntObjectProcedure; +import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; /** * Created by IntelliJ IDEA. @@ -62,8 +66,21 @@ abstract class IntObjectMultiMaplet implements Streamable stream.println(context.getValue(a)); stream.println(" Values:"); + final List list = new LinkedList (); + for (final V value : b) { - value.toStream(context, stream); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final PrintStream s = new PrintStream(baos); + + value.toStream(context, s); + + list.add(baos.toString()); + } + + Collections.sort(list); + + for (final String l : list) { + stream.print(l); } stream.println(" End Of Values"); From ad488f00b32f16d16fa2a430f9200d4bb2e424cb Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 29 May 2012 18:49:36 +0400 Subject: [PATCH 04/11] cleanup --- .../source/resolve/ClassResolverProcessor.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java index 8d75323420f6..5ff8a99a631d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java @@ -244,23 +244,6 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi } } - /* if (myPlace instanceof PsiJavaCodeReferenceElement) { - final PsiElement element = - PsiTreeUtil.skipParentsOfType(myPlace, PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiReferenceParameterList.class); - if (element instanceof PsiReferenceList) { - final PsiElement pparent = element.getParent(); - if (pparent instanceof PsiClass) { - final PsiClass parentClass = (PsiClass)pparent; - if (element.equals(parentClass.getExtendsList()) || element.equals(parentClass.getImplementsList())) { - final PsiClass containingClass = aClass.getContainingClass(); - if (containingClass != null && !PsiTreeUtil.isAncestor(containingClass, parentClass, false)) { - final PsiElement qualifier = ((PsiJavaCodeReferenceElement)myPlace).getQualifier(); - if (qualifier instanceof PsiReference && parentClass == ((PsiReference)qualifier).resolve()) return false; - } - } - } - } - }*/ boolean accessible = true; if (aClass instanceof PsiTypeParameter) { accessible = !myStaticContext; From 21965d5ee708d2ed7d2c8d1b98987d53fb19d737 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 29 May 2012 19:05:50 +0400 Subject: [PATCH 05/11] IDEA-79442 (re-fix) --- .../src/com/intellij/idea/IdeaApplication.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java index ba971f8f8fe9..679636ad55d1 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java @@ -138,6 +138,16 @@ public class IdeaApplication { setWM(xwm, "METACITY_WM"); // Mutter support absent - mimic Metacity } } + else if ("Muffin".equals(wmName)) { + // Muffin is completely unsupported at the moment - so mimic Mutter if possible, Metacity otherwise + try { + xwmClass.getDeclaredField("MUTTER_WM"); + setWM(xwm, "MUTTER_WM"); + } + catch (NoSuchFieldException e) { + setWM(xwm, "METACITY_WM"); + } + } else if ("awesome".equals(wmName)) { try { xwmClass.getDeclaredField("OTHER_NONREPARENTING_WM"); From 646653f47ebc98e2796d4306558cfcae5431f2ed Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 29 May 2012 19:18:19 +0400 Subject: [PATCH 06/11] Optimization of LibraryRuntimeClasspathScope --- .../scopes/LibraryRuntimeClasspathScope.java | 111 ++++++++++++------ 1 file changed, 73 insertions(+), 38 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java index d02c7bf96610..89a0585a2cad 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java @@ -21,17 +21,15 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.LinkedHashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -39,7 +37,7 @@ import java.util.Set; */ public class LibraryRuntimeClasspathScope extends GlobalSearchScope { private final ProjectFileIndex myIndex; - private final LinkedHashSet myEntries = new LinkedHashSet(); + private final LinkedHashMap myEntries = new LinkedHashMap(); public LibraryRuntimeClasspathScope(final Project project, final List modules) { super(project); @@ -47,45 +45,68 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope { final Set processedSdk = new THashSet(); final Set processedLibraries = new THashSet(); - ProjectRootManager.getInstance(project).orderEntries(modules).recursively().process(new RootPolicy>() { - public LinkedHashSet visitLibraryOrderEntry(final LibraryOrderEntry libraryOrderEntry, - final LinkedHashSet value) { - final Library library = libraryOrderEntry.getLibrary(); - if (library != null && processedLibraries.add(library)) { - ContainerUtil.addAll(value, libraryOrderEntry.getRootFiles(OrderRootType.CLASSES)); - } - return value; + ProjectRootManager.getInstance(project).orderEntries(modules).recursively() + .process(new RootPolicy>() { + @Override + public LinkedHashMap visitLibraryOrderEntry(final LibraryOrderEntry libraryOrderEntry, + final LinkedHashMap value) { + final Library library = libraryOrderEntry.getLibrary(); + if (library != null && processedLibraries.add(library)) { + addAll(value, libraryOrderEntry.getRootFiles(OrderRootType.CLASSES)); } + return value; + } - public LinkedHashSet visitModuleSourceOrderEntry(final ModuleSourceOrderEntry moduleSourceOrderEntry, - final LinkedHashSet value) { - ContainerUtil.addAll(value, moduleSourceOrderEntry.getFiles(OrderRootType.SOURCES)); - return value; - } + @Override + public LinkedHashMap visitModuleSourceOrderEntry(final ModuleSourceOrderEntry moduleSourceOrderEntry, + final LinkedHashMap value) { + addAll(value, moduleSourceOrderEntry.getFiles(OrderRootType.SOURCES)); + return value; + } - @Override - public LinkedHashSet visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, LinkedHashSet value) { - final Module depModule = moduleOrderEntry.getModule(); - if (depModule != null) { - ContainerUtil.addAll(value, ModuleRootManager.getInstance(depModule).getSourceRoots()); - } - return value; + @Override + public LinkedHashMap visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, + LinkedHashMap value) { + final Module depModule = moduleOrderEntry.getModule(); + if (depModule != null) { + addAll(value, ModuleRootManager.getInstance(depModule).getSourceRoots()); } + return value; + } - public LinkedHashSet visitJdkOrderEntry(final JdkOrderEntry jdkOrderEntry, final LinkedHashSet value) { - final Sdk jdk = jdkOrderEntry.getJdk(); - if (jdk != null && processedSdk.add(jdk)) { - ContainerUtil.addAll(value, jdkOrderEntry.getRootFiles(OrderRootType.CLASSES)); - } - return value; + @Override + public LinkedHashMap visitJdkOrderEntry(JdkOrderEntry jdkOrderEntry, + LinkedHashMap value) { + final Sdk jdk = jdkOrderEntry.getJdk(); + if (jdk != null && processedSdk.add(jdk)) { + addAll(value, jdkOrderEntry.getRootFiles(OrderRootType.CLASSES)); } - }, myEntries); + return value; + } + }, myEntries); + + fillIndexes(); } public LibraryRuntimeClasspathScope(Project project, LibraryOrderEntry entry) { super(project); myIndex = ProjectRootManager.getInstance(project).getFileIndex(); - Collections.addAll(myEntries, entry.getRootFiles(OrderRootType.CLASSES)); + addAll(myEntries, entry.getRootFiles(OrderRootType.CLASSES)); + + fillIndexes(); + } + + private void fillIndexes() { + int i = 0; + for (Map.Entry entry : myEntries.entrySet()) { + entry.setValue(i++); + } + } + + private static void addAll(Map map, VirtualFile[] files) { + for (VirtualFile file : files) { + map.put(file, null); + } } public int hashCode() { @@ -101,7 +122,7 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope { } public boolean contains(VirtualFile file) { - return myEntries.contains(getFileRoot(file)); + return myEntries.containsKey(getFileRoot(file)); } @Nullable @@ -121,11 +142,25 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope { public int compare(VirtualFile file1, VirtualFile file2) { final VirtualFile r1 = getFileRoot(file1); final VirtualFile r2 = getFileRoot(file2); - for (VirtualFile root : myEntries) { - if (r1 == root) return 1; - if (r2 == root) return -1; + + //for (VirtualFile root : myEntries) { + // if (r1 == root) return 1; + // if (r2 == root) return -1; + //} + //return 0; + + Integer index1 = myEntries.get(r1); + Integer index2 = myEntries.get(r2); + + if (index1 == null) { + return index2 == null ? 0 : -1; } - return 0; + + if (index2 == null) { + return 1; + } + + return index2.compareTo(index1); } public boolean isSearchInModuleContent(@NotNull Module aModule) { From 12c83d4ddd7990a44bb18c76e8a407048c20b5a1 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 29 May 2012 17:05:55 +0200 Subject: [PATCH 07/11] IDEA-86773 Speed search in navigation bar --- .../ide/navigationToolbar/NavBarListener.java | 52 ++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java index 634501e5e74b..bc8bb588ff35 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,13 +20,16 @@ import com.intellij.ide.actions.CopyAction; import com.intellij.ide.actions.CutAction; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.AnActionListener; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootListener; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.vcs.FileStatusListener; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.problems.WolfTheProblemSolver; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiTreeChangeEvent; @@ -36,10 +39,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; +import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; @@ -49,7 +49,7 @@ import java.util.List; */ public class NavBarListener extends WolfTheProblemSolver.ProblemListener implements ActionListener, FocusListener, FileStatusListener, AnActionListener, - PsiTreeChangeListener, ModuleRootListener, NavBarModelListener, PropertyChangeListener { + PsiTreeChangeListener, ModuleRootListener, NavBarModelListener, PropertyChangeListener, KeyListener { private static final String LISTENER = "NavBarListener"; private static final String BUS = "NavBarMessageBus"; private final NavBarPanel myPanel; @@ -71,6 +71,7 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener connection.subscribe(ProjectTopics.PROJECT_ROOTS, listener); connection.subscribe(NavBarModelListener.NAV_BAR, listener); panel.putClientProperty(BUS, connection); + panel.addKeyListener(listener); } static void unsubscribeFrom(NavBarPanel panel) { @@ -256,7 +257,46 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener || action instanceof CutAction; } + @Override + public void keyPressed(final KeyEvent e) { + if (!(e.isAltDown() || e.isMetaDown() || e.isControlDown() || myPanel.isNodePopupActive())) { + if (!Character.isLetter(e.getKeyChar())) { + return; + } + + final IdeFocusManager focusManager = IdeFocusManager.getInstance(myPanel.getProject()); + final ActionCallback firstCharTyped = new ActionCallback(); + focusManager.typeAheadUntil(firstCharTyped); + myPanel.moveDown(); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + try { + final Robot robot = new Robot(); + final boolean shiftOn = e.isShiftDown(); + final int code = e.getKeyCode(); + if (shiftOn) { + robot.keyPress(KeyEvent.VK_SHIFT); + } + robot.keyPress(code); + robot.keyRelease(code); + + //don't release Shift + firstCharTyped.setDone(); + } + catch (AWTException ignored) { + } + } + }); + } + } + //---- Ignored + @Override + public void keyTyped(KeyEvent e) {} + + @Override + public void keyReleased(KeyEvent e) {} + @Override public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {} From f312698ff49316a0bed38029520265f8c08f013b Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 May 2012 14:08:11 +0200 Subject: [PATCH 08/11] resize lookup if new items are added slowly --- .../src/com/intellij/codeInsight/lookup/impl/LookupImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index b5701a575345..f005cf441d56 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -460,7 +460,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable updateListHeight(listModel); myList.setSelectedIndex(toSelect); - return Arrays.equals(oldModel, items.toArray()); + return !Arrays.equals(oldModel, items.toArray()); } } @@ -1260,7 +1260,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable } Rectangle rectangle = calculatePosition(); myMaximumHeight = rectangle.height; - + if (myResizePending || itemsChanged) { myResizePending = false; pack(); From a0c88987253f24f99987a62fb15cdffc093e5395 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 May 2012 17:32:24 +0200 Subject: [PATCH 09/11] revert including library sources into project scope --- .../core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java b/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java index 684136c1b0e8..1b45424b150e 100644 --- a/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java +++ b/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java @@ -35,6 +35,8 @@ public class ProjectScopeImpl extends GlobalSearchScope { public boolean contains(VirtualFile file) { if (file instanceof VirtualFileWindow) return true; + if (myFileIndex.isInLibraryClasses(file) && !myFileIndex.isInSourceContent(file)) return false; + return myFileIndex.isInContent(file); } From 10d695a002694678ffb0953cb525d85251f4dded Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 May 2012 18:01:37 +0200 Subject: [PATCH 10/11] IDEA-85760 completion menu shouldn't offer null where it makes no sense --- .../intellij/codeInsight/completion/JavaCompletionData.java | 3 ++- .../testData/codeInsight/completion/normal/IncNull.java | 5 +++++ .../codeInsight/completion/NormalCompletionTest.groovy | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/IncNull.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java index bb12266e5564..40ee3e7c8b89 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java @@ -148,7 +148,8 @@ public class JavaCompletionData extends JavaAwareCompletionData{ not( or(psiElement(PsiTypeCastExpression.class), psiElement(PsiSwitchLabelStatement.class), - psiElement(PsiExpressionStatement.class) + psiElement(PsiExpressionStatement.class), + psiElement(PsiPrefixExpression.class) ) ) )), diff --git a/java/java-tests/testData/codeInsight/completion/normal/IncNull.java b/java/java-tests/testData/codeInsight/completion/normal/IncNull.java new file mode 100644 index 000000000000..64ee7547491e --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/IncNull.java @@ -0,0 +1,5 @@ +class Foo { + { + ++nu + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index bde8a4883d74..a36ed6e1c861 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -539,6 +539,7 @@ public class ListUtils { } public void testNoThisInComment() throws Throwable { doAntiTest() } + public void testIncNull() throws Throwable { doAntiTest() } public void testLastExpressionInFor() throws Throwable { doTest(); } From 644f381a9e18a974a84c6b92b056e1ba0d1270ef Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 May 2012 18:10:49 +0200 Subject: [PATCH 11/11] a failing test for zombie groovy stubs being recompiled --- .../groovy/compiler/GroovyCompilerTest.groovy | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy index f7d020fb394b..85a3fdd2dd67 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy @@ -640,6 +640,22 @@ public class Main { CompileServerManager.instance.shutdownServer() } + public void "_test make stub-level error and correct it"() { + def foo = myFixture.addFileToProject('Foo.groovy', 'class Foo { }') + myFixture.addFileToProject('Bar.java', 'class Bar extends Foo {}') + + assertEmpty make() + + setFileText(foo, 'class Foo implements Runnabl {}') + + shouldFail { make() } + + setFileText(foo, 'class Foo {}') + + assertEmpty make() + } + + //todo jeka: when recompiling module, delete all class files including those with excluded source public void "_test reporting module compile errors caused by missing files excluded from compilation"() { def foo = myFixture.addFileToProject('Foo.groovy', 'class Foo {}') myFixture.addFileToProject('Bar.groovy', 'class Bar extends Foo {}')