mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-79246 IDEA completion suggest raw type for element of array of typed class
This commit is contained in:
+40
-7
@@ -1,5 +1,7 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.codeInsight.generation.GenerateMembersUtil;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementUtil;
|
||||
import com.intellij.codeInsight.generation.PsiGenerationInfo;
|
||||
@@ -68,7 +70,9 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
|
||||
|
||||
boolean fillTypeArgs = false;
|
||||
if (delegate instanceof PsiTypeLookupItem) {
|
||||
fillTypeArgs = psiClass.getTypeParameters().length > 0 && ((PsiTypeLookupItem)delegate).calcGenerics().isEmpty();
|
||||
fillTypeArgs = !isRawTypeExpected(context, (PsiTypeLookupItem)delegate) &&
|
||||
psiClass.getTypeParameters().length > 0 &&
|
||||
((PsiTypeLookupItem)delegate).calcGenerics(position).isEmpty();
|
||||
delegate.handleInsert(context);
|
||||
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting(context.getFile().getViewProvider());
|
||||
}
|
||||
@@ -95,12 +99,7 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
|
||||
editor.getDocument().insertString(offset, " {}");
|
||||
editor.getCaretModel().moveToOffset(offset + 2);
|
||||
|
||||
if (fillTypeArgs) {
|
||||
int refEnd = context.getOffset(insideRef);
|
||||
context.getDocument().insertString(refEnd, "<>");
|
||||
editor.getCaretModel().moveToOffset(refEnd + 1);
|
||||
return;
|
||||
}
|
||||
if (fillTypeArgs && promptTypeArgs(context, context.getOffset(insideRef))) return;
|
||||
|
||||
context.setLaterRunnable(generateAnonymousBody(editor, context.getFile()));
|
||||
}
|
||||
@@ -117,9 +116,43 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
|
||||
if (mySmart) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW);
|
||||
}
|
||||
if (fillTypeArgs && promptTypeArgs(context, context.getOffset(insideRef))) return;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isRawTypeExpected(InsertionContext context, PsiTypeLookupItem delegate) {
|
||||
PsiNewExpression newExpr =
|
||||
PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiNewExpression.class, false);
|
||||
if (newExpr != null) {
|
||||
for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes(newExpr, true)) {
|
||||
PsiType expected = info.getDefaultType();
|
||||
if (expected.isAssignableFrom(delegate.getPsiType())) {
|
||||
if (expected instanceof PsiClassType && ((PsiClassType)expected).isRaw()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean promptTypeArgs(InsertionContext context, int offset) {
|
||||
if (offset < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OffsetKey key = context.trackOffset(offset, false);
|
||||
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
|
||||
offset = context.getOffset(key);
|
||||
if (offset < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
context.getDocument().insertString(offset, "<>");
|
||||
context.getEditor().getCaretModel().moveToOffset(offset + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean insertParentheses(InsertionContext context,
|
||||
LookupItem delegate,
|
||||
final PsiClass psiClass,
|
||||
|
||||
+1
-7
@@ -30,7 +30,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.FilterPositionUtil;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -127,12 +126,7 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
|
||||
}
|
||||
|
||||
if (fillTypeArgs) {
|
||||
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting();
|
||||
int typeArgs = context.getOffset(refEnd);
|
||||
if (typeArgs >= 0) {
|
||||
context.getDocument().insertString(typeArgs, "<>");
|
||||
context.getEditor().getCaretModel().moveToOffset(typeArgs + 1);
|
||||
}
|
||||
ConstructorInsertHandler.promptTypeArgs(context, context.getOffset(refEnd));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.lookup;
|
||||
|
||||
import com.intellij.codeInsight.completion.DefaultInsertHandler;
|
||||
import com.intellij.codeInsight.completion.InsertHandler;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.JavaPsiClassReferenceElement;
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.util.ClassConditionKey;
|
||||
@@ -74,7 +71,9 @@ public class PsiTypeLookupItem extends LookupItem {
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
context.getDocument().insertString(context.getTailOffset(), calcGenerics());
|
||||
PsiElement position = context.getFile().findElementAt(context.getStartOffset());
|
||||
assert position != null;
|
||||
context.getDocument().insertString(context.getTailOffset(), calcGenerics(position));
|
||||
DefaultInsertHandler.addImportForItem(context, this);
|
||||
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
|
||||
|
||||
@@ -99,18 +98,21 @@ public class PsiTypeLookupItem extends LookupItem {
|
||||
}
|
||||
}
|
||||
|
||||
public String calcGenerics() {
|
||||
public String calcGenerics(@NotNull PsiElement context) {
|
||||
if (myDiamond) {
|
||||
return "<>";
|
||||
}
|
||||
|
||||
if (getObject() instanceof PsiClass) {
|
||||
PsiClass psiClass = (PsiClass)getObject();
|
||||
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(psiClass.getProject()).getResolveHelper();
|
||||
PsiSubstitutor substitutor = getSubstitutor();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (PsiTypeParameter parameter : psiClass.getTypeParameters()) {
|
||||
PsiType substitute = substitutor.substitute(parameter);
|
||||
if (substitute == null || PsiUtil.resolveClassInType(substitute) == parameter) {
|
||||
if (substitute == null ||
|
||||
(PsiUtil.resolveClassInType(substitute) == parameter &&
|
||||
resolveHelper.resolveReferencedClass(parameter.getName(), context) != CompletionUtil.getOriginalOrSelf(parameter))) {
|
||||
return "";
|
||||
}
|
||||
if (builder.length() > 0) {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class Bar<T> {
|
||||
{
|
||||
Bar<T> f = new Bar<T>();<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Bar<T> {
|
||||
{
|
||||
Bar<T> f = new <caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
interface Foo {}
|
||||
class FooEx<T> implements Foo {}
|
||||
|
||||
class Bar {
|
||||
{
|
||||
Foo f = new FooEx<<caret>>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
interface Foo {}
|
||||
class FooEx<T> implements Foo {}
|
||||
|
||||
class Bar {
|
||||
{
|
||||
Foo f = new FE<caret>
|
||||
}
|
||||
}
|
||||
+2
@@ -895,6 +895,8 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testIfConditionExpectedType() throws Exception { doTest(); }
|
||||
|
||||
public void testUnboundTypeArgs() throws Exception { doTest(); }
|
||||
public void testUnboundTypeArgs2() throws Exception { doTest(); }
|
||||
public void testSameTypeArg() throws Exception { doTest(); }
|
||||
|
||||
public void testIDEADEV2668() throws Exception {
|
||||
doTest();
|
||||
|
||||
Reference in New Issue
Block a user