mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 15:09:39 +07:00
[java] avoid copying nullability type annotations (IDEA-132058)
This commit is contained in:
@@ -342,7 +342,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
|
||||
if (parameter == null) {
|
||||
continue;
|
||||
}
|
||||
notNull(field, parameter);
|
||||
NullableNotNullManager.getInstance(field.getProject()).copyNotNullAnnotation(field, parameter);
|
||||
cleanupElements.add(parameter);
|
||||
final PsiElement assignmentStatement = AssignFieldFromParameterAction.addFieldAssignmentStatement(project, field, parameter, editor);
|
||||
if (assignmentStatement != null) {
|
||||
@@ -356,14 +356,6 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
|
||||
}
|
||||
}
|
||||
|
||||
private static void notNull(PsiField field, PsiParameter parameter) {
|
||||
final PsiAnnotation notNull = NullableNotNullManager.getInstance(field.getProject()).copyNotNullAnnotation(field);
|
||||
if (notNull != null) {
|
||||
//noinspection ConstantConditions
|
||||
parameter.getModifierList().addBefore(notNull, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiParameter findParamByName(String newName,
|
||||
PsiType type,
|
||||
|
||||
@@ -275,13 +275,7 @@ public class GenerateConstructorHandler extends GenerateMembersHandlerBase {
|
||||
parmName = javaStyle.suggestUniqueVariableName(parmName, dummyConstructor, true);
|
||||
PsiParameter parm = factory.createParameter(parmName, field.getType(), aClass);
|
||||
|
||||
PsiAnnotation notNull = NullableNotNullManager.getInstance(project).copyNotNullAnnotation(field);
|
||||
if (notNull != null) {
|
||||
PsiModifierList modifierList = parm.getModifierList();
|
||||
if (modifierList != null) {
|
||||
modifierList.addAfter(notNull, null);
|
||||
}
|
||||
}
|
||||
NullableNotNullManager.getInstance(project).copyNotNullAnnotation(field, parm);
|
||||
|
||||
if (constructor.isVarArgs()) {
|
||||
final PsiParameterList parameterList = constructor.getParameterList();
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationTargetUtil;
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -685,19 +686,9 @@ public class GenerateMembersUtil {
|
||||
}
|
||||
result = (PsiMethod)CodeStyleManager.getInstance(project).reformat(result);
|
||||
|
||||
PsiModifierListOwner listOwner = null;
|
||||
if (isGetter) {
|
||||
listOwner = result;
|
||||
}
|
||||
else {
|
||||
final PsiParameter[] parameters = result.getParameterList().getParameters();
|
||||
if (parameters.length == 1) {
|
||||
listOwner = parameters[0];
|
||||
}
|
||||
}
|
||||
if (listOwner != null) {
|
||||
PropertyUtil.annotateWithNullableStuff(field, listOwner);
|
||||
}
|
||||
PsiModifierListOwner annotationTarget = isGetter ? result : result.getParameterList().getParameters()[0];
|
||||
NullableNotNullManager.getInstance(project).copyNullableOrNotNullAnnotation(field, annotationTarget);
|
||||
|
||||
return generatePrototype(field, result);
|
||||
}
|
||||
|
||||
|
||||
@@ -195,17 +195,7 @@ public final class FieldFromParameterUtils {
|
||||
modifierList.setModifierProperty(PsiModifier.STATIC, isStatic);
|
||||
modifierList.setModifierProperty(PsiModifier.FINAL, isFinal);
|
||||
|
||||
final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
|
||||
final PsiAnnotation nullable = manager.copyNullableAnnotation(parameter);
|
||||
if (nullable != null) {
|
||||
modifierList.addAfter(nullable, null);
|
||||
}
|
||||
else if (isFinal) {
|
||||
final PsiAnnotation notNull = manager.copyNotNullAnnotation(parameter);
|
||||
if (notNull != null) {
|
||||
modifierList.addAfter(notNull, null);
|
||||
}
|
||||
}
|
||||
NullableNotNullManager.getInstance(project).copyNullableOrNotNullAnnotation(parameter, field);
|
||||
|
||||
PsiCodeBlock methodBody = method.getBody();
|
||||
if (methodBody == null) return;
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.intellij.refactoring.inheritanceToDelegation;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
|
||||
import com.intellij.codeInsight.generation.GenerateMembersUtil;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementUtil;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementExploreUtil;
|
||||
import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
|
||||
import com.intellij.lang.findUsages.DescriptiveNameUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -53,7 +53,6 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -465,7 +464,7 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor {
|
||||
|
||||
final PsiExpression newExpr;
|
||||
final PsiReferenceExpression ref;
|
||||
@NonNls final String delegateQualifier;
|
||||
final String delegateQualifier;
|
||||
if (!(expression instanceof PsiThisExpression || expression instanceof PsiSuperExpression)) {
|
||||
delegateQualifier = "a.";
|
||||
} else {
|
||||
@@ -498,7 +497,7 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor {
|
||||
if (!myAbstractDelegatedMethods.contains(method)) {
|
||||
PsiMethod methodToAdd = delegateMethod(myFieldName, method, getSuperSubstitutor(method.getContainingClass()));
|
||||
|
||||
String visibility = myDelegatedMethodsVisibility.get(method);
|
||||
@PsiModifier.ModifierConstant String visibility = myDelegatedMethodsVisibility.get(method);
|
||||
if (visibility != null) {
|
||||
PsiUtil.setModifierProperty(methodToAdd, visibility, true);
|
||||
}
|
||||
@@ -508,25 +507,15 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private PsiMethod delegateMethod(@NonNls String delegationTarget,
|
||||
private PsiMethod delegateMethod(String delegationTarget,
|
||||
PsiMethod method,
|
||||
PsiSubstitutor substitutor) throws IncorrectOperationException {
|
||||
substitutor = OverrideImplementUtil.correctSubstitutor(method, substitutor);
|
||||
substitutor = OverrideImplementExploreUtil.correctSubstitutor(method, substitutor);
|
||||
PsiMethod methodToAdd = GenerateMembersUtil.substituteGenericMethod(method, substitutor);
|
||||
|
||||
final PsiModifierList modifierList = methodToAdd.getModifierList();
|
||||
final NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject);
|
||||
modifierList.setModifierProperty(PsiModifier.ABSTRACT, false);
|
||||
final PsiAnnotation nullable = manager.copyNullableAnnotation(method);
|
||||
if (nullable != null) {
|
||||
modifierList.addAfter(nullable, null);
|
||||
}
|
||||
else {
|
||||
final PsiAnnotation notNull = manager.copyNotNullAnnotation(method);
|
||||
if (notNull != null) {
|
||||
modifierList.addAfter(notNull, null);
|
||||
}
|
||||
}
|
||||
methodToAdd.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, false);
|
||||
|
||||
NullableNotNullManager.getInstance(myProject).copyNullableOrNotNullAnnotation(method, methodToAdd);
|
||||
|
||||
final String delegationBody = getDelegationBody(methodToAdd, delegationTarget);
|
||||
PsiCodeBlock newBody = myFactory.createCodeBlockFromText(delegationBody, method);
|
||||
@@ -546,7 +535,7 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
private static String getDelegationBody(PsiMethod methodToAdd, String delegationTarget) {
|
||||
@NonNls final StringBuffer buffer = new StringBuffer();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("{\n");
|
||||
|
||||
if (!PsiType.VOID.equals(methodToAdd.getReturnType())) {
|
||||
@@ -618,7 +607,7 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor {
|
||||
|
||||
if (myGenerateGetter) {
|
||||
final String getterVisibility = PsiModifier.PUBLIC;
|
||||
@NonNls StringBuffer getterBuffer = new StringBuffer();
|
||||
StringBuffer getterBuffer = new StringBuffer();
|
||||
getterBuffer.append(getterVisibility);
|
||||
getterBuffer.append(" Object ");
|
||||
getterBuffer.append(myGetterName);
|
||||
@@ -647,12 +636,12 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor {
|
||||
return PsiModifier.PRIVATE;
|
||||
}
|
||||
|
||||
private @NonNls String defaultClassFieldType() {
|
||||
private String defaultClassFieldType() {
|
||||
return (myIsInnerClassNeeded ? myInnerClassName : "Object");
|
||||
}
|
||||
|
||||
private PsiField createField(final String fieldVisibility, final boolean fieldInitializerNeeded, String defaultTypeName) throws IncorrectOperationException {
|
||||
@NonNls StringBuffer buffer = new StringBuffer();
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append(fieldVisibility);
|
||||
buffer.append(" final " + defaultTypeName + " ");
|
||||
buffer.append(myFieldName);
|
||||
@@ -671,7 +660,7 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor {
|
||||
for (PsiMethod constructor : constructors) {
|
||||
PsiCodeBlock body = constructor.getBody();
|
||||
final PsiStatement[] statements = body.getStatements();
|
||||
@NonNls String fieldQualifier = "";
|
||||
String fieldQualifier = "";
|
||||
PsiParameter[] constructorParams = constructor.getParameterList().getParameters();
|
||||
for (PsiParameter constructorParam : constructorParams) {
|
||||
if (myFieldName.equals(constructorParam.getName())) {
|
||||
@@ -679,7 +668,7 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor {
|
||||
break;
|
||||
}
|
||||
}
|
||||
final @NonNls String assignmentText = fieldQualifier + myFieldName + "= new " + defaultClassFieldType() + "()";
|
||||
final String assignmentText = fieldQualifier + myFieldName + "= new " + defaultClassFieldType() + "()";
|
||||
if (statements.length < 1 || !JavaHighlightUtil.isSuperOrThisCall(statements[0], true, true) || myBaseClass.isInterface()) {
|
||||
PsiExpressionStatement assignmentStatement =
|
||||
(PsiExpressionStatement)myFactory.createStatementFromText(
|
||||
|
||||
@@ -137,10 +137,42 @@ public abstract class NullableNotNullManager implements PersistentStateComponent
|
||||
return findNullabilityAnnotationWithDefault(owner, checkBases, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiAnnotation copyNotNullAnnotation(@NotNull PsiModifierListOwner original, @NotNull PsiModifierListOwner generated) {
|
||||
return copyAnnotation(getNotNullAnnotation(original, false), generated);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiAnnotation copyNullableOrNotNullAnnotation(@NotNull PsiModifierListOwner original, @NotNull PsiModifierListOwner generated) {
|
||||
PsiAnnotation annotation = getNullableAnnotation(original, false);
|
||||
if (annotation == null) annotation = getNotNullAnnotation(original, false);
|
||||
return copyAnnotation(annotation, generated);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiAnnotation copyAnnotation(PsiAnnotation annotation, PsiModifierListOwner target) {
|
||||
// type annotations are part of target's type and should not to be copied explicitly to avoid duplication
|
||||
if (annotation != null && !AnnotationTargetUtil.isTypeAnnotation(annotation)) {
|
||||
String qualifiedName = checkContainer(annotation, false);
|
||||
if (qualifiedName != null) {
|
||||
PsiModifierList modifierList = target.getModifierList();
|
||||
if (modifierList != null && modifierList.findAnnotation(qualifiedName) == null) {
|
||||
return modifierList.addAnnotation(qualifiedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #copyNotNullAnnotation(PsiModifierListOwner, PsiModifierListOwner)} (to be removed in IDEA 17) */
|
||||
@SuppressWarnings("unused")
|
||||
public PsiAnnotation copyNotNullAnnotation(PsiModifierListOwner owner) {
|
||||
return copyAnnotation(owner, getNotNullAnnotation(owner, false));
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #copyNullableOrNotNullAnnotation(PsiModifierListOwner, PsiModifierListOwner)} (to be removed in IDEA 17) */
|
||||
@SuppressWarnings("unused")
|
||||
public PsiAnnotation copyNullableAnnotation(PsiModifierListOwner owner) {
|
||||
return copyAnnotation(owner, getNullableAnnotation(owner, false));
|
||||
}
|
||||
|
||||
@@ -401,7 +401,7 @@ public class PropertyUtil {
|
||||
PsiUtil.setModifierProperty(getMethod, PsiModifier.STATIC, true);
|
||||
}
|
||||
|
||||
annotateWithNullableStuff(field, getMethod);
|
||||
NullableNotNullManager.getInstance(project).copyNullableOrNotNullAnnotation(field, getMethod);
|
||||
|
||||
PsiCodeBlock body = factory.createCodeBlockFromText("{\nreturn " + name + ";\n}", null);
|
||||
getMethod.getBody().replace(body);
|
||||
@@ -457,7 +457,7 @@ public class PropertyUtil {
|
||||
String parameterName = codeStyleManager.propertyNameToVariableName(propertyName, VariableKind.PARAMETER);
|
||||
PsiParameter param = factory.createParameter(parameterName, field.getType());
|
||||
|
||||
annotateWithNullableStuff(field, param);
|
||||
NullableNotNullManager.getInstance(project).copyNullableOrNotNullAnnotation(field, param);
|
||||
|
||||
setMethod.getParameterList().add(param);
|
||||
PsiUtil.setModifierProperty(setMethod, PsiModifier.PUBLIC, true);
|
||||
@@ -496,27 +496,11 @@ public class PropertyUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated use {@link NullableNotNullManager#copyNullableOrNotNullAnnotation(PsiModifierListOwner, PsiModifierListOwner)} (to be removed in IDEA 17) */
|
||||
@SuppressWarnings("unused")
|
||||
public static void annotateWithNullableStuff(@NotNull PsiModifierListOwner field,
|
||||
@NotNull PsiModifierListOwner listOwner)
|
||||
throws IncorrectOperationException {
|
||||
final NullableNotNullManager manager = NullableNotNullManager.getInstance(field.getProject());
|
||||
final PsiAnnotation notNull = manager.copyNotNullAnnotation(field);
|
||||
if (notNull != null) {
|
||||
annotate(listOwner, notNull);
|
||||
}
|
||||
else {
|
||||
final PsiAnnotation nullable = manager.copyNullableAnnotation(field);
|
||||
if (nullable != null) {
|
||||
annotate(listOwner, nullable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void annotate(@NotNull PsiModifierListOwner listOwner, @NotNull PsiAnnotation annotation)
|
||||
throws IncorrectOperationException {
|
||||
final PsiModifierList modifierList = listOwner.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
modifierList.addAfter(annotation, null);
|
||||
@NotNull PsiModifierListOwner listOwner) throws IncorrectOperationException {
|
||||
NullableNotNullManager.getInstance(field.getProject()).copyNullableOrNotNullAnnotation(field, listOwner);
|
||||
}
|
||||
|
||||
public static String suggestPropertyName(@NotNull PsiField field) {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import foo.TestNotNull;
|
||||
|
||||
class C {
|
||||
private @TestNotNull String s;
|
||||
|
||||
public C(@TestNotNull String s) {
|
||||
this.s = s;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import foo.TestNotNull;
|
||||
|
||||
class C {
|
||||
private @TestNotNull String s;
|
||||
|
||||
<caret>
|
||||
}
|
||||
@@ -15,21 +15,36 @@
|
||||
*/
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.generation.ClassMember;
|
||||
import com.intellij.codeInsight.generation.GenerateConstructorHandler;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
public class GenerateConstructorTest extends LightCodeInsightTestCase {
|
||||
public class GenerateConstructorTest extends LightCodeInsightFixtureTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_8;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/generateConstructor";
|
||||
}
|
||||
|
||||
public void testAbstractClass() { doTest(); }
|
||||
public void testPackageLocalClass() { doTest(); }
|
||||
public void testPrivateClass() { doTest(); }
|
||||
@@ -61,13 +76,21 @@ public class GenerateConstructorTest extends LightCodeInsightTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testTypeAnnotatedField() {
|
||||
myFixture.addClass("package foo;\n\nimport java.lang.annotation.*;\n\n@Target(ElementType.TYPE_USE) public @interface TestNotNull { }");
|
||||
NullableNotNullManager manager = NullableNotNullManager.getInstance(getProject());
|
||||
manager.setNotNulls("foo.TestNotNull");
|
||||
Disposer.register(myTestRootDisposable, manager::setNotNulls);
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
private void doTest(boolean preSelect) {
|
||||
String name = getTestName(false);
|
||||
configureByFile("/codeInsight/generateConstructor/before" + name + ".java");
|
||||
myFixture.configureByFile("before" + name + ".java");
|
||||
new GenerateConstructorHandler() {
|
||||
@Override
|
||||
protected ClassMember[] chooseMembers(ClassMember[] members, boolean allowEmpty, boolean copyJavadoc, Project project, Editor editor) {
|
||||
@@ -80,6 +103,6 @@ public class GenerateConstructorTest extends LightCodeInsightTestCase {
|
||||
}
|
||||
}
|
||||
}.invoke(getProject(), getEditor(), getFile());
|
||||
checkResultByFile("/codeInsight/generateConstructor/after" + name + ".java");
|
||||
myFixture.checkResultByFile("after" + name + ".java");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -554,35 +554,17 @@ public class GroovyPropertyUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static void annotateWithNullableStuff(final PsiModifierListOwner field, final PsiModifierListOwner listOwner)
|
||||
throws IncorrectOperationException {
|
||||
final NullableNotNullManager manager = NullableNotNullManager.getInstance(field.getProject());
|
||||
final PsiAnnotation notNull = manager.copyNotNullAnnotation(field);
|
||||
if (notNull != null) {
|
||||
annotate(listOwner, notNull);
|
||||
}
|
||||
else {
|
||||
final PsiAnnotation nullable = manager.copyNullableAnnotation(field);
|
||||
if (nullable != null) {
|
||||
annotate(listOwner, nullable);
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("MagicConstant")
|
||||
private static void annotateWithNullableStuff(PsiModifierListOwner original,
|
||||
PsiModifierListOwner generated) throws IncorrectOperationException {
|
||||
NullableNotNullManager.getInstance(original.getProject()).copyNullableOrNotNullAnnotation(original, generated);
|
||||
|
||||
final PsiModifierList modifierList = listOwner.getModifierList();
|
||||
if (modifierList.hasExplicitModifier(GrModifier.DEF)) {
|
||||
PsiModifierList modifierList = generated.getModifierList();
|
||||
if (modifierList != null && modifierList.hasExplicitModifier(GrModifier.DEF)) {
|
||||
LOG.assertTrue(modifierList instanceof GrModifierList);
|
||||
if (modifierList.getAnnotations().length > 0 || ((GrModifierList)modifierList).getModifiers().length > 1) {
|
||||
((GrModifierList)modifierList).setModifierProperty(GrModifier.DEF, false);
|
||||
modifierList.setModifierProperty(GrModifier.DEF, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void annotate(final PsiModifierListOwner listOwner, final PsiAnnotation annotation)
|
||||
throws IncorrectOperationException {
|
||||
final PsiModifierList modifierList = listOwner.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
modifierList.addAnnotation(annotation.getQualifiedName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user