mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
This commit is contained in:
+2
-2
@@ -56,7 +56,7 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
|
||||
if (item.getUserData(LookupItem.BRACKETS_COUNT_ATTR) == null && !inAnonymous) {
|
||||
if (((PsiClass)item.getObject()).hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
if (mySmart) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.anonymous");
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW_ANONYMOUS);
|
||||
}
|
||||
|
||||
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting(context.getFile().getViewProvider());
|
||||
@@ -77,7 +77,7 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
|
||||
}
|
||||
}
|
||||
if (mySmart) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.afternew");
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class InheritorsHolder implements Consumer<LookupElement> {
|
||||
private final PsiElement myPosition;
|
||||
private final Set<String> myAddedClasses = new HashSet<String>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
+9
-38
@@ -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<String> addedClasses = new THashSet<String>();
|
||||
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<LookupElement>() {
|
||||
@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<LookupElement>() {
|
||||
@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<String> 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<PsiReference, CompletionResultSet>() {
|
||||
@@ -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<String> 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<LookupElement> lookupSet = new LinkedHashSet<LookupElement>();
|
||||
@@ -595,5 +567,4 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
+7
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
+9
-2
@@ -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<PsiReference> 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<PsiReference> refs = ReferencesSearch.search(myElementToRename, referencesSearchScope, false).findAll();
|
||||
|
||||
addReferenceAtCaret(refs);
|
||||
|
||||
|
||||
+54
-20
@@ -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<String, Integer> counts = new TreeMap<String, Integer>(new Comparator<String>() {
|
||||
@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<String, String> attrs = new HashMap<String, String>();
|
||||
attrs.put(ATTR_NAME, myRuntimeConfiguration.getName());
|
||||
Map<String, String> runAttrs = new HashMap<String, String>();
|
||||
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<String, Integer> entry : counts.entrySet()) {
|
||||
Map<String, String> a = new HashMap<String, String>();
|
||||
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<String, Integer> counts, String status) {
|
||||
Integer count = counts.get(status);
|
||||
counts.put(status, count != null ? count + 1 : 1);
|
||||
}
|
||||
|
||||
private void processNode(AbstractTestProxy node) throws SAXException {
|
||||
Map<String, String> attrs = new HashMap<String, String>();
|
||||
attrs.put(ATTR_NAME, node.getName());
|
||||
@@ -145,7 +165,7 @@ public class TestResultsXmlFormatter {
|
||||
}
|
||||
if (buffer.length() > 0) {
|
||||
Map<String, String> a = new HashMap<String, String>();
|
||||
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<String, String> attributes) throws SAXException {
|
||||
|
||||
+174
-125
@@ -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;
|
||||
}
|
||||
|
||||
</style>
|
||||
<xsl:text disable-output-escaping="yes"><![CDATA[
|
||||
|
||||
@@ -525,8 +564,9 @@ jQuery.cookie = function(name, value, options) {
|
||||
window.console && console.log("%o was toggled", this);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#content").css("padding-top", $("#header").height());
|
||||
});
|
||||
</script>
|
||||
|
||||
]]></xsl:text>
|
||||
@@ -535,19 +575,22 @@ jQuery.cookie = function(name, value, options) {
|
||||
<div id="container">
|
||||
<div id="header">
|
||||
<xsl:call-template name="duration"/>
|
||||
<h1>
|
||||
<h1 class="title">
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:text>: </xsl:text>
|
||||
<xsl:value-of select="@total"/>
|
||||
<xsl:text> total, </xsl:text>
|
||||
<span class="success">
|
||||
<xsl:value-of select="@passed"/>
|
||||
<xsl:text> passed, </xsl:text>
|
||||
</span>
|
||||
<span class="failed">
|
||||
<xsl:value-of select="@failed"/>
|
||||
<xsl:text> failed</xsl:text>
|
||||
</span>
|
||||
</h1>
|
||||
<h1>
|
||||
<xsl:for-each select="count">
|
||||
<xsl:variable name="status" select="@name"/>
|
||||
<span class="{$status}">
|
||||
<xsl:value-of select="@value"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="$status"/>
|
||||
<xsl:if test="count(../count) > position()">
|
||||
<xsl:text>, </xsl:text>
|
||||
</xsl:if>
|
||||
</span>
|
||||
</xsl:for-each>
|
||||
</h1>
|
||||
</div>
|
||||
<div id="treecontrol">
|
||||
@@ -571,6 +614,108 @@ jQuery.cookie = function(name, value, options) {
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="suite">
|
||||
<xsl:variable name="class">
|
||||
<xsl:text>level </xsl:text>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="parent::suite">
|
||||
<xsl:text>suite</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>top</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
|
||||
<xsl:call-template name="get-node-class"/>
|
||||
</xsl:variable>
|
||||
<xsl:element name="li">
|
||||
<xsl:attribute name="class">
|
||||
<xsl:value-of select="$class"/>
|
||||
</xsl:attribute>
|
||||
<span>
|
||||
<em class="time">
|
||||
<xsl:call-template name="duration"/>
|
||||
</em>
|
||||
<xsl:value-of select="@name"/>
|
||||
</span>
|
||||
<ul>
|
||||
<xsl:apply-templates/>
|
||||
</ul>
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="test">
|
||||
<xsl:variable name="class">
|
||||
<xsl:text>level test</xsl:text>
|
||||
<xsl:call-template name="get-node-class"/>
|
||||
</xsl:variable>
|
||||
<li class="{$class}">
|
||||
<span>
|
||||
<em class="time">
|
||||
<xsl:call-template name="duration"/>
|
||||
</em>
|
||||
<em class="status">
|
||||
<xsl:value-of select="@status"/>
|
||||
</em>
|
||||
<xsl:value-of select="@name"/>
|
||||
</span>
|
||||
<ul>
|
||||
<xsl:for-each select="output">
|
||||
<xsl:variable name="displayText">
|
||||
<xsl:call-template name="string-replace-all">
|
||||
<xsl:with-param name="text" select="text()"/>
|
||||
<xsl:with-param name="replace" select="' '"/>
|
||||
<xsl:with-param name="by" select="'<br/>'"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<li class="text">
|
||||
<xsl:variable name="output-type" select="@type"/>
|
||||
<span class="{$output-type}">
|
||||
<xsl:value-of disable-output-escaping="yes" select="$displayText"/>
|
||||
</span>
|
||||
</li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</li>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="get-node-class">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@status='failed' or @status='error'">
|
||||
<xsl:text> failed open</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="@status='ignored' or @status='skipped'">
|
||||
<xsl:text> ignored open</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="@status='passed'">
|
||||
<xsl:if test="name(.) != 'test' and count(parent::*) = 1">
|
||||
<xsl:text> open</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="string-replace-all">
|
||||
<xsl:param name="text"/>
|
||||
<xsl:param name="replace"/>
|
||||
<xsl:param name="by"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains($text, $replace)">
|
||||
<xsl:value-of select="substring-before($text,$replace)"/>
|
||||
<xsl:value-of select="$by"/>
|
||||
<xsl:call-template name="string-replace-all">
|
||||
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
|
||||
<xsl:with-param name="replace" select="$replace"/>
|
||||
<xsl:with-param name="by" select="$by"/>
|
||||
</xsl:call-template>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$text"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="duration">
|
||||
<xsl:if test="@duration">
|
||||
<xsl:variable name="msec" select="number(@duration)"/>
|
||||
@@ -613,100 +758,4 @@ jQuery.cookie = function(name, value, options) {
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="suite">
|
||||
<xsl:variable name="class">
|
||||
<xsl:text>level </xsl:text>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="parent::suite">
|
||||
<xsl:text>suite</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>top</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="@status!='passed'">
|
||||
<xsl:text> failed open</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:if test="count(parent::*) = 1">
|
||||
<xsl:text> open</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<xsl:element name="li">
|
||||
<xsl:attribute name="class">
|
||||
<xsl:value-of select="$class"/>
|
||||
</xsl:attribute>
|
||||
<span>
|
||||
<em class="time">
|
||||
<xsl:call-template name="duration"/>
|
||||
</em>
|
||||
<xsl:value-of select="@name"/>
|
||||
</span>
|
||||
<ul>
|
||||
<xsl:apply-templates/>
|
||||
</ul>
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="test">
|
||||
<xsl:variable name="class">
|
||||
<xsl:text>level test</xsl:text>
|
||||
<xsl:if test="@status!='passed'">
|
||||
<xsl:text> failed open</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:variable>
|
||||
<li class="{$class}">
|
||||
<span>
|
||||
<em class="time">
|
||||
<xsl:call-template name="duration"/>
|
||||
</em>
|
||||
<em class="status">
|
||||
<xsl:value-of select="@status"/>
|
||||
</em>
|
||||
<xsl:value-of select="@name"/>
|
||||
</span>
|
||||
<ul>
|
||||
<xsl:for-each select="output">
|
||||
<xsl:variable name="displayText">
|
||||
<xsl:call-template name="string-replace-all">
|
||||
<xsl:with-param name="text" select="text()"/>
|
||||
<xsl:with-param name="replace" select="' '"/>
|
||||
<xsl:with-param name="by" select="'<br/>'"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<li class="text">
|
||||
<span>
|
||||
<xsl:value-of disable-output-escaping="yes" select="$displayText"/>
|
||||
</span>
|
||||
</li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</li>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="string-replace-all">
|
||||
<xsl:param name="text"/>
|
||||
<xsl:param name="replace"/>
|
||||
<xsl:param name="by"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains($text, $replace)">
|
||||
<xsl:value-of select="substring-before($text,$replace)"/>
|
||||
<xsl:value-of select="$by"/>
|
||||
<xsl:call-template name="string-replace-all">
|
||||
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
|
||||
<xsl:with-param name="replace" select="$replace"/>
|
||||
<xsl:with-param name="by" select="$by"/>
|
||||
</xsl:call-template>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$text"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<orderEntry type="module" module-name="IntelliLang" />
|
||||
<orderEntry type="module" module-name="ant" />
|
||||
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
+3
-3
@@ -53,9 +53,9 @@ public class GroovyClassNameInsertHandler implements InsertHandler<JavaPsiClassR
|
||||
|
||||
final boolean inNew = position != null && isReferenceInNewExpression(position.getParent());
|
||||
|
||||
final PsiClass psiClass = item.getObject();
|
||||
if (isInVariable(position) || GroovyCompletionContributor.isInClosurePropertyParameters(position)) {
|
||||
Project project = context.getProject();
|
||||
PsiClass psiClass = item.getObject();
|
||||
String qname = psiClass.getQualifiedName();
|
||||
String shortName = psiClass.getName();
|
||||
if (qname == null) return;
|
||||
@@ -71,8 +71,8 @@ public class GroovyClassNameInsertHandler implements InsertHandler<JavaPsiClassR
|
||||
}
|
||||
AllClassesGetter.TRY_SHORTENING.handleInsert(context, item);
|
||||
|
||||
if (inNew) {
|
||||
JavaCompletionUtil.insertParentheses(context, item, false, GroovyCompletionUtil.hasConstructorParameters(item.getObject()));
|
||||
if (inNew && !JavaCompletionUtil.hasAccessibleInnerClass(psiClass, position)) {
|
||||
JavaCompletionUtil.insertParentheses(context, item, false, GroovyCompletionUtil.hasConstructorParameters(psiClass));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+116
-105
@@ -200,92 +200,27 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
};
|
||||
|
||||
private static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, final InheritorsHolder inheritors) {
|
||||
result.stopHere();
|
||||
AllClassesGetter.processJavaClasses(parameters, result.getPrefixMatcher(), parameters.getInvocationCount() <= 1, new Consumer<PsiClass>() {
|
||||
@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<CompletionParameters>() {
|
||||
@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<PsiModifierListOwner, LookupElement> staticMembers = hashMap();
|
||||
((GrReferenceElement)reference).processVariants(new Consumer<Object>() {
|
||||
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<PsiMember, PsiClass>() {
|
||||
@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<CompletionParameters> classNameProvider = new CompletionProvider<CompletionParameters>() {
|
||||
extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider<CompletionParameters>() {
|
||||
@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<PsiClass>() {
|
||||
@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<CompletionParameters>() {
|
||||
@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<PsiModifierListOwner, LookupElement> staticMembers = hashMap();
|
||||
reference.processVariants(new Consumer<Object>() {
|
||||
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<PsiMember, PsiClass>() {
|
||||
@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() {
|
||||
|
||||
+53
-40
@@ -70,7 +70,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
|
||||
GrAssignmentExpression.class),
|
||||
psiElement(
|
||||
GrVariable.class))));
|
||||
private static final ElementPattern<PsiElement> AFTER_NEW =
|
||||
static final ElementPattern<PsiElement> AFTER_NEW =
|
||||
psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW).andNot(psiElement().afterLeaf(psiElement().withText(PsiKeyword.THROW))));
|
||||
private static final TObjectHashingStrategy<TypeConstraint> EXPECTED_TYPE_INFO_STRATEGY =
|
||||
new TObjectHashingStrategy<TypeConstraint>() {
|
||||
@@ -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<PsiType> 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<PsiClassType> expectedClassTypes = new SmartList<PsiClassType>();
|
||||
|
||||
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<PsiType>() {
|
||||
public void consume(final PsiType type) {
|
||||
addExpectedType(result, type, identifierCopy);
|
||||
generateInheritorVariants(parameters, result.getPrefixMatcher(), new Consumer<LookupElement>() {
|
||||
@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<LookupElement> consumer) {
|
||||
final PsiElement identifierCopy = parameters.getPosition();
|
||||
final GrExpression expression = PsiTreeUtil.getParentOfType(identifierCopy, GrExpression.class);
|
||||
if (expression == null) return;
|
||||
|
||||
final Set<PsiType> 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<PsiClassType> expectedClassTypes = new SmartList<PsiClassType>();
|
||||
|
||||
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<PsiType>() {
|
||||
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) {
|
||||
|
||||
+9
-1
@@ -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<LookupItem<PsiClassType>> {
|
||||
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<PsiClassType> item) {
|
||||
@@ -62,6 +66,10 @@ public class AfterNewClassInsertHandler implements InsertHandler<LookupItem<PsiC
|
||||
}
|
||||
});
|
||||
|
||||
if (myTriggerFeature) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW);
|
||||
}
|
||||
|
||||
if (hasParams) {
|
||||
ParenthesesInsertHandler.WITH_PARAMETERS.handleInsert(context, item);
|
||||
}
|
||||
|
||||
+20
@@ -320,4 +320,24 @@ class A {
|
||||
def getFileText(PsiFile file) {
|
||||
return PsiDocumentManager.getInstance(project).getDocument(file).text
|
||||
}
|
||||
|
||||
void configure(String text) {
|
||||
myFixture.configureByText("a.groovy", text)
|
||||
}
|
||||
|
||||
public void testGenericsAfterNew() {
|
||||
configure "List<String> l = new ArrLi<caret>"
|
||||
myFixture.completeBasic()
|
||||
myFixture.type '\n'
|
||||
myFixture.checkResult "List<String> l = new ArrayList<String>(<caret>)"
|
||||
}
|
||||
|
||||
public void testAfterNewWithInner() {
|
||||
myFixture.addClass """class Zzoo {
|
||||
static class Impl {}
|
||||
}"""
|
||||
configure "Zzoo l = new Zz<caret>"
|
||||
myFixture.completeBasic()
|
||||
myFixture.checkResult "Zzoo l = new Zzoo<caret>"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user