mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -17,10 +17,11 @@ package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.AnnotatedMembersSearch;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -37,15 +38,11 @@ public class FunctionalInterfaceSuggester {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final Set<PsiType> types = new LinkedHashSet<PsiType>();
|
||||
final String uniqueExprName = JavaCodeStyleManager.getInstance(project).suggestUniqueVariableName("l", expression, true);
|
||||
AnnotatedMembersSearch.search(functionalInterfaceClass, expression.getResolveScope()).forEach(new Processor<PsiMember>() {
|
||||
@Override
|
||||
public boolean process(PsiMember member) {
|
||||
if (member instanceof PsiClass) {
|
||||
final PsiType type = getAcceptableType((PsiClass)member, expression, uniqueExprName);
|
||||
if (type != null) {
|
||||
types.add(type);
|
||||
}
|
||||
ContainerUtil.addIfNotNull(types, composeAcceptableType((PsiClass)member, expression));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -53,26 +50,60 @@ public class FunctionalInterfaceSuggester {
|
||||
return types;
|
||||
}
|
||||
|
||||
private static PsiType getAcceptableType(PsiClass interface2Consider, PsiFunctionalExpression expression, String uniqueExprName) {
|
||||
private static PsiType composeAcceptableType(@NotNull PsiClass interface2Consider, @NotNull PsiFunctionalExpression expression) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(interface2Consider.getProject());
|
||||
//todo try to infer type
|
||||
final PsiDeclarationStatement exprDeclaration = (PsiDeclarationStatement)elementFactory
|
||||
.createStatementFromText(interface2Consider.getQualifiedName() + " " + uniqueExprName + " = " + expression.getText() + ";", expression);
|
||||
|
||||
final PsiLocalVariable var = (PsiLocalVariable)exprDeclaration.getDeclaredElements()[0];
|
||||
final PsiExpression exprAsInitializer = var.getInitializer();
|
||||
if (exprAsInitializer instanceof PsiFunctionalExpression) {
|
||||
|
||||
if (!((PsiFunctionalExpression)exprAsInitializer).isAcceptable(var.getType())) {
|
||||
return null;
|
||||
}
|
||||
final PsiType type = ((PsiFunctionalExpression)exprAsInitializer).getFunctionalInterfaceType();
|
||||
if (type instanceof PsiLambdaExpressionType || type instanceof PsiLambdaParameterType || type instanceof PsiMethodReferenceType) {
|
||||
return null;
|
||||
}
|
||||
final PsiType type = elementFactory.createType(interface2Consider, PsiSubstitutor.EMPTY);
|
||||
if (expression.isAcceptable(type)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
return composeAcceptableType(interface2Consider, expression, elementFactory);
|
||||
}
|
||||
|
||||
private static PsiType composeAcceptableType(final PsiClass interface2Consider,
|
||||
final PsiFunctionalExpression expression,
|
||||
final PsiElementFactory elementFactory) {
|
||||
|
||||
if (interface2Consider.hasTypeParameters()) {
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(interface2Consider);
|
||||
if (interfaceMethod != null) {
|
||||
final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
|
||||
final PsiParameter[] functionalExprParameters;
|
||||
if (expression instanceof PsiLambdaExpression && ((PsiLambdaExpression)expression).hasFormalParameterTypes()) {
|
||||
functionalExprParameters = ((PsiLambdaExpression)expression).getParameterList().getParameters();
|
||||
}
|
||||
else if (expression instanceof PsiMethodReferenceExpression && ((PsiMethodReferenceExpression)expression).isExact()) {
|
||||
final PsiElement exactMethod = ((PsiMethodReferenceExpression)expression).resolve();
|
||||
if (!(exactMethod instanceof PsiMethod)) {
|
||||
return null;
|
||||
}
|
||||
functionalExprParameters = ((PsiMethod)exactMethod).getParameterList().getParameters();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (parameters.length != functionalExprParameters.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiType[] left = new PsiType[parameters.length];
|
||||
final PsiType[] right = new PsiType[parameters.length];
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
left[i] = parameters[i].getType();
|
||||
right[i] = functionalExprParameters[i].getType();
|
||||
}
|
||||
|
||||
final PsiSubstitutor substitutor = PsiResolveHelper.SERVICE.getInstance(interface2Consider.getProject())
|
||||
.inferTypeArguments(interface2Consider.getTypeParameters(), left, right, PsiUtil.getLanguageLevel(expression));
|
||||
|
||||
PsiType type = elementFactory.createType(interface2Consider, substitutor);
|
||||
|
||||
if (expression.isAcceptable(type)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -135,7 +135,7 @@ public class InplaceIntroduceConstantPopup extends AbstractInplaceIntroduceField
|
||||
public PsiField compute() {
|
||||
|
||||
PsiField field = elementFactory.createFieldFromText(
|
||||
psiType.getCanonicalText() + " " + (getInputName() != null ? getInputName() : names[0]) + " = " + myInitializerText + ";",
|
||||
psiType.getCanonicalText() + " " + (chooseName(names, myParentClass.getLanguage())) + " = " + myInitializerText + ";",
|
||||
myParentClass);
|
||||
PsiUtil.setModifierProperty(field, PsiModifier.FINAL, true);
|
||||
PsiUtil.setModifierProperty(field, PsiModifier.STATIC, true);
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public class InplaceIntroduceFieldPopup extends AbstractInplaceIntroduceFieldPop
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiField>() {
|
||||
@Override
|
||||
public PsiField compute() {
|
||||
PsiField field = elementFactory.createField(getInputName() != null ? getInputName() : names[0], defaultType);
|
||||
PsiField field = elementFactory.createField(chooseName(names, myParentClass.getLanguage()), defaultType);
|
||||
field = (PsiField)myParentClass.add(field);
|
||||
if (myExprText != null) {
|
||||
updateInitializer(elementFactory, field);
|
||||
|
||||
+8
-1
@@ -6,6 +6,7 @@ import com.intellij.codeInsight.template.Expression;
|
||||
import com.intellij.codeInsight.template.ExpressionContext;
|
||||
import com.intellij.codeInsight.template.Result;
|
||||
import com.intellij.codeInsight.template.TextResult;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
@@ -49,7 +50,6 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro
|
||||
|
||||
@Override
|
||||
protected String[] suggestNames(boolean replaceAll, PsiVariable variable) {
|
||||
myTypeSelectorManager.setAllOccurrences(replaceAll);
|
||||
final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
final String propertyName = variable != null
|
||||
? JavaCodeStyleManager.getInstance(myProject).variableNameToPropertyName(variable.getName(), VariableKind.LOCAL_VARIABLE)
|
||||
@@ -204,4 +204,11 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro
|
||||
};
|
||||
}
|
||||
|
||||
protected String chooseName(String[] names, Language language) {
|
||||
String inputName = getInputName();
|
||||
if (inputName != null && !isIdentifier(inputName, language)) {
|
||||
inputName = null;
|
||||
}
|
||||
return inputName != null ? inputName : names[0];
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -116,10 +116,9 @@ public class InplaceIntroduceParameterPopup extends AbstractJavaInplaceIntroduce
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiParameter>() {
|
||||
@Override
|
||||
public PsiParameter compute() {
|
||||
final String name = getInputName() != null ? getInputName() : names[0];
|
||||
final PsiParameter anchor = JavaIntroduceParameterMethodUsagesProcessor.getAnchorParameter(myMethod);
|
||||
final PsiParameter psiParameter = (PsiParameter)myMethod.getParameterList()
|
||||
.addAfter(elementFactory.createParameter(name, defaultType), anchor);
|
||||
.addAfter(elementFactory.createParameter(chooseName(names, myMethod.getLanguage()), defaultType), anchor);
|
||||
PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, myPanel.hasFinalModifier());
|
||||
myParameterIndex = myMethod.getParameterList().getParameterIndex(psiParameter);
|
||||
return psiParameter;
|
||||
|
||||
-4
@@ -185,7 +185,6 @@ public abstract class IntroduceParameterSettingsUI {
|
||||
box.setSelected(myCbReplaceAllOccurences.isSelected());
|
||||
}
|
||||
}
|
||||
getTypeSelectionManager().setAllOccurrences(myCbReplaceAllOccurences.isSelected());
|
||||
if (myCbReplaceAllOccurences.isSelected()) {
|
||||
if (myCbDeleteLocalVariable != null) {
|
||||
myCbDeleteLocalVariable.makeSelectable();
|
||||
@@ -197,9 +196,6 @@ public abstract class IntroduceParameterSettingsUI {
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
getTypeSelectionManager().setAllOccurrences(myIsInvokedOnDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract TypeSelectorManager getTypeSelectionManager();
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
public class Derr {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String value;
|
||||
|
||||
value = "1";
|
||||
value = "1";
|
||||
value = "<caret>1";
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
public class Derr {
|
||||
|
||||
public static final String STRING = "1";
|
||||
|
||||
public static void main(String[] args) {
|
||||
String value;
|
||||
|
||||
value = STRING;
|
||||
value = STRING;
|
||||
value = STRING;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public class Derr {
|
||||
|
||||
public static void main(String[] args) {
|
||||
long value;
|
||||
|
||||
value = new Long(1);
|
||||
value = new L<caret>ong(1);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public class Derr {
|
||||
|
||||
public static void main(String[] args, Long aLong) {
|
||||
long value;
|
||||
|
||||
value = aLong;
|
||||
value = aLong;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.util.function.Consumer;
|
||||
|
||||
class Foo {
|
||||
void test() {
|
||||
Consumer<Integer> l = System::exit;
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Foo {
|
||||
void test() {
|
||||
<selection>System::exit</selection>;
|
||||
}
|
||||
}
|
||||
@@ -78,6 +78,16 @@ public class InplaceIntroduceConstantTest extends AbstractJavaInplaceIntroduceTe
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testReplaceAllWithBrokenIdentifier() throws Exception {
|
||||
doTest(new Pass<AbstractInplaceIntroducer>() {
|
||||
@Override
|
||||
public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) {
|
||||
type("A B");
|
||||
inplaceIntroduceFieldPopup.setReplaceAllOccurrences(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testReplaceAllFromSecondOccurrence() throws Exception {
|
||||
|
||||
|
||||
@@ -60,6 +60,16 @@ public class InplaceIntroduceParameterTest extends AbstractJavaInplaceIntroduceT
|
||||
});
|
||||
}
|
||||
|
||||
public void testReplaceAllBrokenIdentifier() throws Exception {
|
||||
doTest(new Pass<AbstractInplaceIntroducer>() {
|
||||
@Override
|
||||
public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) {
|
||||
type("ONE TWO");
|
||||
inplaceIntroduceFieldPopup.setReplaceAllOccurrences(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testReplaceAll2() throws Exception {
|
||||
doTest(new Pass<AbstractInplaceIntroducer>() {
|
||||
@Override
|
||||
|
||||
@@ -437,7 +437,11 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
|
||||
}
|
||||
|
||||
public void testMethodRefNotInContext() {
|
||||
doTest(new MockIntroduceVariableHandler("l", false, false, false, "java.util.function.IntConsumer"));
|
||||
doTest(new MockIntroduceVariableHandler("l", false, false, false, "java.util.function.IntConsumer", true));
|
||||
}
|
||||
|
||||
public void testMethodRefNotInContextInferred() {
|
||||
doTest(new MockIntroduceVariableHandler("l", false, false, false, "java.util.function.Consumer<java.lang.Integer>", true));
|
||||
}
|
||||
|
||||
public void testOneLineLambdaVoidCompatible() {
|
||||
|
||||
+2
-1
@@ -51,6 +51,7 @@ import com.intellij.psi.PsiCompiledElement;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.refactoring.rename.inplace.InplaceRefactoring;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -198,7 +199,7 @@ public class SurroundWithHandler implements CodeInsightActionHandler {
|
||||
editor.getCaretModel().moveToLogicalPosition(pos);
|
||||
}
|
||||
TextRange range = surrounder.surroundElements(project, editor, elements);
|
||||
if (TemplateManager.getInstance(project).getActiveTemplate(editor) == null) {
|
||||
if (TemplateManager.getInstance(project).getActiveTemplate(editor) == null && InplaceRefactoring.getActiveInplaceRenamer(editor) == null) {
|
||||
LogicalPosition pos1 = new LogicalPosition(line, col);
|
||||
editor.getCaretModel().moveToLogicalPosition(pos1);
|
||||
}
|
||||
|
||||
+13
-8
@@ -318,14 +318,19 @@ public abstract class AbstractInplaceIntroducer<V extends PsiNameIdentifierOwner
|
||||
myEditor.putUserData(INTRODUCE_RESTART, true);
|
||||
try {
|
||||
final TextRange range = templateState.getCurrentVariableRange();
|
||||
if (range != null && range.isEmpty()) {
|
||||
final String[] names = suggestNames(isReplaceAllOccurrences(), getLocalVariable());
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myEditor.getDocument().insertString(myEditor.getCaretModel().getOffset(), names[0]);
|
||||
}
|
||||
});
|
||||
if (range != null) {
|
||||
final TextResult inputText = templateState.getVariableValue(PRIMARY_VARIABLE_NAME);
|
||||
final String inputName = inputText != null ? inputText.getText() : null;
|
||||
final V variable = getVariable();
|
||||
if (inputName == null || variable == null || !isIdentifier(inputName, variable.getLanguage())) {
|
||||
final String[] names = suggestNames(isReplaceAllOccurrences(), getLocalVariable());
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myEditor.getDocument().replaceString(range.getStartOffset(), range.getEndOffset(), names[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
templateState.gotoEnd(true);
|
||||
try {
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ChangeSet {
|
||||
public ChangeSet(long id, long timestamp) {
|
||||
myId = id;
|
||||
myTimestamp = timestamp;
|
||||
myChanges = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
myChanges = new ArrayList<Change>();
|
||||
}
|
||||
|
||||
public ChangeSet(DataInput in) throws IOException {
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public class ClassWithOnlyPrivateConstructorsInspectionBase extends BaseInspecti
|
||||
@Override
|
||||
public void visitClass(PsiClass aClass) {
|
||||
super.visitClass(aClass);
|
||||
if (aClass.isEnum()) {
|
||||
if (aClass.isEnum() || aClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
return;
|
||||
}
|
||||
final PsiMethod[] constructors = aClass.getConstructors();
|
||||
|
||||
+6
@@ -41,6 +41,12 @@ public class ClassWithOnlyPrivateConstructorsInspectionTest extends LightInspect
|
||||
doTest("class X {}");
|
||||
}
|
||||
|
||||
public void testNoWarnOnFinalClass() {
|
||||
doTest("final class X {" +
|
||||
" private X() {}" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testEnum() {
|
||||
doTest("enum Currencies {\n" +
|
||||
" EURO, DOLLAR;\n" +
|
||||
|
||||
Reference in New Issue
Block a user