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

This commit is contained in:
Eugene Kudelevsky
2011-03-11 19:45:45 +03:00
11 changed files with 192 additions and 53 deletions
@@ -0,0 +1,5 @@
public class SomeClass {
void foo(String param) {
if (param.<caret>)
}
}
@@ -0,0 +1,5 @@
public class SomeClass {
void foo(String param) {
if (param.equals(<caret>))
}
}
@@ -858,6 +858,16 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
assertStringItems("myField1", "myField2");
}
public void testAfterCommonPrefix() throws Throwable {
configure()
type 'eq'
assertStringItems("equals", "equalsIgnoreCase");
complete()
assertStringItems("equals", "equalsIgnoreCase");
type '('
checkResult()
}
public void testClassNameInsideIdentifierInIf() throws Throwable {
configure()
type '\n'
@@ -119,21 +119,19 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
psiFile.putUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING, Boolean.TRUE);
CompletionPhase phase = CompletionServiceImpl.getCompletionPhase();
CompletionProgressIndicator indicator = phase.newCompletionStarted();
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
if (indicator != null) {
boolean repeated = indicator.isRepeatedInvocation(myCompletionType, editor);
if (repeated && !indicator.isRunning() && (!isAutocompleteCommonPrefixOnInvocation() || indicator.fillInCommonPrefix(true))) {
CompletionProgressIndicator oldIndicator = phase.indicator;
if (oldIndicator != null) {
boolean repeated = oldIndicator.isRepeatedInvocation(myCompletionType, editor);
if (repeated && isAutocompleteCommonPrefixOnInvocation() && phase instanceof CompletionPhase.ItemsCalculated && oldIndicator.fillInCommonPrefix(true)) {
return;
}
oldIndicator.closeAndFinish(false);
if (repeated) {
time = Math.max(indicator.getParameters().getInvocationCount() + 1, 2);
indicator.restorePrefix(phase);
time = phase.handleRepeatedInvocation(time);
}
}
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
if (time > 1) {
if (myCompletionType == CompletionType.CLASS_NAME) {
@@ -43,8 +43,8 @@ import java.util.EventObject;
public abstract class CompletionPhase implements Disposable {
public static final CompletionPhase NoCompletion = new CompletionPhase(null) {
@Override
public CompletionProgressIndicator newCompletionStarted() {
return null;
public int handleRepeatedInvocation(int time) {
return time;
}
};
@@ -58,8 +58,7 @@ public abstract class CompletionPhase implements Disposable {
public void dispose() {
}
@Nullable
public abstract CompletionProgressIndicator newCompletionStarted();
public abstract int handleRepeatedInvocation(int time);
public static class AutoPopupAlarm extends CompletionPhase {
public AutoPopupAlarm() {
@@ -67,8 +66,8 @@ public abstract class CompletionPhase implements Disposable {
}
@Override
public CompletionProgressIndicator newCompletionStarted() {
return null;
public int handleRepeatedInvocation(int time) {
return time;
}
}
public static class Synchronous extends CompletionPhase {
@@ -77,7 +76,7 @@ public abstract class CompletionPhase implements Disposable {
}
@Override
public CompletionProgressIndicator newCompletionStarted() {
public int handleRepeatedInvocation(int time) {
throw new UnsupportedOperationException("Not implemented");
}
}
@@ -96,9 +95,8 @@ public abstract class CompletionPhase implements Disposable {
}
@Override
public CompletionProgressIndicator newCompletionStarted() {
indicator.closeAndFinish(false);
return indicator;
public int handleRepeatedInvocation(int time) {
return indicator.restorePrefix(null);
}
}
public static class ItemsCalculated extends CompletionPhase {
@@ -110,9 +108,8 @@ public abstract class CompletionPhase implements Disposable {
}
@Override
public CompletionProgressIndicator newCompletionStarted() {
indicator.closeAndFinish(false);
return indicator;
public int handleRepeatedInvocation(int time) {
return indicator.restorePrefix(null);
}
}
public static class Restarted extends CompletionPhase {
@@ -121,13 +118,12 @@ public abstract class CompletionPhase implements Disposable {
}
@Override
public CompletionProgressIndicator newCompletionStarted() {
indicator.closeAndFinish(false);
return indicator;
public int handleRepeatedInvocation(int time) {
return indicator.restorePrefix(null);
}
}
public static class ZombiePhase extends CompletionPhase {
public static abstract class ZombiePhase extends CompletionPhase {
protected ZombiePhase(@Nullable final LightweightHint hint, final CompletionProgressIndicator indicator) {
super(indicator);
@@ -179,10 +175,6 @@ public abstract class CompletionPhase implements Disposable {
});
}
@Override
public CompletionProgressIndicator newCompletionStarted() {
return indicator;
}
}
public static class InsertedSingleItem extends ZombiePhase {
@@ -192,21 +184,23 @@ public abstract class CompletionPhase implements Disposable {
super(null, indicator);
this.restorePrefix = restorePrefix;
}
@Override
public int handleRepeatedInvocation(int time) {
return indicator.restorePrefix(restorePrefix);
}
}
public static class NoSuggestionsHint extends ZombiePhase {
public NoSuggestionsHint(@Nullable LightweightHint hint, CompletionProgressIndicator indicator) {
super(hint, indicator);
}
}
public static class PossiblyDisturbingAutoPopup extends CompletionPhase {
public PossiblyDisturbingAutoPopup(CompletionProgressIndicator indicator) {
super(indicator);
}
@Override
public CompletionProgressIndicator newCompletionStarted() {
return null;
public int handleRepeatedInvocation(int time) {
return indicator.restorePrefix(null);
}
}
public static class EmptyAutoPopup extends CompletionPhase {
public final Editor editor;
@@ -302,8 +296,8 @@ public abstract class CompletionPhase implements Disposable {
}
@Override
public CompletionProgressIndicator newCompletionStarted() {
return null;
public int handleRepeatedInvocation(int time) {
return time;
}
}
@@ -526,19 +526,19 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
return aBoolean.booleanValue();
}
public void restorePrefix(final CompletionPhase zombie) {
public int restorePrefix(final Runnable customRestore) {
new WriteCommandAction(getProject(), getCompletionCommandName()) {
@Override
protected void run(Result result) throws Throwable {
setMergeCommand();
if (zombie instanceof CompletionPhase.InsertedSingleItem) {
((CompletionPhase.InsertedSingleItem)zombie).restorePrefix.run();
if (customRestore != null) {
customRestore.run();
}
getLookup().restorePrefix();
}
}.execute();
return Math.max(getParameters().getInvocationCount() + 1, 2);
}
public Editor getEditor() {
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.completion.impl;
import com.intellij.codeInsight.lookup.Classifier;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.MultiMap;
@@ -40,7 +41,7 @@ class LiftShorterItemsClassifier extends Classifier<LookupElement> {
@Override
public void addElement(LookupElement element) {
final Set<String> strings = element.getAllLookupStrings();
final Set<String> strings = getAllLookupStrings(element);
for (String string : strings) {
if (string.length() == 0) continue;
@@ -85,7 +86,7 @@ class LiftShorterItemsClassifier extends Classifier<LookupElement> {
for (LookupElement element : list) {
if (processed.add(element)) {
final List<String> prefixes = new SmartList<String>();
for (String string : element.getAllLookupStrings()) {
for (String string : getAllLookupStrings(element)) {
prefixes.addAll(myPrefixes.get(string));
}
Collections.sort(prefixes);
@@ -110,6 +111,14 @@ class LiftShorterItemsClassifier extends Classifier<LookupElement> {
return result;
}
private static Set<String> getAllLookupStrings(LookupElement element) {
HashSet<String> result = new HashSet<String>();
for (String s : element.getAllLookupStrings()) {
result.add(StringUtil.toLowerCase(s));
}
return result;
}
@Override
public void describeItems(LinkedHashMap<LookupElement, StringBuilder> map) {
final HashSet<LookupElement> lifted = new HashSet<LookupElement>();
+2
View File
@@ -231,6 +231,8 @@
<pom.declarationSearcher implementation="org.jetbrains.plugins.groovy.lang.psi.GroovyDeclarationSearcher"/>
<typeDeclarationProvider implementation="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyTypeDeclarationProvider" order="first"/>
<!--Run/debug-->
<configurationType implementation="org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationType"/>
<configurationProducer implementation="org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationProducer"/>
@@ -52,15 +52,14 @@ public class GrKindWeigher extends CompletionWeigher {
}
final PsiElement position = location.getCompletionParameters().getPosition();
if (!(position.getParent() instanceof GrReferenceElement)) {
if (position.getContainingFile() instanceof GroovyFileBase) {
if (o instanceof PsiClass || o instanceof PsiPackage) return 0;
return 1;
}
if (!(position.getContainingFile() instanceof GroovyFileBase)) {
return null;
}
if (!(o instanceof PsiElement)) return null;
if (!(position.getParent() instanceof GrReferenceElement)) {
if (o instanceof PsiClass || o instanceof PsiPackage) return 0;
return 1;
}
final GrReferenceElement parent = (GrReferenceElement)position.getParent();
@@ -70,6 +69,7 @@ public class GrKindWeigher extends CompletionWeigher {
if (o instanceof PsiPackage) return NotQualifiedKind.aPackage;
if (isLightElement(o)) return NotQualifiedKind.anImplicitGroovyMethod;
if (o instanceof PsiMember) return NotQualifiedKind.aMember;
if (o instanceof String) return NotQualifiedKind.aString;
}
else {
if (o instanceof PsiClass) return QualifiedKind.aClass;
@@ -87,6 +87,7 @@ public class GrKindWeigher extends CompletionWeigher {
}
return QualifiedKind.aMember;
}
if (o instanceof String) return QualifiedKind.aString;
}
return null;
}
@@ -96,10 +97,10 @@ public class GrKindWeigher extends CompletionWeigher {
}
static enum NotQualifiedKind {
aPackage, aClass, anImplicitGroovyMethod, aMember, aLocal
aPackage, aClass, anImplicitGroovyMethod, aMember, aLocal, aString
}
static enum QualifiedKind {
aPackage, aClass, aTrashMethod, anImplicitGroovyMethod, aMember, anEnumConstant
aPackage, aClass, aTrashMethod, anImplicitGroovyMethod, aMember, anEnumConstant, aString
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2000-2011 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.lang.psi.impl;
import com.intellij.codeInsight.navigation.actions.TypeDeclarationProvider;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
/**
* @author Sergey Evdokimov
*/
public class GroovyTypeDeclarationProvider implements TypeDeclarationProvider {
@Nullable
public PsiElement[] getSymbolTypeDeclarations(final PsiElement targetElement) {
PsiType type;
if (targetElement instanceof GrVariable){
type = ((GrVariable)targetElement).getTypeGroovy();
}
else if (targetElement instanceof GrMethod){
type = ((GrMethod)targetElement).getInferredReturnType();
}
else {
return null;
}
if (type == null) return null;
PsiClass psiClass = PsiUtil.resolveClassInType(type);
return psiClass == null ? null : new PsiElement[] {psiClass};
}
}
@@ -0,0 +1,70 @@
/*
* Copyright 2000-2011 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
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.codeInsight.navigation.actions.GotoTypeDeclarationAction
import com.intellij.psi.PsiClass
/**
* @author Sergey Evdokimov
*/
class GroovyGoToTypeDeclarationTest extends LightCodeInsightFixtureTestCase {
public void testGoToTypeDeclarationMethod() {
myFixture.configureByText("g.groovy", """
class A {
public def method() {
return new B();
}
{
method<caret>()
}
}
class B {
}
""")
def res = GotoTypeDeclarationAction.findSymbolType(myFixture.editor, myFixture.caretOffset)
assertInstanceOf(res, PsiClass.class)
assertEquals("B", ((PsiClass)res).getName())
}
public void testGoToTypeDeclarationVariable() {
myFixture.configureByText("g.groovy", """
class A {
{
def a = new B()
println(a<caret>)
}
}
class B {
}
""")
def res = GotoTypeDeclarationAction.findSymbolType(myFixture.editor, myFixture.caretOffset)
assertInstanceOf(res, PsiClass.class)
assertEquals("B", ((PsiClass)res).getName())
}
}