Merge remote branch 'origin/master'

This commit is contained in:
Evgeny Zakrevsky
2012-02-29 21:14:51 +04:00
10 changed files with 94 additions and 29 deletions
@@ -42,7 +42,7 @@ public class JavaCharFilter extends CharFilter {
return psiElement != null && psiElement.getParent() instanceof PsiLiteralExpression;
}
public static boolean isNonImportedClassEntered(LookupImpl lookup) {
public static boolean isNonImportedClassEntered(LookupImpl lookup, boolean orPackage) {
if (lookup.isSelectionTouched() || !lookup.isCompletion()) return false;
CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion();
@@ -66,6 +66,10 @@ public class JavaCharFilter extends CharFilter {
}
}
if (orPackage && prefix.length() > 1 && JavaPsiFacade.getInstance(file.getProject()).findPackage(prefix) != null) {
return true;
}
return false;
}
@@ -117,7 +121,8 @@ public class JavaCharFilter extends CharFilter {
return Result.HIDE_LOOKUP;
}
if ((c == '[' || c == '<' || c == '.' || c == ' ' || c == '(') && isNonImportedClassEntered((LookupImpl)lookup)) {
if ((c == '[' || c == '<' || c == '.' || c == ' ' || c == '(') &&
isNonImportedClassEntered((LookupImpl)lookup, c == '.')) {
return Result.HIDE_LOOKUP;
}
@@ -20,14 +20,16 @@ import com.intellij.codeInsight.lookup.CharFilter;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConditionalExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
/**
* @author ilyas
@@ -45,7 +47,8 @@ public class GroovyReferenceCharFilter extends CharFilter {
return Result.ADD_TO_PREFIX;
}
if ((c == '[' || c == '<' || c == '.' || c == ' ' || c == '(') && JavaCharFilter.isNonImportedClassEntered((LookupImpl)lookup)) {
if ((c == '[' || c == '<' || c == '.' || c == ' ' || c == '(') &&
JavaCharFilter.isNonImportedClassEntered((LookupImpl)lookup, c == '.')) {
return Result.HIDE_LOOKUP;
}
@@ -58,12 +61,16 @@ public class GroovyReferenceCharFilter extends CharFilter {
if (c == ':') {
PsiFile file = lookup.getPsiFile();
PsiDocumentManager.getInstance(file.getProject()).commitDocument(lookup.getEditor().getDocument());
PsiElement element = lookup.getPsiElement();
if (PsiTreeUtil.getParentOfType(element, GrCaseLabel.class) != null ||
PsiTreeUtil.getParentOfType(element, GrConditionalExpression.class) != null ||
PsiTreeUtil.getParentOfType(element, GrArgumentList.class) != null ||
PsiTreeUtil.getParentOfType(element, GrListOrMap.class) != null
) {
PsiElement element = file.findElementAt(Math.max(caret - 1, 0));
if (psiElement().withParent(
psiElement(GrReferenceExpression.class).withParent(
StandardPatterns.or(psiElement(GrCaseLabel.class),
psiElement(GrConditionalExpression.class)))).accepts(element)) {
return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
}
if (item.getObject() instanceof NamedArgumentDescriptor &&
(MapArgumentCompletionProvider.IN_ARGUMENT_LIST_OF_CALL.accepts(element) ||
MapArgumentCompletionProvider.IN_LABEL.accepts(element))) {
return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
}
return Result.HIDE_LOOKUP;
@@ -51,20 +51,19 @@ import static org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor.Pr
*/
class MapArgumentCompletionProvider extends CompletionProvider<CompletionParameters> {
public static final ElementPattern<PsiElement> IN_ARGUMENT_LIST_OF_CALL = psiElement().withParent(psiElement(GrReferenceExpression.class).withParent(
StandardPatterns.or(psiElement(GrArgumentList.class), psiElement(GrListOrMap.class)))
);
public static final ElementPattern<PsiElement> IN_LABEL = psiElement(GroovyTokenTypes.mIDENT).withParent(GrArgumentLabel.class);
private MapArgumentCompletionProvider() {
}
public static void register(CompletionContributor contributor) {
MapArgumentCompletionProvider instance = new MapArgumentCompletionProvider();
ElementPattern<PsiElement> inArgumentListOfCall = psiElement().withParent(psiElement(GrReferenceExpression.class).withParent(
StandardPatterns.or(psiElement(GrArgumentList.class), psiElement(GrListOrMap.class)))
);
ElementPattern<PsiElement> inLabel = psiElement(GroovyTokenTypes.mIDENT).withParent(GrArgumentLabel.class);
contributor.extend(CompletionType.BASIC, inArgumentListOfCall, instance);
contributor.extend(CompletionType.BASIC, inLabel, instance);
contributor.extend(CompletionType.BASIC, IN_ARGUMENT_LIST_OF_CALL, instance);
contributor.extend(CompletionType.BASIC, IN_LABEL, instance);
}
@Override
@@ -463,19 +463,23 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
final GrExpression right = expression.getRightOperand();
final IElementType opType = expression.getOperationTokenType();
final FakeInstruction binaryEnd =
opType == GroovyTokenTypes.mLAND || opType == GroovyTokenTypes.mLOR ? new FakeInstruction(myInstructionNumber++) : null;
InstructionImpl start = myHead;
left.accept(this);
if (binaryEnd != null && myHead != null) {
addEdge(myHead, binaryEnd);
if (right != null) {
if (opType == GroovyTokenTypes.mLOR) {
addPendingEdge(expression, myHead);
myHead = start;
myNegate = !myNegate;
left.accept(this);
myNegate = !myNegate;
}
right.accept(this);
}
if (right != null) right.accept(this);
visitCall(expression);
if (binaryEnd != null) addNode(binaryEnd);
}
/**
@@ -232,4 +232,23 @@ class GroovyAutoPopupTest extends CompletionAutoPopupTestCase {
assert myFixture.file.text == 'FIS:'
}
public void testEnteringNamedArg() {
myFixture.configureByText 'a.groovy', 'foo(<caret>)'
type 'has:'
myFixture.checkResult 'foo(has:<caret>)'
}
public void testEnteringMapKey() {
myFixture.configureByText 'a.groovy', '[<caret>]'
type 'has:'
myFixture.checkResult '[has:<caret>]'
}
public void testTypingFqn() {
CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE
myFixture.configureByText 'a.groovy', '<caret>'
type 'java.'
myFixture.checkResult 'java.<caret>'
}
}
@@ -111,6 +111,9 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase {
doBasicTest();
}
public void testInstanceofHelpsDetermineTypeInBinaryAnd() throws Throwable { doBasicTest() }
public void testInstanceofHelpsDetermineTypeInBinaryOr() throws Throwable { doBasicTest() }
public void testNotInstanceofDoesntHelpDetermineType() throws Throwable {
myFixture.testCompletion(getTestName(false) + ".groovy", getTestName(false) + ".groovy");
}
@@ -0,0 +1,7 @@
public class Parent {
def foo(o) {
return o instanceof String && o.subst<caret>
}
}
@@ -0,0 +1,7 @@
public class Parent {
def foo(o) {
return o instanceof String && o.substring(<caret>)
}
}
@@ -0,0 +1,7 @@
public class Parent {
def foo(o) {
return !(o instanceof String) || o.subst<caret>
}
}
@@ -0,0 +1,7 @@
public class Parent {
def foo(o) {
return !(o instanceof String) || o.substring(<caret>)
}
}