mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-08-18 16:17:00 +07:00
308 lines
15 KiB
Java
308 lines
15 KiB
Java
/*
|
|
* Copyright 2000-2016 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;
|
|
|
|
import com.intellij.JavaTestUtil;
|
|
import com.intellij.codeInsight.hint.ParameterInfoComponent;
|
|
import com.intellij.codeInsight.hint.api.impls.AnnotationParameterInfoHandler;
|
|
import com.intellij.codeInsight.hint.api.impls.MethodParameterInfoHandler;
|
|
import com.intellij.codeInsight.lookup.LookupElement;
|
|
import com.intellij.codeInsight.lookup.LookupElementPresentation;
|
|
import com.intellij.lang.parameterInfo.CreateParameterInfoContext;
|
|
import com.intellij.lang.parameterInfo.ParameterInfoUIContextEx;
|
|
import com.intellij.openapi.util.Disposer;
|
|
import com.intellij.openapi.util.registry.Registry;
|
|
import com.intellij.openapi.util.text.StringUtil;
|
|
import com.intellij.psi.*;
|
|
import com.intellij.psi.infos.MethodCandidateInfo;
|
|
import com.intellij.psi.util.PsiTreeUtil;
|
|
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
|
import com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext;
|
|
import com.intellij.testFramework.utils.parameterInfo.MockParameterInfoUIContext;
|
|
import com.intellij.testFramework.utils.parameterInfo.MockUpdateParameterInfoContext;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.io.IOException;
|
|
|
|
public class ParameterInfoTest extends LightCodeInsightFixtureTestCase {
|
|
@Override
|
|
protected String getBasePath() {
|
|
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/parameterInfo/";
|
|
}
|
|
|
|
public void testPrivateMethodOfEnclosingClass() { doTest("param"); }
|
|
public void testNotAccessible() { doTest("param"); }
|
|
|
|
private void doTest(String paramsList) {
|
|
myFixture.configureByFile(getTestName(false) + ".java");
|
|
|
|
MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
|
|
CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile());
|
|
PsiExpressionList list = handler.findElementForParameterInfo(context);
|
|
assertNotNull(list);
|
|
Object[] itemsToShow = context.getItemsToShow();
|
|
assertNotNull(itemsToShow);
|
|
assertTrue(itemsToShow.length > 0);
|
|
Object[] params = handler.getParametersForDocumentation(itemsToShow[0], context);
|
|
assertNotNull(params);
|
|
String joined = StringUtil.join(params, o -> ((PsiParameter)o).getName(), ",");
|
|
assertEquals(paramsList, joined);
|
|
}
|
|
|
|
public void testParameterInfoDoesNotShowInternalJetbrainsAnnotations() throws IOException {
|
|
myFixture.configureByText("x.java", "class X { void f(@org.intellij.lang.annotations.Flow int i) { f(<caret>0); }}");
|
|
|
|
CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile());
|
|
PsiMethod method = PsiTreeUtil.getParentOfType(getFile().findElementAt(context.getOffset()), PsiMethod.class);
|
|
assertNotNull(method);
|
|
MockParameterInfoUIContext<PsiMethod> uiContext = new MockParameterInfoUIContext<>(method);
|
|
String list = MethodParameterInfoHandler.updateMethodPresentation(method, PsiSubstitutor.EMPTY, uiContext);
|
|
assertEquals("int i", list);
|
|
PsiAnnotation[] annotations = AnnotationUtil.getAllAnnotations(method.getParameterList().getParameters()[0], false, null);
|
|
assertEquals(1, annotations.length);
|
|
}
|
|
|
|
public void testSelectionWithGenerics() {
|
|
doTest2CandidatesWithPreselection();
|
|
}
|
|
|
|
public void testOverloadWithVarargs() {
|
|
doTest2CandidatesWithPreselection();
|
|
}
|
|
|
|
public void testOverloadWithVarargsMultipleArgs() {
|
|
doTest2CandidatesWithPreselection();
|
|
}
|
|
|
|
public void testOverloadWithVarargsSingleArg() {
|
|
doTest2CandidatesWithPreselection();
|
|
}
|
|
|
|
public void testOverloadWithVarargsArray() {
|
|
doTest2CandidatesWithPreselection();
|
|
}
|
|
|
|
public void testSuperConstructorCalls() throws Exception {
|
|
myFixture.configureByText("x.java",
|
|
"class A {\n" +
|
|
" public A(String s, int... p) {}\n" +
|
|
" }\n" +
|
|
" class B extends A {\n" +
|
|
" public B() {\n" +
|
|
" super(<caret>\"a\", 1);\n" +
|
|
" }\n" +
|
|
" }");
|
|
PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiMethodCallExpression.class);
|
|
assertNotNull(callExpression);
|
|
assertNotNull(new MethodParameterInfoHandler().findElementForUpdatingParameterInfo(
|
|
new MockUpdateParameterInfoContext(getEditor(), getFile(), new Object[] {callExpression.resolveMethodGenerics()})));
|
|
}
|
|
|
|
private void doTest2CandidatesWithPreselection() {
|
|
myFixture.configureByFile(getTestName(false) + ".java");
|
|
|
|
MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
|
|
CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile());
|
|
PsiExpressionList list = handler.findElementForParameterInfo(context);
|
|
assertNotNull(list);
|
|
Object[] itemsToShow = context.getItemsToShow();
|
|
assertNotNull(itemsToShow);
|
|
assertEquals(2, itemsToShow.length);
|
|
assertTrue(itemsToShow[0] instanceof MethodCandidateInfo);
|
|
ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, -1);
|
|
MockUpdateParameterInfoContext updateParameterInfoContext = updateParameterInfo(handler, list, itemsToShow);
|
|
assertTrue(updateParameterInfoContext.isUIComponentEnabled(0) || updateParameterInfoContext.isUIComponentEnabled(1));
|
|
}
|
|
|
|
@NotNull
|
|
private MockUpdateParameterInfoContext updateParameterInfo(MethodParameterInfoHandler handler,
|
|
PsiExpressionList list,
|
|
Object[] itemsToShow) {
|
|
MockUpdateParameterInfoContext updateParameterInfoContext = new MockUpdateParameterInfoContext(getEditor(), getFile(), itemsToShow);
|
|
updateParameterInfoContext.setParameterOwner(list);
|
|
handler.updateParameterInfo(list, updateParameterInfoContext);
|
|
return updateParameterInfoContext;
|
|
}
|
|
|
|
public void testStopAtAccessibleStaticCorrectCandidate() {
|
|
myFixture.configureByFile(getTestName(false) + ".java");
|
|
|
|
MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
|
|
CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile());
|
|
PsiExpressionList list = handler.findElementForParameterInfo(context);
|
|
assertNotNull(list);
|
|
Object[] itemsToShow = context.getItemsToShow();
|
|
assertNotNull(itemsToShow);
|
|
assertEquals(1, itemsToShow.length);
|
|
assertEquals(0, ((MethodCandidateInfo)itemsToShow[0]).getElement().getParameterList().getParametersCount());
|
|
}
|
|
|
|
public void testAfterGenericsInsideCall() {
|
|
myFixture.configureByFile(getTestName(false) + ".java");
|
|
|
|
MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
|
|
CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile());
|
|
PsiExpressionList list = handler.findElementForParameterInfo(context);
|
|
assertNotNull(list);
|
|
Object[] itemsToShow = context.getItemsToShow();
|
|
assertNotNull(itemsToShow);
|
|
assertEquals(2, itemsToShow.length);
|
|
assertTrue(itemsToShow[0] instanceof MethodCandidateInfo);
|
|
PsiMethod method = ((MethodCandidateInfo)itemsToShow[0]).getElement();
|
|
ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, 1);
|
|
parameterContext.setUIComponentEnabled(true);
|
|
PsiSubstitutor substitutor = ((MethodCandidateInfo)itemsToShow[0]).getSubstitutor();
|
|
String presentation = MethodParameterInfoHandler.updateMethodPresentation(method, substitutor, parameterContext);
|
|
assertEquals("<html>Class<T> type, <b>boolean tags</b></html>", presentation);
|
|
}
|
|
|
|
public void testNoParams() { doTestPresentation("<html><no parameters></html>", -1); }
|
|
public void testGenericsInsideCall() { doTestPresentation("<html>List<String> param</html>", -1); }
|
|
public void testGenericsOutsideCall() { doTestPresentation("<html>List<String> param</html>", -1); }
|
|
public void testIgnoreVarargs() { doTestPresentation("<html>Class<T> a, <b>Class<? extends CharSequence>... stopAt</b></html>", 1); }
|
|
|
|
private void doTestPresentation(String expectedString, int parameterIndex) {
|
|
myFixture.configureByFile(getTestName(false) + ".java");
|
|
String presentation = parameterPresentation(parameterIndex);
|
|
assertEquals(expectedString, presentation);
|
|
}
|
|
|
|
private String parameterPresentation(int parameterIndex) {
|
|
return parameterPresentation(0, parameterIndex);
|
|
}
|
|
|
|
private String parameterPresentation(int lineIndex, int parameterIndex) {
|
|
MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
|
|
CreateParameterInfoContext context = createContext();
|
|
PsiExpressionList list = handler.findElementForParameterInfo(context);
|
|
assertNotNull(list);
|
|
Object[] itemsToShow = context.getItemsToShow();
|
|
assertNotNull(itemsToShow);
|
|
assertTrue(itemsToShow[lineIndex] instanceof MethodCandidateInfo);
|
|
PsiMethod method = ((MethodCandidateInfo)itemsToShow[lineIndex]).getElement();
|
|
ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, parameterIndex);
|
|
PsiSubstitutor substitutor = ((MethodCandidateInfo)itemsToShow[lineIndex]).getSubstitutor();
|
|
return MethodParameterInfoHandler.updateMethodPresentation(method, substitutor, parameterContext);
|
|
}
|
|
|
|
private CreateParameterInfoContext createContext() {
|
|
int caretOffset = getEditor().getCaretModel().getOffset();
|
|
PsiExpressionList argList = PsiTreeUtil.findElementOfClassAtOffset(getFile(), caretOffset, PsiExpressionList.class, false);
|
|
return new MockCreateParameterInfoContext(getEditor(), getFile()) {
|
|
@Override
|
|
public int getParameterListStart() {
|
|
return argList == null ? caretOffset : argList.getTextRange().getStartOffset();
|
|
}
|
|
};
|
|
}
|
|
|
|
public void testAnnotationWithGenerics() {
|
|
myFixture.configureByFile(getTestName(false) + ".java");
|
|
String text = annoParameterPresentation();
|
|
assertEquals("<html>Class<List<String[]>> <b>value</b>()</html>", text);
|
|
}
|
|
|
|
private String annoParameterPresentation() {
|
|
AnnotationParameterInfoHandler handler = new AnnotationParameterInfoHandler();
|
|
CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile());
|
|
PsiAnnotationParameterList list = handler.findElementForParameterInfo(context);
|
|
assertNotNull(list);
|
|
Object[] itemsToShow = context.getItemsToShow();
|
|
assertNotNull(itemsToShow);
|
|
assertEquals(1, itemsToShow.length);
|
|
assertTrue(itemsToShow[0] instanceof PsiAnnotationMethod);
|
|
PsiAnnotationMethod method = (PsiAnnotationMethod)itemsToShow[0];
|
|
ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, -1);
|
|
return AnnotationParameterInfoHandler.updateUIText(method, parameterContext);
|
|
}
|
|
|
|
public void testParameterAnnotation() {
|
|
myFixture.addClass("import java.lang.annotation.*;\n@Documented @Target({ElementType.PARAMETER}) @interface TA { }");
|
|
myFixture.configureByText("a.java", "class C {\n void m(@TA String s) { }\n void t() { m(<caret>\"test\"); }\n}");
|
|
assertEquals("<html>@TA String s</html>", parameterPresentation(-1));
|
|
}
|
|
|
|
public void testParameterUndocumentedAnnotation() {
|
|
myFixture.addClass("import java.lang.annotation.*;\n@Target({ElementType.PARAMETER}) @interface TA { }");
|
|
myFixture.configureByText("a.java", "class C {\n void m(@TA String s) { }\n void t() { m(<caret>\"test\"); }\n}");
|
|
assertEquals("<html>String s</html>", parameterPresentation(-1));
|
|
}
|
|
|
|
public void testParameterTypeAnnotation() {
|
|
myFixture.addClass("import java.lang.annotation.*;\n@Documented @Target({ElementType.PARAMETER, ElementType.TYPE_USE}) @interface TA { }");
|
|
myFixture.configureByText("a.java", "class C {\n void m(@TA String s) { }\n void t() { m(<caret>\"test\"); }\n}");
|
|
assertEquals("<html>@TA String s</html>", parameterPresentation(-1));
|
|
}
|
|
|
|
public void testParameterUndocumentedTypeAnnotation() {
|
|
myFixture.addClass("import java.lang.annotation.*;\n@Target({ElementType.PARAMETER, ElementType.TYPE_USE}) @interface TA { }");
|
|
myFixture.configureByText("a.java", "class C {\n void m(@TA String s) { }\n void t() { m(<caret>\"test\"); }\n}");
|
|
assertEquals("<html>@TA String s</html>", parameterPresentation(-1));
|
|
}
|
|
|
|
public void testHighlightMethodJustChosenInCompletion() {
|
|
myFixture.configureByText("a.java", "class Foo {" +
|
|
"{ bar<caret> }" +
|
|
"void bar(boolean a);" +
|
|
"void bar(String a);" +
|
|
"void bar(int a);" +
|
|
"void bar2(int a);" +
|
|
"}");
|
|
LookupElement[] elements = myFixture.completeBasic();
|
|
assertEquals("(String a)", LookupElementPresentation.renderElement(elements[1]).getTailText());
|
|
myFixture.getLookup().setCurrentItem(elements[1]);
|
|
myFixture.type('\n');
|
|
|
|
assertEquals("<html>boolean a</html>", parameterPresentation(0, -1));
|
|
assertEquals("<html>String a</html>", parameterPresentation(1, -1));
|
|
assertEquals("<html>int a</html>", parameterPresentation(2, -1));
|
|
|
|
checkHighlighted(1);
|
|
}
|
|
|
|
public void testHighlightConstructorJustChosenInCompletion() {
|
|
Registry.get("java.completion.show.constructors").setValue(true);
|
|
Disposer.register(myFixture.getTestRootDisposable(), () -> Registry.get("java.completion.show.constructors").setValue(false));
|
|
|
|
myFixture.addClass("class Bar {" +
|
|
"Bar(boolean a);" +
|
|
"Bar(String a);" +
|
|
"Bar(int a);" +
|
|
"}; " +
|
|
"class Bar2 {}");
|
|
myFixture.configureByText("a.java", "class Foo {{ new Bar<caret> }}");
|
|
LookupElement[] elements = myFixture.completeBasic();
|
|
assertEquals("(boolean a) (default package)", LookupElementPresentation.renderElement(elements[2]).getTailText());
|
|
myFixture.getLookup().setCurrentItem(elements[2]);
|
|
myFixture.type('\n');
|
|
myFixture.checkResult("class Foo {{ new Bar(<caret>) }}");
|
|
|
|
assertEquals("<html>boolean a</html>", parameterPresentation(0, -1));
|
|
assertEquals("<html>String a</html>", parameterPresentation(1, -1));
|
|
assertEquals("<html>int a</html>", parameterPresentation(2, -1));
|
|
|
|
checkHighlighted(0);
|
|
}
|
|
|
|
private void checkHighlighted(int lineIndex) {
|
|
MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
|
|
CreateParameterInfoContext context = createContext();
|
|
PsiExpressionList list = handler.findElementForParameterInfo(context);
|
|
Object[] itemsToShow = context.getItemsToShow();
|
|
assertEquals(itemsToShow[lineIndex], updateParameterInfo(handler, list, itemsToShow).getHighlightedParameter());
|
|
}
|
|
|
|
} |