diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java index c8286431349c..b28f350e2c2e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FramesListRenderer.java @@ -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); } } } diff --git a/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java b/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java index 4ebdbebc72ce..40cd9bde5f65 100644 --- a/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java +++ b/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java @@ -109,37 +109,7 @@ public class SegmentedInputStream extends InputStream { } public int available() throws IOException { - - final HashMap map = new HashMap(); - 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 { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index 34fa83928758..17e03380cc8f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -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> { 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 item) { @SuppressWarnings({"unchecked"}) final LookupItem delegate = item.getDelegate(); @@ -50,7 +55,9 @@ class ConstructorInsertHandler implements InsertHandler { - 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 infos = new THashSet(); - 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 infos); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ExpressionSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ExpressionSmartCompletionContributor.java index ef9a1de0b794..026625166d4c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ExpressionSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ExpressionSmartCompletionContributor.java @@ -38,7 +38,7 @@ public abstract class ExpressionSmartCompletionContributor extends AbstractCompl public void fillCompletionVariants(final JavaSmartCompletionParameters parameters, CompletionResultSet result) { for (final Pair, CompletionProvider> 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); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/InheritorsHolder.java b/java/java-impl/src/com/intellij/codeInsight/completion/InheritorsHolder.java new file mode 100644 index 000000000000..5230f321b66b --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/completion/InheritorsHolder.java @@ -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 { + private final PsiElement myPosition; + private final Set myAddedClasses = new HashSet(); + private final CompletionResultSet myResult; + + public InheritorsHolder(PsiElement position, CompletionResultSet result) { + myPosition = position; + myResult = result; + } + + @Override + public void consume(LookupElement lookupElement) { + final Object object = lookupElement.getObject(); + if (object instanceof PsiClass) { + final PsiClass psiClass = (PsiClass)object; + if (JavaCompletionUtil.hasAccessibleInnerClass(psiClass, myPosition)) return; + + ContainerUtil.addIfNotNull(myAddedClasses, psiClass.getQualifiedName()); + } + myResult.addElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElement)); + } + + public boolean alreadyProcessed(@NotNull LookupElement element) { + final Object object = element.getObject(); + if (object instanceof PsiClass) { + if (alreadyProcessed((PsiClass)object)) return true; + } + return false; + } + + public boolean alreadyProcessed(@NotNull PsiClass object) { + final String qualifiedName = object.getQualifiedName(); + if (qualifiedName == null || myAddedClasses.contains(qualifiedName)) { + return true; + } + return false; + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java index 26b51fa27baa..2a487a5ae069 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java @@ -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(false) { + extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider() { 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)) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 7950cc21013c..5ff788e71fbe 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -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 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() { + 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() { + @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() { 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 lookupSet = new LinkedHashSet(); final Set keywordVariants = new HashSet(); + 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() { - @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; } - } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionFeatures.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionFeatures.java index 4eb7426ae16b..144bc8ca81a0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionFeatures.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionFeatures.java @@ -26,4 +26,6 @@ public interface JavaCompletionFeatures { @NonNls String SECOND_SMART_COMPLETION_ASLIST = "editing.completion.second.smarttype.aslist"; @NonNls String SECOND_SMART_COMPLETION_ARRAY_MEMBER = "editing.completion.second.smarttype.array.member"; @NonNls String IMPORT_STATIC = "editing.completion.import.static"; + @NonNls String AFTER_NEW = "editing.completion.smarttype.afternew"; + @NonNls String AFTER_NEW_ANONYMOUS = "editing.completion.smarttype.afternew"; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index 5a7f23960f39..8b07edc1ab5b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -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; + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java index aee7bfbbaa17..83620cd2a2cf 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java @@ -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( - true) { + extend(CompletionType.BASIC, PsiJavaPatterns.psiElement().inside(PsiDocTagValue.class), new CompletionProvider() { 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); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java new file mode 100644 index 000000000000..bcd7081347f4 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java @@ -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 { + 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 infoCollection = Arrays.asList(infos); + generateVariants(parameters, result.getPrefixMatcher(), infos, new Consumer() { + @Override + public void consume(LookupElement lookupElement) { + result.addElement(JavaSmartCompletionContributor.decorate(lookupElement, infoCollection)); + } + }); + } + + public void generateVariants(final CompletionParameters parameters, final PrefixMatcher prefixMatcher, final Consumer consumer) { + generateVariants(parameters, prefixMatcher, JavaSmartCompletionContributor.getExpectedTypes(parameters), consumer); + } + + private void generateVariants(final CompletionParameters parameters, final PrefixMatcher prefixMatcher, + final ExpectedTypeInfo[] infos, final Consumer consumer) { + + addArrayTypes(parameters.getPosition(), infos, prefixMatcher, consumer); + + processInheritors(parameters, extractClassTypes(infos), prefixMatcher, new Consumer() { + 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 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 extractClassTypes(ExpectedTypeInfo[] infos) { + final List expectedClassTypes = new SmartList(); + 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 expectedClassTypes, + final PrefixMatcher matcher, final Consumer consumer) { + //quick + if (!processMostProbableInheritors(parameters, expectedClassTypes, consumer)) return; + + //long + final Condition shortNameCondition = new Condition() { + 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 expectedClassTypes, + Consumer 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 statVariants = new THashSet(); + final Processor 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; + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 79d409b53a23..af744f812710 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -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(false) { + extend(CompletionType.SMART, psiElement().afterLeaf(PsiKeyword.INSTANCEOF), new CompletionProvider() { 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() { - public void consume(PsiType type) { - final PsiClass psiClass = PsiUtil.resolveClassInType(type); - if (psiClass == null) return; + JavaInheritorsGetter + .processInheritors(parameters, expectedClassTypes, result.getPrefixMatcher(), new Consumer() { + 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 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 typeList = Collections.singletonList((PsiClassType)TypeConversionUtil.typeParameterErasure(targetParameter)); - processInheritors(parameters, context, parameters.getOriginalFile(), typeList, new Consumer() { - public void consume(final PsiType type) { - final PsiClass psiClass = PsiUtil.resolveClassInType(type); - if (psiClass == null) return; + JavaInheritorsGetter + .processInheritors(parameters, typeList, resultSet.getPrefixMatcher(), new Consumer() { + 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(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 expectedClassTypes = new SmartList(); - final List expectedArrayTypes = new SmartList(); - final List infos = new SmartList(); - - 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() { - 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 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 expectedClassTypes, - final Consumer 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 statVariants = new THashSet(); - final Processor 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 shortNameCondition = new Condition() { - 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 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 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"); } - } diff --git a/java/java-impl/src/com/intellij/codeInspection/actions/ReplaceImplementsWithStaticImportAction.java b/java/java-impl/src/com/intellij/codeInspection/actions/ReplaceImplementsWithStaticImportAction.java index 5e17e98119a8..aee7122c6866 100644 --- a/java/java-impl/src/com/intellij/codeInspection/actions/ReplaceImplementsWithStaticImportAction.java +++ b/java/java-impl/src/com/intellij/codeInspection/actions/ReplaceImplementsWithStaticImportAction.java @@ -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 methods = new ArrayList(Arrays.asList(targetClass.getAllMethods())); final PsiClass objectClass = JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_OBJECT, GlobalSearchScope.allScope(project)); diff --git a/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java b/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java index 8378ba3242bc..1ad4c520cbc6 100644 --- a/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java +++ b/java/java-impl/src/com/intellij/psi/filters/getters/ClassLiteralGetter.java @@ -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 { 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() { - @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 shortNameCondition, final PsiType classParameter, CompletionResultSet result) { - final String canonicalText = ApplicationManager.getApplication().runReadAction(new Computable() { - 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 result = new THashSet(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()]); } - } diff --git a/java/java-tests/testData/codeInsight/completion/className/importAfterNew/after2.java b/java/java-tests/testData/codeInsight/completion/className/importAfterNew/after2.java index 1c7cb6f6f2dc..95d797874ffc 100644 --- a/java/java-tests/testData/codeInsight/completion/className/importAfterNew/after2.java +++ b/java/java-tests/testData/codeInsight/completion/className/importAfterNew/after2.java @@ -2,6 +2,6 @@ import pack.WithInnerAClass; public class Test1 { public void foo() { - new WithInnerAClass() + new WithInnerAClass } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameAnonymous.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameAnonymous.java new file mode 100644 index 000000000000..449600704f68 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameAnonymous.java @@ -0,0 +1,9 @@ +class Foo { + { + Zzoo l = new Zz + } +} + +interface Zzoo { + void run(); +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameAnonymous_after.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameAnonymous_after.java new file mode 100644 index 000000000000..47114349916a --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameAnonymous_after.java @@ -0,0 +1,14 @@ +class Foo { + { + Zzoo l = new Zzoo() { + @Override + public void run() { + //To change body of implemented methods use File | Settings | File Templates. + } + } + } +} + +interface Zzoo { + void run(); +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameGenerics.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameGenerics.java new file mode 100644 index 000000000000..6cd8c280d94c --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameGenerics.java @@ -0,0 +1,7 @@ +import java.util.List; + +class Foo { + { + List l = new ArraLi + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameGenerics_after.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameGenerics_after.java new file mode 100644 index 000000000000..77077f665ab3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameGenerics_after.java @@ -0,0 +1,8 @@ +import java.util.ArrayList; +import java.util.List; + +class Foo { + { + List l = new ArrayList() + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInner.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInner.java new file mode 100644 index 000000000000..58913ee34e16 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInner.java @@ -0,0 +1,11 @@ +class Foo { + { + Zzoo l = new Zz + } +} + +interface Zzoo { + void run(); + + class Impl implements Zzoo {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInner_after.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInner_after.java new file mode 100644 index 000000000000..6225e351dd9a --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithInner_after.java @@ -0,0 +1,11 @@ +class Foo { + { + Zzoo l = new Zzoo + } +} + +interface Zzoo { + void run(); + + class Impl implements Zzoo {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/InstanceMagicMethod.java b/java/java-tests/testData/codeInsight/completion/normal/InstanceMagicMethod.java new file mode 100644 index 000000000000..0f2880cd57f0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/InstanceMagicMethod.java @@ -0,0 +1,7 @@ +public class JavaClass { + T magic() {} + + void foo() { + mag + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/InstanceMagicMethod_after.java b/java/java-tests/testData/codeInsight/completion/normal/InstanceMagicMethod_after.java new file mode 100644 index 000000000000..4ebc59a6afc9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/InstanceMagicMethod_after.java @@ -0,0 +1,7 @@ +public class JavaClass { + T magic() {} + + void foo() { + magic() + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/NoMethodsInParameterType.java b/java/java-tests/testData/codeInsight/completion/normal/NoMethodsInParameterType.java new file mode 100644 index 000000000000..b2a6fae52e00 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/NoMethodsInParameterType.java @@ -0,0 +1,3 @@ +class Foo { + static void foo(fint a) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClasses.java b/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClasses.java new file mode 100644 index 000000000000..c4319743bff1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClasses.java @@ -0,0 +1,6 @@ +import static foo.Foo.foo; + +class Bar {{ + foo(); + ba +}} diff --git a/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClassesUnqualifiedOnly.java b/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClassesUnqualifiedOnly.java new file mode 100644 index 000000000000..b0f1402fe76c --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClassesUnqualifiedOnly.java @@ -0,0 +1,7 @@ +import foo.Foo; +import static foo.Foo.foo; + +class Bar {{ + foo(); + new Foo().baz +}} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClassesUnqualifiedOnly_after.java b/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClassesUnqualifiedOnly_after.java new file mode 100644 index 000000000000..9476b0947ff3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClassesUnqualifiedOnly_after.java @@ -0,0 +1,7 @@ +import foo.Foo; +import static foo.Foo.foo; + +class Bar {{ + foo(); + new Foo().bar(); +}} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClasses_after.java b/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClasses_after.java new file mode 100644 index 000000000000..39afee0561a7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/SuggestMembersOfStaticallyImportedClasses_after.java @@ -0,0 +1,7 @@ +import static foo.Foo.bar; +import static foo.Foo.foo; + +class Bar {{ + foo(); + bar(); +}} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index 9bbdb4f10a35..11f075ae5adb 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -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 - }} - """) - complete() - myFixture.checkResult """ - import static foo.Foo.bar; - import static foo.Foo.foo; - - class Bar {{ - foo(); - bar(); - }} - """ + 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().baz - }} - """) - complete() + configure() assertOneElement(myFixture.getLookupElements()) myFixture.type '\t' - myFixture.checkResult """ - import foo.Foo; - import static foo.Foo.foo; - - class Bar {{ - foo(); - new Foo().bar(); - }} - """ + checkResult() } finally { CodeInsightSettings.instance.SHOW_STATIC_AFTER_INSTANCE = old } } - public void testInstanceMagicMethod() throws Exception { - myFixture.configureByText("a.java", """ - public class JavaClass { - T magic() {} - - void foo() { - mag - } - } - """) - myFixture.completeBasic() - myFixture.checkResult """ - public class JavaClass { - T magic() {} - - void foo() { - magic() - } - } - """ - } + public void testInstanceMagicMethod() throws Exception { doTest() } public void testNoMethodsInParameterType() { - myFixture.configureByText("a.java", """ - class Foo { - static void foo(fint a) {} - } - """) - myFixture.completeBasic() + configure() assertOrderedEquals myFixture.lookupElementStrings, "final", "float" } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/EntryPointsConverterTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/EntryPointsConverterTest.java index cefd971947ca..f7355a6dfb0a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/EntryPointsConverterTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/EntryPointsConverterTest.java @@ -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(); } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/AbstractCompletionContributor.java b/platform/lang-api/src/com/intellij/codeInsight/completion/AbstractCompletionContributor.java index 8eab3559f61f..649b0ed437b7 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/AbstractCompletionContributor.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/AbstractCompletionContributor.java @@ -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 pattern, final CompletionParameters parameters, - final ProcessingContext context) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - public Boolean compute() { - return pattern.accepts(parameters.getPosition(), context); - } - }).booleanValue(); - } } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java index ed0758c99a9e..9ad079f101ee 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java @@ -152,7 +152,7 @@ public abstract class CompletionContributor extends AbstractCompletionContributo public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) { for (final Pair, CompletionProvider> 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, CompletionProvider> 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; diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionProvider.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionProvider.java index fab4c674a441..bb818251ac85 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionProvider.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionProvider.java @@ -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 { - 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); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index ec481ab3db82..f2458c7f82c8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -108,6 +108,10 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { } public void invokeCompletion(final Project project, final Editor editor, final PsiFile psiFile, int time) { + if (CompletionAutoPopupHandler.ourTestingAutopopup) { + System.out.println("CodeCompletionHandlerBase.doComplete"); + } + if (!ApplicationManager.getApplication().isUnitTestMode()) { assert !ApplicationManager.getApplication().isWriteAccessAllowed() : "Completion should not be invoked inside write action"; } @@ -252,6 +256,9 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { } private void doComplete(final int invocationCount, CompletionInitializationContext initContext) { + if (CompletionAutoPopupHandler.ourTestingAutopopup) { + System.out.println("CodeCompletionHandlerBase.doComplete"); + } final Editor editor = initContext.getEditor(); final CompletionParameters parameters = createCompletionParameters(invocationCount, initContext); @@ -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"; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java index 1ed42076a386..3ea452bf6872 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java @@ -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 hard = ContainerUtil.findAll(references, new Condition() { public boolean value(final PsiReference object) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java index fc38b698fa13..c325c8a8b8d8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java @@ -77,7 +77,7 @@ public class FilePathCompletionContributor extends CompletionContributor { } }); - extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider(false) { + extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider() { @Override protected void addCompletions(@NotNull final CompletionParameters parameters, ProcessingContext context, diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java index 12d78fe19501..e6f3aa597255 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java @@ -74,7 +74,7 @@ public class LegacyCompletionContributor extends CompletionContributor { final CompletionResultSet result, final CompletionData completionData) { final Ref hasVariants = Ref.create(false); - processReferences(parameters, result, completionData, new PairConsumer() { + processReferences(parameters, result, new PairConsumer() { public void consume(final PsiReference reference, final CompletionResultSet resultSet) { final Set lookupSet = new LinkedHashSet(); 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 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); } } diff --git a/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java b/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java index b7eeceeac391..7fd253f3ea71 100644 --- a/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java +++ b/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java @@ -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); } } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureDetector.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureDetector.java index 784dfc9fa111..05beac7a1f4f 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureDetector.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureDetector.java @@ -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; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java index aba7340be56d..800d857bd1f0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java @@ -42,27 +42,28 @@ public final class LoadTextUtil { } private static Pair 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; diff --git a/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java b/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java index 0a05dbccbbf8..a16ddd779961 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java @@ -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 myUpdaters; private CacheUpdateSession mySession; @@ -135,25 +136,27 @@ class CacheUpdateRunner { final Ref isFinished = new Ref(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 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 ref = new Ref(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; + } } diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java index 14c772acddf5..ad0d71af14a8 100644 --- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java @@ -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 counts = new TreeMap(new Comparator() { + @Override + public int compare(String o1, String o2) { + if (TOTAL_STATUS.equals(o1) && !TOTAL_STATUS.equals(o2)) return -1; + if (TOTAL_STATUS.equals(o2) && !TOTAL_STATUS.equals(o1)) return 1; + return o1.compareTo(o2); + } + }); for (AbstractTestProxy node : myTestRoot.getAllTests()) { if (!node.isLeaf()) continue; - total++; - if (node.isPassed()) passed++; + String status = getStatusString(node); + increment(counts, status); + increment(counts, TOTAL_STATUS); } - Map attrs = new HashMap(); - attrs.put(ATTR_NAME, myRuntimeConfiguration.getName()); + Map runAttrs = new HashMap(); + runAttrs.put(ATTR_NAME, myRuntimeConfiguration.getName()); Integer duration = myTestRoot.getDuration(); if (duration != null) { - attrs.put(ATTR_DURATION, String.valueOf(duration)); + runAttrs.put(ATTR_DURATION, String.valueOf(duration)); } - attrs.put(ATTR_TOTAL, String.valueOf(total)); - attrs.put(ATTR_PASSED, String.valueOf(passed)); - attrs.put(ATTR_FAILED, String.valueOf(total - passed)); - startElement(ELEM_RUN, attrs); + startElement(ELEM_RUN, runAttrs); + + for (Map.Entry entry : counts.entrySet()) { + Map a = new HashMap(); + a.put(ATTR_NAME, entry.getKey()); + a.put(ATTR_VALUE, String.valueOf(entry.getValue())); + startElement(ELEM_COUNT, a); + endElement(ELEM_COUNT); + } + if (myTestRoot.shouldSkipRootNodeForExport()) { for (AbstractTestProxy node : myTestRoot.getChildren()) { processNode(node); @@ -92,6 +107,11 @@ public class TestResultsXmlFormatter { myResultHandler.endDocument(); } + private static void increment(Map counts, String status) { + Integer count = counts.get(status); + counts.put(status, count != null ? count + 1 : 1); + } + private void processNode(AbstractTestProxy node) throws SAXException { Map attrs = new HashMap(); attrs.put(ATTR_NAME, node.getName()); @@ -145,7 +165,7 @@ public class TestResultsXmlFormatter { } if (buffer.length() > 0) { Map a = new HashMap(); - a.put(ATTR_OUTPUT_TYPE, lastType.toString()); + a.put(ATTR_OUTPUT_TYPE, getTypeString(lastType.get())); startElement(ELEM_OUTPUT, a); writeText(buffer.toString()); endElement(ELEM_OUTPUT); @@ -160,12 +180,26 @@ public class TestResultsXmlFormatter { } private static String getTypeString(ConsoleViewContentType type) { - return type == ConsoleViewContentType.ERROR_OUTPUT ? "error" : "normal"; + return type == ConsoleViewContentType.ERROR_OUTPUT ? "stderr" : "stdout"; } private static String getStatusString(AbstractTestProxy node) { - if (node.isPassed()) return "passed"; - return "failed"; // TODO + int magnitude = node.getMagnitude(); + // TODO enumeration! + switch (magnitude) { + case 0: + return "skipped"; + case 5: + return "ignored"; + case 1: + return "passed"; + case 6: + return "failed"; + case 8: + return "error"; + default: + return node.isPassed() ? "passed" : "failed"; + } } private void startElement(String name, Map attributes) throws SAXException { diff --git a/platform/testRunner/src/com/intellij/execution/testframework/export/intellij-export.xsl b/platform/testRunner/src/com/intellij/execution/testframework/export/intellij-export.xsl index fcc64f0c0428..6d234683e7fd 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/export/intellij-export.xsl +++ b/platform/testRunner/src/com/intellij/execution/testframework/export/intellij-export.xsl @@ -61,6 +61,7 @@ h1 { color: #151515; font-size: 180%; + line-height: 1.1em; font-weight: bold; } @@ -88,10 +89,22 @@ color: #ff0000 } - span.success { + span.error { + color: #ff0000 + } + + span.passed { color: #1d9d01 } + span.ignored { + color: #f8d216 + } + + span.skipped { + color: #f8d216 + } + hr { background-color: blue } @@ -101,31 +114,32 @@ } #header { - padding: 1.3em 0 1em 0; + padding: 0; position: fixed; width: 100%; - height: 2em; z-index: 10; background-color: #c7ceda; } + #header h1.title { + margin-top: 1em; + margin-bottom: 0; + } + #header h1 { - margin: 0 3em 0 1.7em; + margin: 0 3em 1em 1.7em; } #header .time { - margin-right: 3em; + margin-top: 2.2em; + margin-right: 3.4em; float: right; } #treecontrol { margin: 0; - padding: 1em 3em .5em 0; - position: fixed; - top: 4em; - right: 0; + padding: .5em 3em .5em 0; text-align: right; - width: 100%; background-color: #fff; } @@ -136,7 +150,7 @@ } #content { - padding: 7em 2.5em 2em 1.7em; + padding: 0 2.5em 2em 1.7em; } #content ul { @@ -158,7 +172,7 @@ } #content ul li.level.top > span { - padding: .5em 0 .5em 1em; + padding: .5em .4em .5em 1em; font-size: 120%; color: #151515; background-color: #f2f2f2; @@ -169,6 +183,10 @@ border-left: solid 10px #f02525; } + #content ul li.level.top.ignored > span { + border-left: solid 10px #f8d216; + } + #content ul li.level.suite > span { margin-bottom: .8em; padding: 0 0 0 .8em; @@ -183,6 +201,10 @@ border-left: solid 15px #f02525; } + #content ul li.level.suite.ignored > span { + border-left: solid 15px #f8d216; + } + #content ul li.level.suite > ul { margin-bottom: 1.5em; } @@ -191,15 +213,19 @@ padding: .3em 0 .3em 1em; color: #0046b0; font-size: 100%; - border-left: solid 3px #93e078; + border-left: solid 6px #93e078; border-bottom: solid 1px #dbdbdb; } #content ul li.level.test.failed > span { - border-left: solid 3px #f02525; + border-left: solid 6px #f02525; } - #content ul li.text span { + #content ul li.level.test.ignored > span { + border-left: solid 6px #f8d216; + } + + #content ul li.text p, #content ul li.text span { margin-bottom: 1.5em; color: #151515 !important; font-size: 90% !important; @@ -210,16 +236,24 @@ border: none !important; } + #content ul li.text span { + margin-bottom: 0; + display: block; + } + + #content ul li.text span.stderr { + color: #8b0000 !important; + } + #content ul li .time { margin-right: .5em; width: 5em; text-align: right; - font-size: 90%; + font-size: 13px; color: #151515; font-style: normal; font-weight: normal; float: right; - background-color: #fff; } #content ul li span .status { @@ -235,6 +269,11 @@ #content ul li.failed > span .status { color: #ff0000; } + + #content ul li.ignored > span .status { + color: #f8d216; + } + ]]> @@ -535,19 +575,22 @@ jQuery.cookie = function(name, value, options) {
@@ -571,6 +614,108 @@ jQuery.cookie = function(name, value, options) { + + + level + + + + suite + + + top + + + + + + + + + + + + + + + +
    + +
+
+
+ + + + level test + + +
  • + + + + + + + + + +
      + + + + + + + + +
    • + + + + +
    • +
      +
    +
  • +
    + + + + + failed open + + + ignored open + + + + open + + + + + + + + + + + + + + + + + + + + + + + + + @@ -613,100 +758,4 @@ jQuery.cookie = function(name, value, options) { - - - level - - - - suite - - - top - - - - - - failed open - - - - open - - - - - - - - - - - - - - -
      - -
    -
    -
    - - - - level test - - failed open - - -
  • - - - - - - - - - -
      - - - - - - - - -
    • - - - -
    • -
      -
    -
  • -
    - - - - - - - - - - - - - - - - - - - - - diff --git a/platform/util/src/com/intellij/openapi/util/objectTree/ObjectNode.java b/platform/util/src/com/intellij/openapi/util/objectTree/ObjectNode.java index b6f10eef4295..04cff69d31ae 100644 --- a/platform/util/src/com/intellij/openapi/util/objectTree/ObjectNode.java +++ b/platform/util/src/com/intellij/openapi/util/objectTree/ObjectNode.java @@ -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 { action.execute(myObject); myTree.fireExecuted(myObject); } + catch (ProcessCanceledException e) { + throw new ProcessCanceledException(e); + } catch (Throwable e) { LOG.error(e); } diff --git a/plugins/groovy/jetgroovy.iml b/plugins/groovy/jetgroovy.iml index c01f8d1bd815..75ba9501f021 100644 --- a/plugins/groovy/jetgroovy.iml +++ b/plugins/groovy/jetgroovy.iml @@ -35,6 +35,7 @@ + diff --git a/plugins/groovy/resources/standardDsls/categoryTransform.gdsl b/plugins/groovy/resources/standardDsls/categoryTransform.gdsl index e1916664096a..24df1224b240 100644 --- a/plugins/groovy/resources/standardDsls/categoryTransform.gdsl +++ b/plugins/groovy/resources/standardDsls/categoryTransform.gdsl @@ -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() } } diff --git a/plugins/groovy/resources/standardDsls/gantScript.gdsl b/plugins/groovy/resources/standardDsls/gantScript.gdsl index 21cebab7146a..35648d9e665b 100644 --- a/plugins/groovy/resources/standardDsls/gantScript.gdsl +++ b/plugins/groovy/resources/standardDsls/gantScript.gdsl @@ -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" diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 0db4ed3f7b97..229e21415f2d 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -37,7 +37,7 @@ - + @@ -62,8 +62,8 @@ - - + + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyFileTypeLoader.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyFileTypeLoader.java index fc28045fc9f4..36af46963a4f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyFileTypeLoader.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyFileTypeLoader.java @@ -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; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyIconProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyIconProvider.java index c9f86f15e299..f4ceff1e9f95 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyIconProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyIconProvider.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java index fa25173c56b8..6e8982a2003c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java @@ -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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy index 730f47b24b9d..3a4ba24cc0dd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy @@ -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 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: if (args.scope) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptType.java index 630c8cfb6486..046548f5dc05 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptType.java @@ -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 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(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptTypeDetector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptTypeDetector.java new file mode 100644 index 000000000000..147ef3674349 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptTypeDetector.java @@ -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 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(); + } + }; + +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptTypeEP.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptTypeEP.java deleted file mode 100644 index 71c6541712a9..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyScriptTypeEP.java +++ /dev/null @@ -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 myInstance = new AtomicNotNullLazyValue() { - @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(); - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java index 1cbfccdb47a7..877ec41e2b4c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java @@ -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)); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantMemberContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantMemberContributor.java index ba8023f1f2c8..b66dae33794e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantMemberContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantMemberContributor.java @@ -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; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantPositionManagerHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantPositionManagerHelper.java index f204e8ee6cf6..1e68c99e890f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantPositionManagerHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantPositionManagerHelper.java @@ -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) { } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptType.java index 704323725a1f..7a4e5eaa207a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptType.java @@ -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 diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptTypeDetector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptTypeDetector.java new file mode 100644 index 000000000000..beebf3f2c1d4 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptTypeDetector.java @@ -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); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantUtils.java index 6c1f758f2903..5b7790d84fe5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantUtils.java @@ -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 labels = new ArrayList(); for (PsiElement child : file.getChildren()) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradlePositionManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradlePositionManager.java index 865e0e5afc9a..3c55c30dcd78 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradlePositionManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradlePositionManager.java @@ -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; } } -} \ No newline at end of file +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleScriptType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleScriptType.java index 674fd4554d1f..f6db00b5dc77 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleScriptType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleScriptType.java @@ -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 diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleScriptTypeDetector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleScriptTypeDetector.java new file mode 100644 index 000000000000..86cc33a1e4d1 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleScriptTypeDetector.java @@ -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()); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyClassNameInsertHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyClassNameInsertHandler.java index 219eaf254105..bb6665a7753b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyClassNameInsertHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyClassNameInsertHandler.java @@ -53,9 +53,9 @@ public class GroovyClassNameInsertHandler implements InsertHandler AFTER_NEW = - psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW).andNot(psiElement().afterLeaf(psiElement().withText(PsiKeyword.THROW)))) - .withSuperParent(3, GrVariable.class); - private static final ElementPattern 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 results = new ArrayList(); - //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() { + @Override + public void consume(PsiClass psiClass) { + if (!inheritors.alreadyProcessed(psiClass)) { + result.addElement(GroovyCompletionUtil.createClassLookupItem(psiClass)); + } + } + }); + } + public GroovyCompletionContributor() { extend(CompletionType.BASIC, psiElement(PsiElement.class), new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull final CompletionResultSet result) { - final PsiElement position = parameters.getPosition(); - final PsiElement reference = position.getParent(); + final PsiElement reference = parameters.getPosition().getParent(); if (reference instanceof GrReferenceElement) { - final int invocationCount = parameters.getInvocationCount(); - final boolean secondCompletionInvoked = - CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION ? invocationCount > 0 : invocationCount > 1; - - final String prefix = result.getPrefixMatcher().getPrefix(); - final boolean skipAccessors = !secondCompletionInvoked && !prefix.startsWith(GET_PREFIX) && - !prefix.startsWith(SET_PREFIX) && - !prefix.startsWith(IS_PREFIX); - - - result.restartCompletionOnPrefixChange(GET_PREFIX); - result.restartCompletionOnPrefixChange(SET_PREFIX); - result.restartCompletionOnPrefixChange(IS_PREFIX); - final Map staticMembers = hashMap(); - ((GrReferenceElement)reference).processVariants(new Consumer() { - public void consume(Object element) { - final LookupElement lookupElement = element instanceof PsiClass - ? GroovyCompletionUtil.createClassLookupItem((PsiClass)element) - : GroovyCompletionUtil.getLookupElement(element); - Object object = lookupElement.getObject(); - PsiSubstitutor substitutor = null; - if (object instanceof GroovyResolveResult) { - substitutor = ((GroovyResolveResult)object).getSubstitutor(); - object = ((GroovyResolveResult)object).getElement(); - } - - - //skip default groovy methods - if (!secondCompletionInvoked && - object instanceof GrGdkMethod && - GroovyCompletionUtil.skipDefGroovyMethod((GrGdkMethod)object, substitutor)) { - showInfo(); - return; - } - - //skip operator methods - if (!secondCompletionInvoked && - object instanceof PsiMethod && - GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(((PsiMethod)object).getName())) { - showInfo(); - return; - } - - //skip accessors if there is no get, set, is prefix - if (skipAccessors && object instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)object)) { - showInfo(); - return; - } - - if ((object instanceof PsiMethod || object instanceof PsiField) && - ((PsiModifierListOwner)object).hasModifierProperty(PsiModifier.STATIC)) { - if (lookupElement.getLookupString().equals(((PsiMember)object).getName())) { - staticMembers.put((PsiModifierListOwner)object, lookupElement); - return; - } - } - result.addElement(lookupElement); - } - }); - - if (((GrReferenceElement)reference).getQualifier() == null) { - completeStaticMembers(position).processMembersOfRegisteredClasses(null, new PairConsumer() { - @Override - public void consume(PsiMember member, PsiClass psiClass) { - if (member instanceof GrAccessorMethod) { - member = ((GrAccessorMethod)member).getProperty(); - } - final String name = member.getName(); - if (name == null || !result.getPrefixMatcher().prefixMatches(name)) { - staticMembers.remove(member); - return; - } - staticMembers.put(member, new JavaGlobalMemberLookupElement(member, psiClass, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_IMPORT_INSERT_HANDLER, true)); - } - }); - } - result.addAllElements(staticMembers.values()); + completeReference(parameters, result, (GrReferenceElement)reference); } } }); - extend(CompletionType.SMART, AFTER_NEW, new CompletionProvider(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 expectedClassTypes = new SmartList(); - final List expectedArrayTypes = new ArrayList(); - - 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() { - public void consume(final PsiType type) { - addExpectedType(result, type, identifierCopy); - } - }, result.getPrefixMatcher()); - } - }); - //provide 'this' and 'super' completions in ClassName. extend(CompletionType.BASIC, AFTER_DOT, new CompletionProvider() { @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 classNameProvider = new CompletionProvider() { + extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, - @NotNull final CompletionResultSet result) { - result.stopHere(); - AllClassesGetter - .processJavaClasses(parameters, result.getPrefixMatcher(), parameters.getInvocationCount() <= 1, new Consumer() { - @Override - public void consume(PsiClass psiClass) { - result.addElement(GroovyCompletionUtil.createClassLookupItem(psiClass)); - } - }); - } - }; - extend(CompletionType.CLASS_NAME, psiElement(), classNameProvider); - - extend(CompletionType.BASIC, psiElement().withParent(GrReferenceElement.class), new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull final CompletionResultSet result) { - final PsiElement position = parameters.getPosition(); - if (((GrReferenceElement)position.getParent()).getQualifier() != null) return; - - final String s = result.getPrefixMatcher().getPrefix(); - if (StringUtil.isEmpty(s) || !Character.isUpperCase(s.charAt(0))) return; - - classNameProvider.addCompletionVariants(parameters, context, result); + @NotNull CompletionResultSet result) { + addAllClasses(parameters, result, new InheritorsHolder(parameters.getPosition(), result)); } }); + + } + + private static void completeReference(CompletionParameters parameters, final CompletionResultSet result, GrReferenceElement reference) { + PsiElement position = parameters.getPosition(); + + final InheritorsHolder inheritors = new InheritorsHolder(position, result); + if (GroovySmartCompletionContributor.AFTER_NEW.accepts(position)) { + GroovySmartCompletionContributor.generateInheritorVariants(parameters, result.getPrefixMatcher(), inheritors); + } + + final int invocationCount = parameters.getInvocationCount(); + final boolean secondCompletionInvoked = CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CODE_COMPLETION ? invocationCount > 0 : invocationCount > 1; + + final String prefix = result.getPrefixMatcher().getPrefix(); + final boolean skipAccessors = !secondCompletionInvoked && !prefix.startsWith(GET_PREFIX) && + !prefix.startsWith(SET_PREFIX) && + !prefix.startsWith(IS_PREFIX); + + + result.restartCompletionOnPrefixChange(GET_PREFIX); + result.restartCompletionOnPrefixChange(SET_PREFIX); + result.restartCompletionOnPrefixChange(IS_PREFIX); + final Map staticMembers = hashMap(); + reference.processVariants(new Consumer() { + public void consume(Object element) { + if (element instanceof PsiClass && inheritors.alreadyProcessed((PsiClass)element)) { + return; + } + if (element instanceof LookupElement && inheritors.alreadyProcessed((LookupElement)element)) { + return; + } + + final LookupElement lookupElement = element instanceof PsiClass + ? GroovyCompletionUtil.createClassLookupItem((PsiClass)element) + : GroovyCompletionUtil.getLookupElement(element); + Object object = lookupElement.getObject(); + PsiSubstitutor substitutor = null; + if (object instanceof GroovyResolveResult) { + substitutor = ((GroovyResolveResult)object).getSubstitutor(); + object = ((GroovyResolveResult)object).getElement(); + } + + //skip default groovy methods + if (!secondCompletionInvoked && + object instanceof GrGdkMethod && + GroovyCompletionUtil.skipDefGroovyMethod((GrGdkMethod)object, substitutor)) { + showInfo(); + return; + } + + //skip operator methods + if (!secondCompletionInvoked && + object instanceof PsiMethod && + GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(((PsiMethod)object).getName())) { + showInfo(); + return; + } + + //skip accessors if there is no get, set, is prefix + if (skipAccessors && object instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)object)) { + showInfo(); + return; + } + + if ((object instanceof PsiMethod || object instanceof PsiField) && + ((PsiModifierListOwner)object).hasModifierProperty(PsiModifier.STATIC)) { + if (lookupElement.getLookupString().equals(((PsiMember)object).getName())) { + staticMembers.put((PsiModifierListOwner)object, lookupElement); + return; + } + } + result.addElement(lookupElement); + } + }); + + if (reference.getQualifier() == null) { + completeStaticMembers(position).processMembersOfRegisteredClasses(null, new PairConsumer() { + @Override + public void consume(PsiMember member, PsiClass psiClass) { + if (member instanceof GrAccessorMethod) { + member = ((GrAccessorMethod)member).getProperty(); + } + final String name = member.getName(); + if (name == null || !result.getPrefixMatcher().prefixMatches(name)) { + staticMembers.remove(member); + return; + } + staticMembers.put(member, new JavaGlobalMemberLookupElement(member, psiClass, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_IMPORT_INSERT_HANDLER, true)); + + } + }); + + final String s = result.getPrefixMatcher().getPrefix(); + if (!StringUtil.isEmpty(s) && Character.isUpperCase(s.charAt(0))) { + addAllClasses(parameters, result, inheritors); + } + } + result.addAllElements(staticMembers.values()); } private static void showInfo() { @@ -495,7 +458,7 @@ public class GroovyCompletionContributor extends CompletionContributor { Map writableProperties = new HashMap(); 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)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java index 6321909f292e..dc650d47fba4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java @@ -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 AFTER_NEW = + psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW).andNot(psiElement().afterLeaf(psiElement().withText(PsiKeyword.THROW)))); private static final TObjectHashingStrategy EXPECTED_TYPE_INFO_STRATEGY = new TObjectHashingStrategy() { public int computeHashCode(final TypeConstraint object) { @@ -183,8 +186,89 @@ public class GroovySmartCompletionContributor extends CompletionContributor { } } }); + + extend(CompletionType.SMART, AFTER_NEW, new CompletionProvider() { + protected void addCompletions(@NotNull final CompletionParameters parameters, + final ProcessingContext matchingContext, + @NotNull final CompletionResultSet result) { + generateInheritorVariants(parameters, result.getPrefixMatcher(), new Consumer() { + @Override + public void consume(LookupElement lookupElement) { + result.addElement(lookupElement); + } + }); + } + }); + } + static void generateInheritorVariants(CompletionParameters parameters, PrefixMatcher matcher, final Consumer consumer) { + final PsiElement identifierCopy = parameters.getPosition(); + final GrExpression expression = PsiTreeUtil.getParentOfType(identifierCopy, GrExpression.class); + if (expression == null) return; + + final Set types = GroovyExpectedTypesProvider.getDefaultExpectedTypes(expression); + for (PsiType type : types) { + if (type instanceof PsiArrayType) { + final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), identifierCopy); + if (item.getObject() instanceof PsiClass) { + JavaCompletionUtil.setShowFQN(item); + } + item.setInsertHandler(new ArrayInsertHandler()); + consumer.consume(item); + } + } + + + final List expectedClassTypes = new SmartList(); + + for (PsiType psiType : types) { + if (psiType instanceof PsiClassType) { + PsiType type = JavaCompletionUtil.eliminateWildcards(JavaCompletionUtil.originalize(psiType)); + final PsiClassType classType = (PsiClassType)type; + if (classType.resolve() != null) { + expectedClassTypes.add(classType); + } + } + } + + JavaInheritorsGetter.processInheritors(parameters, expectedClassTypes, matcher, new Consumer() { + public void consume(final PsiType type) { + final LookupElement element = addExpectedType(type, identifierCopy); + if (element != null) { + consumer.consume(element); + } + } + }); + } + + @Override + public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) { + super.fillCompletionVariants(parameters, result); + } + + @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; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java index a3270a0745f9..bf6a0ead6808 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java @@ -19,8 +19,10 @@ package org.jetbrains.plugins.groovy.lang.completion.handlers; import com.intellij.codeInsight.AutoPopupController; import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.InsertionContext; +import com.intellij.codeInsight.completion.JavaCompletionFeatures; import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler; import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.openapi.util.Condition; import com.intellij.psi.*; import com.intellij.util.containers.ContainerUtil; @@ -34,10 +36,12 @@ import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; public class AfterNewClassInsertHandler implements InsertHandler> { private final PsiClassType myClassType; private final PsiElement myPlace; + private final boolean myTriggerFeature; - public AfterNewClassInsertHandler(PsiClassType classType, PsiElement place) { + public AfterNewClassInsertHandler(PsiClassType classType, PsiElement place, boolean triggerFeature) { myClassType = classType; myPlace = place; + myTriggerFeature = triggerFeature; } public void handleInsert(InsertionContext context, LookupItem item) { @@ -62,6 +66,10 @@ public class AfterNewClassInsertHandler implements InsertHandler compute(final GroovyFile file, final GlobalSearchScope baseScope) { return CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider() { public Result 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); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java index c2fb0b745c07..654b85a0a82d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java @@ -440,7 +440,7 @@ public class GrClosureSignatureUtil { @NotNull GrClosableBlock[] closureArguments, final boolean partial) { List innerArgs = new ArrayList(); - 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) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GroovyVariableValidator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GroovyVariableValidator.java index 41afa480db01..8eae59f56d3a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GroovyVariableValidator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GroovyVariableValidator.java @@ -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 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 list = isOKImpl(varName, allOccurences); String result = ""; - for (String s : list.values()) { + final String[] strings = ArrayUtil.toStringArray((Collection)list.values()); + Arrays.sort(strings, new Comparator() { + @Override + public int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }); + + for (String s : strings) { result = result + s.replaceAll("", "").replaceAll("", "") + "\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++; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/javaToGrovyRename/RenameJavaFileToGroovyFileAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/javaToGrovyRename/RenameJavaFileToGroovyFileAction.java index 8e673f7ba867..4984ea040e95 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/javaToGrovyRename/RenameJavaFileToGroovyFileAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/javaToGrovyRename/RenameJavaFileToGroovyFileAction.java @@ -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; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfiguration.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfiguration.java index 9aab7fc5d64e..0f6c1d6dd13e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfiguration.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfiguration.java @@ -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 l = new ArrLi" + myFixture.completeBasic() + myFixture.type '\n' + myFixture.checkResult "List l = new ArrayList()" + } + + public void testAfterNewWithInner() { + myFixture.addClass """class Zzoo { + static class Impl {} + }""" + configure "Zzoo l = new Zz" + myFixture.completeBasic() + myFixture.checkResult "Zzoo l = new Zzoo" + } } \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTestBase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.java similarity index 97% rename from plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTestBase.java rename to plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.java index 4474a21ddce0..37fedaaa0fc3 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyCompletionTestBase.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTestBase.java @@ -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; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovySmartCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovySmartCompletionTest.groovy new file mode 100644 index 000000000000..f77d806e465f --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovySmartCompletionTest.groovy @@ -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 + } +} \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/completion/CaretAfterSmartCompletionAfterNewInDeclaration.groovy b/plugins/groovy/testdata/groovy/completion/smart/CaretAfterSmartCompletionAfterNewInDeclaration.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/CaretAfterSmartCompletionAfterNewInDeclaration.groovy rename to plugins/groovy/testdata/groovy/completion/smart/CaretAfterSmartCompletionAfterNewInDeclaration.groovy diff --git a/plugins/groovy/testdata/groovy/completion/CaretAfterSmartCompletionAfterNewInDeclaration_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/CaretAfterSmartCompletionAfterNewInDeclaration_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/CaretAfterSmartCompletionAfterNewInDeclaration_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/CaretAfterSmartCompletionAfterNewInDeclaration_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/IncSmartCompletion.groovy b/plugins/groovy/testdata/groovy/completion/smart/IncSmartCompletion.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/IncSmartCompletion.groovy rename to plugins/groovy/testdata/groovy/completion/smart/IncSmartCompletion.groovy diff --git a/plugins/groovy/testdata/groovy/completion/InheritConstructorsAnnotation.groovy b/plugins/groovy/testdata/groovy/completion/smart/InheritConstructorsAnnotation.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/InheritConstructorsAnnotation.groovy rename to plugins/groovy/testdata/groovy/completion/smart/InheritConstructorsAnnotation.groovy diff --git a/plugins/groovy/testdata/groovy/completion/InheritConstructorsAnnotation_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/InheritConstructorsAnnotation_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/InheritConstructorsAnnotation_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/InheritConstructorsAnnotation_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/InnerClassInStaticMethodCompletion.groovy b/plugins/groovy/testdata/groovy/completion/smart/InnerClassInStaticMethodCompletion.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/InnerClassInStaticMethodCompletion.groovy rename to plugins/groovy/testdata/groovy/completion/smart/InnerClassInStaticMethodCompletion.groovy diff --git a/plugins/groovy/testdata/groovy/completion/InnerClassInStaticMethodCompletion_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/InnerClassInStaticMethodCompletion_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/InnerClassInStaticMethodCompletion_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/InnerClassInStaticMethodCompletion_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/ReturnStatement.groovy b/plugins/groovy/testdata/groovy/completion/smart/ReturnStatement.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/ReturnStatement.groovy rename to plugins/groovy/testdata/groovy/completion/smart/ReturnStatement.groovy diff --git a/plugins/groovy/testdata/groovy/completion/ShortenNamesInSmartCompletionAfterNewInDeclaration.groovy b/plugins/groovy/testdata/groovy/completion/smart/ShortenNamesInSmartCompletionAfterNewInDeclaration.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/ShortenNamesInSmartCompletionAfterNewInDeclaration.groovy rename to plugins/groovy/testdata/groovy/completion/smart/ShortenNamesInSmartCompletionAfterNewInDeclaration.groovy diff --git a/plugins/groovy/testdata/groovy/completion/ShortenNamesInSmartCompletionAfterNewInDeclaration_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/ShortenNamesInSmartCompletionAfterNewInDeclaration_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/ShortenNamesInSmartCompletionAfterNewInDeclaration_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/ShortenNamesInSmartCompletionAfterNewInDeclaration_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SimpleMethodParameter.groovy b/plugins/groovy/testdata/groovy/completion/smart/SimpleMethodParameter.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SimpleMethodParameter.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SimpleMethodParameter.groovy diff --git a/plugins/groovy/testdata/groovy/completion/smart/SmartAfterNewInCall.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartAfterNewInCall.groovy new file mode 100644 index 000000000000..f61e84642448 --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/smart/SmartAfterNewInCall.groovy @@ -0,0 +1,2 @@ +def foo(List l) {} +foo(new ArrLi) \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/completion/smart/SmartAfterNewInCall_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartAfterNewInCall_after.groovy new file mode 100644 index 000000000000..f5e5b6c60266 --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/smart/SmartAfterNewInCall_after.groovy @@ -0,0 +1,2 @@ +def foo(List l) {} +foo(new ArrayList()) \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/completion/SmartCastCompletion.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletion.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCastCompletion.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletion.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCastCompletionWithRParenth.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletionWithRParenth.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCastCompletionWithRParenth.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletionWithRParenth.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCastCompletionWithRParenth_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletionWithRParenth_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCastCompletionWithRParenth_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletionWithRParenth_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCastCompletionWithoutRParenth.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletionWithoutRParenth.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCastCompletionWithoutRParenth.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletionWithoutRParenth.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCastCompletionWithoutRParenth_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletionWithoutRParenth_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCastCompletionWithoutRParenth_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletionWithoutRParenth_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCastCompletion_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletion_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCastCompletion_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCastCompletion_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclaration.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclaration.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclaration.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclaration.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithAbstractClass.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithAbstractClass.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithAbstractClass.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithAbstractClass.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithAbstractClass_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithAbstractClass_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithAbstractClass_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithAbstractClass_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithArray.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithArray.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithArray.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithArray.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithArray_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithArray_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithArray_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithArray_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithIntArray.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithIntArray.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithIntArray.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithIntArray.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithIntArray_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithIntArray_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithIntArray_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithIntArray_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithInterface.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithInterface.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithInterface.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithInterface.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithInterface_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithInterface_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionAfterNewInDeclarationWithInterface_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionAfterNewInDeclarationWithInterface_after.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionInAssignmentExpression.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionInAssignmentExpression.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionInAssignmentExpression.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionInAssignmentExpression.groovy diff --git a/plugins/groovy/testdata/groovy/completion/SmartCompletionInAssignmentExpression_after.groovy b/plugins/groovy/testdata/groovy/completion/smart/SmartCompletionInAssignmentExpression_after.groovy similarity index 100% rename from plugins/groovy/testdata/groovy/completion/SmartCompletionInAssignmentExpression_after.groovy rename to plugins/groovy/testdata/groovy/completion/smart/SmartCompletionInAssignmentExpression_after.groovy diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java b/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java index 7886e2ff9823..d9f5c05fa6b9 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java @@ -252,12 +252,13 @@ public class TestsPacketsReceiver implements PacketProcessor, Disposable { while (parent != null) { final List children = parent.getChildren(); final TestState parentState = parent.getState(); - LOG.assertTrue(parentState instanceof SuiteState); - if (!child.isInProgress() && child.equals(children.get(children.size() - 1))) { - ((SuiteState)parentState).setRunning(false); - parent.flush(); + if (parentState instanceof SuiteState) { + if (!child.isInProgress() && child.equals(children.get(children.size() - 1))) { + ((SuiteState)parentState).setRunning(false); + parent.flush(); + } + ((SuiteState)parentState).updateMagnitude(magnitude); } - ((SuiteState)parentState).updateMagnitude(magnitude); child = parent; parent = parent.getParent(); } @@ -270,8 +271,9 @@ public class TestsPacketsReceiver implements PacketProcessor, Disposable { TestProxy parent = testProxy.getParent(); while (parent != null) { final TestState state = parent.getState(); - LOG.assertTrue(state instanceof SuiteState); - ((SuiteState)state).setRunning(true); + if (state instanceof SuiteState) { + ((SuiteState)state).setRunning(true); + } parent = parent.getParent(); } } diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java index b1e4f012b310..023751322050 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java @@ -83,7 +83,7 @@ public class XmlCompletionContributor extends CompletionContributor { public XmlCompletionContributor() { extend(CompletionType.BASIC, XmlPatterns.psiElement().inside(XmlPatterns.xmlAttributeValue()), - new CompletionProvider(false) { + new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context,