mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
@@ -22,7 +22,6 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.ui.ColoredListCellRenderer;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.xdebugger.ui.DebuggerColors;
|
||||
import com.sun.jdi.Method;
|
||||
@@ -92,28 +91,11 @@ class FramesListRenderer extends ColoredListCellRenderer {
|
||||
}
|
||||
else {
|
||||
append(label.substring(0, openingBrace - 1), attributes);
|
||||
|
||||
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
builder.append(" (");
|
||||
builder.append(label.substring(openingBrace + 1, closingBrace));
|
||||
builder.append(")");
|
||||
append(builder.toString(), SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES);
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(builder);
|
||||
}
|
||||
append(" (" + label.substring(openingBrace + 1, closingBrace) + ")", SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES);
|
||||
|
||||
append(label.substring(closingBrace + 1, label.length()), attributes);
|
||||
if (shouldHighlightAsRecursive && descriptor.isRecursiveCall()) {
|
||||
final StringBuilder _builder = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
_builder.append(" [").append(descriptor.getOccurrenceIndex()).append("]");
|
||||
append(_builder.toString(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(_builder);
|
||||
}
|
||||
append(" [" + descriptor.getOccurrenceIndex() + "]", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,37 +109,7 @@ public class SegmentedInputStream extends InputStream {
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
|
||||
final HashMap<String, String> map = new HashMap<String, String>();
|
||||
map.keySet();
|
||||
while (mySourceStream.ready()) {
|
||||
|
||||
while(myStartupPassed < SegmentedStream.STARTUP_MESSAGE.length()) {
|
||||
final int aChar = readNext();
|
||||
if (aChar != SegmentedStream.STARTUP_MESSAGE.charAt(myStartupPassed)) {
|
||||
mySourceStream.pushBack(aChar);
|
||||
final char[] charsRead = SegmentedStream.STARTUP_MESSAGE.substring(0, myStartupPassed).toCharArray();
|
||||
mySourceStream.pushBack(charsRead);
|
||||
myStartupPassed = 0;
|
||||
return charsRead.length + 1;
|
||||
}
|
||||
myStartupPassed++;
|
||||
}
|
||||
|
||||
final int b = mySourceStream.next();
|
||||
if (b != SegmentedStream.SPECIAL_SYMBOL) {
|
||||
mySourceStream.pushBack(b);
|
||||
return 1;
|
||||
}
|
||||
final Integer packetRead = readControlSequence();
|
||||
if (packetRead != null) {
|
||||
// push back quoted slash
|
||||
mySourceStream.pushBack(packetRead);
|
||||
mySourceStream.pushBack(b);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return mySourceStream.ready() ? 1 : 0;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
|
||||
+13
-4
@@ -17,7 +17,6 @@ import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -33,7 +32,13 @@ import java.util.List;
|
||||
*/
|
||||
class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<LookupItem>> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.ConstructorInsertHandler");
|
||||
public static final ConstructorInsertHandler INSTANCE = new ConstructorInsertHandler();
|
||||
public static final ConstructorInsertHandler SMART_INSTANCE = new ConstructorInsertHandler(true);
|
||||
public static final ConstructorInsertHandler BASIC_INSTANCE = new ConstructorInsertHandler(false);
|
||||
private final boolean mySmart;
|
||||
|
||||
private ConstructorInsertHandler(boolean smart) {
|
||||
mySmart = smart;
|
||||
}
|
||||
|
||||
public void handleInsert(InsertionContext context, LookupElementDecorator<LookupItem> item) {
|
||||
@SuppressWarnings({"unchecked"}) final LookupItem<PsiClass> delegate = item.getDelegate();
|
||||
@@ -50,7 +55,9 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
|
||||
|
||||
if (item.getUserData(LookupItem.BRACKETS_COUNT_ATTR) == null && !inAnonymous) {
|
||||
if (((PsiClass)item.getObject()).hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.anonymous");
|
||||
if (mySmart) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW_ANONYMOUS);
|
||||
}
|
||||
|
||||
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting(context.getFile().getViewProvider());
|
||||
|
||||
@@ -69,7 +76,9 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
|
||||
CodeStyleManager.getInstance(context.getProject()).reformat(classReference);
|
||||
}
|
||||
}
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.afternew");
|
||||
if (mySmart) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-14
@@ -15,13 +15,11 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiLiteralExpression;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -31,21 +29,11 @@ import java.util.Collection;
|
||||
*/
|
||||
public abstract class ExpectedTypeBasedCompletionProvider extends CompletionProvider<CompletionParameters> {
|
||||
|
||||
public ExpectedTypeBasedCompletionProvider() {
|
||||
super(false);
|
||||
}
|
||||
|
||||
public void addCompletions(@NotNull final CompletionParameters params, final ProcessingContext matchingContext, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement position = params.getPosition();
|
||||
if (position.getParent() instanceof PsiLiteralExpression) return;
|
||||
|
||||
final THashSet<ExpectedTypeInfo> infos = new THashSet<ExpectedTypeInfo>();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
ContainerUtil.addAll(infos, JavaSmartCompletionContributor.getExpectedTypes(params));
|
||||
}
|
||||
});
|
||||
addCompletions(params, result, infos);
|
||||
addCompletions(params, result, Sets.newHashSet(JavaSmartCompletionContributor.getExpectedTypes(params)));
|
||||
}
|
||||
|
||||
protected abstract void addCompletions(CompletionParameters params, CompletionResultSet result, Collection<ExpectedTypeInfo> infos);
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public abstract class ExpressionSmartCompletionContributor extends AbstractCompl
|
||||
public void fillCompletionVariants(final JavaSmartCompletionParameters parameters, CompletionResultSet result) {
|
||||
for (final Pair<ElementPattern<? extends PsiElement>, CompletionProvider<JavaSmartCompletionParameters>> pair : myList) {
|
||||
final ProcessingContext context = new ProcessingContext();
|
||||
if (isPatternSuitable(pair.first, parameters, context)) {
|
||||
if (pair.first.accepts(parameters.getPosition(), context)) {
|
||||
pair.second.addCompletionVariants(parameters, context, result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -66,7 +66,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
return;
|
||||
}
|
||||
|
||||
if (completingRawConstructor(context, item)) {
|
||||
if (completingRawConstructor(context, item) && !JavaCompletionUtil.hasAccessibleInnerClass(item.getObject(), file)) {
|
||||
ConstructorInsertHandler.insertParentheses(context, item, item.getObject());
|
||||
DefaultInsertHandler.addImportForItem(context.getFile(), context.getStartOffset(), item);
|
||||
} else {
|
||||
@@ -97,7 +97,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
};
|
||||
|
||||
public JavaClassNameCompletionContributor() {
|
||||
extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider<CompletionParameters>(false) {
|
||||
extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider<CompletionParameters>() {
|
||||
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext matchingContext, @NotNull final CompletionResultSet result) {
|
||||
if (shouldShowSecondSmartCompletionHint(parameters) &&
|
||||
CompletionUtil.shouldShowFeature(parameters, CodeCompletionFeatures.SECOND_CLASS_NAME_COMPLETION)) {
|
||||
|
||||
+54
-42
@@ -18,11 +18,7 @@ package com.intellij.codeInsight.completion;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFix;
|
||||
import com.intellij.codeInsight.hint.ShowParameterInfoHandler;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.lookup.LookupItemUtil;
|
||||
import com.intellij.codeInsight.lookup.TailTypeDecorator;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.lang.LangBundle;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
@@ -47,7 +43,6 @@ import com.intellij.psi.filters.getters.ExpectedTypesGetter;
|
||||
import com.intellij.psi.filters.types.AssignableFromFilter;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.scope.ElementClassFilter;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
@@ -87,6 +82,9 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return type instanceof PsiClassType;
|
||||
}
|
||||
})));
|
||||
private static final ElementPattern<PsiElement> AFTER_NUMBER_LITERAL =
|
||||
psiElement().afterLeaf(psiElement().withElementType(
|
||||
elementType().oneOf(JavaTokenType.DOUBLE_LITERAL, JavaTokenType.LONG_LITERAL, JavaTokenType.FLOAT_LITERAL, JavaTokenType.INTEGER_LITERAL)));
|
||||
|
||||
@Nullable
|
||||
private static ElementFilter getReferenceFilter(PsiElement position) {
|
||||
@@ -165,7 +163,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return TrueFilter.INSTANCE;
|
||||
}
|
||||
|
||||
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet _result) {
|
||||
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
|
||||
if (parameters.getCompletionType() != CompletionType.BASIC) {
|
||||
return;
|
||||
}
|
||||
@@ -175,46 +173,66 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiFile file = parameters.getOriginalFile();
|
||||
final int offset = parameters.getOffset();
|
||||
final PsiElement lastElement = file.findElementAt(offset - 1);
|
||||
if (lastElement == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ASTNode node = lastElement.getNode();
|
||||
assert node != null;
|
||||
final IElementType elementType = node.getElementType();
|
||||
if (elementType == JavaTokenType.DOUBLE_LITERAL || elementType == JavaTokenType.LONG_LITERAL || elementType == JavaTokenType.INTEGER_LITERAL || elementType == JavaTokenType.FLOAT_LITERAL) {
|
||||
if (AFTER_NUMBER_LITERAL.accepts(position)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ANNOTATION_ATTRIBUTE_NAME.accepts(position)) {
|
||||
completeAnnotationAttributeName(_result, position, parameters);
|
||||
_result.stopHere();
|
||||
completeAnnotationAttributeName(result, position, parameters);
|
||||
result.stopHere();
|
||||
return;
|
||||
}
|
||||
|
||||
final JavaAwareCompletionData completionData = PsiUtil.isLanguageLevel5OrHigher(lastElement) ? ourJava15CompletionData : ourJavaCompletionData;
|
||||
final boolean checkAccess = parameters.getInvocationCount() <= 1;
|
||||
final InheritorsHolder inheritors = new InheritorsHolder(position, result);
|
||||
if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) {
|
||||
new JavaInheritorsGetter(ConstructorInsertHandler.BASIC_INSTANCE).generateVariants(parameters, result.getPrefixMatcher(), inheritors);
|
||||
}
|
||||
|
||||
LegacyCompletionContributor.processReferences(parameters, _result, completionData, new PairConsumer<PsiReference, CompletionResultSet>() {
|
||||
addReferenceVariants(parameters, result, inheritors);
|
||||
|
||||
addKeywords(parameters, result);
|
||||
|
||||
if (shouldRunClassNameCompletion(result, position)) {
|
||||
result.runRemainingContributors(
|
||||
new CompletionParameters(position, parameters.getOriginalFile(), CompletionType.CLASS_NAME, parameters.getOffset(), parameters.getInvocationCount()),
|
||||
new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement lookupElement) {
|
||||
if (!inheritors.alreadyProcessed(lookupElement)) {
|
||||
result.addElement(lookupElement);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
result.stopHere();
|
||||
}
|
||||
|
||||
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>() {
|
||||
public void consume(final PsiReference reference, final CompletionResultSet result) {
|
||||
if (reference instanceof PsiJavaReference) {
|
||||
final ElementFilter filter = getReferenceFilter(position);
|
||||
if (filter != null) {
|
||||
final boolean isSwitchLabel = SWITCH_LABEL.accepts(position);
|
||||
final PsiFile originalFile = parameters.getOriginalFile();
|
||||
for (LookupElement element : JavaCompletionUtil.processJavaReference(position,
|
||||
(PsiJavaReference) reference,
|
||||
(PsiJavaReference)reference,
|
||||
new ElementExtractorFilter(filter),
|
||||
checkAccess,
|
||||
result.getPrefixMatcher(), parameters)) {
|
||||
if (inheritors.alreadyProcessed(element)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isSwitchLabel) {
|
||||
result.addElement(TailTypeDecorator.withTail(element, TailType.createSimpleTailType(':')));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
final LookupItem item = element.as(LookupItem.class);
|
||||
if (file instanceof PsiJavaCodeReferenceCodeFragment &&
|
||||
!((PsiJavaCodeReferenceCodeFragment)file).isClassesAccepted() && item != null) {
|
||||
if (originalFile instanceof PsiJavaCodeReferenceCodeFragment &&
|
||||
!((PsiJavaCodeReferenceCodeFragment)originalFile).isClassesAccepted() && item != null) {
|
||||
item.setTailType(TailType.NONE);
|
||||
}
|
||||
|
||||
@@ -234,11 +252,13 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
if (completion == null) {
|
||||
LOG.error("Position=" + position + "\n;Reference=" + reference + "\n;variants=" + Arrays.toString(variants));
|
||||
}
|
||||
if (completion instanceof LookupElement) {
|
||||
if (completion instanceof LookupElement && !inheritors.alreadyProcessed((LookupElement)completion)) {
|
||||
result.addElement((LookupElement)completion);
|
||||
}
|
||||
else if (completion instanceof PsiClass) {
|
||||
result.addElement(JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true));
|
||||
if (!inheritors.alreadyProcessed((PsiClass)completion)) {
|
||||
result.addElement(JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true));
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.addElement(LookupItemUtil.objectToLookupItem(completion));
|
||||
@@ -246,27 +266,20 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void addKeywords(CompletionParameters parameters, CompletionResultSet result) {
|
||||
PsiElement position = parameters.getPosition();
|
||||
final Set<LookupElement> lookupSet = new LinkedHashSet<LookupElement>();
|
||||
final Set<CompletionVariant> keywordVariants = new HashSet<CompletionVariant>();
|
||||
final JavaCompletionData completionData = PsiUtil.isLanguageLevel5OrHigher(position) ? ourJava15CompletionData : ourJavaCompletionData;
|
||||
completionData.addKeywordVariants(keywordVariants, position, parameters.getOriginalFile());
|
||||
final CompletionResultSet result = _result.withPrefixMatcher(completionData.findPrefix(position, offset));
|
||||
completionData.completeKeywordsBySet(lookupSet, keywordVariants, position, result.getPrefixMatcher(), parameters.getOriginalFile());
|
||||
completionData.fillCompletions(parameters, result);
|
||||
|
||||
for (final LookupElement item : lookupSet) {
|
||||
result.addElement(item);
|
||||
}
|
||||
|
||||
if (shouldRunClassNameCompletion(result, position)) {
|
||||
result.runRemainingContributors(new CompletionParameters(position, file, CompletionType.CLASS_NAME, offset, parameters.getInvocationCount()), new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement lookupElement) {
|
||||
result.addElement(lookupElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
result.stopHere();
|
||||
}
|
||||
|
||||
private static boolean shouldRunClassNameCompletion(CompletionResultSet result, PsiElement position) {
|
||||
@@ -455,7 +468,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
if (parent instanceof PsiReferenceExpression && ((PsiReferenceExpression)parent).getQualifier() != null) return false;
|
||||
if (parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiReferenceExpression) return true;
|
||||
|
||||
return new ExpectedTypesGetter().get(element, null).length > 0;
|
||||
return ExpectedTypesGetter.getExpectedTypes(element, false).length > 0;
|
||||
}
|
||||
|
||||
private static boolean shouldSuggestClassNameCompletion(final PsiElement element) {
|
||||
@@ -554,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";
|
||||
}
|
||||
|
||||
@@ -992,4 +992,17 @@ public class JavaCompletionUtil {
|
||||
JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences((PsiJavaCodeReferenceElement)ref);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasAccessibleInnerClass(@NotNull PsiClass psiClass, @NotNull PsiElement position) {
|
||||
final PsiClass[] inners = psiClass.getAllInnerClasses();
|
||||
if (inners.length > 0) {
|
||||
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(position.getProject()).getResolveHelper();
|
||||
for (PsiClass inner : inners) {
|
||||
if (resolveHelper.isAccessible(inner, position, null)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -66,8 +66,7 @@ public class JavaDocCompletionContributor extends CompletionContributor {
|
||||
public JavaDocCompletionContributor() {
|
||||
extend(CompletionType.BASIC, PsiJavaPatterns.psiElement(PsiDocToken.DOC_TAG_NAME), new TagChooser());
|
||||
|
||||
extend(CompletionType.BASIC, PsiJavaPatterns.psiElement().inside(PsiDocTagValue.class), new CompletionProvider<CompletionParameters>(
|
||||
true) {
|
||||
extend(CompletionType.BASIC, PsiJavaPatterns.psiElement().inside(PsiDocTagValue.class), new CompletionProvider<CompletionParameters>() {
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
boolean isArg = PsiJavaPatterns.psiElement().afterLeaf("(").accepts(position);
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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.CodeInsightUtil;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.getters.ExpectedTypesGetter;
|
||||
import com.intellij.psi.statistics.JavaStatisticsManager;
|
||||
import com.intellij.psi.statistics.StatisticsInfo;
|
||||
import com.intellij.psi.statistics.StatisticsManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.SmartList;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class JavaInheritorsGetter extends CompletionProvider<CompletionParameters> {
|
||||
private final ConstructorInsertHandler myConstructorInsertHandler;
|
||||
|
||||
public JavaInheritorsGetter(final ConstructorInsertHandler constructorInsertHandler) {
|
||||
myConstructorInsertHandler = constructorInsertHandler;
|
||||
}
|
||||
|
||||
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext matchingContext, @NotNull final CompletionResultSet result) {
|
||||
final ExpectedTypeInfo[] infos = JavaSmartCompletionContributor.getExpectedTypes(parameters);
|
||||
|
||||
final List<ExpectedTypeInfo> infoCollection = Arrays.asList(infos);
|
||||
generateVariants(parameters, result.getPrefixMatcher(), infos, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement lookupElement) {
|
||||
result.addElement(JavaSmartCompletionContributor.decorate(lookupElement, infoCollection));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void generateVariants(final CompletionParameters parameters, final PrefixMatcher prefixMatcher, final Consumer<LookupElement> consumer) {
|
||||
generateVariants(parameters, prefixMatcher, JavaSmartCompletionContributor.getExpectedTypes(parameters), consumer);
|
||||
}
|
||||
|
||||
private void generateVariants(final CompletionParameters parameters, final PrefixMatcher prefixMatcher,
|
||||
final ExpectedTypeInfo[] infos, final Consumer<LookupElement> consumer) {
|
||||
|
||||
addArrayTypes(parameters.getPosition(), infos, prefixMatcher, consumer);
|
||||
|
||||
processInheritors(parameters, extractClassTypes(infos), prefixMatcher, new Consumer<PsiType>() {
|
||||
public void consume(final PsiType type) {
|
||||
final LookupElement element = addExpectedType(type, parameters);
|
||||
if (element != null) {
|
||||
consumer.consume(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void addArrayTypes(PsiElement identifierCopy,
|
||||
ExpectedTypeInfo[] infos, PrefixMatcher matcher, final Consumer<LookupElement> consumer) {
|
||||
|
||||
for (final PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) {
|
||||
if (type instanceof PsiArrayType && matcher.prefixMatches(type.getCanonicalText())) {
|
||||
|
||||
final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), identifierCopy);
|
||||
if (item.getObject() instanceof PsiClass) {
|
||||
JavaCompletionUtil.setShowFQN(item);
|
||||
}
|
||||
item.setInsertHandler(new DefaultInsertHandler()); //braces & shortening
|
||||
consumer.consume(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<PsiClassType> extractClassTypes(ExpectedTypeInfo[] infos) {
|
||||
final List<PsiClassType> expectedClassTypes = new SmartList<PsiClassType>();
|
||||
for (PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) {
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
if (classType.resolve() != null) {
|
||||
expectedClassTypes.add(classType);
|
||||
}
|
||||
}
|
||||
}
|
||||
return expectedClassTypes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private LookupElement addExpectedType(final PsiType type,
|
||||
final CompletionParameters parameters) {
|
||||
if (!JavaCompletionUtil.hasAccessibleConstructor(type)) return null;
|
||||
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null) return null;
|
||||
|
||||
final PsiClass parentClass = psiClass.getContainingClass();
|
||||
if (parentClass != null && !psiClass.hasModifierProperty(PsiModifier.STATIC) &&
|
||||
!PsiTreeUtil.isAncestor(parentClass, parameters.getPosition(), false) &&
|
||||
!(parentClass.getContainingFile().equals(parameters.getOriginalFile()) &&
|
||||
parentClass.getTextRange().contains(parameters.getOffset()))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), parameters.getPosition());
|
||||
JavaCompletionUtil.setShowFQN(item);
|
||||
|
||||
if (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
item.setAttribute(LookupItem.INDICATE_ANONYMOUS, "");
|
||||
}
|
||||
|
||||
return LookupElementDecorator.withInsertHandler(item, myConstructorInsertHandler);
|
||||
}
|
||||
|
||||
public static void processInheritors(final CompletionParameters parameters,
|
||||
final Collection<PsiClassType> expectedClassTypes,
|
||||
final PrefixMatcher matcher, final Consumer<PsiType> consumer) {
|
||||
//quick
|
||||
if (!processMostProbableInheritors(parameters, expectedClassTypes, consumer)) return;
|
||||
|
||||
//long
|
||||
final Condition<String> shortNameCondition = new Condition<String>() {
|
||||
public boolean value(String s) {
|
||||
return matcher.prefixMatches(s);
|
||||
}
|
||||
};
|
||||
for (final PsiClassType type : expectedClassTypes) {
|
||||
final PsiClass psiClass = type.resolve();
|
||||
if (psiClass != null && !psiClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
for (final PsiType psiType : CodeInsightUtil.addSubtypes(type, parameters.getPosition(), false, shortNameCondition)) {
|
||||
consumer.consume(psiType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean processMostProbableInheritors(CompletionParameters parameters,
|
||||
Collection<PsiClassType> expectedClassTypes,
|
||||
Consumer<PsiType> consumer) {
|
||||
PsiFile file = parameters.getOriginalFile();
|
||||
for (final PsiClassType type : expectedClassTypes) {
|
||||
consumer.consume(type);
|
||||
|
||||
final PsiClassType.ClassResolveResult baseResult = JavaCompletionUtil.originalize(type).resolveGenerics();
|
||||
final PsiClass baseClass = baseResult.getElement();
|
||||
if (baseClass == null) return false;
|
||||
|
||||
final PsiSubstitutor baseSubstitutor = baseResult.getSubstitutor();
|
||||
|
||||
final THashSet<PsiType> statVariants = new THashSet<PsiType>();
|
||||
final Processor<PsiClass> processor = CodeInsightUtil.createInheritorsProcessor(parameters.getPosition(), type, 0, false,
|
||||
statVariants, baseClass, baseSubstitutor);
|
||||
final StatisticsInfo[] stats = StatisticsManager.getInstance().getAllValues(JavaStatisticsManager.getAfterNewKey(type));
|
||||
for (final StatisticsInfo statisticsInfo : stats) {
|
||||
final String value = statisticsInfo.getValue();
|
||||
if (value.startsWith(JavaStatisticsManager.CLASS_PREFIX)) {
|
||||
final String qname = value.substring(JavaStatisticsManager.CLASS_PREFIX.length());
|
||||
final PsiClass psiClass = JavaPsiFacade.getInstance(file.getProject()).findClass(qname, file.getResolveScope());
|
||||
if (psiClass != null && !PsiTreeUtil.isAncestor(file, psiClass, true) && !processor.process(psiClass)) break;
|
||||
}
|
||||
}
|
||||
|
||||
for (final PsiType variant : statVariants) {
|
||||
consumer.consume(variant);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+21
-134
@@ -18,7 +18,6 @@ package com.intellij.codeInsight.completion;
|
||||
import com.intellij.codeInsight.*;
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
@@ -38,9 +37,6 @@ import com.intellij.psi.filters.types.AssignableToFilter;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.statistics.JavaStatisticsManager;
|
||||
import com.intellij.psi.statistics.StatisticsInfo;
|
||||
import com.intellij.psi.statistics.StatisticsManager;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -124,7 +120,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
psiElement(PsiReferenceExpression.class).withParent(
|
||||
psiElement(PsiExpressionList.class).withParent(PsiMethodCallExpression.class))), new SameSignatureCallParametersProvider());
|
||||
|
||||
extend(CompletionType.SMART, psiElement().afterLeaf(PsiKeyword.INSTANCEOF), new CompletionProvider<CompletionParameters>(false) {
|
||||
extend(CompletionType.SMART, psiElement().afterLeaf(PsiKeyword.INSTANCEOF), new CompletionProvider<CompletionParameters>() {
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiType[] leftTypes = InstanceOfLeftPartTypeGetter.getLeftTypes(position);
|
||||
@@ -141,16 +137,17 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
|
||||
processInheritors(parameters, position, position.getContainingFile(), expectedClassTypes, new Consumer<PsiType>() {
|
||||
public void consume(PsiType type) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null) return;
|
||||
JavaInheritorsGetter
|
||||
.processInheritors(parameters, expectedClassTypes, result.getPrefixMatcher(), new Consumer<PsiType>() {
|
||||
public void consume(PsiType type) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null) return;
|
||||
|
||||
if (expectedClassTypes.contains(type)) return;
|
||||
if (expectedClassTypes.contains(type)) return;
|
||||
|
||||
result.addElement(createInstanceofLookupElement(psiClass, parameterizedTypes));
|
||||
}
|
||||
}, result.getPrefixMatcher());
|
||||
result.addElement(createInstanceofLookupElement(psiClass, parameterizedTypes));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -164,7 +161,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
final List<ExpectedTypeInfo> infos = Arrays.asList(getExpectedTypes(parameters));
|
||||
for (final LookupElement item : completeReference(element, reference, filter, true, parameters)) {
|
||||
if (item.getObject() instanceof PsiClass) {
|
||||
result.addElement(decorate(LookupElementDecorator.withInsertHandler((LookupItem)item, ConstructorInsertHandler.INSTANCE), infos));
|
||||
result.addElement(decorate(LookupElementDecorator.withInsertHandler((LookupItem)item, ConstructorInsertHandler.SMART_INSTANCE), infos));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,59 +318,22 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
} else {
|
||||
final List<PsiClassType> typeList = Collections.singletonList((PsiClassType)TypeConversionUtil.typeParameterErasure(targetParameter));
|
||||
processInheritors(parameters, context, parameters.getOriginalFile(), typeList, new Consumer<PsiType>() {
|
||||
public void consume(final PsiType type) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null) return;
|
||||
JavaInheritorsGetter
|
||||
.processInheritors(parameters, typeList, resultSet.getPrefixMatcher(), new Consumer<PsiType>() {
|
||||
public void consume(final PsiType type) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null) return;
|
||||
|
||||
resultSet.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(psiClass), tail));
|
||||
}
|
||||
}, resultSet.getPrefixMatcher());
|
||||
resultSet.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(psiClass), tail));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
extend(CompletionType.SMART, AFTER_NEW, new CompletionProvider<CompletionParameters>(false) {
|
||||
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext matchingContext, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement identifierCopy = parameters.getPosition();
|
||||
final PsiFile file = parameters.getOriginalFile();
|
||||
|
||||
final List<PsiClassType> expectedClassTypes = new SmartList<PsiClassType>();
|
||||
final List<PsiArrayType> expectedArrayTypes = new SmartList<PsiArrayType>();
|
||||
final List<ExpectedTypeInfo> infos = new SmartList<ExpectedTypeInfo>();
|
||||
|
||||
ContainerUtil.addAll(infos, getExpectedTypes(parameters));
|
||||
for (PsiType type : ExpectedTypesGetter.getExpectedTypes(identifierCopy, true)) {
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
if (classType.resolve() != null) {
|
||||
expectedClassTypes.add(classType);
|
||||
}
|
||||
}
|
||||
else if (type instanceof PsiArrayType) {
|
||||
expectedArrayTypes.add((PsiArrayType)type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (final PsiArrayType type : expectedArrayTypes) {
|
||||
final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), identifierCopy);
|
||||
if (item.getObject() instanceof PsiClass) {
|
||||
JavaCompletionUtil.setShowFQN(item);
|
||||
}
|
||||
item.setInsertHandler(new DefaultInsertHandler()); //braces & shortening
|
||||
result.addElement(decorate(item, infos));
|
||||
}
|
||||
|
||||
processInheritors(parameters, identifierCopy, file, expectedClassTypes, new Consumer<PsiType>() {
|
||||
public void consume(final PsiType type) {
|
||||
addExpectedType(result, type, parameters, infos);
|
||||
}
|
||||
}, result.getPrefixMatcher());
|
||||
}
|
||||
});
|
||||
extend(CompletionType.SMART, AFTER_NEW, new JavaInheritorsGetter(ConstructorInsertHandler.SMART_INSTANCE));
|
||||
}
|
||||
|
||||
public static SmartCompletionDecorator decorate(LookupElement lookupElement, Collection<ExpectedTypeInfo> infos) {
|
||||
@@ -438,53 +398,6 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
|
||||
public static void processInheritors(final CompletionParameters parameters, final PsiElement identifierCopy, final PsiFile file, final Collection<PsiClassType> expectedClassTypes,
|
||||
final Consumer<PsiType> consumer, final PrefixMatcher matcher) {
|
||||
//quick
|
||||
for (final PsiClassType type : expectedClassTypes) {
|
||||
consumer.consume(type);
|
||||
|
||||
final PsiClassType.ClassResolveResult baseResult = JavaCompletionUtil.originalize(type).resolveGenerics();
|
||||
final PsiClass baseClass = baseResult.getElement();
|
||||
if (baseClass == null) return;
|
||||
|
||||
final PsiSubstitutor baseSubstitutor = baseResult.getSubstitutor();
|
||||
|
||||
final THashSet<PsiType> statVariants = new THashSet<PsiType>();
|
||||
final Processor<PsiClass> processor = CodeInsightUtil.createInheritorsProcessor(parameters.getPosition(), type, 0, false,
|
||||
statVariants, baseClass, baseSubstitutor);
|
||||
final StatisticsInfo[] statisticsInfos =
|
||||
StatisticsManager.getInstance().getAllValues(JavaStatisticsManager.getAfterNewKey(type));
|
||||
for (final StatisticsInfo statisticsInfo : statisticsInfos) {
|
||||
final String value = statisticsInfo.getValue();
|
||||
if (value.startsWith(JavaStatisticsManager.CLASS_PREFIX)) {
|
||||
final String qname = value.substring(JavaStatisticsManager.CLASS_PREFIX.length());
|
||||
final PsiClass psiClass = JavaPsiFacade.getInstance(file.getProject()).findClass(qname, file.getResolveScope());
|
||||
if (psiClass != null && !PsiTreeUtil.isAncestor(file, psiClass, true) && !processor.process(psiClass)) break;
|
||||
}
|
||||
}
|
||||
|
||||
for (final PsiType variant : statVariants) {
|
||||
consumer.consume(variant);
|
||||
}
|
||||
}
|
||||
|
||||
//long
|
||||
final Condition<String> shortNameCondition = new Condition<String>() {
|
||||
public boolean value(String s) {
|
||||
return matcher.prefixMatches(s);
|
||||
}
|
||||
};
|
||||
for (final PsiClassType type : expectedClassTypes) {
|
||||
final PsiClass psiClass = type.resolve();
|
||||
if (psiClass != null && !psiClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
for (final PsiType psiType : CodeInsightUtil.addSubtypes(type, identifierCopy, false, shortNameCondition)) {
|
||||
consumer.consume(psiType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ExpectedTypeInfo[] getExpectedTypes(final CompletionParameters parameters) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
if (psiElement().withParent(psiElement(PsiReferenceExpression.class).withParent(PsiThrowStatement.class)).accepts(position)) {
|
||||
@@ -508,31 +421,6 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
return ExpectedTypesProvider.getExpectedTypes(expression, true, parameters.getCompletionType() == CompletionType.SMART, false);
|
||||
}
|
||||
|
||||
private static void addExpectedType(final CompletionResultSet result, final PsiType type, final CompletionParameters parameters, Collection<ExpectedTypeInfo> infos) {
|
||||
if (!JavaCompletionUtil.hasAccessibleConstructor(type)) return;
|
||||
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null) return;
|
||||
|
||||
final PsiClass parentClass = psiClass.getContainingClass();
|
||||
if (parentClass != null && !psiClass.hasModifierProperty(PsiModifier.STATIC) &&
|
||||
!PsiTreeUtil.isAncestor(parentClass, parameters.getPosition(), false) &&
|
||||
!(parentClass.getContainingFile().equals(parameters.getOriginalFile()) &&
|
||||
parentClass.getTextRange().contains(parameters.getOffset()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), parameters.getPosition());
|
||||
JavaCompletionUtil.setShowFQN(item);
|
||||
|
||||
if (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
item.setAttribute(LookupItem.INDICATE_ANONYMOUS, "");
|
||||
}
|
||||
|
||||
result.addElement(decorate(type instanceof PsiClassType ? LookupElementDecorator.withInsertHandler(item, ConstructorInsertHandler.INSTANCE) : item, infos));
|
||||
}
|
||||
|
||||
static Set<LookupElement> completeReference(final PsiElement element, PsiReference reference, final ElementFilter filter, final boolean acceptClasses, CompletionParameters parameters) {
|
||||
if (reference instanceof PsiMultiReference) {
|
||||
reference = ContainerUtil.findInstance(((PsiMultiReference) reference).getReferences(), PsiJavaReference.class);
|
||||
@@ -541,7 +429,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
if (reference instanceof PsiJavaReference) {
|
||||
final PsiJavaReference javaReference = (PsiJavaReference)reference;
|
||||
|
||||
return JavaCompletionUtil.processJavaReference(element, javaReference, new ElementFilter() {
|
||||
return JavaCompletionUtil.processJavaReference(element, javaReference, new ElementFilter() {
|
||||
public boolean isAcceptable(Object element, PsiElement context) {
|
||||
return filter.isAcceptable(element, context);
|
||||
}
|
||||
@@ -606,5 +494,4 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
context.setDummyIdentifier("xxx");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-2
@@ -85,8 +85,7 @@ public class ReplaceImplementsWithStaticImportAction extends PsiElementBaseInten
|
||||
return false;
|
||||
}
|
||||
final PsiReferenceList extendsList = targetClass.getExtendsList();
|
||||
LOG.assertTrue(extendsList != null);
|
||||
if (extendsList.getReferencedTypes().length > 0) {
|
||||
if (extendsList != null && extendsList.getReferencedTypes().length > 0) {
|
||||
final List<PsiMethod> methods = new ArrayList<PsiMethod>(Arrays.asList(targetClass.getAllMethods()));
|
||||
final PsiClass objectClass =
|
||||
JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_OBJECT, GlobalSearchScope.allScope(project));
|
||||
|
||||
@@ -21,9 +21,7 @@ import com.intellij.codeInsight.completion.CompletionResultSet;
|
||||
import com.intellij.codeInsight.completion.JavaSmartCompletionParameters;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
@@ -36,10 +34,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class ClassLiteralGetter extends CompletionProvider<JavaSmartCompletionParameters> {
|
||||
private static final Logger LOG = Logger.getInstance("com.intellij.psi.filters.getters.ClassLiteralGetter");
|
||||
|
||||
public ClassLiteralGetter() {
|
||||
super(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addCompletions(@NotNull final JavaSmartCompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
@@ -52,12 +46,7 @@ public class ClassLiteralGetter extends CompletionProvider<JavaSmartCompletionPa
|
||||
}
|
||||
};
|
||||
|
||||
PsiType classParameter = ApplicationManager.getApplication().runReadAction(new Computable<PsiType>() {
|
||||
@Nullable
|
||||
public PsiType compute() {
|
||||
return PsiUtil.substituteTypeParameter(parameters.getExpectedType(), CommonClassNames.JAVA_LANG_CLASS, 0, false);
|
||||
}
|
||||
});
|
||||
PsiType classParameter = PsiUtil.substituteTypeParameter(parameters.getExpectedType(), CommonClassNames.JAVA_LANG_CLASS, 0, false);
|
||||
|
||||
boolean addInheritors = false;
|
||||
if (classParameter instanceof PsiWildcardType) {
|
||||
@@ -80,11 +69,7 @@ public class ClassLiteralGetter extends CompletionProvider<JavaSmartCompletionPa
|
||||
Condition<String> shortNameCondition,
|
||||
final PsiType classParameter,
|
||||
CompletionResultSet result) {
|
||||
final String canonicalText = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
public String compute() {
|
||||
return classParameter.getCanonicalText();
|
||||
}
|
||||
});
|
||||
final String canonicalText = classParameter.getCanonicalText();
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT.equals(canonicalText) && StringUtil.isEmpty(result.getPrefixMatcher().getPrefix())) {
|
||||
return;
|
||||
}
|
||||
@@ -95,22 +80,16 @@ public class ClassLiteralGetter extends CompletionProvider<JavaSmartCompletionPa
|
||||
}
|
||||
|
||||
private static void addClassLiteralLookupElement(@Nullable final PsiType type, final CompletionResultSet resultSet, final PsiElement context) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
if (type instanceof PsiClassType &&
|
||||
type.isValid() &&
|
||||
PsiUtil.resolveClassInType(type) != null &&
|
||||
!((PsiClassType)type).hasParameters() &&
|
||||
!(((PsiClassType)type).resolve() instanceof PsiTypeParameter)) {
|
||||
try {
|
||||
resultSet.addElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(new ClassLiteralLookupElement((PsiClassType)type, context)));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
if (type instanceof PsiClassType &&
|
||||
PsiUtil.resolveClassInType(type) != null &&
|
||||
!((PsiClassType)type).hasParameters() &&
|
||||
!(((PsiClassType)type).resolve() instanceof PsiTypeParameter)) {
|
||||
try {
|
||||
resultSet.addElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(new ClassLiteralLookupElement((PsiClassType)type, context)));
|
||||
}
|
||||
});
|
||||
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,12 +43,13 @@ public class ExpectedTypesGetter implements ContextGetter{
|
||||
}
|
||||
|
||||
public static PsiType[] getExpectedTypes(final PsiElement context, boolean defaultTypes) {
|
||||
ExpectedTypesProvider typesProvider = ExpectedTypesProvider.getInstance(context.getProject());
|
||||
PsiExpression expression = PsiTreeUtil.getContextOfType(context, PsiExpression.class, true);
|
||||
if(expression == null) return PsiType.EMPTY_ARRAY;
|
||||
|
||||
ExpectedTypeInfo[] infos = typesProvider.getExpectedTypes(expression, true);
|
||||
return extractTypes(ExpectedTypesProvider.getExpectedTypes(expression, true), defaultTypes);
|
||||
}
|
||||
|
||||
public static PsiType[] extractTypes(ExpectedTypeInfo[] infos, boolean defaultTypes) {
|
||||
Set<PsiType> result = new THashSet<PsiType>(infos.length);
|
||||
for (ExpectedTypeInfo info : infos) {
|
||||
final PsiType type = info.getType();
|
||||
@@ -60,5 +61,4 @@ public class ExpectedTypesGetter implements ContextGetter{
|
||||
}
|
||||
return result.toArray(new PsiType[result.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,6 +2,6 @@ import pack.WithInnerAClass;
|
||||
|
||||
public class Test1 {
|
||||
public void foo() {
|
||||
new WithInnerAClass()<caret>
|
||||
new WithInnerAClass<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
{
|
||||
Zzoo l = new Zz<caret>
|
||||
}
|
||||
}
|
||||
|
||||
interface Zzoo {
|
||||
void run();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
class Foo {
|
||||
{
|
||||
Zzoo l = new Zzoo() {
|
||||
@Override
|
||||
public void run() {
|
||||
<selection>//To change body of implemented methods use File | Settings | File Templates.</selection>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Zzoo {
|
||||
void run();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import java.util.List;
|
||||
|
||||
class Foo {
|
||||
{
|
||||
List<String> l = new ArraLi<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class Foo {
|
||||
{
|
||||
List<String> l = new ArrayList<String>(<caret>)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class Foo {
|
||||
{
|
||||
Zzoo l = new Zz<caret>
|
||||
}
|
||||
}
|
||||
|
||||
interface Zzoo {
|
||||
void run();
|
||||
|
||||
class Impl implements Zzoo {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class Foo {
|
||||
{
|
||||
Zzoo l = new Zzoo<caret>
|
||||
}
|
||||
}
|
||||
|
||||
interface Zzoo {
|
||||
void run();
|
||||
|
||||
class Impl implements Zzoo {}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
public class JavaClass {
|
||||
<T> T magic() {}
|
||||
|
||||
void foo() {
|
||||
mag<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
public class JavaClass {
|
||||
<T> T magic() {}
|
||||
|
||||
void foo() {
|
||||
magic()<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class Foo {
|
||||
static void foo(f<caret>int a) {}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import static foo.Foo.foo;
|
||||
|
||||
class Bar {{
|
||||
foo();
|
||||
ba<caret>
|
||||
}}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import foo.Foo;
|
||||
import static foo.Foo.foo;
|
||||
|
||||
class Bar {{
|
||||
foo();
|
||||
new Foo().ba<caret>z
|
||||
}}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import foo.Foo;
|
||||
import static foo.Foo.foo;
|
||||
|
||||
class Bar {{
|
||||
foo();
|
||||
new Foo().bar();<caret>
|
||||
}}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import static foo.Foo.bar;
|
||||
import static foo.Foo.foo;
|
||||
|
||||
class Bar {{
|
||||
foo();
|
||||
bar();<caret>
|
||||
}}
|
||||
+48
-97
@@ -106,7 +106,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
myFixture.completeBasic()
|
||||
myFixture.type 'a\n'
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testSimpleVariable() throws Exception { doTest() }
|
||||
@@ -311,7 +311,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
try {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
type('(');
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
finally {
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = old;
|
||||
@@ -336,7 +336,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testExcessSpaceInTypeCast() throws Throwable {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
selectItem(myItems[0]);
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testPackageInAnnoParam() throws Throwable {
|
||||
@@ -359,9 +359,9 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
|
||||
public void testUndoCommonPrefixOnHide() throws Throwable {//actually don't undo
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
LookupManager.getInstance(getProject()).hideActiveLookup();
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testOnlyKeywordsInsideSwitch() throws Throwable {
|
||||
@@ -380,13 +380,13 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testChainedCallOnNextLine() throws Throwable {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
selectItem(myItems[0]);
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testFinishWithDot() throws Throwable {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
type('.');
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testEnclosingThis() throws Throwable { doTest(); }
|
||||
@@ -394,7 +394,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testSeamlessConstant() throws Throwable {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
selectItem(myItems[0]);
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testDefaultAnnoParam() throws Throwable { doTest(); }
|
||||
@@ -403,7 +403,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
type(' ');
|
||||
assertNull(getLookup());
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testNoSpaceInParensWithoutParams() throws Throwable {
|
||||
@@ -430,14 +430,14 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
type('g');
|
||||
complete();
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
assertStringItems("getBar", "getFoo", "getClass");
|
||||
}
|
||||
|
||||
public void testQualifierAsPackage() throws Throwable {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
selectItem(myItems[0]);
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testQualifierAsPackage2() throws Throwable {
|
||||
@@ -459,7 +459,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testMethodReturnTypeNoSpace() throws Throwable {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
selectItem(myItems[0]);
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testEnumWithoutConstants() throws Throwable {
|
||||
@@ -489,13 +489,13 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testFinishClassNameWithDot() throws Throwable {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
type('.');
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testFinishClassNameWithLParen() throws Throwable {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
type('(');
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testSelectNoParameterSignature() throws Throwable {
|
||||
@@ -509,7 +509,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
}
|
||||
}.execute().throwException();
|
||||
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testCompletionInsideClassLiteral() throws Throwable {
|
||||
@@ -520,7 +520,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
getLookup().finishLookup(Lookup.NORMAL_SELECT_CHAR);
|
||||
}
|
||||
}.execute().throwException();
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testSuperInConstructor() throws Throwable {
|
||||
@@ -575,13 +575,27 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
type('~');
|
||||
assertNull(getLookup());
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testAnnotationQualifiedName() throws Throwable {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testClassNameGenerics() throws Throwable {
|
||||
configure()
|
||||
type '\n'
|
||||
checkResult();
|
||||
}
|
||||
|
||||
public void testClassNameAnonymous() throws Throwable {
|
||||
configure()
|
||||
type '\n'
|
||||
checkResult();
|
||||
}
|
||||
|
||||
public void testClassNameWithInner() throws Throwable { doTest() }
|
||||
|
||||
public void testDoubleFalse() throws Throwable {
|
||||
configureByFile(getTestName(false) + ".java");
|
||||
assertStringItems("false", "finalize");
|
||||
@@ -637,7 +651,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
type('a');
|
||||
complete();
|
||||
assertStringItems("fai1", "fai2", "fai3");
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testSuggestInaccessibleOnSecondInvocation() throws Throwable {
|
||||
@@ -646,13 +660,8 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
complete();
|
||||
assertStringItems("_bar", "_goo", "_foo");
|
||||
getLookup().setCurrentItem(getLookup().getItems().get(2));
|
||||
new WriteCommandAction.Simple(getProject(), new PsiFile[0]) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
getLookup().finishLookup(Lookup.NORMAL_SELECT_CHAR);
|
||||
}
|
||||
}.execute().throwException();
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
selectItem(lookup.items[2], Lookup.NORMAL_SELECT_CHAR)
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testNoCommonPrefixInsideIdentifier() throws Throwable {
|
||||
@@ -665,20 +674,17 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testProtectedInaccessibleOnSecondInvocation() throws Throwable {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
myFixture.complete(CompletionType.BASIC, 2);
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testPropertyReferencePrefix() throws Throwable {
|
||||
myFixture.addFileToProject("test.properties", "foo.bar=Foo! Bar!").getVirtualFile();
|
||||
|
||||
configure()
|
||||
checkResultByFile(getTestName(false) + ".java");
|
||||
assertNull(getLookup());
|
||||
doAntiTest()
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
configure()
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult();
|
||||
}
|
||||
|
||||
private void doAntiTest() throws Exception {
|
||||
@@ -693,6 +699,10 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testSpaceAfterReturn() throws Throwable {
|
||||
configure()
|
||||
type '\n'
|
||||
checkResult()
|
||||
}
|
||||
|
||||
private def checkResult() {
|
||||
checkResultByFile(getTestName(false) + "_after.java")
|
||||
}
|
||||
|
||||
@@ -720,13 +730,13 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testSuggestExpectedTypeMembers() throws Throwable {
|
||||
configure()
|
||||
selectItem myItems[0]
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testSuggestExpectedTypeMembersInCall() throws Throwable {
|
||||
configure()
|
||||
selectItem myItems[0]
|
||||
checkResultByFile(getTestName(false) + "_after.java");
|
||||
checkResult();
|
||||
}
|
||||
|
||||
public void testRightShift() throws Throwable {
|
||||
@@ -741,24 +751,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public static void bar() {}
|
||||
}
|
||||
""")
|
||||
myFixture.configureByText("a.java", """
|
||||
import static foo.Foo.foo;
|
||||
|
||||
class Bar {{
|
||||
foo();
|
||||
ba<caret>
|
||||
}}
|
||||
""")
|
||||
complete()
|
||||
myFixture.checkResult """
|
||||
import static foo.Foo.bar;
|
||||
import static foo.Foo.foo;
|
||||
|
||||
class Bar {{
|
||||
foo();
|
||||
bar();<caret>
|
||||
}}
|
||||
"""
|
||||
doTest()
|
||||
}
|
||||
|
||||
public void testSuggestMembersOfStaticallyImportedClassesUnqualifiedOnly() throws Exception {
|
||||
@@ -772,62 +765,20 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public static void bar() {}
|
||||
}
|
||||
""")
|
||||
myFixture.configureByText("a.java", """
|
||||
import foo.Foo;
|
||||
import static foo.Foo.foo;
|
||||
|
||||
class Bar {{
|
||||
foo();
|
||||
new Foo().ba<caret>z
|
||||
}}
|
||||
""")
|
||||
complete()
|
||||
configure()
|
||||
assertOneElement(myFixture.getLookupElements())
|
||||
myFixture.type '\t'
|
||||
myFixture.checkResult """
|
||||
import foo.Foo;
|
||||
import static foo.Foo.foo;
|
||||
|
||||
class Bar {{
|
||||
foo();
|
||||
new Foo().bar();<caret>
|
||||
}}
|
||||
"""
|
||||
checkResult()
|
||||
}
|
||||
finally {
|
||||
CodeInsightSettings.instance.SHOW_STATIC_AFTER_INSTANCE = old
|
||||
}
|
||||
}
|
||||
|
||||
public void testInstanceMagicMethod() throws Exception {
|
||||
myFixture.configureByText("a.java", """
|
||||
public class JavaClass {
|
||||
<T> T magic() {}
|
||||
|
||||
void foo() {
|
||||
mag<caret>
|
||||
}
|
||||
}
|
||||
""")
|
||||
myFixture.completeBasic()
|
||||
myFixture.checkResult """
|
||||
public class JavaClass {
|
||||
<T> T magic() {}
|
||||
|
||||
void foo() {
|
||||
magic()<caret>
|
||||
}
|
||||
}
|
||||
"""
|
||||
}
|
||||
public void testInstanceMagicMethod() throws Exception { doTest() }
|
||||
|
||||
public void testNoMethodsInParameterType() {
|
||||
myFixture.configureByText("a.java", """
|
||||
class Foo {
|
||||
static void foo(f<caret>int a) {}
|
||||
}
|
||||
""")
|
||||
myFixture.completeBasic()
|
||||
configure()
|
||||
assertOrderedEquals myFixture.lookupElementStrings, "final", "float"
|
||||
}
|
||||
|
||||
|
||||
@@ -9,16 +9,25 @@ import junit.framework.TestCase;
|
||||
import org.jdom.Element;
|
||||
|
||||
public class EntryPointsConverterTest extends TestCase {
|
||||
private boolean myUnregisterExtensionPoint = false;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Extensions.getRootArea().registerExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL, EntryPoint.class.getName());
|
||||
try {
|
||||
Extensions.getExtensions(ExtensionPoints.DEAD_CODE_TOOL, null);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
myUnregisterExtensionPoint = true;
|
||||
Extensions.getRootArea().registerExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL, EntryPoint.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
Extensions.getRootArea().unregisterExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
|
||||
if (myUnregisterExtensionPoint) {
|
||||
Extensions.getRootArea().unregisterExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
|
||||
-15
@@ -15,12 +15,6 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -37,13 +31,4 @@ public abstract class AbstractCompletionContributor<Params extends CompletionPar
|
||||
* @see CompletionService#getVariantsFromContributors(com.intellij.openapi.extensions.ExtensionPointName, CompletionParameters, AbstractCompletionContributor , com.intellij.util.Consumer)
|
||||
*/
|
||||
public abstract void fillCompletionVariants(Params parameters, CompletionResultSet result);
|
||||
|
||||
protected static boolean isPatternSuitable(final ElementPattern<? extends PsiElement> pattern, final CompletionParameters parameters,
|
||||
final ProcessingContext context) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
public Boolean compute() {
|
||||
return pattern.accepts(parameters.getPosition(), context);
|
||||
}
|
||||
}).booleanValue();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -152,7 +152,7 @@ public abstract class CompletionContributor extends AbstractCompletionContributo
|
||||
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
|
||||
for (final Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>> pair : myMap.get(parameters.getCompletionType())) {
|
||||
final ProcessingContext context = new ProcessingContext();
|
||||
if (isPatternSuitable(pair.first, parameters, context)) {
|
||||
if (pair.first.accepts(parameters.getPosition(), context)) {
|
||||
pair.second.addCompletionVariants(parameters, context, result);
|
||||
if (result.isStopped()) {
|
||||
return;
|
||||
@@ -161,7 +161,7 @@ public abstract class CompletionContributor extends AbstractCompletionContributo
|
||||
}
|
||||
for (final Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>> pair : myMap.get(null)) {
|
||||
final ProcessingContext context = new ProcessingContext();
|
||||
if (isPatternSuitable(pair.first, parameters, context)) {
|
||||
if (pair.first.accepts(parameters.getPosition(), context)) {
|
||||
pair.second.addCompletionVariants(parameters, context, result);
|
||||
if (result.isStopped()) {
|
||||
return;
|
||||
|
||||
@@ -16,34 +16,23 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class CompletionProvider<V extends CompletionParameters> {
|
||||
private final boolean myStartInReadAction;
|
||||
|
||||
protected CompletionProvider() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected CompletionProvider(final boolean startInReadAction) {
|
||||
myStartInReadAction = startInReadAction;
|
||||
}
|
||||
|
||||
protected abstract void addCompletions(@NotNull V parameters, final ProcessingContext context, @NotNull CompletionResultSet result);
|
||||
|
||||
public final void addCompletionVariants(@NotNull final V parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
if (myStartInReadAction) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
addCompletions(parameters, context, result);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
addCompletions(parameters, context, result);
|
||||
}
|
||||
addCompletions(parameters, context, result);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-1
@@ -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);
|
||||
@@ -542,7 +549,9 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
Document document = fileCopy.getViewProvider().getDocument();
|
||||
assert document != null : "no document";
|
||||
initContext.getFileCopyPatcher().patchFileCopy(fileCopy, document, initContext.getOffsetMap());
|
||||
PsiDocumentManager.getInstance(hostFile.getProject()).commitDocument(document);
|
||||
final Document hostDocument = hostFile.getViewProvider().getDocument();
|
||||
assert hostDocument != null : "no host document";
|
||||
PsiDocumentManager.getInstance(hostFile.getProject()).commitDocument(hostDocument);
|
||||
assert hostFile.isValid() : "file became invalid";
|
||||
assert hostMap.getOffset(CompletionInitializationContext.START_OFFSET) < hostFile.getTextLength() : "startOffset outside the host file";
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@ public class CompletionData {
|
||||
}
|
||||
}
|
||||
|
||||
protected PsiReference[] getReferences(final PsiMultiReference multiReference) {
|
||||
protected static PsiReference[] getReferences(final PsiMultiReference multiReference) {
|
||||
final PsiReference[] references = multiReference.getReferences();
|
||||
final List<PsiReference> hard = ContainerUtil.findAll(references, new Condition<PsiReference>() {
|
||||
public boolean value(final PsiReference object) {
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ public class FilePathCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
});
|
||||
|
||||
extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider<CompletionParameters>(false) {
|
||||
extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
|
||||
+2
-3
@@ -74,7 +74,7 @@ public class LegacyCompletionContributor extends CompletionContributor {
|
||||
final CompletionResultSet result,
|
||||
final CompletionData completionData) {
|
||||
final Ref<Boolean> hasVariants = Ref.create(false);
|
||||
processReferences(parameters, result, completionData, new PairConsumer<PsiReference, CompletionResultSet>() {
|
||||
processReferences(parameters, result, new PairConsumer<PsiReference, CompletionResultSet>() {
|
||||
public void consume(final PsiReference reference, final CompletionResultSet resultSet) {
|
||||
final Set<LookupElement> lookupSet = new LinkedHashSet<LookupElement>();
|
||||
completionData
|
||||
@@ -92,12 +92,11 @@ public class LegacyCompletionContributor extends CompletionContributor {
|
||||
|
||||
public static void processReferences(final CompletionParameters parameters,
|
||||
final CompletionResultSet result,
|
||||
final CompletionData completionData,
|
||||
final PairConsumer<PsiReference, CompletionResultSet> consumer) {
|
||||
final int startOffset = parameters.getOffset();
|
||||
final PsiReference ref = parameters.getPosition().getContainingFile().findReferenceAt(startOffset);
|
||||
if (ref instanceof PsiMultiReference) {
|
||||
for (final PsiReference reference : completionData.getReferences((PsiMultiReference)ref)) {
|
||||
for (final PsiReference reference : CompletionData.getReferences((PsiMultiReference)ref)) {
|
||||
processReference(result, startOffset, consumer, reference);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -36,6 +37,7 @@ import java.util.regex.Pattern;
|
||||
* @author peter
|
||||
*/
|
||||
public class DumpLookupElementWeights extends AnAction implements DumbAware {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.internal.DumpLookupElementWeights");
|
||||
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
|
||||
@@ -80,9 +82,13 @@ public class DumpLookupElementWeights extends AnAction implements DumbAware {
|
||||
for (String s : toExclude) {
|
||||
weight = StringUtil.replace(weight, s, "", false);
|
||||
}
|
||||
System.out.println(item.getLookupString() + weight);
|
||||
final String s = item.getLookupString() + weight;
|
||||
System.out.println(s);
|
||||
LOG.info(s);
|
||||
if (i == count - 1) {
|
||||
System.out.println("------------");
|
||||
final String separator = "------------";
|
||||
System.out.println(separator);
|
||||
LOG.info(separator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -87,7 +87,10 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
|
||||
public void rootsChanged(ModuleRootEvent event) {
|
||||
final FileDocumentManager documentManager = FileDocumentManager.getInstance();
|
||||
for (VirtualFile file : myFileEditorManager.getOpenFiles()) {
|
||||
addDocListener(documentManager.getDocument(file));
|
||||
final Document document = documentManager.getDocument(file);
|
||||
if (document != null) {
|
||||
addDocListener(document);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -101,8 +104,7 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
|
||||
final MyDocumentChangeAdapter adapter = myListenerMap.get(element.getContainingFile());
|
||||
if (adapter != null && adapter.getCurrentInfo() != null) {
|
||||
final LanguageChangeSignatureDetector detector = LanguageChangeSignatureDetectors.INSTANCE.forLanguage(element.getLanguage());
|
||||
LOG.assertTrue(detector != null);
|
||||
return detector.isChangeSignatureAvailable(element, adapter.getCurrentInfo());
|
||||
return detector != null && detector.isChangeSignatureAvailable(element, adapter.getCurrentInfo());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -112,9 +114,8 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
|
||||
final MyDocumentChangeAdapter adapter = myListenerMap.get(element.getContainingFile());
|
||||
if (adapter != null && adapter.getCurrentInfo() != null) {
|
||||
final LanguageChangeSignatureDetector detector = LanguageChangeSignatureDetectors.INSTANCE.forLanguage(element.getLanguage());
|
||||
LOG.assertTrue(detector != null);
|
||||
final ChangeInfo currentInfo = adapter.getCurrentInfo();
|
||||
if (detector.isChangeSignatureAvailable(element, currentInfo)) {
|
||||
if (detector != null && detector.isChangeSignatureAvailable(element, currentInfo)) {
|
||||
return currentInfo instanceof RenameChangeInfo ? ChangeSignatureDetectorAction.NEW_NAME
|
||||
: ChangeSignatureDetectorAction.CHANGE_SIGNATURE;
|
||||
}
|
||||
|
||||
@@ -42,27 +42,28 @@ public final class LoadTextUtil {
|
||||
}
|
||||
|
||||
private static Pair<CharSequence, String> convertLineSeparators(final CharBuffer buffer) {
|
||||
final int LF = 1;
|
||||
final int CR = 2;
|
||||
int line_separator = 0;
|
||||
|
||||
int dst = 0;
|
||||
char prev = ' ';
|
||||
int crCount = 0;
|
||||
int lfCount = 0;
|
||||
int crlfCount = 0;
|
||||
|
||||
final int length = buffer.length();
|
||||
for (int src = 0; src < length; src++) {
|
||||
char c = buffer.charAt(src);
|
||||
switch (c) {
|
||||
case '\r':
|
||||
buffer.put(dst++, '\n');
|
||||
line_separator = CR;
|
||||
crCount++;
|
||||
break;
|
||||
case '\n':
|
||||
if (prev == '\r') {
|
||||
line_separator = CR + LF;
|
||||
crCount--;
|
||||
crlfCount++;
|
||||
}
|
||||
else {
|
||||
buffer.put(dst++, '\n');
|
||||
line_separator = LF;
|
||||
lfCount++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -73,16 +74,14 @@ public final class LoadTextUtil {
|
||||
}
|
||||
|
||||
String detectedLineSeparator = null;
|
||||
switch (line_separator) {
|
||||
case CR:
|
||||
detectedLineSeparator = "\r";
|
||||
break;
|
||||
case LF:
|
||||
detectedLineSeparator = "\n";
|
||||
break;
|
||||
case CR + LF:
|
||||
detectedLineSeparator = "\r\n";
|
||||
break;
|
||||
if (crlfCount > crCount && crlfCount > lfCount) {
|
||||
detectedLineSeparator = "\r\n";
|
||||
}
|
||||
else if (crCount > lfCount) {
|
||||
detectedLineSeparator = "\r";
|
||||
}
|
||||
else if (lfCount > 0) {
|
||||
detectedLineSeparator = "\n";
|
||||
}
|
||||
|
||||
CharSequence result;
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
*/
|
||||
package com.intellij.openapi.project;
|
||||
|
||||
import com.intellij.concurrency.Job;
|
||||
import com.intellij.concurrency.JobScheduler;
|
||||
import com.intellij.ide.caches.CacheUpdater;
|
||||
import com.intellij.ide.caches.FileContent;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationAdapter;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
@@ -35,9 +34,11 @@ import gnu.trove.THashSet;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
class CacheUpdateRunner {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.project.CacheUpdateRunner");
|
||||
private static final int PROC_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
private final Project myProject;
|
||||
private final Collection<CacheUpdater> myUpdaters;
|
||||
private CacheUpdateSession mySession;
|
||||
@@ -135,25 +136,27 @@ class CacheUpdateRunner {
|
||||
final Ref<Boolean> isFinished = new Ref<Boolean>(Boolean.FALSE);
|
||||
try {
|
||||
int threadsCount = Registry.intValue("caches.indexerThreadsCount");
|
||||
if (threadsCount == -1) {
|
||||
threadsCount = Math.min(Runtime.getRuntime().availableProcessors(), ApplicationManager.getApplication().isUnitTestMode() ? 1 : 2);
|
||||
if (threadsCount <= 0) {
|
||||
threadsCount = Math.min(PROC_COUNT, ApplicationManager.getApplication().isUnitTestMode() ? 4 : 2);
|
||||
}
|
||||
if (true) {
|
||||
if (threadsCount == 1) {
|
||||
Runnable process = new MyRunnable(innerIndicator, queue, isFinished, progressUpdater, processInReadAction, application);
|
||||
ProgressManager.getInstance().runProcess(process, innerIndicator);
|
||||
}
|
||||
else {
|
||||
final Job<Object> job = JobScheduler.getInstance().createJob("Indexing", Thread.NORM_PRIORITY);
|
||||
final Ref[] finishedRefs = new Ref[threadsCount];
|
||||
Future<?>[] futures = new Future<?>[threadsCount];
|
||||
for (int i = 0; i < threadsCount; i++) {
|
||||
final Ref<Boolean> ref = new Ref<Boolean>(Boolean.FALSE);
|
||||
finishedRefs[i] = ref;
|
||||
Runnable process = new MyRunnable(innerIndicator, queue, ref, progressUpdater, processInReadAction, application);
|
||||
job.addTask(process);
|
||||
futures[i] = ApplicationManager.getApplication().executeOnPooledThread(getProcessWrapper(process));
|
||||
}
|
||||
try {
|
||||
job.scheduleAndWaitForResults();
|
||||
|
||||
for (Future<?> future : futures) {
|
||||
future.get();
|
||||
}
|
||||
|
||||
boolean allFinished = true;
|
||||
for (Ref ref : finishedRefs) {
|
||||
if (!(Boolean)ref.get()) {
|
||||
@@ -234,4 +237,19 @@ class CacheUpdateRunner {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Runnable getProcessWrapper(final Runnable process) {
|
||||
return ApplicationManager.getApplication().isWriteAccessAllowed() ? new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean old = ApplicationImpl.setExceptionalThreadWithReadAccessFlag(true);
|
||||
try {
|
||||
process.run();
|
||||
}
|
||||
finally {
|
||||
ApplicationImpl.setExceptionalThreadWithReadAccessFlag(old);
|
||||
}
|
||||
}
|
||||
} : process;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.ui;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -167,7 +168,21 @@ abstract public class AbstractExpandableItemsHandler<KeyType, ComponentType exte
|
||||
handleSelectionChange(selected, false);
|
||||
}
|
||||
|
||||
protected void handleSelectionChange(KeyType selected, boolean processIfUnfocused) {
|
||||
private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
|
||||
protected void handleSelectionChange(final KeyType selected, final boolean processIfUnfocused) {
|
||||
if (!ApplicationManager.getApplication().isDispatchThread()) {
|
||||
return;
|
||||
}
|
||||
myUpdateAlarm.cancelAllRequests();
|
||||
myUpdateAlarm.addRequest(new Runnable() {
|
||||
public void run() {
|
||||
doHandleSelectionChange(selected, processIfUnfocused);
|
||||
}
|
||||
}, 150);
|
||||
}
|
||||
|
||||
private void doHandleSelectionChange(KeyType selected, boolean processIfUnfocused) {
|
||||
if (!isEnabled) return;
|
||||
|
||||
if (selected == null || !myComponent.isShowing() || (!myComponent.isFocusOwner() && !processIfUnfocused)) {
|
||||
@@ -193,7 +208,8 @@ abstract public class AbstractExpandableItemsHandler<KeyType, ComponentType exte
|
||||
}
|
||||
}
|
||||
|
||||
protected final void hideHint() {
|
||||
private void hideHint() {
|
||||
myUpdateAlarm.cancelAllRequests();
|
||||
if (myHint != null) {
|
||||
myHint.hide();
|
||||
myHint = null;
|
||||
|
||||
+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>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.util.objectTree;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
@@ -123,6 +124,9 @@ public final class ObjectNode<T> {
|
||||
action.execute(myObject);
|
||||
myTree.fireExecuted(myObject);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw new ProcessCanceledException(e);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ contributor(ctype:hasAnnotation("groovy.lang.Mixin")) {
|
||||
def annotations = psiClass?.getAnnotations("groovy.lang.Mixin")
|
||||
for (a in annotations) {
|
||||
def refs = a.findAttributeValue("value")
|
||||
for (c in refs.asList()) {
|
||||
for (c in refs?.asList()) {
|
||||
delegatesTo c?.bind()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
def ctx = context(scope: scriptScope(), filetypes : ["gant"])
|
||||
def ctx = context(scope: scriptScope(), scripttype : ["gant"])
|
||||
|
||||
contributor ([ctx], {
|
||||
property name:"ant", type:"org.codehaus.gant.GantBuilder"
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
<extensionPoint name="positionManagerDelegate" interface="org.jetbrains.plugins.groovy.extensions.debugger.ScriptPositionManagerHelper"/>
|
||||
<extensionPoint name="compilerExtension" interface="org.jetbrains.plugins.groovy.compiler.GroovyCompilerExtension"/>
|
||||
<extensionPoint name="scriptType" beanClass="org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeEP"/>
|
||||
<extensionPoint name="scriptTypeDetector" interface="org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector"/>
|
||||
|
||||
<extensionPoint name="callExpressionTypeCalculator" interface="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrCallExpressionTypeCalculator"/>
|
||||
|
||||
@@ -62,8 +62,8 @@
|
||||
|
||||
<callExpressionTypeCalculator implementation="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.DefaultCallExpressionTypeCalculator" order="last" />
|
||||
|
||||
<scriptType extensions="gant" descriptorClass="org.jetbrains.plugins.groovy.gant.GantScriptType"/>
|
||||
<scriptType extensions="gradle" descriptorClass="org.jetbrains.plugins.groovy.gradle.GradleScriptType"/>
|
||||
<scriptTypeDetector implementation="org.jetbrains.plugins.groovy.gant.GantScriptTypeDetector" />
|
||||
<scriptTypeDetector implementation="org.jetbrains.plugins.groovy.gradle.GradleScriptTypeDetector"/>
|
||||
|
||||
<!-- GroovyDSL extensions -->
|
||||
<gdslTopLevelProvider implementation="org.jetbrains.plugins.groovy.dsl.dsltop.GroovyDslDefaultMembers"/>
|
||||
|
||||
@@ -20,15 +20,10 @@ import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeConsumer;
|
||||
import com.intellij.openapi.fileTypes.FileTypeFactory;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeEP;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
@@ -45,8 +40,8 @@ public class GroovyFileTypeLoader extends FileTypeFactory{
|
||||
strings.add("gdsl");
|
||||
strings.add("gpp");
|
||||
strings.add("grunit");
|
||||
for (GroovyScriptTypeEP ep : GroovyScriptType.EP_NAME.getExtensions()) {
|
||||
ContainerUtil.addAll(strings, ep.extensions.split(";"));
|
||||
for (GroovyScriptTypeDetector ep : GroovyScriptTypeDetector.EP_NAME.getExtensions()) {
|
||||
Collections.addAll(strings, ep.getExtensions());
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
|
||||
@@ -43,7 +43,7 @@ public class GroovyIconProvider extends IconProvider implements DumbAware {
|
||||
return GroovyIcons.GROOVY_ICON_16x16;
|
||||
}
|
||||
|
||||
return GroovyScriptType.getScriptType(file).getScriptIcon();
|
||||
return GroovyScriptTypeDetector.getScriptType(file).getScriptIcon();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -72,6 +72,7 @@ import org.jetbrains.groovy.compiler.rt.GroovycRunner;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
import org.jetbrains.plugins.groovy.util.GroovyUtils;
|
||||
@@ -412,7 +413,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler {
|
||||
public Boolean compute() {
|
||||
PsiFile psiFile = manager.findFile(file);
|
||||
if (psiFile instanceof GroovyFile && ((GroovyFile)psiFile).isScript()) {
|
||||
final GroovyScriptType scriptType = GroovyScriptType.getScriptType((GroovyFile)psiFile);
|
||||
final GroovyScriptType scriptType = GroovyScriptTypeDetector.getScriptType((GroovyFile)psiFile);
|
||||
return scriptType.shouldBeCompiled((GroovyFile)psiFile);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -5,8 +5,12 @@ import com.intellij.patterns.ElementPattern
|
||||
import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.Scope
|
||||
import static com.intellij.patterns.PlatformPatterns.psiFile
|
||||
import static com.intellij.patterns.PlatformPatterns.virtualFile
|
||||
import org.jetbrains.plugins.groovy.dsl.GroovyClassDescriptor
|
||||
import com.intellij.util.ProcessingContext
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector
|
||||
|
||||
/**
|
||||
/**
|
||||
* @author ilyas
|
||||
*/
|
||||
class Context {
|
||||
@@ -24,6 +28,21 @@ class Context {
|
||||
addFilter new FileContextFilter(psiFile().withVirtualFile(vfilePattern))
|
||||
}
|
||||
|
||||
List<String> scripttype = args.scripttype
|
||||
if (scripttype) {
|
||||
addFilter(new ContextFilter() {
|
||||
@Override
|
||||
boolean isApplicable(GroovyClassDescriptor descriptor, ProcessingContext ctx) {
|
||||
def file = descriptor.placeFile
|
||||
if (file instanceof GroovyFile && ((GroovyFile)file).isScript()) {
|
||||
def scripTypeId = GroovyScriptTypeDetector.getScriptType((GroovyFile)file).getId()
|
||||
return scripttype.contains(scripTypeId)
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// filter by scope first, then by ctype
|
||||
// scope: <scope>
|
||||
if (args.scope) {
|
||||
|
||||
@@ -16,13 +16,10 @@
|
||||
package org.jetbrains.plugins.groovy.extensions;
|
||||
|
||||
import com.intellij.execution.Location;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyIcons;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.runner.DefaultGroovyScriptRunner;
|
||||
import org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfiguration;
|
||||
import org.jetbrains.plugins.groovy.runner.GroovyScriptRunner;
|
||||
|
||||
@@ -34,44 +31,17 @@ import java.util.List;
|
||||
* @author ilyas
|
||||
*/
|
||||
public abstract class GroovyScriptType {
|
||||
public static final ExtensionPointName<GroovyScriptTypeEP> EP_NAME = ExtensionPointName.create("org.intellij.groovy.scriptType");
|
||||
public static final GroovyScriptType DEFAULT_TYPE = new GroovyScriptType() {
|
||||
@Override
|
||||
public boolean isSpecificScriptFile(GroovyFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldBeCompiled(GroovyFile script) {
|
||||
return true;
|
||||
}
|
||||
private final String id;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Icon getScriptIcon() {
|
||||
return GroovyIcons.GROOVY_ICON_16x16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroovyScriptRunner getRunner() {
|
||||
return new DefaultGroovyScriptRunner();
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static GroovyScriptType getScriptType(@NotNull GroovyFile script) {
|
||||
assert script.isScript();
|
||||
for (final GroovyScriptTypeEP typeEP : EP_NAME.getExtensions()) {
|
||||
final GroovyScriptType descriptor = typeEP.getTypeDescriptor();
|
||||
if (descriptor.isSpecificScriptFile(script)) {
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
return DEFAULT_TYPE;
|
||||
protected GroovyScriptType(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
public abstract boolean isSpecificScriptFile(GroovyFile file);
|
||||
@NotNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract Icon getScriptIcon();
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 org.jetbrains.plugins.groovy.extensions;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.GroovyIcons;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.runner.DefaultGroovyScriptRunner;
|
||||
import org.jetbrains.plugins.groovy.runner.GroovyScriptRunner;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author sergey.evdokimov
|
||||
*/
|
||||
public abstract class GroovyScriptTypeDetector {
|
||||
|
||||
public static final ExtensionPointName<GroovyScriptTypeDetector> EP_NAME = ExtensionPointName.create("org.intellij.groovy.scriptTypeDetector");
|
||||
|
||||
private final GroovyScriptType myScriptType;
|
||||
|
||||
private final String[] myExtensions;
|
||||
|
||||
protected GroovyScriptTypeDetector(GroovyScriptType scriptType, String ... extensions) {
|
||||
myScriptType = scriptType;
|
||||
myExtensions = extensions;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final String[] getExtensions() {
|
||||
return myExtensions;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final GroovyScriptType getScriptType() {
|
||||
return myScriptType;
|
||||
}
|
||||
|
||||
public abstract boolean isSpecificScriptFile(@NotNull GroovyFile script);
|
||||
|
||||
@NotNull
|
||||
public static GroovyScriptType getScriptType(@NotNull GroovyFile script) {
|
||||
assert script.isScript();
|
||||
for (GroovyScriptTypeDetector detector : EP_NAME.getExtensions()) {
|
||||
if (detector.isSpecificScriptFile(script)) {
|
||||
return detector.getScriptType();
|
||||
}
|
||||
}
|
||||
|
||||
return DEFAULT_TYPE;
|
||||
}
|
||||
|
||||
public static boolean isSpecificScriptFile(@NotNull PsiFile file, GroovyScriptType scriptType) {
|
||||
if (!(file instanceof GroovyFile)) return false;
|
||||
if (!((GroovyFile)file).isScript()) return false;
|
||||
return isSpecificScriptFile((GroovyFile)file, scriptType);
|
||||
}
|
||||
|
||||
public static boolean isSpecificScriptFile(@NotNull GroovyFile script, GroovyScriptType scriptType) {
|
||||
assert script.isScript();
|
||||
if (scriptType == DEFAULT_TYPE) {
|
||||
return getScriptType(script) == DEFAULT_TYPE;
|
||||
}
|
||||
|
||||
for (GroovyScriptTypeDetector detector : EP_NAME.getExtensions()) {
|
||||
if (detector.getScriptType() == scriptType) {
|
||||
if (detector.isSpecificScriptFile(script)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final GroovyScriptType DEFAULT_TYPE = new GroovyScriptType("default") {
|
||||
@Override
|
||||
public boolean shouldBeCompiled(GroovyFile script) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Icon getScriptIcon() {
|
||||
return GroovyIcons.GROOVY_ICON_16x16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroovyScriptRunner getRunner() {
|
||||
return new DefaultGroovyScriptRunner();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.extensions;
|
||||
|
||||
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
|
||||
import com.intellij.openapi.util.AtomicNotNullLazyValue;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class GroovyScriptTypeEP extends AbstractExtensionPointBean {
|
||||
|
||||
@Attribute("extensions")
|
||||
public String extensions;
|
||||
|
||||
@Attribute("descriptorClass")
|
||||
public String descriptorClass;
|
||||
|
||||
private final AtomicNotNullLazyValue<GroovyScriptType> myInstance = new AtomicNotNullLazyValue<GroovyScriptType>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected GroovyScriptType compute() {
|
||||
try {
|
||||
return instantiate(descriptorClass, ApplicationManager.getApplication().getPicoContainer());
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public GroovyScriptType getTypeDescriptor() {
|
||||
return myInstance.getValue();
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.lang.UrlClassLoader;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
|
||||
@@ -103,7 +103,7 @@ public class AntTasksProvider {
|
||||
ContainerUtil.addAll(jars, OrderEnumerator.orderEntries(module).getAllLibrariesAndSdkClassesRoots());
|
||||
}
|
||||
|
||||
if (groovyFile.isScript() && GroovyScriptType.getScriptType(groovyFile) instanceof GantScriptType) {
|
||||
if (groovyFile.isScript() && GroovyScriptTypeDetector.getScriptType(groovyFile) instanceof GantScriptType) {
|
||||
jars.addAll(GantScriptType.additionalScopeFiles(groovyFile));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
|
||||
@@ -79,7 +80,7 @@ public class GantMemberContributor extends NonCodeMembersContributor {
|
||||
// ------- gant-specific
|
||||
|
||||
PsiFile file = place.getContainingFile();
|
||||
if (!GantUtils.isGantScriptFile(file)) {
|
||||
if (file == null || !GroovyScriptTypeDetector.isSpecificScriptFile(file, GantScriptType.INSTANCE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+16
-1
@@ -23,6 +23,7 @@ import com.intellij.psi.search.FilenameIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.extensions.debugger.ScriptPositionManagerHelper;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
|
||||
@@ -36,7 +37,7 @@ public class GantPositionManagerHelper extends ScriptPositionManagerHelper {
|
||||
}
|
||||
|
||||
public boolean isAppropriateScriptFile(@NotNull final PsiFile scriptFile) {
|
||||
return GantUtils.isGantScriptFile(scriptFile);
|
||||
return GroovyScriptTypeDetector.isSpecificScriptFile(scriptFile, GantScriptType.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -49,6 +50,20 @@ public class GantPositionManagerHelper extends ScriptPositionManagerHelper {
|
||||
PsiFile[] files = FilenameIndex.getFilesByName(project, runtimeName + "." + GantScriptType.DEFAULT_EXTENSION,
|
||||
GlobalSearchScope.allScope(project));
|
||||
if (files.length == 1) return files[0];
|
||||
|
||||
if (files.length == 0) {
|
||||
files = FilenameIndex.getFilesByName(project, runtimeName + ".groovy", GlobalSearchScope.allScope(project));
|
||||
|
||||
PsiFile candidate = null;
|
||||
for (PsiFile file : files) {
|
||||
if (GroovyScriptTypeDetector.isSpecificScriptFile(file, GantScriptType.INSTANCE)) {
|
||||
if (candidate != null) return null;
|
||||
candidate = file;
|
||||
}
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
catch (ProcessCanceledException ignored) {
|
||||
}
|
||||
|
||||
@@ -47,8 +47,10 @@ import java.util.List;
|
||||
public class GantScriptType extends GroovyScriptType {
|
||||
@NonNls public static final String DEFAULT_EXTENSION = "gant";
|
||||
|
||||
public boolean isSpecificScriptFile(final GroovyFile file) {
|
||||
return GantUtils.isGantScriptFile(file);
|
||||
public static final GroovyScriptType INSTANCE = new GantScriptType();
|
||||
|
||||
private GantScriptType() {
|
||||
super("gant");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 org.jetbrains.plugins.groovy.gant;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
|
||||
/**
|
||||
* @author sergey.evdokimov
|
||||
*/
|
||||
public class GantScriptTypeDetector extends GroovyScriptTypeDetector {
|
||||
public GantScriptTypeDetector() {
|
||||
super(GantScriptType.INSTANCE, "gant");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpecificScriptFile(@NotNull GroovyFile script) {
|
||||
String name = script.getName();
|
||||
return name.endsWith(GantScriptType.DEFAULT_EXTENSION);
|
||||
}
|
||||
}
|
||||
@@ -49,16 +49,6 @@ public class GantUtils {
|
||||
private GantUtils() {
|
||||
}
|
||||
|
||||
public static boolean isGantScriptFile(PsiFile file) {
|
||||
if (file instanceof GroovyFile) {
|
||||
GroovyFile groovyFile = (GroovyFile)file;
|
||||
if (!groovyFile.isScript()) return false;
|
||||
String name = file.getName();
|
||||
return name.endsWith(GantScriptType.DEFAULT_EXTENSION);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static GrArgumentLabel[] getScriptTargets(GroovyFile file) {
|
||||
ArrayList<GrArgumentLabel> labels = new ArrayList<GrArgumentLabel>();
|
||||
for (PsiElement child : file.getChildren()) {
|
||||
|
||||
@@ -37,7 +37,7 @@ import com.sun.jdi.AbsentInformationException;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.extensions.debugger.ScriptPositionManagerHelper;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
|
||||
@@ -61,7 +61,7 @@ public class GradlePositionManager extends ScriptPositionManagerHelper {
|
||||
}
|
||||
|
||||
public boolean isAppropriateScriptFile(@NotNull final PsiFile scriptFile) {
|
||||
return GroovyScriptType.getScriptType((GroovyFile)scriptFile) instanceof GradleScriptType;
|
||||
return GroovyScriptTypeDetector.isSpecificScriptFile((GroovyFile)scriptFile, GradleScriptType.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -177,4 +177,4 @@ public class GradlePositionManager extends ScriptPositionManagerHelper {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.NonClasspathDirectoryScope;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
|
||||
@@ -64,12 +63,13 @@ import java.util.regex.Pattern;
|
||||
* @author peter
|
||||
*/
|
||||
public class GradleScriptType extends GroovyScriptType {
|
||||
@NonNls private static final String GRADLE_EXTENSION = "gradle";
|
||||
|
||||
private static final Pattern MAIN_CLASS_NAME_PATTERN = Pattern.compile("\nSTARTER_MAIN_CLASS=(.*)\n");
|
||||
|
||||
@Override
|
||||
public boolean isSpecificScriptFile(GroovyFile file) {
|
||||
return GRADLE_EXTENSION.equals(file.getViewProvider().getVirtualFile().getExtension());
|
||||
public static final GroovyScriptType INSTANCE = new GradleScriptType();
|
||||
|
||||
private GradleScriptType() {
|
||||
super("gradle");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 org.jetbrains.plugins.groovy.gradle;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author sergey.evdokimov
|
||||
*/
|
||||
public class GradleScriptTypeDetector extends GroovyScriptTypeDetector {
|
||||
|
||||
@NonNls private static final String GRADLE_EXTENSION = "gradle";
|
||||
|
||||
public GradleScriptTypeDetector() {
|
||||
super(GradleScriptType.INSTANCE, GRADLE_EXTENSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpecificScriptFile(@NotNull GroovyFile script) {
|
||||
return GRADLE_EXTENSION.equals(script.getViewProvider().getVirtualFile().getExtension());
|
||||
}
|
||||
}
|
||||
+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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+120
-179
@@ -19,8 +19,6 @@ import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
@@ -30,19 +28,15 @@ import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
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.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.GroovyBundle;
|
||||
import org.jetbrains.plugins.groovy.GroovyIcons;
|
||||
import org.jetbrains.plugins.groovy.lang.completion.handlers.AfterNewClassInsertHandler;
|
||||
import org.jetbrains.plugins.groovy.lang.completion.handlers.ArrayInsertHandler;
|
||||
import org.jetbrains.plugins.groovy.lang.completion.handlers.NamedArgumentInsertHandler;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
|
||||
@@ -70,6 +64,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatem
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.CompletionProcessor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
|
||||
@@ -89,10 +84,6 @@ import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.skipWhitespaces
|
||||
*/
|
||||
public class GroovyCompletionContributor extends CompletionContributor {
|
||||
|
||||
private static final ElementPattern<PsiElement> AFTER_NEW =
|
||||
psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW).andNot(psiElement().afterLeaf(psiElement().withText(PsiKeyword.THROW))))
|
||||
.withSuperParent(3, GrVariable.class);
|
||||
|
||||
private static final ElementPattern<PsiElement> AFTER_DOT = psiElement().afterLeaf(".").withParent(GrReferenceExpression.class);
|
||||
|
||||
private static final String[] MODIFIERS =
|
||||
@@ -156,7 +147,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
|
||||
final GrCall call = (GrCall)argumentList.getParent();
|
||||
List<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>();
|
||||
//costructor call
|
||||
//constructor call
|
||||
if (call instanceof GrConstructorCall) {
|
||||
GrConstructorCall constructorCall = (GrConstructorCall)call;
|
||||
ContainerUtil.addAll(results, constructorCall.multiResolveConstructor());
|
||||
@@ -209,135 +200,31 @@ 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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
extend(CompletionType.SMART, AFTER_NEW, new CompletionProvider<CompletionParameters>(false) {
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters,
|
||||
final ProcessingContext matchingContext,
|
||||
@NotNull final CompletionResultSet result) {
|
||||
final PsiElement identifierCopy = parameters.getPosition();
|
||||
final PsiFile file = parameters.getOriginalFile();
|
||||
|
||||
final List<PsiClassType> expectedClassTypes = new SmartList<PsiClassType>();
|
||||
final List<PsiArrayType> expectedArrayTypes = new ArrayList<PsiArrayType>();
|
||||
|
||||
PsiType psiType = ((GrVariable)identifierCopy.getParent().getParent().getParent()).getTypeGroovy();
|
||||
if (psiType instanceof PsiClassType) {
|
||||
PsiType type = JavaCompletionUtil.eliminateWildcards(JavaCompletionUtil.originalize(psiType));
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
if (classType.resolve() != null) {
|
||||
expectedClassTypes.add(classType);
|
||||
}
|
||||
}
|
||||
else if (psiType instanceof PsiArrayType) {
|
||||
expectedArrayTypes.add((PsiArrayType)psiType);
|
||||
}
|
||||
|
||||
for (final PsiArrayType type : expectedArrayTypes) {
|
||||
final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), identifierCopy);
|
||||
if (item.getObject() instanceof PsiClass) {
|
||||
JavaCompletionUtil.setShowFQN(item);
|
||||
}
|
||||
item.setInsertHandler(new ArrayInsertHandler());
|
||||
result.addElement(item);
|
||||
}
|
||||
|
||||
JavaSmartCompletionContributor.processInheritors(parameters, identifierCopy, file, expectedClassTypes, new Consumer<PsiType>() {
|
||||
public void consume(final PsiType type) {
|
||||
addExpectedType(result, type, identifierCopy);
|
||||
}
|
||||
}, result.getPrefixMatcher());
|
||||
}
|
||||
});
|
||||
|
||||
//provide 'this' and 'super' completions in ClassName.<caret>
|
||||
extend(CompletionType.BASIC, AFTER_DOT, new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
@@ -354,7 +241,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
GrReferenceExpression referenceExpression = (GrReferenceExpression)qualifier;
|
||||
final PsiElement resolved = referenceExpression.resolve();
|
||||
if (!(resolved instanceof PsiClass)) return;
|
||||
if (!org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, position, false)) return;
|
||||
if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, position, false)) return;
|
||||
|
||||
for (String keyword : THIS_SUPER) {
|
||||
result.addElement(LookupElementBuilder.create(keyword));
|
||||
@@ -414,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() {
|
||||
@@ -495,7 +458,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
Map<String, PsiMethod> writableProperties = new HashMap<String, PsiMethod>();
|
||||
for (PsiMethod method : containingClass.getAllMethods()) {
|
||||
if (GroovyPropertyUtils.isSimplePropertySetter(method)) {
|
||||
if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isStaticsOK(method, call)) {
|
||||
if (PsiUtil.isStaticsOK(method, call)) {
|
||||
final String name = GroovyPropertyUtils.getPropertyNameBySetter(method);
|
||||
if (name != null && !writableProperties.containsKey(name)) {
|
||||
writableProperties.put(name, method);
|
||||
@@ -539,28 +502,6 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static boolean checkForInnerClass(PsiClass psiClass, PsiElement identifierCopy) {
|
||||
return !PsiUtil.isInnerClass(psiClass) ||
|
||||
org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil
|
||||
.hasEnclosingInstanceInScope(psiClass.getContainingClass(), identifierCopy, true);
|
||||
}
|
||||
|
||||
private static void addExpectedType(final CompletionResultSet result, final PsiType type, final PsiElement place) {
|
||||
if (!JavaCompletionUtil.hasAccessibleConstructor(type)) return;
|
||||
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null) return;
|
||||
|
||||
if (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) return;
|
||||
if (!checkForInnerClass(psiClass, place)) return;
|
||||
|
||||
final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), place);
|
||||
JavaCompletionUtil.setShowFQN(item);
|
||||
item.setInsertHandler(new AfterNewClassInsertHandler((PsiClassType)type, place));
|
||||
result.addElement(item);
|
||||
}
|
||||
|
||||
public void beforeCompletion(@NotNull final CompletionInitializationContext context) {
|
||||
if (context.getCompletionType() == CompletionType.BASIC && context.getFile() instanceof GroovyFile) {
|
||||
if (semicolonNeeded(context)) {
|
||||
|
||||
+88
-4
@@ -26,20 +26,20 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.SmartList;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.completion.handlers.AfterNewClassInsertHandler;
|
||||
import org.jetbrains.plugins.groovy.lang.completion.handlers.ArrayInsertHandler;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
@@ -53,6 +53,7 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
@@ -69,6 +70,8 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
|
||||
GrAssignmentExpression.class),
|
||||
psiElement(
|
||||
GrVariable.class))));
|
||||
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>() {
|
||||
public int computeHashCode(final TypeConstraint object) {
|
||||
@@ -183,8 +186,89 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
extend(CompletionType.SMART, AFTER_NEW, new CompletionProvider<CompletionParameters>() {
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters,
|
||||
final ProcessingContext matchingContext,
|
||||
@NotNull final CompletionResultSet result) {
|
||||
generateInheritorVariants(parameters, result.getPrefixMatcher(), new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement lookupElement) {
|
||||
result.addElement(lookupElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@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 null;
|
||||
|
||||
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, true));
|
||||
return item;
|
||||
}
|
||||
|
||||
private static boolean checkForInnerClass(PsiClass psiClass, PsiElement identifierCopy) {
|
||||
return !com.intellij.psi.util.PsiUtil.isInnerClass(psiClass) ||
|
||||
PsiUtil.hasEnclosingInstanceInScope(psiClass.getContainingClass(), identifierCopy, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void beforeCompletion(@NotNull CompletionInitializationContext context) {
|
||||
if (context.getCompletionType() != CompletionType.SMART) return;
|
||||
|
||||
+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);
|
||||
}
|
||||
|
||||
+1
-10
@@ -169,16 +169,7 @@ public class GroovyFoldingBuilder implements FoldingBuilder, GroovyElementTypes,
|
||||
}
|
||||
|
||||
private static boolean isWellEndedComment(PsiElement element) {
|
||||
if (element instanceof PsiComment) {
|
||||
PsiComment comment = (PsiComment)element;
|
||||
ASTNode node = comment.getNode();
|
||||
if (node != null &&
|
||||
node.getElementType() == mML_COMMENT &&
|
||||
node.getText().endsWith("*/")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return element.getText().endsWith("*/");
|
||||
}
|
||||
|
||||
private static boolean isWellEndedString(PsiElement element) {
|
||||
|
||||
@@ -42,7 +42,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.GroovyIcons;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
@@ -202,7 +202,7 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile {
|
||||
result.add(getPackageName());
|
||||
ContainerUtil.addAll(result, IMPLICITLY_IMPORTED_PACKAGES);
|
||||
if (isScript()) {
|
||||
result.addAll(GroovyScriptType.getScriptType(this).appendImplicitImports(this));
|
||||
result.addAll(GroovyScriptTypeDetector.getScriptType(this).appendImplicitImports(this));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -247,7 +247,7 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile {
|
||||
|
||||
@Nullable
|
||||
public Icon getIcon(int flags) {
|
||||
final Icon baseIcon = isScript() ? GroovyScriptType.getScriptType(this).getScriptIcon() : GroovyIcons.GROOVY_ICON_16x16;
|
||||
final Icon baseIcon = isScript() ? GroovyScriptTypeDetector.getScriptType(this).getScriptIcon() : GroovyIcons.GROOVY_ICON_16x16;
|
||||
return ElementBase.createLayeredIcon(baseIcon, ElementBase.transformFlags(this, flags));
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile {
|
||||
protected CachedValue<GlobalSearchScope> compute(final GroovyFile file, final GlobalSearchScope baseScope) {
|
||||
return CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider<GlobalSearchScope>() {
|
||||
public Result<GlobalSearchScope> compute() {
|
||||
GlobalSearchScope scope = GroovyScriptType.getScriptType(file).patchResolveScope(file, baseScope);
|
||||
GlobalSearchScope scope = GroovyScriptTypeDetector.getScriptType(file).patchResolveScope(file, baseScope);
|
||||
return Result.create(scope, file, ProjectRootManager.getInstance(file.getProject()));
|
||||
}
|
||||
}, false);
|
||||
|
||||
+6
-4
@@ -440,7 +440,7 @@ public class GrClosureSignatureUtil {
|
||||
@NotNull GrClosableBlock[] closureArguments, final boolean partial) {
|
||||
List<InnerArg> innerArgs = new ArrayList<InnerArg>();
|
||||
|
||||
boolean hasNamedArgs = namedArgs != null && namedArgs.length > 0;
|
||||
boolean hasNamedArgs = namedArgs.length > 0;
|
||||
GrClosureParameter[] params = signature.getParameters();
|
||||
|
||||
if (hasNamedArgs) {
|
||||
@@ -454,10 +454,12 @@ public class GrClosureSignatureUtil {
|
||||
}
|
||||
}
|
||||
|
||||
if (expressionArgs != null) {
|
||||
for (GrExpression expression : expressionArgs) {
|
||||
innerArgs.add(new InnerArg(expression.getType(), expression));
|
||||
for (GrExpression expression : expressionArgs) {
|
||||
PsiType type = expression.getType();
|
||||
if (expression instanceof GrNewExpression && com.intellij.psi.util.PsiUtil.resolveClassInType(type) == null) {
|
||||
type = null;
|
||||
}
|
||||
innerArgs.add(new InnerArg(type, expression));
|
||||
}
|
||||
|
||||
for (GrClosableBlock closureArgument : closureArguments) {
|
||||
|
||||
+17
-5
@@ -21,12 +21,12 @@ import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.ui.ConflictsDialog;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
@@ -37,6 +37,10 @@ import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceDialog;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceSettings;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
*/
|
||||
@@ -59,7 +63,7 @@ public class GroovyVariableValidator implements GroovyIntroduceVariableBase.Vali
|
||||
}
|
||||
|
||||
private MultiMap<PsiElement, String> isOKImpl(String varName, boolean replaceAllOccurrences) {
|
||||
GrExpression firstOccurence = null;
|
||||
GrExpression firstOccurence;
|
||||
if (replaceAllOccurrences) {
|
||||
GroovyRefactoringUtil.sortOccurrences(myContext.occurrences);
|
||||
firstOccurence = ((GrExpression)myContext.occurrences[0]);
|
||||
@@ -81,7 +85,15 @@ public class GroovyVariableValidator implements GroovyIntroduceVariableBase.Vali
|
||||
public String isOKTest(String varName, boolean allOccurences) {
|
||||
MultiMap<PsiElement, String> list = isOKImpl(varName, allOccurences);
|
||||
String result = "";
|
||||
for (String s : list.values()) {
|
||||
final String[] strings = ArrayUtil.toStringArray((Collection<String>)list.values());
|
||||
Arrays.sort(strings, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return o1.compareTo(o2);
|
||||
}
|
||||
});
|
||||
|
||||
for (String s : strings) {
|
||||
result = result + s.replaceAll("<b><code>", "").replaceAll("</code></b>", "") + "\n";
|
||||
}
|
||||
if (list.size() > 0) {
|
||||
@@ -170,11 +182,11 @@ public class GroovyVariableValidator implements GroovyIntroduceVariableBase.Vali
|
||||
*/
|
||||
public String validateName(String name, boolean increaseNumber) {
|
||||
String result = name;
|
||||
if (!isOKTest(name, true).equals("ok") && !increaseNumber || name.length() == 0) {
|
||||
if (isOKImpl(name, true).size() > 0 && !increaseNumber || name.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
int i = 1;
|
||||
while (!isOKTest(result, true).equals("ok")) {
|
||||
while (isOKImpl(result, true).size() > 0) {
|
||||
result = name + i;
|
||||
i++;
|
||||
}
|
||||
|
||||
+3
-2
@@ -34,6 +34,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.util.LibrariesUtil;
|
||||
|
||||
@@ -91,8 +92,8 @@ public class RenameJavaFileToGroovyFileAction extends AnAction implements DumbAw
|
||||
final Language language = file.getLanguage();
|
||||
if (language == GroovyFileType.GROOVY_LANGUAGE) {
|
||||
if (((GroovyFile)file).isScript()) {
|
||||
final GroovyScriptType type = GroovyScriptType.getScriptType((GroovyFile)file);
|
||||
if (type != GroovyScriptType.DEFAULT_TYPE) {
|
||||
final GroovyScriptType type = GroovyScriptTypeDetector.getScriptType((GroovyFile)file);
|
||||
if (type != GroovyScriptTypeDetector.DEFAULT_TYPE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyBundle;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
|
||||
@@ -128,7 +128,7 @@ public class GroovyScriptRunConfiguration extends ModuleBasedConfiguration<RunCo
|
||||
return new DefaultGroovyScriptRunner();
|
||||
}
|
||||
|
||||
return GroovyScriptType.getScriptType((GroovyFile)psiFile).getRunner();
|
||||
return GroovyScriptTypeDetector.getScriptType((GroovyFile)psiFile).getRunner();
|
||||
}
|
||||
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
|
||||
+3
-3
@@ -31,7 +31,7 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
@@ -123,7 +123,7 @@ public class GroovyScriptRunConfigurationProducer extends RuntimeConfigurationPr
|
||||
final RunnerAndConfigurationSettings settings = createConfiguration(scriptClass);
|
||||
if (settings != null) {
|
||||
final GroovyScriptRunConfiguration configuration = (GroovyScriptRunConfiguration)settings.getConfiguration();
|
||||
GroovyScriptType.getScriptType(groovyFile).tuneConfiguration(groovyFile, configuration, location);
|
||||
GroovyScriptTypeDetector.getScriptType(groovyFile).tuneConfiguration(groovyFile, configuration, location);
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
@@ -157,7 +157,7 @@ public class GroovyScriptRunConfigurationProducer extends RuntimeConfigurationPr
|
||||
if (file instanceof GroovyFile) {
|
||||
final VirtualFile vfile = file.getVirtualFile();
|
||||
if (vfile != null && FileUtil.toSystemIndependentName(path).equals(vfile.getPath())) {
|
||||
if (GroovyScriptType.getScriptType((GroovyFile)file).isConfigurationByLocation(existing, location)) {
|
||||
if (GroovyScriptTypeDetector.getScriptType((GroovyFile)file).isConfigurationByLocation(existing, location)) {
|
||||
return existingConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy
|
||||
package org.jetbrains.plugins.groovy.completion
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ContentEntry
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy;
|
||||
package org.jetbrains.plugins.groovy.completion;
|
||||
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings
|
||||
+23
-70
@@ -14,15 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.groovy;
|
||||
package org.jetbrains.plugins.groovy.completion;
|
||||
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.plugins.groovy.util.TestUtils
|
||||
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
*/
|
||||
@@ -38,36 +39,6 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase {
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.groovy");
|
||||
}
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclaration() throws Throwable {
|
||||
myFixture.configureByFile(getTestName(false) + ".groovy");
|
||||
myFixture.complete(CompletionType.SMART);
|
||||
assertOrderedEquals(myFixture.getLookupElementStrings(), "Bar", "Foo");
|
||||
}
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithInterface() throws Throwable {
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
public void testCaretAfterSmartCompletionAfterNewInDeclaration() throws Throwable {
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithAbstractClass() throws Throwable {
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithArray() throws Throwable {
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithIntArray() throws Throwable {
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
public void testShortenNamesInSmartCompletionAfterNewInDeclaration() throws Throwable {
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
public void testNamedParametersForApplication() throws Throwable {
|
||||
doVariantableTest("abx", "aby");
|
||||
}
|
||||
@@ -149,11 +120,6 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase {
|
||||
myFixture.testCompletionVariants(getTestName(false) + ".groovy", "Inner1", "Inner2");
|
||||
}
|
||||
|
||||
public void testInnerClassInStaticMethodCompletion() throws Throwable {
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
|
||||
public void testQualifiedThisCompletion() throws Throwable {
|
||||
myFixture.testCompletionVariants(getTestName(false) + ".groovy", "foo1", "foo2");
|
||||
}
|
||||
@@ -206,42 +172,9 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase {
|
||||
myFixture.testCompletionVariants(getTestName(false) + ".groovy", "geteMail", "getePost");
|
||||
}
|
||||
|
||||
public void testSmartCompletionInAssignmentExpression() throws Throwable {
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
public void testSimpleMethodParameter() throws Throwable {
|
||||
doSmartCompletion("d1", "d2");
|
||||
}
|
||||
|
||||
public void testReturnStatement() throws Exception {
|
||||
doSmartCompletion("b", "b1", "b2", "foo");
|
||||
}
|
||||
|
||||
public void testIncSmartCompletion() throws Exception {
|
||||
doSmartCompletion("a", "b");
|
||||
}
|
||||
|
||||
public void testInheritConstructorsAnnotation() throws Throwable {
|
||||
myFixture.addFileToProject("groovy/transform/InheritConstructors.java", "package groovy.transform;\n" +
|
||||
"\n" +
|
||||
"import java.lang.annotation.ElementType;\n" +
|
||||
"import java.lang.annotation.Retention;\n" +
|
||||
"import java.lang.annotation.RetentionPolicy;\n" +
|
||||
"import java.lang.annotation.Target;@Retention(RetentionPolicy.SOURCE)\n" +
|
||||
"@Target({ElementType.TYPE})\n" +
|
||||
"public @interface InheritConstructors {\n" +
|
||||
"}");
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
public void testIntCompletionInPlusMethod() {doBasicTest();}
|
||||
public void testIntCompletionInGenericParameter() {doBasicTest();}
|
||||
|
||||
public void testSmartCastCompletion() {doSmartTest();}
|
||||
public void testSmartCastCompletionWithoutRParenth() {doSmartTest();}
|
||||
public void testSmartCastCompletionWithRParenth() {doSmartTest();}
|
||||
|
||||
public void testWhenSiblingIsStaticallyImported_Method() throws Exception {
|
||||
myFixture.addFileToProject "foo/Foo.groovy", """package foo
|
||||
class Foo {
|
||||
@@ -387,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>"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy;
|
||||
package org.jetbrains.plugins.groovy.completion;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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 org.jetbrains.plugins.groovy.completion;
|
||||
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.plugins.groovy.util.TestUtils
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class GroovySmartCompletionTest extends GroovyCompletionTestBase {
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return TestUtils.getTestDataPath() + "groovy/completion/smart";
|
||||
}
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclaration() throws Throwable {
|
||||
myFixture.configureByFile(getTestName(false) + ".groovy");
|
||||
myFixture.complete(CompletionType.SMART);
|
||||
assertOrderedEquals(myFixture.getLookupElementStrings(), "Bar", "Foo");
|
||||
}
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithInterface() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testCaretAfterSmartCompletionAfterNewInDeclaration() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithAbstractClass() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithArray() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithIntArray() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testShortenNamesInSmartCompletionAfterNewInDeclaration() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testSmartAfterNewInCall() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testInnerClassInStaticMethodCompletion() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testSmartCompletionInAssignmentExpression() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testSimpleMethodParameter() throws Throwable {
|
||||
doSmartCompletion("d1", "d2");
|
||||
}
|
||||
|
||||
public void testReturnStatement() throws Exception {
|
||||
doSmartCompletion("b", "b1", "b2", "foo");
|
||||
}
|
||||
|
||||
public void testIncSmartCompletion() throws Exception {
|
||||
doSmartCompletion("a", "b");
|
||||
}
|
||||
|
||||
public void testInheritConstructorsAnnotation() throws Throwable {
|
||||
myFixture.addFileToProject("groovy/transform/InheritConstructors.java", "package groovy.transform;\n" +
|
||||
"\n" +
|
||||
"import java.lang.annotation.ElementType;\n" +
|
||||
"import java.lang.annotation.Retention;\n" +
|
||||
"import java.lang.annotation.RetentionPolicy;\n" +
|
||||
"import java.lang.annotation.Target;@Retention(RetentionPolicy.SOURCE)\n" +
|
||||
"@Target({ElementType.TYPE})\n" +
|
||||
"public @interface InheritConstructors {\n" +
|
||||
"}");
|
||||
doSmartTest();
|
||||
}
|
||||
|
||||
public void testSmartCastCompletion() {doSmartTest();}
|
||||
public void testSmartCastCompletionWithoutRParenth() {doSmartTest();}
|
||||
public void testSmartCastCompletionWithRParenth() {doSmartTest();}
|
||||
|
||||
def getFileText(PsiFile file) {
|
||||
return PsiDocumentManager.getInstance(project).getDocument(file).text
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
def foo(List<String> l) {}
|
||||
foo(new ArrLi<caret>)
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
def foo(List<String> l) {}
|
||||
foo(new ArrayList<String>(<caret>))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user