diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index 08c40bd21be1..17e03380cc8f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -56,7 +56,7 @@ class ConstructorInsertHandler implements InsertHandler { + private final PsiElement myPosition; + private final Set myAddedClasses = new HashSet(); + private final CompletionResultSet myResult; + + public InheritorsHolder(PsiElement position, CompletionResultSet result) { + myPosition = position; + myResult = result; + } + + @Override + public void consume(LookupElement lookupElement) { + final Object object = lookupElement.getObject(); + if (object instanceof PsiClass) { + final PsiClass psiClass = (PsiClass)object; + if (JavaCompletionUtil.hasAccessibleInnerClass(psiClass, myPosition)) return; + + ContainerUtil.addIfNotNull(myAddedClasses, psiClass.getQualifiedName()); + } + myResult.addElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElement)); + } + + public boolean alreadyProcessed(@NotNull LookupElement element) { + final Object object = element.getObject(); + if (object instanceof PsiClass) { + if (alreadyProcessed((PsiClass)object)) return true; + } + return false; + } + + public boolean alreadyProcessed(@NotNull PsiClass object) { + final String qualifiedName = object.getQualifiedName(); + if (qualifiedName == null || myAddedClasses.contains(qualifiedName)) { + return true; + } + return false; + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 9c70c205ebb5..5ff788e71fbe 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -48,8 +48,6 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.util.Consumer; import com.intellij.util.PairConsumer; import com.intellij.util.ProcessingContext; -import com.intellij.util.containers.ContainerUtil; -import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -185,25 +183,12 @@ public class JavaCompletionContributor extends CompletionContributor { return; } - final Set addedClasses = new THashSet(); + final InheritorsHolder inheritors = new InheritorsHolder(position, result); if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) { - final JavaInheritorsGetter getter = new JavaInheritorsGetter(ConstructorInsertHandler.BASIC_INSTANCE); - getter.generateVariants(parameters, result.getPrefixMatcher(), new Consumer() { - @Override - public void consume(LookupElement lookupElement) { - final Object object = lookupElement.getObject(); - if (object instanceof PsiClass) { - final PsiClass psiClass = (PsiClass)object; - if (JavaCompletionUtil.hasAccessibleInnerClass(psiClass, position)) return; - - ContainerUtil.addIfNotNull(addedClasses, psiClass.getQualifiedName()); - } - result.addElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElement)); - } - }); + new JavaInheritorsGetter(ConstructorInsertHandler.BASIC_INSTANCE).generateVariants(parameters, result.getPrefixMatcher(), inheritors); } - addReferenceVariants(parameters, result, addedClasses); + addReferenceVariants(parameters, result, inheritors); addKeywords(parameters, result); @@ -213,7 +198,7 @@ public class JavaCompletionContributor extends CompletionContributor { new Consumer() { @Override public void consume(LookupElement lookupElement) { - if (!isAlreadyAdded(lookupElement, addedClasses)) { + if (!inheritors.alreadyProcessed(lookupElement)) { result.addElement(lookupElement); } } @@ -222,7 +207,7 @@ public class JavaCompletionContributor extends CompletionContributor { result.stopHere(); } - private static void addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, final Set addedClasses) { + private static void addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, final InheritorsHolder inheritors) { final PsiElement position = parameters.getPosition(); final boolean checkAccess = parameters.getInvocationCount() <= 1; LegacyCompletionContributor.processReferences(parameters, result, new PairConsumer() { @@ -237,7 +222,7 @@ public class JavaCompletionContributor extends CompletionContributor { new ElementExtractorFilter(filter), checkAccess, result.getPrefixMatcher(), parameters)) { - if (isAlreadyAdded(element, addedClasses)) { + if (inheritors.alreadyProcessed(element)) { continue; } @@ -267,14 +252,12 @@ public class JavaCompletionContributor extends CompletionContributor { if (completion == null) { LOG.error("Position=" + position + "\n;Reference=" + reference + "\n;variants=" + Arrays.toString(variants)); } - if (completion instanceof LookupElement && !isAlreadyAdded((LookupElement)completion, addedClasses)) { + if (completion instanceof LookupElement && !inheritors.alreadyProcessed((LookupElement)completion)) { result.addElement((LookupElement)completion); } else if (completion instanceof PsiClass) { - final PsiClass psiClass = (PsiClass)completion; - final String qname = psiClass.getQualifiedName(); - if (qname == null || !addedClasses.contains(qname)) { - result.addElement(JavaClassNameCompletionContributor.createClassLookupItem(psiClass, true)); + if (!inheritors.alreadyProcessed((PsiClass)completion)) { + result.addElement(JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true)); } } else { @@ -285,17 +268,6 @@ public class JavaCompletionContributor extends CompletionContributor { }); } - private static boolean isAlreadyAdded(LookupElement element, Set addedClasses) { - final Object object = element.getObject(); - if (object instanceof PsiClass) { - final String qualifiedName = ((PsiClass)object).getQualifiedName(); - if (qualifiedName != null && addedClasses.contains(qualifiedName)) { - return true; - } - } - return false; - } - private static void addKeywords(CompletionParameters parameters, CompletionResultSet result) { PsiElement position = parameters.getPosition(); final Set lookupSet = new LinkedHashSet(); @@ -595,5 +567,4 @@ public class JavaCompletionContributor extends CompletionContributor { } return null; } - } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionFeatures.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionFeatures.java index 4eb7426ae16b..144bc8ca81a0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionFeatures.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionFeatures.java @@ -26,4 +26,6 @@ public interface JavaCompletionFeatures { @NonNls String SECOND_SMART_COMPLETION_ASLIST = "editing.completion.second.smarttype.aslist"; @NonNls String SECOND_SMART_COMPLETION_ARRAY_MEMBER = "editing.completion.second.smarttype.array.member"; @NonNls String IMPORT_STATIC = "editing.completion.import.static"; + @NonNls String AFTER_NEW = "editing.completion.smarttype.afternew"; + @NonNls String AFTER_NEW_ANONYMOUS = "editing.completion.smarttype.afternew"; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 1e975d5c9a4b..f2458c7f82c8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -108,6 +108,10 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { } public void invokeCompletion(final Project project, final Editor editor, final PsiFile psiFile, int time) { + if (CompletionAutoPopupHandler.ourTestingAutopopup) { + System.out.println("CodeCompletionHandlerBase.doComplete"); + } + if (!ApplicationManager.getApplication().isUnitTestMode()) { assert !ApplicationManager.getApplication().isWriteAccessAllowed() : "Completion should not be invoked inside write action"; } @@ -252,6 +256,9 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { } private void doComplete(final int invocationCount, CompletionInitializationContext initContext) { + if (CompletionAutoPopupHandler.ourTestingAutopopup) { + System.out.println("CodeCompletionHandlerBase.doComplete"); + } final Editor editor = initContext.getEditor(); final CompletionParameters parameters = createCompletionParameters(invocationCount, initContext); diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageAction.java index a66f6de4a6c1..6316b85c1b96 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageAction.java @@ -37,6 +37,9 @@ public class CreateDirectoryOrPackageAction extends AnAction implements DumbAwar IdeView view = e.getData(LangDataKeys.IDE_VIEW); Project project = e.getData(PlatformDataKeys.PROJECT); + if (view == null) { + return; + } PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view); if (directory == null) return; @@ -51,7 +54,7 @@ public class CreateDirectoryOrPackageAction extends AnAction implements DumbAwar Messages.getQuestionIcon(), "", validator); final PsiElement result = validator.getCreatedElement(); - if (result != null && view != null) { + if (result != null) { view.selectElement(result); } } diff --git a/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooserUtil.java b/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooserUtil.java index cf8d9c23e681..ada4ce149e56 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooserUtil.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooserUtil.java @@ -24,6 +24,7 @@ import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.psi.PsiDirectory; import com.intellij.refactoring.RefactoringBundle; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -34,7 +35,7 @@ public class DirectoryChooserUtil { } @Nullable - public static PsiDirectory getOrChooseDirectory(IdeView view) { + public static PsiDirectory getOrChooseDirectory(@NotNull IdeView view) { PsiDirectory[] dirs = view.getDirectories(); if (dirs.length == 0) return null; if (dirs.length == 1) { diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java index 8ee589527c61..7d597ac05fe1 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java @@ -90,6 +90,7 @@ public class ModuleManagerImpl extends ModuleManager implements ProjectComponent @NonNls private static final String ATTRIBUTE_GROUP = "group"; private long myModificationCount; private final MessageBusConnection myConnection; + private final ProgressManager myProgressManager; private final MessageBus myMessageBus; public static ModuleManagerImpl getInstanceImpl(Project project) { @@ -101,8 +102,9 @@ public class ModuleManagerImpl extends ModuleManager implements ProjectComponent myCachedSortedModules = null; } - public ModuleManagerImpl(Project project, MessageBus bus) { + public ModuleManagerImpl(Project project, ProgressManager progressManager, MessageBus bus) { myProject = project; + myProgressManager = progressManager; myMessageBus = bus; myConnection = bus.connect(project); @@ -568,7 +570,7 @@ public class ModuleManagerImpl extends ModuleManager implements ProjectComponent } }; - ProgressManager.getInstance().runProcessWithProgressSynchronously(runnableWithProgress, "Loading modules", false, myProject); + myProgressManager.runProcessWithProgressSynchronously(runnableWithProgress, "Loading modules", false, myProject); myModuleModel.projectOpened(); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java index 3c399cc39ac9..3e6b1d5ede86 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java @@ -39,12 +39,14 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.ProjectScope; import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; @@ -109,8 +111,13 @@ public class VariableInplaceRenamer { if (InjectedLanguageUtil.isInInjectedLanguagePrefixSuffix(myElementToRename)) { return false; } - - final Collection refs = ReferencesSearch.search(myElementToRename).findAll(); + + VirtualFile vFile = myElementToRename.getContainingFile().getVirtualFile(); + SearchScope referencesSearchScope = vFile == null || ProjectRootManager.getInstance(myProject).getFileIndex().isInContent(vFile) + ? ProjectScope.getProjectScope(myElementToRename.getProject()) + : new LocalSearchScope(myElementToRename.getContainingFile()); + + final Collection refs = ReferencesSearch.search(myElementToRename, referencesSearchScope, false).findAll(); addReferenceAtCaret(refs); diff --git a/platform/testRunner/src/com/intellij/execution/testframework/export/TestResultsXmlFormatter.java b/platform/testRunner/src/com/intellij/execution/testframework/export/TestResultsXmlFormatter.java index c8418e0f942a..913b76122837 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/export/TestResultsXmlFormatter.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/export/TestResultsXmlFormatter.java @@ -27,8 +27,10 @@ import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; +import java.util.TreeMap; public class TestResultsXmlFormatter { @@ -37,16 +39,16 @@ public class TestResultsXmlFormatter { private static final String ELEM_SUITE = "suite"; private static final String ATTR_NAME = "name"; private static final String ATTR_DURATION = "duration"; - private static final String ATTR_TOTAL = "total"; - private static final String ATTR_PASSED = "passed"; - private static final String ATTR_FAILED = "failed"; + private static final String ELEM_COUNT = "count"; + private static final String ATTR_VALUE = "value"; + private static final String ELEM_OUTPUT = "output"; + private static final String ATTR_OUTPUT_TYPE = "type"; private static final String ATTR_STATUS = "status"; + private static final String TOTAL_STATUS = "total"; private final RuntimeConfiguration myRuntimeConfiguration; private final ContentHandler myResultHandler; private final AbstractTestProxy myTestRoot; - private static final String ELEM_OUTPUT = "output"; - private static final String ATTR_OUTPUT_TYPE = "type"; public static void execute(AbstractTestProxy root, RuntimeConfiguration runtimeConfiguration, ContentHandler resultHandler) throws SAXException { @@ -62,24 +64,37 @@ public class TestResultsXmlFormatter { private void execute() throws SAXException { myResultHandler.startDocument(); - int total = 0; - int passed = 0; + TreeMap counts = new TreeMap(new Comparator() { + @Override + public int compare(String o1, String o2) { + if (TOTAL_STATUS.equals(o1) && !TOTAL_STATUS.equals(o2)) return -1; + if (TOTAL_STATUS.equals(o2) && !TOTAL_STATUS.equals(o1)) return 1; + return o1.compareTo(o2); + } + }); for (AbstractTestProxy node : myTestRoot.getAllTests()) { if (!node.isLeaf()) continue; - total++; - if (node.isPassed()) passed++; + String status = getStatusString(node); + increment(counts, status); + increment(counts, TOTAL_STATUS); } - Map attrs = new HashMap(); - attrs.put(ATTR_NAME, myRuntimeConfiguration.getName()); + Map runAttrs = new HashMap(); + runAttrs.put(ATTR_NAME, myRuntimeConfiguration.getName()); Integer duration = myTestRoot.getDuration(); if (duration != null) { - attrs.put(ATTR_DURATION, String.valueOf(duration)); + runAttrs.put(ATTR_DURATION, String.valueOf(duration)); } - attrs.put(ATTR_TOTAL, String.valueOf(total)); - attrs.put(ATTR_PASSED, String.valueOf(passed)); - attrs.put(ATTR_FAILED, String.valueOf(total - passed)); - startElement(ELEM_RUN, attrs); + startElement(ELEM_RUN, runAttrs); + + for (Map.Entry entry : counts.entrySet()) { + Map a = new HashMap(); + a.put(ATTR_NAME, entry.getKey()); + a.put(ATTR_VALUE, String.valueOf(entry.getValue())); + startElement(ELEM_COUNT, a); + endElement(ELEM_COUNT); + } + if (myTestRoot.shouldSkipRootNodeForExport()) { for (AbstractTestProxy node : myTestRoot.getChildren()) { processNode(node); @@ -92,6 +107,11 @@ public class TestResultsXmlFormatter { myResultHandler.endDocument(); } + private static void increment(Map counts, String status) { + Integer count = counts.get(status); + counts.put(status, count != null ? count + 1 : 1); + } + private void processNode(AbstractTestProxy node) throws SAXException { Map attrs = new HashMap(); attrs.put(ATTR_NAME, node.getName()); @@ -145,7 +165,7 @@ public class TestResultsXmlFormatter { } if (buffer.length() > 0) { Map a = new HashMap(); - a.put(ATTR_OUTPUT_TYPE, lastType.toString()); + a.put(ATTR_OUTPUT_TYPE, getTypeString(lastType.get())); startElement(ELEM_OUTPUT, a); writeText(buffer.toString()); endElement(ELEM_OUTPUT); @@ -160,12 +180,26 @@ public class TestResultsXmlFormatter { } private static String getTypeString(ConsoleViewContentType type) { - return type == ConsoleViewContentType.ERROR_OUTPUT ? "error" : "normal"; + return type == ConsoleViewContentType.ERROR_OUTPUT ? "stderr" : "stdout"; } private static String getStatusString(AbstractTestProxy node) { - if (node.isPassed()) return "passed"; - return "failed"; // TODO + int magnitude = node.getMagnitude(); + // TODO enumeration! + switch (magnitude) { + case 0: + return "skipped"; + case 5: + return "ignored"; + case 1: + return "passed"; + case 6: + return "failed"; + case 8: + return "error"; + default: + return node.isPassed() ? "passed" : "failed"; + } } private void startElement(String name, Map attributes) throws SAXException { diff --git a/platform/testRunner/src/com/intellij/execution/testframework/export/intellij-export.xsl b/platform/testRunner/src/com/intellij/execution/testframework/export/intellij-export.xsl index fcc64f0c0428..6d234683e7fd 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/export/intellij-export.xsl +++ b/platform/testRunner/src/com/intellij/execution/testframework/export/intellij-export.xsl @@ -61,6 +61,7 @@ h1 { color: #151515; font-size: 180%; + line-height: 1.1em; font-weight: bold; } @@ -88,10 +89,22 @@ color: #ff0000 } - span.success { + span.error { + color: #ff0000 + } + + span.passed { color: #1d9d01 } + span.ignored { + color: #f8d216 + } + + span.skipped { + color: #f8d216 + } + hr { background-color: blue } @@ -101,31 +114,32 @@ } #header { - padding: 1.3em 0 1em 0; + padding: 0; position: fixed; width: 100%; - height: 2em; z-index: 10; background-color: #c7ceda; } + #header h1.title { + margin-top: 1em; + margin-bottom: 0; + } + #header h1 { - margin: 0 3em 0 1.7em; + margin: 0 3em 1em 1.7em; } #header .time { - margin-right: 3em; + margin-top: 2.2em; + margin-right: 3.4em; float: right; } #treecontrol { margin: 0; - padding: 1em 3em .5em 0; - position: fixed; - top: 4em; - right: 0; + padding: .5em 3em .5em 0; text-align: right; - width: 100%; background-color: #fff; } @@ -136,7 +150,7 @@ } #content { - padding: 7em 2.5em 2em 1.7em; + padding: 0 2.5em 2em 1.7em; } #content ul { @@ -158,7 +172,7 @@ } #content ul li.level.top > span { - padding: .5em 0 .5em 1em; + padding: .5em .4em .5em 1em; font-size: 120%; color: #151515; background-color: #f2f2f2; @@ -169,6 +183,10 @@ border-left: solid 10px #f02525; } + #content ul li.level.top.ignored > span { + border-left: solid 10px #f8d216; + } + #content ul li.level.suite > span { margin-bottom: .8em; padding: 0 0 0 .8em; @@ -183,6 +201,10 @@ border-left: solid 15px #f02525; } + #content ul li.level.suite.ignored > span { + border-left: solid 15px #f8d216; + } + #content ul li.level.suite > ul { margin-bottom: 1.5em; } @@ -191,15 +213,19 @@ padding: .3em 0 .3em 1em; color: #0046b0; font-size: 100%; - border-left: solid 3px #93e078; + border-left: solid 6px #93e078; border-bottom: solid 1px #dbdbdb; } #content ul li.level.test.failed > span { - border-left: solid 3px #f02525; + border-left: solid 6px #f02525; } - #content ul li.text span { + #content ul li.level.test.ignored > span { + border-left: solid 6px #f8d216; + } + + #content ul li.text p, #content ul li.text span { margin-bottom: 1.5em; color: #151515 !important; font-size: 90% !important; @@ -210,16 +236,24 @@ border: none !important; } + #content ul li.text span { + margin-bottom: 0; + display: block; + } + + #content ul li.text span.stderr { + color: #8b0000 !important; + } + #content ul li .time { margin-right: .5em; width: 5em; text-align: right; - font-size: 90%; + font-size: 13px; color: #151515; font-style: normal; font-weight: normal; float: right; - background-color: #fff; } #content ul li span .status { @@ -235,6 +269,11 @@ #content ul li.failed > span .status { color: #ff0000; } + + #content ul li.ignored > span .status { + color: #f8d216; + } + ]]> @@ -535,19 +575,22 @@ jQuery.cookie = function(name, value, options) {
@@ -571,6 +614,108 @@ jQuery.cookie = function(name, value, options) { + + + level + + + + suite + + + top + + + + + + + + + + + + + + + +
    + +
+
+
+ + + + level test + + +
  • + + + + + + + + + +
      + + + + + + + + +
    • + + + + +
    • +
      +
    +
  • +
    + + + + + failed open + + + ignored open + + + + open + + + + + + + + + + + + + + + + + + + + + + + + + @@ -613,100 +758,4 @@ jQuery.cookie = function(name, value, options) { - - - level - - - - suite - - - top - - - - - - failed open - - - - open - - - - - - - - - - - - - - -
      - -
    -
    -
    - - - - level test - - failed open - - -
  • - - - - - - - - - -
      - - - - - - - - -
    • - - - -
    • -
      -
    -
  • -
    - - - - - - - - - - - - - - - - - - - - - diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/update/UpdateInfoTree.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/update/UpdateInfoTree.java index 6d42413f1601..331b1ddebb9f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/update/UpdateInfoTree.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/update/UpdateInfoTree.java @@ -215,7 +215,7 @@ public class UpdateInfoTree extends PanelWithActionsAndCloseButton implements Di } public Object getData(String dataId) { - if (myTreeBrowser.isVisible()) { + if (myTreeBrowser != null && myTreeBrowser.isVisible()) { return null; } if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { @@ -229,7 +229,7 @@ public class UpdateInfoTree extends PanelWithActionsAndCloseButton implements Di return getFileArray(); } else if (PlatformDataKeys.TREE_EXPANDER.is(dataId)) { if (myGroupByChangeList) { - return myTreeBrowser.getTreeExpander(); + return myTreeBrowser != null ? myTreeBrowser.getTreeExpander() : null; } else { return myTreeExpander; diff --git a/plugins/groovy/jetgroovy.iml b/plugins/groovy/jetgroovy.iml index c01f8d1bd815..75ba9501f021 100644 --- a/plugins/groovy/jetgroovy.iml +++ b/plugins/groovy/jetgroovy.iml @@ -35,6 +35,7 @@ + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyClassNameInsertHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyClassNameInsertHandler.java index 219eaf254105..bb6665a7753b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyClassNameInsertHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyClassNameInsertHandler.java @@ -53,9 +53,9 @@ public class GroovyClassNameInsertHandler implements InsertHandler() { + @Override + public void consume(PsiClass psiClass) { + if (!inheritors.alreadyProcessed(psiClass)) { + result.addElement(GroovyCompletionUtil.createClassLookupItem(psiClass)); + } + } + }); + } + public GroovyCompletionContributor() { extend(CompletionType.BASIC, psiElement(PsiElement.class), new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull final CompletionResultSet result) { - final PsiElement position = parameters.getPosition(); - final PsiElement reference = position.getParent(); + final PsiElement reference = parameters.getPosition().getParent(); if (reference instanceof GrReferenceElement) { - final int invocationCount = parameters.getInvocationCount(); - final boolean secondCompletionInvoked = - CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION ? invocationCount > 0 : invocationCount > 1; - - final String prefix = result.getPrefixMatcher().getPrefix(); - final boolean skipAccessors = !secondCompletionInvoked && !prefix.startsWith(GET_PREFIX) && - !prefix.startsWith(SET_PREFIX) && - !prefix.startsWith(IS_PREFIX); - - - result.restartCompletionOnPrefixChange(GET_PREFIX); - result.restartCompletionOnPrefixChange(SET_PREFIX); - result.restartCompletionOnPrefixChange(IS_PREFIX); - final Map staticMembers = hashMap(); - ((GrReferenceElement)reference).processVariants(new Consumer() { - public void consume(Object element) { - final LookupElement lookupElement = element instanceof PsiClass - ? GroovyCompletionUtil.createClassLookupItem((PsiClass)element) - : GroovyCompletionUtil.getLookupElement(element); - Object object = lookupElement.getObject(); - PsiSubstitutor substitutor = null; - if (object instanceof GroovyResolveResult) { - substitutor = ((GroovyResolveResult)object).getSubstitutor(); - object = ((GroovyResolveResult)object).getElement(); - } - - - //skip default groovy methods - if (!secondCompletionInvoked && - object instanceof GrGdkMethod && - GroovyCompletionUtil.skipDefGroovyMethod((GrGdkMethod)object, substitutor)) { - showInfo(); - return; - } - - //skip operator methods - if (!secondCompletionInvoked && - object instanceof PsiMethod && - GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(((PsiMethod)object).getName())) { - showInfo(); - return; - } - - //skip accessors if there is no get, set, is prefix - if (skipAccessors && object instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)object)) { - showInfo(); - return; - } - - if ((object instanceof PsiMethod || object instanceof PsiField) && - ((PsiModifierListOwner)object).hasModifierProperty(PsiModifier.STATIC)) { - if (lookupElement.getLookupString().equals(((PsiMember)object).getName())) { - staticMembers.put((PsiModifierListOwner)object, lookupElement); - return; - } - } - result.addElement(lookupElement); - } - }); - - if (((GrReferenceElement)reference).getQualifier() == null) { - completeStaticMembers(position).processMembersOfRegisteredClasses(null, new PairConsumer() { - @Override - public void consume(PsiMember member, PsiClass psiClass) { - if (member instanceof GrAccessorMethod) { - member = ((GrAccessorMethod)member).getProperty(); - } - final String name = member.getName(); - if (name == null || !result.getPrefixMatcher().prefixMatches(name)) { - staticMembers.remove(member); - return; - } - staticMembers.put(member, new JavaGlobalMemberLookupElement(member, psiClass, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_IMPORT_INSERT_HANDLER, true)); - } - }); - } - result.addAllElements(staticMembers.values()); + completeReference(parameters, result, (GrReferenceElement)reference); } } }); @@ -366,37 +301,113 @@ public class GroovyCompletionContributor extends CompletionContributor { }); - final CompletionProvider classNameProvider = new CompletionProvider() { + extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, - @NotNull final CompletionResultSet result) { - result.stopHere(); - AllClassesGetter - .processJavaClasses(parameters, result.getPrefixMatcher(), parameters.getInvocationCount() <= 1, new Consumer() { - @Override - public void consume(PsiClass psiClass) { - result.addElement(GroovyCompletionUtil.createClassLookupItem(psiClass)); - } - }); - } - }; - extend(CompletionType.CLASS_NAME, psiElement(), classNameProvider); - - extend(CompletionType.BASIC, psiElement().withParent(GrReferenceElement.class), new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull final CompletionResultSet result) { - final PsiElement position = parameters.getPosition(); - if (((GrReferenceElement)position.getParent()).getQualifier() != null) return; - - final String s = result.getPrefixMatcher().getPrefix(); - if (StringUtil.isEmpty(s) || !Character.isUpperCase(s.charAt(0))) return; - - classNameProvider.addCompletionVariants(parameters, context, result); + @NotNull CompletionResultSet result) { + addAllClasses(parameters, result, new InheritorsHolder(parameters.getPosition(), result)); } }); + + } + + private static void completeReference(CompletionParameters parameters, final CompletionResultSet result, GrReferenceElement reference) { + PsiElement position = parameters.getPosition(); + + final InheritorsHolder inheritors = new InheritorsHolder(position, result); + if (GroovySmartCompletionContributor.AFTER_NEW.accepts(position)) { + GroovySmartCompletionContributor.generateInheritorVariants(parameters, result.getPrefixMatcher(), inheritors); + } + + final int invocationCount = parameters.getInvocationCount(); + final boolean secondCompletionInvoked = CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION ? invocationCount > 0 : invocationCount > 1; + + final String prefix = result.getPrefixMatcher().getPrefix(); + final boolean skipAccessors = !secondCompletionInvoked && !prefix.startsWith(GET_PREFIX) && + !prefix.startsWith(SET_PREFIX) && + !prefix.startsWith(IS_PREFIX); + + + result.restartCompletionOnPrefixChange(GET_PREFIX); + result.restartCompletionOnPrefixChange(SET_PREFIX); + result.restartCompletionOnPrefixChange(IS_PREFIX); + final Map staticMembers = hashMap(); + reference.processVariants(new Consumer() { + public void consume(Object element) { + if (element instanceof PsiClass && inheritors.alreadyProcessed((PsiClass)element)) { + return; + } + if (element instanceof LookupElement && inheritors.alreadyProcessed((LookupElement)element)) { + return; + } + + final LookupElement lookupElement = element instanceof PsiClass + ? GroovyCompletionUtil.createClassLookupItem((PsiClass)element) + : GroovyCompletionUtil.getLookupElement(element); + Object object = lookupElement.getObject(); + PsiSubstitutor substitutor = null; + if (object instanceof GroovyResolveResult) { + substitutor = ((GroovyResolveResult)object).getSubstitutor(); + object = ((GroovyResolveResult)object).getElement(); + } + + //skip default groovy methods + if (!secondCompletionInvoked && + object instanceof GrGdkMethod && + GroovyCompletionUtil.skipDefGroovyMethod((GrGdkMethod)object, substitutor)) { + showInfo(); + return; + } + + //skip operator methods + if (!secondCompletionInvoked && + object instanceof PsiMethod && + GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(((PsiMethod)object).getName())) { + showInfo(); + return; + } + + //skip accessors if there is no get, set, is prefix + if (skipAccessors && object instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)object)) { + showInfo(); + return; + } + + if ((object instanceof PsiMethod || object instanceof PsiField) && + ((PsiModifierListOwner)object).hasModifierProperty(PsiModifier.STATIC)) { + if (lookupElement.getLookupString().equals(((PsiMember)object).getName())) { + staticMembers.put((PsiModifierListOwner)object, lookupElement); + return; + } + } + result.addElement(lookupElement); + } + }); + + if (reference.getQualifier() == null) { + completeStaticMembers(position).processMembersOfRegisteredClasses(null, new PairConsumer() { + @Override + public void consume(PsiMember member, PsiClass psiClass) { + if (member instanceof GrAccessorMethod) { + member = ((GrAccessorMethod)member).getProperty(); + } + final String name = member.getName(); + if (name == null || !result.getPrefixMatcher().prefixMatches(name)) { + staticMembers.remove(member); + return; + } + staticMembers.put(member, new JavaGlobalMemberLookupElement(member, psiClass, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_IMPORT_INSERT_HANDLER, true)); + + } + }); + + final String s = result.getPrefixMatcher().getPrefix(); + if (!StringUtil.isEmpty(s) && Character.isUpperCase(s.charAt(0))) { + addAllClasses(parameters, result, inheritors); + } + } + result.addAllElements(staticMembers.values()); } private static void showInfo() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java index ceb96c6eba0c..dc650d47fba4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java @@ -70,7 +70,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor { GrAssignmentExpression.class), psiElement( GrVariable.class)))); - private static final ElementPattern AFTER_NEW = + static final ElementPattern AFTER_NEW = psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW).andNot(psiElement().afterLeaf(psiElement().withText(PsiKeyword.THROW)))); private static final TObjectHashingStrategy EXPECTED_TYPE_INFO_STRATEGY = new TObjectHashingStrategy() { @@ -191,38 +191,10 @@ public class GroovySmartCompletionContributor extends CompletionContributor { protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext matchingContext, @NotNull final CompletionResultSet result) { - final PsiElement identifierCopy = parameters.getPosition(); - final GrExpression expression = PsiTreeUtil.getParentOfType(identifierCopy, GrExpression.class); - if (expression == null) return; - - final Set types = GroovyExpectedTypesProvider.getDefaultExpectedTypes(expression); - for (PsiType type : types) { - if (type instanceof PsiArrayType) { - final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), identifierCopy); - if (item.getObject() instanceof PsiClass) { - JavaCompletionUtil.setShowFQN(item); - } - item.setInsertHandler(new ArrayInsertHandler()); - result.addElement(item); - } - } - - - final List expectedClassTypes = new SmartList(); - - for (PsiType psiType : types) { - if (psiType instanceof PsiClassType) { - PsiType type = JavaCompletionUtil.eliminateWildcards(JavaCompletionUtil.originalize(psiType)); - final PsiClassType classType = (PsiClassType)type; - if (classType.resolve() != null) { - expectedClassTypes.add(classType); - } - } - } - - JavaInheritorsGetter.processInheritors(parameters, expectedClassTypes, result.getPrefixMatcher(), new Consumer() { - public void consume(final PsiType type) { - addExpectedType(result, type, identifierCopy); + generateInheritorVariants(parameters, result.getPrefixMatcher(), new Consumer() { + @Override + public void consume(LookupElement lookupElement) { + result.addElement(lookupElement); } }); } @@ -230,24 +202,65 @@ public class GroovySmartCompletionContributor extends CompletionContributor { } + static void generateInheritorVariants(CompletionParameters parameters, PrefixMatcher matcher, final Consumer consumer) { + final PsiElement identifierCopy = parameters.getPosition(); + final GrExpression expression = PsiTreeUtil.getParentOfType(identifierCopy, GrExpression.class); + if (expression == null) return; + + final Set types = GroovyExpectedTypesProvider.getDefaultExpectedTypes(expression); + for (PsiType type : types) { + if (type instanceof PsiArrayType) { + final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), identifierCopy); + if (item.getObject() instanceof PsiClass) { + JavaCompletionUtil.setShowFQN(item); + } + item.setInsertHandler(new ArrayInsertHandler()); + consumer.consume(item); + } + } + + + final List expectedClassTypes = new SmartList(); + + for (PsiType psiType : types) { + if (psiType instanceof PsiClassType) { + PsiType type = JavaCompletionUtil.eliminateWildcards(JavaCompletionUtil.originalize(psiType)); + final PsiClassType classType = (PsiClassType)type; + if (classType.resolve() != null) { + expectedClassTypes.add(classType); + } + } + } + + JavaInheritorsGetter.processInheritors(parameters, expectedClassTypes, matcher, new Consumer() { + public void consume(final PsiType type) { + final LookupElement element = addExpectedType(type, identifierCopy); + if (element != null) { + consumer.consume(element); + } + } + }); + } + @Override public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) { super.fillCompletionVariants(parameters, result); } - private static void addExpectedType(final CompletionResultSet result, final PsiType type, final PsiElement place) { - if (!JavaCompletionUtil.hasAccessibleConstructor(type)) return; + @Nullable + private static LookupElement addExpectedType(final PsiType type, final PsiElement place) { + if (!JavaCompletionUtil.hasAccessibleConstructor(type)) return null; final PsiClass psiClass = com.intellij.psi.util.PsiUtil.resolveClassInType(type); - if (psiClass == null) return; + if (psiClass == null) return null; - if (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) return; - if (!checkForInnerClass(psiClass, place)) return; + if (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) return null; + if (!checkForInnerClass(psiClass, place)) return null; final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), place); JavaCompletionUtil.setShowFQN(item); - item.setInsertHandler(new AfterNewClassInsertHandler((PsiClassType)type, place)); - result.addElement(item); + item.setInsertHandler(new AfterNewClassInsertHandler((PsiClassType)type, place, true)); + return item; } private static boolean checkForInnerClass(PsiClass psiClass, PsiElement identifierCopy) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java index a3270a0745f9..bf6a0ead6808 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java @@ -19,8 +19,10 @@ package org.jetbrains.plugins.groovy.lang.completion.handlers; import com.intellij.codeInsight.AutoPopupController; import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.InsertionContext; +import com.intellij.codeInsight.completion.JavaCompletionFeatures; import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler; import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.openapi.util.Condition; import com.intellij.psi.*; import com.intellij.util.containers.ContainerUtil; @@ -34,10 +36,12 @@ import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; public class AfterNewClassInsertHandler implements InsertHandler> { private final PsiClassType myClassType; private final PsiElement myPlace; + private final boolean myTriggerFeature; - public AfterNewClassInsertHandler(PsiClassType classType, PsiElement place) { + public AfterNewClassInsertHandler(PsiClassType classType, PsiElement place, boolean triggerFeature) { myClassType = classType; myPlace = place; + myTriggerFeature = triggerFeature; } public void handleInsert(InsertionContext context, LookupItem item) { @@ -62,6 +66,10 @@ public class AfterNewClassInsertHandler implements InsertHandler l = new ArrLi" + myFixture.completeBasic() + myFixture.type '\n' + myFixture.checkResult "List l = new ArrayList()" + } + + public void testAfterNewWithInner() { + myFixture.addClass """class Zzoo { + static class Impl {} + }""" + configure "Zzoo l = new Zz" + myFixture.completeBasic() + myFixture.checkResult "Zzoo l = new Zzoo" + } } \ No newline at end of file