don't do costly findReference in java's beforeCompletion (IDEA-92486)

This commit is contained in:
peter
2012-10-04 18:12:47 +02:00
parent 33e693e855
commit 68ab8931c4
3 changed files with 13 additions and 69 deletions
@@ -138,7 +138,7 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
public static void removeEndOfIdentifier(InsertionContext context){
final Document document = context.getEditor().getDocument();
JavaCompletionUtil.initOffsets(context.getFile(), context.getProject(), context.getOffsetMap());
JavaCompletionUtil.initOffsets(context.getFile(), context.getOffsetMap());
document.deleteString(context.getSelectionEndOffset(), context.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
if(context.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET) > 0){
document.deleteString(context.getOffsetMap().getOffset(JavaCompletionUtil.LPAREN_OFFSET),
@@ -171,7 +171,7 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
@Override
protected void populateInsertMap(@NotNull final PsiFile file, @NotNull final OffsetMap offsetMap) {
JavaCompletionUtil.initOffsets(file, file.getProject(), offsetMap);
JavaCompletionUtil.initOffsets(file, offsetMap);
}
public static class InsertHandlerState{
@@ -587,7 +587,7 @@ public class JavaCompletionContributor extends CompletionContributor {
final PsiFile file = context.getFile();
if (file instanceof PsiJavaFile) {
JavaCompletionUtil.initOffsets(file, context.getProject(), context.getOffsetMap());
JavaCompletionUtil.initOffsets(file, context.getOffsetMap());
autoImport(file, context.getStartOffset() - 1, context.getEditor());
@@ -36,29 +36,24 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NullableLazyKey;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.PsiElementPattern;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.html.HtmlTag;
import com.intellij.psi.impl.FakePsiElement;
import com.intellij.psi.impl.light.LightVariableBuilder;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.impl.source.PsiImmediateClassType;
import com.intellij.psi.javadoc.PsiDocToken;
import com.intellij.psi.scope.BaseScopeProcessor;
import com.intellij.psi.scope.ElementClassHint;
import com.intellij.psi.scope.NameHint;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.psi.xml.XmlToken;
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NullableFunction;
import com.intellij.util.PairConsumer;
@@ -92,7 +87,7 @@ public class JavaCompletionUtil {
return JavaSmartCompletionContributor.getExpectedTypes(location.getCompletionParameters());
}
});
private static final PsiElementPattern.Capture<PsiElement> LEFT_PAREN = psiElement(JavaTokenType.LPARENTH).andOr(psiElement().withParent(
private static final ElementPattern<PsiElement> LEFT_PAREN = psiElement(JavaTokenType.LPARENTH).andOr(psiElement().withParent(
PsiExpressionList.class), psiElement().afterLeaf(".", PsiKeyword.NEW));
public static final Key<Boolean> SUPER_METHOD_PARAMETERS = Key.create("SUPER_METHOD_PARAMETERS");
@@ -211,39 +206,18 @@ public class JavaCompletionUtil {
return originalSubstitutor;
}
public static void initOffsets(final PsiFile file, final Project project, final OffsetMap offsetMap){
int selectionEndOffset = offsetMap.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET);
PsiElement element = file.findElementAt(selectionEndOffset);
if (element == null) return;
if (LEFT_PAREN.accepts(element)) {
selectionEndOffset--;
element = file.findElementAt(selectionEndOffset);
if (element == null) return;
}
final PsiReference reference = file.findReferenceAt(selectionEndOffset);
if(reference != null) {
offsetMap.addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET,
reference.getElement().getTextRange().getStartOffset() + reference.getRangeInElement().getEndOffset());
element = file.findElementAt(offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
}
else if (isWord(element)){
offsetMap.addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, element.getTextRange().getEndOffset());
element = file.findElementAt(offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
if (element == null) return;
}
public static void initOffsets(final PsiFile file, final OffsetMap offsetMap) {
int offset = Math.max(offsetMap.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET),
offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
PsiElement element = file.findElementAt(offset);
if (element instanceof PsiWhiteSpace &&
( !element.textContains('\n') ||
CodeStyleSettingsManager.getSettings(project).getCommonSettings(JavaLanguage.INSTANCE).METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE
)
){
(!element.textContains('\n') ||
CodeStyleSettingsManager.getSettings(file.getProject()).getCommonSettings(JavaLanguage.INSTANCE).METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE
)) {
element = file.findElementAt(element.getTextRange().getEndOffset());
}
if (element == null) return;
if (LEFT_PAREN.accepts(element)) {
offsetMap.addOffset(LPAREN_OFFSET, element.getTextRange().getStartOffset());
@@ -253,38 +227,8 @@ public class JavaCompletionUtil {
offsetMap.addOffset(RPAREN_OFFSET, last.getTextRange().getStartOffset());
}
offsetMap.addOffset(ARG_LIST_END_OFFSET, list.getTextRange().getEndOffset());
}
}
static boolean isWord(PsiElement element) {
if (element instanceof PsiIdentifier || element instanceof PsiKeyword) {
return true;
}
else if (element instanceof PsiJavaToken) {
final String text = element.getText();
if (PsiKeyword.TRUE.equals(text)) return true;
if (PsiKeyword.FALSE.equals(text)) return true;
if (PsiKeyword.NULL.equals(text)) return true;
return false;
}
else if (element instanceof PsiDocToken) {
IElementType tokenType = ((PsiDocToken)element).getTokenType();
return tokenType == JavaDocTokenType.DOC_TAG_VALUE_TOKEN || tokenType == JavaDocTokenType.DOC_TAG_NAME;
}
else if (element instanceof XmlToken) {
IElementType tokenType = ((XmlToken)element).getTokenType();
return tokenType == XmlTokenType.XML_TAG_NAME ||
tokenType == XmlTokenType.XML_NAME ||
tokenType == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN ||
// html data chars contains whitespaces
(tokenType == XmlTokenType.XML_DATA_CHARACTERS && !(element.getParent() instanceof HtmlTag));
}
else {
return false;
}
}
public static void resetParensInfo(final OffsetMap offsetMap) {