Merge branch 'master' of git@git.labs.intellij.net:idea/community

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

Some files were not shown because too many files have changed in this diff Show More