summaryrefslogtreecommitdiff
path: root/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions
diff options
context:
space:
mode:
Diffstat (limited to 'java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions')
-rw-r--r--java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ChangeClassParametersIntention.java124
-rw-r--r--java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java218
-rw-r--r--java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java145
3 files changed, 487 insertions, 0 deletions
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ChangeClassParametersIntention.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ChangeClassParametersIntention.java
new file mode 100644
index 000000000000..9571807cd229
--- /dev/null
+++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ChangeClassParametersIntention.java
@@ -0,0 +1,124 @@
+package com.intellij.refactoring.typeMigration.intentions;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
+import com.intellij.codeInsight.intention.impl.TypeExpression;
+import com.intellij.codeInsight.template.*;
+import com.intellij.codeInsight.template.impl.TemplateState;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.*;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.refactoring.typeMigration.TypeMigrationProcessor;
+import com.intellij.refactoring.typeMigration.TypeMigrationRules;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author anna
+ */
+public class ChangeClassParametersIntention extends PsiElementBaseIntentionAction {
+
+ private static final Logger LOG = Logger.getInstance("#" + ChangeClassParametersIntention.class);
+
+ @NotNull
+ @Override
+ public String getText() {
+ return getFamilyName();
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Change class type parameter";
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
+ final PsiTypeElement typeElement = PsiTreeUtil.getTopmostParentOfType(element, PsiTypeElement.class);
+ final PsiElement parent = typeElement != null ? typeElement.getParent() : null;
+ final PsiReferenceParameterList parameterList = parent instanceof PsiReferenceParameterList ? (PsiReferenceParameterList)parent : null;
+ if (parameterList != null && parameterList.getTypeArguments().length > 0) {
+ final PsiMember member = PsiTreeUtil.getParentOfType(parameterList, PsiMember.class);
+ if (member instanceof PsiAnonymousClass) {
+ final PsiClassType.ClassResolveResult result = ((PsiAnonymousClass)member).getBaseClassType().resolveGenerics();
+ return result.getElement() != null && ((PsiAnonymousClass)member).getBaseClassReference().getParameterList() == parameterList;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException {
+ if (!FileModificationService.getInstance().preparePsiElementsForWrite(element)) return;
+
+ final PsiTypeElement typeElement = PsiTreeUtil.getTopmostParentOfType(element, PsiTypeElement.class);
+ final PsiReferenceParameterList parameterList = PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class);
+ if (parameterList != null && typeElement != null) {
+ final PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
+ if (aClass instanceof PsiAnonymousClass) {
+ editor.getCaretModel().moveToOffset(aClass.getTextOffset());
+ final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
+ final int changeIdx = ArrayUtil.find(typeElements, typeElement);
+
+ final PsiClassType.ClassResolveResult result = ((PsiAnonymousClass)aClass).getBaseClassType().resolveGenerics();
+ final PsiClass baseClass = result.getElement();
+ LOG.assertTrue(baseClass != null);
+ final PsiTypeParameter typeParameter = baseClass.getTypeParameters()[changeIdx];
+
+ final TemplateBuilderImpl templateBuilder = (TemplateBuilderImpl)TemplateBuilderFactory.getInstance().createTemplateBuilder(aClass);
+
+ final String oldTypeText = typeElement.getText();
+ final String varName = "param";
+ templateBuilder.replaceElement(typeElement, varName, new TypeExpression(project, new PsiType[]{typeElement.getType()}), true);
+
+ final Template template = templateBuilder.buildInlineTemplate();
+ TemplateManager.getInstance(project).startTemplate(editor, template, false, null, new TemplateEditingAdapter() {
+ private String myNewType;
+
+ @Override
+ public void beforeTemplateFinished(TemplateState state, Template template) {
+ final TextResult value = state.getVariableValue(varName);
+ myNewType = value != null ? value.getText() : "";
+ final int segmentsCount = state.getSegmentsCount();
+ final Document document = state.getEditor().getDocument();
+ for (int i = 0; i < segmentsCount; i++) {
+ final TextRange segmentRange = state.getSegmentRange(i);
+ document.replaceString(segmentRange.getStartOffset(), segmentRange.getEndOffset(), oldTypeText);
+ }
+ }
+
+ @Override
+ public void templateFinished(Template template, boolean brokenOff) {
+ if (!brokenOff) {
+ final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
+ try {
+ final PsiType targetParam = elementFactory.createTypeFromText(myNewType, aClass);
+ final TypeMigrationRules myRules = new TypeMigrationRules(((PsiAnonymousClass)aClass).getBaseClassType());
+ final PsiSubstitutor substitutor = result.getSubstitutor().put(typeParameter, targetParam);
+ final PsiType targetClassType = elementFactory.createType(baseClass, substitutor);
+ myRules.setMigrationRootType(targetClassType);
+ myRules.setBoundScope(new LocalSearchScope(aClass));
+ new TypeMigrationProcessor(project, ((PsiAnonymousClass)aClass).getBaseClassReference().getParameterList(), myRules).run();
+ }
+ catch (IncorrectOperationException e) {
+ HintManager.getInstance().showErrorHint(editor, "Incorrect type");
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return true;
+ }
+}
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java
new file mode 100644
index 000000000000..d794d59f9943
--- /dev/null
+++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java
@@ -0,0 +1,218 @@
+package com.intellij.refactoring.typeMigration.intentions;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.intention.LowPriorityAction;
+import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.impl.AllowedApiFilterExtension;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
+import com.intellij.refactoring.typeMigration.TypeMigrationReplacementUtil;
+import com.intellij.refactoring.typeMigration.rules.AtomicConversionRule;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.Query;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.*;
+
+import static com.intellij.psi.util.TypeConversionUtil.isBinaryOperatorApplicable;
+import static com.intellij.util.ObjectUtils.assertNotNull;
+
+/**
+ * @author anna
+ * @since 26-Aug-2009
+ */
+public class ConvertFieldToAtomicIntention extends PsiElementBaseIntentionAction implements LowPriorityAction {
+ private static final Logger LOG = Logger.getInstance("#" + ConvertFieldToAtomicIntention.class.getName());
+
+ private final Map<PsiType, String> myFromToMap = ContainerUtil.newHashMap();
+ {
+ myFromToMap.put(PsiType.INT, AtomicInteger.class.getName());
+ myFromToMap.put(PsiType.LONG, AtomicLong.class.getName());
+ myFromToMap.put(PsiType.BOOLEAN, AtomicBoolean.class.getName());
+ myFromToMap.put(PsiType.INT.createArrayType(), AtomicIntegerArray.class.getName());
+ myFromToMap.put(PsiType.LONG.createArrayType(), AtomicLongArray.class.getName());
+ }
+
+ @NotNull
+ @Override
+ public String getText() {
+ return "Convert to atomic";
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getText();
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
+ PsiVariable psiVariable = getVariable(element);
+ if (psiVariable == null || psiVariable instanceof PsiResourceVariable) return false;
+ if (psiVariable.getLanguage() != JavaLanguage.INSTANCE) return false;
+ if (psiVariable.getTypeElement() == null) return false;
+ if (!PsiUtil.isLanguageLevel5OrHigher(psiVariable)) return false;
+ final PsiType psiType = psiVariable.getType();
+ final PsiClass psiTypeClass = PsiUtil.resolveClassInType(psiType);
+ if (psiTypeClass != null) {
+ final String qualifiedName = psiTypeClass.getQualifiedName();
+ if (qualifiedName != null) { //is already atomic
+ if (myFromToMap.values().contains(qualifiedName) ||
+ qualifiedName.equals(AtomicReference.class.getName()) ||
+ qualifiedName.equals(AtomicReferenceArray.class.getName())) {
+ return false;
+ }
+ }
+ }
+ else if (!myFromToMap.containsKey(psiType)) {
+ return false;
+ }
+ return AllowedApiFilterExtension.isClassAllowed(AtomicReference.class.getName(), element);
+ }
+
+ private static PsiVariable getVariable(PsiElement element) {
+ if (element instanceof PsiIdentifier) {
+ final PsiElement parent = element.getParent();
+ if (parent instanceof PsiLocalVariable || parent instanceof PsiField) {
+ return (PsiVariable)parent;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
+ final PsiVariable psiVariable = getVariable(element);
+ LOG.assertTrue(psiVariable != null);
+
+ final Query<PsiReference> refs = ReferencesSearch.search(psiVariable);
+
+ final Set<PsiElement> elements = new HashSet<PsiElement>();
+ elements.add(element);
+ for (PsiReference reference : refs) {
+ elements.add(reference.getElement());
+ }
+ if (!FileModificationService.getInstance().preparePsiElementsForWrite(elements)) return;
+
+ final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+ final PsiType fromType = psiVariable.getType();
+ PsiClassType toType;
+ final String atomicQualifiedName = myFromToMap.get(fromType);
+ if (atomicQualifiedName != null) {
+ final PsiClass atomicClass = psiFacade.findClass(atomicQualifiedName, GlobalSearchScope.allScope(project));
+ if (atomicClass == null) {//show warning
+ return;
+ }
+ toType = factory.createType(atomicClass);
+ }
+ else if (fromType instanceof PsiArrayType) {
+ final PsiClass atomicReferenceArrayClass =
+ psiFacade.findClass(AtomicReferenceArray.class.getName(), GlobalSearchScope.allScope(project));
+ if (atomicReferenceArrayClass == null) {//show warning
+ return;
+ }
+ final Map<PsiTypeParameter, PsiType> substitutor = ContainerUtil.newHashMap();
+ final PsiTypeParameter[] typeParameters = atomicReferenceArrayClass.getTypeParameters();
+ if (typeParameters.length == 1) {
+ PsiType componentType = ((PsiArrayType)fromType).getComponentType();
+ if (componentType instanceof PsiPrimitiveType) componentType = ((PsiPrimitiveType)componentType).getBoxedType(element);
+ substitutor.put(typeParameters[0], componentType);
+ }
+ toType = factory.createType(atomicReferenceArrayClass, factory.createSubstitutor(substitutor));
+ }
+ else {
+ final PsiClass atomicReferenceClass = psiFacade.findClass(AtomicReference.class.getName(), GlobalSearchScope.allScope(project));
+ if (atomicReferenceClass == null) {//show warning
+ return;
+ }
+ final Map<PsiTypeParameter, PsiType> substitutor = ContainerUtil.newHashMap();
+ final PsiTypeParameter[] typeParameters = atomicReferenceClass.getTypeParameters();
+ if (typeParameters.length == 1) {
+ PsiType type = fromType;
+ if (type instanceof PsiPrimitiveType) type = ((PsiPrimitiveType)fromType).getBoxedType(element);
+ substitutor.put(typeParameters[0], type);
+ }
+ toType = factory.createType(atomicReferenceClass, factory.createSubstitutor(substitutor));
+ }
+
+ try {
+ for (PsiReference reference : refs) {
+ PsiElement psiElement = reference.getElement();
+ if (psiElement instanceof PsiExpression) {
+ final PsiElement parent = psiElement.getParent();
+ if (parent instanceof PsiExpression && !(parent instanceof PsiReferenceExpression || parent instanceof PsiPolyadicExpression)) {
+ psiElement = parent;
+ }
+ if (psiElement instanceof PsiBinaryExpression) {
+ PsiBinaryExpression binary = (PsiBinaryExpression)psiElement;
+ if (isBinaryOperatorApplicable(binary.getOperationTokenType(), binary.getLOperand(), binary.getROperand(), true)) {
+ continue;
+ }
+ }
+ else if (psiElement instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression assignment = (PsiAssignmentExpression)psiElement;
+ final IElementType opSign = TypeConversionUtil.convertEQtoOperation(assignment.getOperationTokenType());
+ if (opSign != null && isBinaryOperatorApplicable(opSign, assignment.getLExpression(), assignment.getRExpression(), true)) {
+ continue;
+ }
+ }
+ final TypeConversionDescriptor directConversion = AtomicConversionRule.findDirectConversion(psiElement, toType, fromType);
+ if (directConversion != null) {
+ TypeMigrationReplacementUtil.replaceExpression((PsiExpression)psiElement, project, directConversion);
+ }
+ }
+ }
+
+ final PsiExpression initializer = psiVariable.getInitializer();
+ if (initializer != null) {
+ final TypeConversionDescriptor directConversion = AtomicConversionRule.wrapWithNewExpression(toType, fromType, null, element);
+ if (directConversion != null) {
+ TypeMigrationReplacementUtil.replaceExpression(initializer, project, directConversion);
+ }
+ }
+ else if (!assertNotNull(psiVariable.getModifierList()).hasModifierProperty(PsiModifier.FINAL)) {
+ final PsiExpression newInitializer = factory.createExpressionFromText("new " + toType.getCanonicalText() + "()", psiVariable);
+ if (psiVariable instanceof PsiLocalVariable) {
+ ((PsiLocalVariable)psiVariable).setInitializer(newInitializer);
+ }
+ else if (psiVariable instanceof PsiField) {
+ ((PsiField)psiVariable).setInitializer(newInitializer);
+ }
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(psiVariable.getInitializer());
+ }
+
+ PsiElement replaced = assertNotNull(psiVariable.getTypeElement()).replace(factory.createTypeElement(toType));
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced);
+
+ if (psiVariable instanceof PsiField || CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS) {
+ final PsiModifierList modifierList = assertNotNull(psiVariable.getModifierList());
+ modifierList.setModifierProperty(PsiModifier.FINAL, true);
+ modifierList.setModifierProperty(PsiModifier.VOLATILE, false);
+ }
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return true;
+ }
+}
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java
new file mode 100644
index 000000000000..e01aaadae7d8
--- /dev/null
+++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java
@@ -0,0 +1,145 @@
+/*
+ * User: anna
+ * Date: 26-Aug-2009
+ */
+package com.intellij.refactoring.typeMigration.intentions;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.intention.LowPriorityAction;
+import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.impl.AllowedApiFilterExtension;
+import com.intellij.psi.impl.PsiDiamondTypeUtil;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
+import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+import com.intellij.refactoring.typeMigration.TypeMigrationReplacementUtil;
+import com.intellij.refactoring.typeMigration.TypeMigrationRules;
+import com.intellij.refactoring.typeMigration.rules.ThreadLocalConversionRule;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.Query;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static com.intellij.util.ObjectUtils.assertNotNull;
+
+public class ConvertFieldToThreadLocalIntention extends PsiElementBaseIntentionAction implements LowPriorityAction {
+ private static final Logger LOG = Logger.getInstance("#" + ConvertFieldToThreadLocalIntention.class.getName());
+
+ @NotNull
+ @Override
+ public String getText() {
+ return "Convert to ThreadLocal";
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getText();
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
+ if (!(element instanceof PsiIdentifier)) return false;
+ final PsiField psiField = PsiTreeUtil.getParentOfType(element, PsiField.class);
+ if (psiField == null) return false;
+ if (psiField.getLanguage() != JavaLanguage.INSTANCE) return false;
+ if (psiField.getTypeElement() == null) return false;
+ final PsiType fieldType = psiField.getType();
+ final PsiClass fieldTypeClass = PsiUtil.resolveClassInType(fieldType);
+ if (fieldType instanceof PsiPrimitiveType || fieldType instanceof PsiArrayType) return true;
+ return fieldTypeClass != null && !Comparing.strEqual(fieldTypeClass.getQualifiedName(), ThreadLocal.class.getName())
+ && AllowedApiFilterExtension.isClassAllowed(ThreadLocal.class.getName(), element);
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
+ final PsiField psiField = PsiTreeUtil.getParentOfType(element, PsiField.class);
+ LOG.assertTrue(psiField != null);
+ final Query<PsiReference> refs = ReferencesSearch.search(psiField);
+
+ final Set<PsiElement> elements = new HashSet<PsiElement>();
+ elements.add(element);
+ for (PsiReference reference : refs) {
+ elements.add(reference.getElement());
+ }
+ if (!FileModificationService.getInstance().preparePsiElementsForWrite(elements)) return;
+
+ final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+ final PsiType fromType = psiField.getType();
+
+ final PsiClass threadLocalClass = psiFacade.findClass(ThreadLocal.class.getName(), GlobalSearchScope.allScope(project));
+ if (threadLocalClass == null) {//show warning
+ return;
+ }
+ final Map<PsiTypeParameter, PsiType> substitutor = ContainerUtil.newHashMap();
+ final PsiTypeParameter[] typeParameters = threadLocalClass.getTypeParameters();
+ if (typeParameters.length == 1) {
+ PsiType type = fromType;
+ if (fromType instanceof PsiPrimitiveType) type = ((PsiPrimitiveType)fromType).getBoxedType(element);
+ substitutor.put(typeParameters[0], type);
+ }
+ final PsiClassType toType = factory.createType(threadLocalClass, factory.createSubstitutor(substitutor));
+
+ try {
+ final TypeMigrationRules rules = new TypeMigrationRules(fromType);
+ rules.setMigrationRootType(toType);
+ rules.setBoundScope(GlobalSearchScope.fileScope(element.getContainingFile()));
+ final TypeMigrationLabeler labeler = new TypeMigrationLabeler(rules);
+ labeler.getMigratedUsages(false, psiField);
+ for (PsiReference reference : refs) {
+ PsiElement psiElement = reference.getElement();
+ if (psiElement instanceof PsiExpression) {
+ final PsiElement parent = psiElement.getParent();
+ if (parent instanceof PsiExpression && !(parent instanceof PsiReferenceExpression || parent instanceof PsiPolyadicExpression)) {
+ psiElement = parent;
+ }
+ final TypeConversionDescriptor conversion = ThreadLocalConversionRule.findDirectConversion(psiElement, toType, fromType, labeler);
+ if (conversion != null) {
+ TypeMigrationReplacementUtil.replaceExpression((PsiExpression)psiElement, project, conversion);
+ }
+ }
+ }
+
+ final PsiExpression initializer = psiField.getInitializer();
+ if (initializer != null) {
+ final TypeConversionDescriptor conversion = ThreadLocalConversionRule.wrapWithNewExpression(toType, fromType, initializer);
+ TypeMigrationReplacementUtil.replaceExpression(initializer, project, conversion);
+ CodeStyleManager.getInstance(project).reformat(psiField);
+ }
+ else if (!assertNotNull(psiField.getModifierList()).hasModifierProperty(PsiModifier.FINAL)) {
+ final String text = "new " + PsiDiamondTypeUtil.getCollapsedType(toType, psiField) + "()";
+ final PsiExpression newInitializer = factory.createExpressionFromText(text, psiField);
+ psiField.setInitializer(newInitializer);
+ }
+
+ assertNotNull(psiField.getTypeElement()).replace(factory.createTypeElement(toType));
+
+ final PsiModifierList modifierList = assertNotNull(psiField.getModifierList());
+ modifierList.setModifierProperty(PsiModifier.FINAL, true);
+ modifierList.setModifierProperty(PsiModifier.VOLATILE, false);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return true;
+ }
+}