0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.code;
0011:
0012: import java.util.ArrayList;
0013: import java.util.Arrays;
0014: import java.util.HashMap;
0015: import java.util.Iterator;
0016: import java.util.List;
0017: import java.util.Map;
0018: import java.util.StringTokenizer;
0019:
0020: import org.eclipse.text.edits.TextEdit;
0021:
0022: import org.eclipse.core.runtime.Assert;
0023: import org.eclipse.core.runtime.CoreException;
0024: import org.eclipse.core.runtime.IProgressMonitor;
0025:
0026: import org.eclipse.ltk.core.refactoring.Change;
0027: import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
0028: import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
0029: import org.eclipse.ltk.core.refactoring.RefactoringStatus;
0030: import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
0031: import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
0032:
0033: import org.eclipse.jdt.core.ICompilationUnit;
0034: import org.eclipse.jdt.core.IJavaElement;
0035: import org.eclipse.jdt.core.IJavaProject;
0036: import org.eclipse.jdt.core.JavaModelException;
0037: import org.eclipse.jdt.core.dom.AST;
0038: import org.eclipse.jdt.core.dom.ASTNode;
0039: import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
0040: import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
0041: import org.eclipse.jdt.core.dom.ArrayCreation;
0042: import org.eclipse.jdt.core.dom.ArrayInitializer;
0043: import org.eclipse.jdt.core.dom.ArrayType;
0044: import org.eclipse.jdt.core.dom.Assignment;
0045: import org.eclipse.jdt.core.dom.Block;
0046: import org.eclipse.jdt.core.dom.CatchClause;
0047: import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
0048: import org.eclipse.jdt.core.dom.CompilationUnit;
0049: import org.eclipse.jdt.core.dom.ConstructorInvocation;
0050: import org.eclipse.jdt.core.dom.Expression;
0051: import org.eclipse.jdt.core.dom.ExpressionStatement;
0052: import org.eclipse.jdt.core.dom.FieldDeclaration;
0053: import org.eclipse.jdt.core.dom.IBinding;
0054: import org.eclipse.jdt.core.dom.IMethodBinding;
0055: import org.eclipse.jdt.core.dom.ITypeBinding;
0056: import org.eclipse.jdt.core.dom.IVariableBinding;
0057: import org.eclipse.jdt.core.dom.Javadoc;
0058: import org.eclipse.jdt.core.dom.MethodDeclaration;
0059: import org.eclipse.jdt.core.dom.Modifier;
0060: import org.eclipse.jdt.core.dom.SimpleName;
0061: import org.eclipse.jdt.core.dom.Type;
0062: import org.eclipse.jdt.core.dom.TypeDeclaration;
0063: import org.eclipse.jdt.core.dom.VariableDeclaration;
0064: import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
0065: import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
0066: import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
0067: import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
0068: import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
0069: import org.eclipse.jdt.core.refactoring.descriptors.ConvertLocalVariableDescriptor;
0070:
0071: import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
0072: import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
0073: import org.eclipse.jdt.internal.corext.dom.ASTNodes;
0074: import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor;
0075: import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
0076: import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
0077: import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup;
0078: import org.eclipse.jdt.internal.corext.refactoring.Checks;
0079: import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
0080: import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
0081: import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
0082: import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
0083: import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
0084: import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
0085: import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
0086: import org.eclipse.jdt.internal.corext.refactoring.rename.TempDeclarationFinder;
0087: import org.eclipse.jdt.internal.corext.refactoring.rename.TempOccurrenceAnalyzer;
0088: import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
0089: import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
0090: import org.eclipse.jdt.internal.corext.util.JdtFlags;
0091: import org.eclipse.jdt.internal.corext.util.Messages;
0092:
0093: import org.eclipse.jdt.ui.CodeGeneration;
0094: import org.eclipse.jdt.ui.JavaElementLabels;
0095:
0096: import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
0097:
0098: public class PromoteTempToFieldRefactoring extends
0099: ScriptableRefactoring {
0100:
0101: private static final String ATTRIBUTE_STATIC = "static"; //$NON-NLS-1$
0102: private static final String ATTRIBUTE_FINAL = "final"; //$NON-NLS-1$
0103: private static final String ATTRIBUTE_VISIBILITY = "visibility"; //$NON-NLS-1$
0104: private static final String ATTRIBUTE_INITIALIZE = "initialize"; //$NON-NLS-1$
0105:
0106: private int fSelectionStart;
0107: private int fSelectionLength;
0108: private ICompilationUnit fCu;
0109:
0110: public static final int INITIALIZE_IN_FIELD = 0;
0111: public static final int INITIALIZE_IN_METHOD = 1;
0112: public static final int INITIALIZE_IN_CONSTRUCTOR = 2;
0113:
0114: private static final String LINKED_NAME = "name"; //$NON-NLS-1$
0115:
0116: //------ settings ---------//
0117: private String fFieldName;
0118: private int fVisibility; /*see Modifier*/
0119: private boolean fDeclareStatic;
0120: private boolean fDeclareFinal;
0121: private int fInitializeIn; /*see INITIALIZE_IN_* constraints */
0122:
0123: //------ fields used for computations ---------//
0124: private CompilationUnit fCompilationUnitNode;
0125: private VariableDeclaration fTempDeclarationNode;
0126: //------ analysis ---------//
0127: private boolean fInitializerUsesLocalTypes;
0128: private boolean fTempTypeUsesClassTypeVariables;
0129: //------ scripting --------//
0130: private boolean fSelfInitializing = false;
0131: private LinkedProposalModel fLinkedProposalModel;
0132:
0133: /**
0134: * Creates a new promote temp to field refactoring.
0135: * @param unit the compilation unit, or <code>null</code> if invoked by scripting
0136: * @param selectionStart
0137: * @param selectionLength
0138: */
0139: public PromoteTempToFieldRefactoring(ICompilationUnit unit,
0140: int selectionStart, int selectionLength) {
0141: Assert.isTrue(selectionStart >= 0);
0142: Assert.isTrue(selectionLength >= 0);
0143: fSelectionStart = selectionStart;
0144: fSelectionLength = selectionLength;
0145: fCu = unit;
0146:
0147: fFieldName = ""; //$NON-NLS-1$
0148: fVisibility = Modifier.PRIVATE;
0149: fDeclareStatic = false;
0150: fDeclareFinal = false;
0151: fInitializeIn = INITIALIZE_IN_METHOD;
0152: fLinkedProposalModel = null;
0153: }
0154:
0155: /**
0156: * Creates a new promote temp to field refactoring.
0157: * @param declaration the variable declaration node to convert to a field
0158: */
0159: public PromoteTempToFieldRefactoring(VariableDeclaration declaration) {
0160: Assert.isTrue(declaration != null);
0161: fTempDeclarationNode = declaration;
0162: IVariableBinding resolveBinding = declaration.resolveBinding();
0163: Assert.isTrue(resolveBinding != null
0164: && !resolveBinding.isParameter()
0165: && !resolveBinding.isField());
0166:
0167: ASTNode root = declaration.getRoot();
0168: Assert.isTrue(root instanceof CompilationUnit);
0169: fCompilationUnitNode = (CompilationUnit) root;
0170:
0171: IJavaElement input = fCompilationUnitNode.getJavaElement();
0172: Assert.isTrue(input instanceof ICompilationUnit);
0173: fCu = (ICompilationUnit) input;
0174:
0175: fSelectionStart = declaration.getStartPosition();
0176: fSelectionLength = declaration.getLength();
0177:
0178: fFieldName = ""; //$NON-NLS-1$
0179: fVisibility = Modifier.PRIVATE;
0180: fDeclareStatic = false;
0181: fDeclareFinal = false;
0182: fInitializeIn = INITIALIZE_IN_METHOD;
0183: fLinkedProposalModel = null;
0184: }
0185:
0186: public String getName() {
0187: return RefactoringCoreMessages.PromoteTempToFieldRefactoring_name;
0188: }
0189:
0190: public int[] getAvailableVisibilities() {
0191: return new int[] { Modifier.PUBLIC, Modifier.PROTECTED,
0192: Modifier.NONE, Modifier.PRIVATE };
0193: }
0194:
0195: public int getVisibility() {
0196: return fVisibility;
0197: }
0198:
0199: public boolean getDeclareFinal() {
0200: return fDeclareFinal;
0201: }
0202:
0203: public boolean getDeclareStatic() {
0204: return fDeclareStatic;
0205: }
0206:
0207: public int getInitializeIn() {
0208: return fInitializeIn;
0209: }
0210:
0211: public void setVisibility(int accessModifier) {
0212: Assert.isTrue(accessModifier == Modifier.PRIVATE
0213: || accessModifier == Modifier.NONE
0214: || accessModifier == Modifier.PROTECTED
0215: || accessModifier == Modifier.PUBLIC);
0216: fVisibility = accessModifier;
0217: }
0218:
0219: public void setDeclareFinal(boolean declareFinal) {
0220: fDeclareFinal = declareFinal;
0221: }
0222:
0223: public void setDeclareStatic(boolean declareStatic) {
0224: fDeclareStatic = declareStatic;
0225: }
0226:
0227: public void setFieldName(String fieldName) {
0228: Assert.isNotNull(fieldName);
0229: fFieldName = fieldName;
0230: }
0231:
0232: public void setInitializeIn(int initializeIn) {
0233: Assert.isTrue(initializeIn == INITIALIZE_IN_CONSTRUCTOR
0234: || initializeIn == INITIALIZE_IN_FIELD
0235: || initializeIn == INITIALIZE_IN_METHOD);
0236: fInitializeIn = initializeIn;
0237: }
0238:
0239: public boolean canEnableSettingStatic() {
0240: return fInitializeIn != INITIALIZE_IN_CONSTRUCTOR
0241: && !isTempDeclaredInStaticMethod()
0242: && !fTempTypeUsesClassTypeVariables;
0243: }
0244:
0245: public boolean canEnableSettingFinal() {
0246: if (fInitializeIn == INITIALIZE_IN_CONSTRUCTOR)
0247: return canEnableSettingDeclareInConstructors()
0248: && !tempHasAssignmentsOtherThanInitialization();
0249: else if (fInitializeIn == INITIALIZE_IN_FIELD)
0250: return canEnableSettingDeclareInFieldDeclaration()
0251: && !tempHasAssignmentsOtherThanInitialization();
0252: else if (getMethodDeclaration().isConstructor())
0253: return !tempHasAssignmentsOtherThanInitialization();
0254: else
0255: return false;
0256: }
0257:
0258: private boolean tempHasAssignmentsOtherThanInitialization() {
0259: TempAssignmentFinder assignmentFinder = new TempAssignmentFinder(
0260: fTempDeclarationNode);
0261: fCompilationUnitNode.accept(assignmentFinder);
0262: return assignmentFinder.hasAssignments();
0263: }
0264:
0265: public boolean canEnableSettingDeclareInConstructors() {
0266: return !fDeclareStatic && !fInitializerUsesLocalTypes
0267: && !getMethodDeclaration().isConstructor()
0268: && !isDeclaredInAnonymousClass()
0269: && !isTempDeclaredInStaticMethod()
0270: && tempHasInitializer();
0271: }
0272:
0273: public boolean canEnableSettingDeclareInMethod() {
0274: return !fDeclareFinal && tempHasInitializer();
0275: }
0276:
0277: private boolean tempHasInitializer() {
0278: return getTempInitializer() != null;
0279: }
0280:
0281: public boolean canEnableSettingDeclareInFieldDeclaration() {
0282: return !fInitializerUsesLocalTypes && tempHasInitializer();
0283: }
0284:
0285: private Expression getTempInitializer() {
0286: return fTempDeclarationNode.getInitializer();
0287: }
0288:
0289: private boolean isTempDeclaredInStaticMethod() {
0290: return Modifier.isStatic(getMethodDeclaration().getModifiers());
0291: }
0292:
0293: private MethodDeclaration getMethodDeclaration() {
0294: return (MethodDeclaration) ASTNodes.getParent(
0295: fTempDeclarationNode, MethodDeclaration.class);
0296: }
0297:
0298: private boolean isDeclaredInAnonymousClass() {
0299: return null != ASTNodes.getParent(fTempDeclarationNode,
0300: AnonymousClassDeclaration.class);
0301: }
0302:
0303: /*
0304: * @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkActivation(org.eclipse.core.runtime.IProgressMonitor)
0305: */
0306: public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
0307: throws CoreException {
0308: RefactoringStatus result = Checks.validateModifiesFiles(
0309: ResourceUtil.getFiles(new ICompilationUnit[] { fCu }),
0310: getValidationContext());
0311: if (result.hasFatalError())
0312: return result;
0313:
0314: initAST(pm);
0315:
0316: if (fTempDeclarationNode == null)
0317: return RefactoringStatus
0318: .createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_select_declaration);
0319:
0320: if (!Checks.isDeclaredIn(fTempDeclarationNode,
0321: MethodDeclaration.class))
0322: return RefactoringStatus
0323: .createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_only_declared_in_methods);
0324:
0325: if (isMethodParameter())
0326: return RefactoringStatus
0327: .createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_method_parameters);
0328:
0329: if (isTempAnExceptionInCatchBlock())
0330: return RefactoringStatus
0331: .createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_exceptions);
0332:
0333: result.merge(checkTempTypeForLocalTypeUsage());
0334: if (result.hasFatalError())
0335: return result;
0336:
0337: checkTempInitializerForLocalTypeUsage();
0338:
0339: if (!fSelfInitializing)
0340: initializeDefaults();
0341: return result;
0342: }
0343:
0344: private void initializeDefaults() {
0345: fVisibility = Modifier.PRIVATE;
0346: fDeclareStatic = Modifier.isStatic(getMethodDeclaration()
0347: .getModifiers());
0348: fDeclareFinal = false;
0349: if (canEnableSettingDeclareInMethod())
0350: fInitializeIn = INITIALIZE_IN_METHOD;
0351: else if (canEnableSettingDeclareInFieldDeclaration())
0352: fInitializeIn = INITIALIZE_IN_FIELD;
0353: else if (canEnableSettingDeclareInConstructors())
0354: fInitializeIn = INITIALIZE_IN_CONSTRUCTOR;
0355: }
0356:
0357: public String[] guessFieldNames() {
0358: String rawTempName = StubUtility
0359: .removePrefixAndSuffixForVariable(fCu.getJavaProject(),
0360: fTempDeclarationNode.resolveBinding());
0361: String[] excludedNames = getNamesOfFieldsInDeclaringType();
0362: int dim = ASTNodes.getDimensions(fTempDeclarationNode);
0363: return StubUtility.getFieldNameSuggestions(
0364: fCu.getJavaProject(), rawTempName, dim, getModifiers(),
0365: excludedNames);
0366: }
0367:
0368: private String getInitialFieldName() {
0369: String[] suggestedNames = guessFieldNames();
0370: if (suggestedNames.length > 0) {
0371: if (fLinkedProposalModel != null) {
0372: LinkedProposalPositionGroup nameGroup = fLinkedProposalModel
0373: .getPositionGroup(LINKED_NAME, true);
0374: for (int i = 0; i < suggestedNames.length; i++) {
0375: nameGroup.addProposal(suggestedNames[i], null,
0376: suggestedNames.length - i);
0377: }
0378: }
0379: return suggestedNames[0];
0380: } else {
0381: return fTempDeclarationNode.getName().getIdentifier();
0382: }
0383: }
0384:
0385: private String[] getNamesOfFieldsInDeclaringType() {
0386: final AbstractTypeDeclaration type = getEnclosingType();
0387: if (type instanceof TypeDeclaration) {
0388: FieldDeclaration[] fields = ((TypeDeclaration) type)
0389: .getFields();
0390: List result = new ArrayList(fields.length);
0391: for (int i = 0; i < fields.length; i++) {
0392: for (Iterator iter = fields[i].fragments().iterator(); iter
0393: .hasNext();) {
0394: VariableDeclarationFragment field = (VariableDeclarationFragment) iter
0395: .next();
0396: result.add(field.getName().getIdentifier());
0397: }
0398: }
0399: return (String[]) result.toArray(new String[result.size()]);
0400: }
0401: return new String[] {};
0402: }
0403:
0404: private void checkTempInitializerForLocalTypeUsage() {
0405: Expression initializer = fTempDeclarationNode.getInitializer();
0406: if (initializer == null)
0407: return;
0408:
0409: IMethodBinding declaringMethodBinding = getMethodDeclaration()
0410: .resolveBinding();
0411: ITypeBinding[] methodTypeParameters = declaringMethodBinding == null ? new ITypeBinding[0]
0412: : declaringMethodBinding.getTypeParameters();
0413: LocalTypeAndVariableUsageAnalyzer localTypeAnalyer = new LocalTypeAndVariableUsageAnalyzer(
0414: methodTypeParameters);
0415: initializer.accept(localTypeAnalyer);
0416: fInitializerUsesLocalTypes = !localTypeAnalyer
0417: .getUsageOfEnclosingNodes().isEmpty();
0418: }
0419:
0420: private RefactoringStatus checkTempTypeForLocalTypeUsage() {
0421: VariableDeclarationStatement vds = getTempDeclarationStatement();
0422: if (vds == null)
0423: return RefactoringStatus
0424: .createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_cannot_promote);
0425: Type type = vds.getType();
0426: ITypeBinding binding = type.resolveBinding();
0427: if (binding == null)
0428: return RefactoringStatus
0429: .createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_cannot_promote);
0430:
0431: IMethodBinding declaringMethodBinding = getMethodDeclaration()
0432: .resolveBinding();
0433: ITypeBinding[] methodTypeParameters = declaringMethodBinding == null ? new ITypeBinding[0]
0434: : declaringMethodBinding.getTypeParameters();
0435: LocalTypeAndVariableUsageAnalyzer analyzer = new LocalTypeAndVariableUsageAnalyzer(
0436: methodTypeParameters);
0437: type.accept(analyzer);
0438: boolean usesLocalTypes = !analyzer.getUsageOfEnclosingNodes()
0439: .isEmpty();
0440: fTempTypeUsesClassTypeVariables = analyzer
0441: .getClassTypeVariablesUsed();
0442: if (usesLocalTypes)
0443: return RefactoringStatus
0444: .createFatalErrorStatus(RefactoringCoreMessages.PromoteTempToFieldRefactoring_uses_type_declared_locally);
0445: return null;
0446: }
0447:
0448: private VariableDeclarationStatement getTempDeclarationStatement() {
0449: return (VariableDeclarationStatement) ASTNodes.getParent(
0450: fTempDeclarationNode,
0451: VariableDeclarationStatement.class);
0452: }
0453:
0454: private boolean isTempAnExceptionInCatchBlock() {
0455: return (fTempDeclarationNode.getParent() instanceof CatchClause);
0456: }
0457:
0458: private boolean isMethodParameter() {
0459: return (fTempDeclarationNode.getParent() instanceof MethodDeclaration);
0460: }
0461:
0462: private void initAST(IProgressMonitor pm) {
0463: if (fCompilationUnitNode == null) {
0464: fCompilationUnitNode = RefactoringASTParser
0465: .parseWithASTProvider(fCu, true, pm);
0466: fTempDeclarationNode = TempDeclarationFinder
0467: .findTempDeclaration(fCompilationUnitNode,
0468: fSelectionStart, fSelectionLength);
0469: }
0470: }
0471:
0472: public RefactoringStatus validateInput() {
0473: return Checks.checkFieldName(fFieldName, fCu);
0474: }
0475:
0476: /*
0477: * @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkInput(org.eclipse.core.runtime.IProgressMonitor)
0478: */
0479: public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
0480: throws CoreException {
0481: try {
0482: RefactoringStatus result = new RefactoringStatus();
0483: result.merge(checkClashesWithExistingFields());
0484: if (fInitializeIn == INITIALIZE_IN_CONSTRUCTOR)
0485: result.merge(checkClashesInConstructors());
0486: return result;
0487: } finally {
0488: pm.done();
0489: }
0490: }
0491:
0492: private RefactoringStatus checkClashesInConstructors() {
0493: Assert.isTrue(fInitializeIn == INITIALIZE_IN_CONSTRUCTOR);
0494: Assert.isTrue(!isDeclaredInAnonymousClass());
0495: final AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) getMethodDeclaration()
0496: .getParent();
0497: if (declaration instanceof TypeDeclaration) {
0498: MethodDeclaration[] methods = ((TypeDeclaration) declaration)
0499: .getMethods();
0500: for (int i = 0; i < methods.length; i++) {
0501: MethodDeclaration method = methods[i];
0502: if (!method.isConstructor())
0503: continue;
0504: NameCollector nameCollector = new NameCollector(method) {
0505: protected boolean visitNode(ASTNode node) {
0506: return true;
0507: }
0508: };
0509: method.accept(nameCollector);
0510: List names = nameCollector.getNames();
0511: if (names.contains(fFieldName)) {
0512: String[] keys = {
0513: fFieldName,
0514: BindingLabelProvider
0515: .getBindingLabel(
0516: method.resolveBinding(),
0517: JavaElementLabels.ALL_FULLY_QUALIFIED) };
0518: String msg = Messages
0519: .format(
0520: RefactoringCoreMessages.PromoteTempToFieldRefactoring_Name_conflict,
0521: keys);
0522: return RefactoringStatus
0523: .createFatalErrorStatus(msg);
0524: }
0525: }
0526: }
0527: return null;
0528: }
0529:
0530: private RefactoringStatus checkClashesWithExistingFields() {
0531: FieldDeclaration[] existingFields = getFieldDeclarations(getBodyDeclarationListOfDeclaringType());
0532: for (int i = 0; i < existingFields.length; i++) {
0533: FieldDeclaration declaration = existingFields[i];
0534: VariableDeclarationFragment[] fragments = (VariableDeclarationFragment[]) declaration
0535: .fragments().toArray(
0536: new VariableDeclarationFragment[declaration
0537: .fragments().size()]);
0538: for (int j = 0; j < fragments.length; j++) {
0539: VariableDeclarationFragment fragment = fragments[j];
0540: if (fFieldName.equals(fragment.getName()
0541: .getIdentifier())) {
0542: //cannot conflict with more than 1 name
0543: RefactoringStatusContext context = JavaStatusContext
0544: .create(fCu, fragment);
0545: return RefactoringStatus
0546: .createFatalErrorStatus(
0547: RefactoringCoreMessages.PromoteTempToFieldRefactoring_Name_conflict_with_field,
0548: context);
0549: }
0550: }
0551: }
0552: return null;
0553: }
0554:
0555: private ChildListPropertyDescriptor getBodyDeclarationListOfDeclaringType() {
0556: ASTNode methodParent = getMethodDeclaration().getParent();
0557: if (methodParent instanceof AbstractTypeDeclaration)
0558: return ((AbstractTypeDeclaration) methodParent)
0559: .getBodyDeclarationsProperty();
0560: if (methodParent instanceof AnonymousClassDeclaration)
0561: return AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;
0562: Assert.isTrue(false);
0563: return null;
0564: }
0565:
0566: private FieldDeclaration[] getFieldDeclarations(
0567: ChildListPropertyDescriptor descriptor) {
0568: final List bodyDeclarations = (List) getMethodDeclaration()
0569: .getParent().getStructuralProperty(descriptor);
0570: List fields = new ArrayList(1);
0571: for (Iterator iter = bodyDeclarations.iterator(); iter
0572: .hasNext();) {
0573: Object each = iter.next();
0574: if (each instanceof FieldDeclaration)
0575: fields.add(each);
0576: }
0577: return (FieldDeclaration[]) fields
0578: .toArray(new FieldDeclaration[fields.size()]);
0579: }
0580:
0581: /*
0582: * @see org.eclipse.jdt.internal.corext.refactoring.base.IRefactoring#createChange(org.eclipse.core.runtime.IProgressMonitor)
0583: */
0584: public Change createChange(IProgressMonitor pm)
0585: throws CoreException {
0586: pm.beginTask("", 1); //$NON-NLS-1$
0587: try {
0588: if (fFieldName.length() == 0) {
0589: fFieldName = getInitialFieldName();
0590: }
0591:
0592: ASTRewrite rewrite = ASTRewrite.create(fCompilationUnitNode
0593: .getAST());
0594: if (fInitializeIn == INITIALIZE_IN_METHOD
0595: && tempHasInitializer())
0596: addLocalDeclarationSplit(rewrite);
0597: else
0598: addLocalDeclarationRemoval(rewrite);
0599: if (fInitializeIn == INITIALIZE_IN_CONSTRUCTOR)
0600: addInitializersToConstructors(rewrite);
0601: addTempRenames(rewrite);
0602: addFieldDeclaration(rewrite);
0603: return createChange(rewrite);
0604: } finally {
0605: pm.done();
0606: }
0607: }
0608:
0609: private void addTempRenames(ASTRewrite rewrite) {
0610: boolean noNameChange = fFieldName.equals(fTempDeclarationNode
0611: .getName().getIdentifier());
0612: if (fLinkedProposalModel == null && noNameChange) {
0613: return; // no changes needed
0614: }
0615: TempOccurrenceAnalyzer analyzer = new TempOccurrenceAnalyzer(
0616: fTempDeclarationNode, false);
0617: analyzer.perform();
0618: SimpleName[] tempRefs = analyzer.getReferenceNodes(); // no javadocs (refactoring not for parameters)
0619:
0620: for (int j = 0; j < tempRefs.length; j++) {
0621: SimpleName occurence = tempRefs[j];
0622: if (noNameChange) {
0623: addLinkedName(rewrite, occurence, false);
0624: } else {
0625: SimpleName newName = getAST().newSimpleName(fFieldName);
0626: addLinkedName(rewrite, newName, false);
0627: rewrite.replace(occurence, newName, null);
0628: }
0629: }
0630: }
0631:
0632: private void addInitializersToConstructors(ASTRewrite rewrite)
0633: throws CoreException {
0634: Assert.isTrue(!isDeclaredInAnonymousClass());
0635: final AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) getMethodDeclaration()
0636: .getParent();
0637: final MethodDeclaration[] constructors = getAllConstructors(declaration);
0638: if (constructors.length == 0) {
0639: AST ast = rewrite.getAST();
0640: MethodDeclaration newConstructor = ast
0641: .newMethodDeclaration();
0642: newConstructor.setConstructor(true);
0643: newConstructor.modifiers().addAll(
0644: ast.newModifiers(declaration.getModifiers()
0645: & ModifierRewrite.VISIBILITY_MODIFIERS));
0646: newConstructor.setName(ast.newSimpleName(declaration
0647: .getName().getIdentifier()));
0648: newConstructor
0649: .setJavadoc(getNewConstructorComment(rewrite));
0650: newConstructor.setBody(ast.newBlock());
0651:
0652: addFieldInitializationToConstructor(rewrite, newConstructor);
0653:
0654: int insertionIndex = computeInsertIndexForNewConstructor(declaration);
0655: rewrite.getListRewrite(declaration,
0656: declaration.getBodyDeclarationsProperty())
0657: .insertAt(newConstructor, insertionIndex, null);
0658: } else {
0659: for (int index = 0; index < constructors.length; index++) {
0660: if (shouldInsertTempInitialization(constructors[index]))
0661: addFieldInitializationToConstructor(rewrite,
0662: constructors[index]);
0663: }
0664: }
0665: }
0666:
0667: private String getEnclosingTypeName() {
0668: return getEnclosingType().getName().getIdentifier();
0669: }
0670:
0671: private AbstractTypeDeclaration getEnclosingType() {
0672: return (AbstractTypeDeclaration) ASTNodes.getParent(
0673: getTempDeclarationStatement(),
0674: AbstractTypeDeclaration.class);
0675: }
0676:
0677: private Javadoc getNewConstructorComment(ASTRewrite rewrite)
0678: throws CoreException {
0679: if (StubUtility.doAddComments(fCu.getJavaProject())) {
0680: String comment = CodeGeneration.getMethodComment(fCu,
0681: getEnclosingTypeName(), getEnclosingTypeName(),
0682: new String[0], new String[0], null, null,
0683: StubUtility.getLineDelimiterUsed(fCu));
0684: if (comment != null && comment.length() > 0) {
0685: return (Javadoc) rewrite.createStringPlaceholder(
0686: comment, ASTNode.JAVADOC);
0687: }
0688: }
0689: return null;
0690: }
0691:
0692: private int computeInsertIndexForNewConstructor(
0693: AbstractTypeDeclaration declaration) {
0694: List declarations = declaration.bodyDeclarations();
0695: if (declarations.isEmpty())
0696: return 0;
0697: int index = findFirstMethodIndex(declaration);
0698: if (index == -1)
0699: return declarations.size();
0700: else
0701: return index;
0702: }
0703:
0704: private int findFirstMethodIndex(
0705: AbstractTypeDeclaration typeDeclaration) {
0706: for (int i = 0, n = typeDeclaration.bodyDeclarations().size(); i < n; i++) {
0707: if (typeDeclaration.bodyDeclarations().get(i) instanceof MethodDeclaration)
0708: return i;
0709: }
0710: return -1;
0711: }
0712:
0713: private void addFieldInitializationToConstructor(
0714: ASTRewrite rewrite, MethodDeclaration constructor)
0715: throws JavaModelException {
0716: if (constructor.getBody() == null)
0717: constructor.setBody(getAST().newBlock());
0718: ExpressionStatement newStatement = createExpressionStatementThatInitializesField(rewrite);
0719: rewrite.getListRewrite(constructor.getBody(),
0720: Block.STATEMENTS_PROPERTY).insertLast(newStatement,
0721: null);
0722: }
0723:
0724: private static boolean shouldInsertTempInitialization(
0725: MethodDeclaration constructor) {
0726: Assert.isTrue(constructor.isConstructor());
0727: if (constructor.getBody() == null)
0728: return false;
0729: List statements = constructor.getBody().statements();
0730: if (statements == null)
0731: return false;
0732: if (statements.size() > 0
0733: && statements.get(0) instanceof ConstructorInvocation)
0734: return false;
0735: return true;
0736: }
0737:
0738: private static MethodDeclaration[] getAllConstructors(
0739: AbstractTypeDeclaration typeDeclaration) {
0740: if (typeDeclaration instanceof TypeDeclaration) {
0741: MethodDeclaration[] allMethods = ((TypeDeclaration) typeDeclaration)
0742: .getMethods();
0743: List result = new ArrayList(Math.min(allMethods.length, 1));
0744: for (int i = 0; i < allMethods.length; i++) {
0745: MethodDeclaration declaration = allMethods[i];
0746: if (declaration.isConstructor())
0747: result.add(declaration);
0748: }
0749: return (MethodDeclaration[]) result
0750: .toArray(new MethodDeclaration[result.size()]);
0751: }
0752: return new MethodDeclaration[] {};
0753: }
0754:
0755: private Change createChange(ASTRewrite rewrite)
0756: throws CoreException {
0757: final Map arguments = new HashMap();
0758: String project = null;
0759: IJavaProject javaProject = fCu.getJavaProject();
0760: if (javaProject != null)
0761: project = javaProject.getElementName();
0762: final IVariableBinding binding = fTempDeclarationNode
0763: .resolveBinding();
0764: final String description = Messages
0765: .format(
0766: RefactoringCoreMessages.PromoteTempToFieldRefactoring_descriptor_description_short,
0767: binding.getName());
0768: final String header = Messages
0769: .format(
0770: RefactoringCoreMessages.PromoteTempToFieldRefactoring_descriptor_description,
0771: new String[] {
0772: BindingLabelProvider
0773: .getBindingLabel(
0774: binding,
0775: JavaElementLabels.ALL_FULLY_QUALIFIED),
0776: BindingLabelProvider
0777: .getBindingLabel(
0778: binding
0779: .getDeclaringMethod(),
0780: JavaElementLabels.ALL_FULLY_QUALIFIED) });
0781: final JDTRefactoringDescriptorComment comment = new JDTRefactoringDescriptorComment(
0782: project, this , header);
0783: comment
0784: .addSetting(Messages
0785: .format(
0786: RefactoringCoreMessages.PromoteTempToFieldRefactoring_original_pattern,
0787: BindingLabelProvider
0788: .getBindingLabel(
0789: binding,
0790: JavaElementLabels.ALL_FULLY_QUALIFIED)));
0791: comment
0792: .addSetting(Messages
0793: .format(
0794: RefactoringCoreMessages.PromoteTempToFieldRefactoring_field_pattern,
0795: fFieldName));
0796: switch (fInitializeIn) {
0797: case INITIALIZE_IN_CONSTRUCTOR:
0798: comment
0799: .addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_initialize_constructor);
0800: break;
0801: case INITIALIZE_IN_FIELD:
0802: comment
0803: .addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_initialize_declaration);
0804: break;
0805: case INITIALIZE_IN_METHOD:
0806: comment
0807: .addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_initialize_method);
0808: break;
0809: }
0810: String visibility = JdtFlags.getVisibilityString(fVisibility);
0811: if ("".equals(visibility)) //$NON-NLS-1$
0812: visibility = RefactoringCoreMessages.PromoteTempToFieldRefactoring_default_visibility;
0813: comment
0814: .addSetting(Messages
0815: .format(
0816: RefactoringCoreMessages.PromoteTempToFieldRefactoring_visibility_pattern,
0817: visibility));
0818: if (fDeclareFinal && fDeclareStatic)
0819: comment
0820: .addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_declare_final_static);
0821: else if (fDeclareFinal)
0822: comment
0823: .addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_declare_final);
0824: else if (fDeclareStatic)
0825: comment
0826: .addSetting(RefactoringCoreMessages.PromoteTempToFieldRefactoring_declare_static);
0827: final ConvertLocalVariableDescriptor descriptor = new ConvertLocalVariableDescriptor(
0828: project, description, comment.asString(), arguments,
0829: RefactoringDescriptor.STRUCTURAL_CHANGE);
0830: arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT,
0831: JavaRefactoringDescriptorUtil.elementToHandle(project,
0832: fCu));
0833: arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME,
0834: fFieldName);
0835: arguments
0836: .put(
0837: JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION,
0838: new Integer(fSelectionStart).toString()
0839: + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$
0840: arguments.put(ATTRIBUTE_STATIC, Boolean.valueOf(fDeclareStatic)
0841: .toString());
0842: arguments.put(ATTRIBUTE_FINAL, Boolean.valueOf(fDeclareFinal)
0843: .toString());
0844: arguments.put(ATTRIBUTE_VISIBILITY, new Integer(fVisibility)
0845: .toString());
0846: arguments.put(ATTRIBUTE_INITIALIZE, new Integer(fInitializeIn)
0847: .toString());
0848: final CompilationUnitChange result = new CompilationUnitChange(
0849: RefactoringCoreMessages.PromoteTempToFieldRefactoring_name,
0850: fCu);
0851: result
0852: .setDescriptor(new RefactoringChangeDescriptor(
0853: descriptor));
0854: TextEdit resultingEdits = rewrite.rewriteAST();
0855: TextChangeCompatibility
0856: .addTextEdit(
0857: result,
0858: RefactoringCoreMessages.PromoteTempToFieldRefactoring_editName,
0859: resultingEdits);
0860: return result;
0861: }
0862:
0863: private void addLocalDeclarationSplit(ASTRewrite rewrite)
0864: throws JavaModelException {
0865: VariableDeclarationStatement tempDeclarationStatement = getTempDeclarationStatement();
0866: Block block = (Block) tempDeclarationStatement.getParent();//XXX can it be anything else?
0867: int statementIndex = block.statements().indexOf(
0868: tempDeclarationStatement);
0869: Assert.isTrue(statementIndex != -1);
0870: List fragments = tempDeclarationStatement.fragments();
0871: int fragmentIndex = fragments.indexOf(fTempDeclarationNode);
0872: Assert.isTrue(fragmentIndex != -1);
0873:
0874: for (int i1 = fragmentIndex, n = fragments.size(); i1 < n; i1++) {
0875: VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments
0876: .get(i1);
0877: rewrite.remove(fragment, null);
0878: }
0879: if (fragmentIndex == 0)
0880: rewrite.remove(tempDeclarationStatement, null);
0881:
0882: Assert.isTrue(tempHasInitializer());
0883: rewrite
0884: .getListRewrite(block, Block.STATEMENTS_PROPERTY)
0885: .insertAt(
0886: createExpressionStatementThatInitializesField(rewrite),
0887: statementIndex + 1, null);
0888:
0889: if (fragmentIndex + 1 < fragments.size()) {
0890: VariableDeclarationFragment firstFragmentAfter = (VariableDeclarationFragment) fragments
0891: .get(fragmentIndex + 1);
0892: VariableDeclarationFragment copyfirstFragmentAfter = (VariableDeclarationFragment) rewrite
0893: .createCopyTarget(firstFragmentAfter);
0894: VariableDeclarationStatement statement = getAST()
0895: .newVariableDeclarationStatement(
0896: copyfirstFragmentAfter);
0897: Type type = (Type) rewrite
0898: .createCopyTarget(tempDeclarationStatement
0899: .getType());
0900: statement.setType(type);
0901: List modifiers = tempDeclarationStatement.modifiers();
0902: if (modifiers.size() > 0) {
0903: ListRewrite modifiersRewrite = rewrite
0904: .getListRewrite(
0905: tempDeclarationStatement,
0906: VariableDeclarationStatement.MODIFIERS2_PROPERTY);
0907: ASTNode firstModifier = (ASTNode) modifiers.get(0);
0908: ASTNode lastModifier = (ASTNode) modifiers
0909: .get(modifiers.size() - 1);
0910: ASTNode modifiersCopy = modifiersRewrite
0911: .createCopyTarget(firstModifier, lastModifier);
0912: statement.modifiers().add(modifiersCopy);
0913: }
0914: for (int i = fragmentIndex + 2; i < fragments.size(); i++) {
0915: VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments
0916: .get(i);
0917: VariableDeclarationFragment fragmentCopy = (VariableDeclarationFragment) rewrite
0918: .createCopyTarget(fragment);
0919: statement.fragments().add(fragmentCopy);
0920: }
0921: rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY)
0922: .insertAt(statement, statementIndex + 2, null);
0923: }
0924: }
0925:
0926: private ExpressionStatement createExpressionStatementThatInitializesField(
0927: ASTRewrite rewrite) throws JavaModelException {
0928: AST ast = getAST();
0929: Assignment assignment = ast.newAssignment();
0930: SimpleName fieldName = ast.newSimpleName(fFieldName);
0931: addLinkedName(rewrite, fieldName, true);
0932: assignment.setLeftHandSide(fieldName);
0933: assignment.setRightHandSide(getTempInitializerCopy(rewrite));
0934: return ast.newExpressionStatement(assignment);
0935: }
0936:
0937: private void addLinkedName(ASTRewrite rewrite,
0938: SimpleName fieldName, boolean isFirst) {
0939: if (fLinkedProposalModel != null) {
0940: fLinkedProposalModel.getPositionGroup(LINKED_NAME, true)
0941: .addPosition(rewrite.track(fieldName), isFirst);
0942: }
0943: }
0944:
0945: private Expression getTempInitializerCopy(ASTRewrite rewrite)
0946: throws JavaModelException {
0947: final Expression initializer = (Expression) rewrite
0948: .createCopyTarget(getTempInitializer());
0949: if (initializer instanceof ArrayInitializer
0950: && ASTNodes.getDimensions(fTempDeclarationNode) > 0) {
0951: ArrayCreation arrayCreation = rewrite.getAST()
0952: .newArrayCreation();
0953: arrayCreation.setType((ArrayType) ASTNodeFactory.newType(
0954: rewrite.getAST(), fTempDeclarationNode));
0955: arrayCreation
0956: .setInitializer((ArrayInitializer) initializer);
0957: return arrayCreation;
0958: }
0959: return initializer;
0960: }
0961:
0962: private void addLocalDeclarationRemoval(ASTRewrite rewrite) {
0963: VariableDeclarationStatement tempDeclarationStatement = getTempDeclarationStatement();
0964: List fragments = tempDeclarationStatement.fragments();
0965:
0966: int fragmentIndex = fragments.indexOf(fTempDeclarationNode);
0967: Assert.isTrue(fragmentIndex != -1);
0968: VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments
0969: .get(fragmentIndex);
0970: rewrite.remove(fragment, null);
0971: if (fragments.size() == 1)
0972: rewrite.remove(tempDeclarationStatement, null);
0973: }
0974:
0975: private void addFieldDeclaration(ASTRewrite rewrite) {
0976: final ChildListPropertyDescriptor descriptor = getBodyDeclarationListOfDeclaringType();
0977: FieldDeclaration[] fields = getFieldDeclarations(getBodyDeclarationListOfDeclaringType());
0978: final ASTNode parent = getMethodDeclaration().getParent();
0979: int insertIndex;
0980: if (fields.length == 0)
0981: insertIndex = 0;
0982: else
0983: insertIndex = ((List) parent
0984: .getStructuralProperty(descriptor))
0985: .indexOf(fields[fields.length - 1]) + 1;
0986:
0987: final FieldDeclaration declaration = createNewFieldDeclaration(rewrite);
0988: rewrite.getListRewrite(parent, descriptor).insertAt(
0989: declaration, insertIndex, null);
0990: }
0991:
0992: private FieldDeclaration createNewFieldDeclaration(
0993: ASTRewrite rewrite) {
0994: AST ast = getAST();
0995: VariableDeclarationFragment fragment = ast
0996: .newVariableDeclarationFragment();
0997: SimpleName variableName = ast.newSimpleName(fFieldName);
0998: fragment.setName(variableName);
0999: addLinkedName(rewrite, variableName, false);
1000: fragment.setExtraDimensions(fTempDeclarationNode
1001: .getExtraDimensions());
1002: if (fInitializeIn == INITIALIZE_IN_FIELD
1003: && tempHasInitializer()) {
1004: Expression initializer = (Expression) rewrite
1005: .createCopyTarget(getTempInitializer());
1006: fragment.setInitializer(initializer);
1007: }
1008: FieldDeclaration fieldDeclaration = ast
1009: .newFieldDeclaration(fragment);
1010:
1011: VariableDeclarationStatement vds = getTempDeclarationStatement();
1012: Type type = (Type) rewrite.createCopyTarget(vds.getType());
1013: fieldDeclaration.setType(type);
1014: fieldDeclaration.modifiers().addAll(
1015: ASTNodeFactory.newModifiers(ast, getModifiers()));
1016: return fieldDeclaration;
1017: }
1018:
1019: private int getModifiers() {
1020: int flags = fVisibility;
1021: if (fDeclareFinal)
1022: flags |= Modifier.FINAL;
1023: if (fDeclareStatic)
1024: flags |= Modifier.STATIC;
1025: return flags;
1026: }
1027:
1028: private AST getAST() {
1029: return fTempDeclarationNode.getAST();
1030: }
1031:
1032: private static class LocalTypeAndVariableUsageAnalyzer extends
1033: HierarchicalASTVisitor {
1034: private final List fLocalDefinitions = new ArrayList(0); // List of IBinding (Variable and Type)
1035: private final List fLocalReferencesToEnclosing = new ArrayList(
1036: 0); // List of ASTNodes
1037: private final List fMethodTypeVariables;
1038: private boolean fClassTypeVariablesUsed = false;
1039:
1040: public LocalTypeAndVariableUsageAnalyzer(
1041: ITypeBinding[] methodTypeVariables) {
1042: fMethodTypeVariables = Arrays.asList(methodTypeVariables);
1043: }
1044:
1045: public List getUsageOfEnclosingNodes() {
1046: return fLocalReferencesToEnclosing;
1047: }
1048:
1049: public boolean getClassTypeVariablesUsed() {
1050: return fClassTypeVariablesUsed;
1051: }
1052:
1053: public boolean visit(SimpleName node) {
1054: ITypeBinding typeBinding = node.resolveTypeBinding();
1055: if (typeBinding != null && typeBinding.isLocal()) {
1056: if (node.isDeclaration()) {
1057: fLocalDefinitions.add(typeBinding);
1058: } else if (!fLocalDefinitions.contains(typeBinding)) {
1059: fLocalReferencesToEnclosing.add(node);
1060: }
1061: }
1062: if (typeBinding != null && typeBinding.isTypeVariable()) {
1063: if (node.isDeclaration()) {
1064: fLocalDefinitions.add(typeBinding);
1065: } else if (!fLocalDefinitions.contains(typeBinding)) {
1066: if (fMethodTypeVariables.contains(typeBinding)) {
1067: fLocalReferencesToEnclosing.add(node);
1068: } else {
1069: fClassTypeVariablesUsed = true;
1070: }
1071: }
1072: }
1073: IBinding binding = node.resolveBinding();
1074: if (binding != null
1075: && binding.getKind() == IBinding.VARIABLE
1076: && !((IVariableBinding) binding).isField()) {
1077: if (node.isDeclaration()) {
1078: fLocalDefinitions.add(binding);
1079: } else if (!fLocalDefinitions.contains(binding)) {
1080: fLocalReferencesToEnclosing.add(node);
1081: }
1082: }
1083: return super .visit(node);
1084: }
1085: }
1086:
1087: public RefactoringStatus initialize(
1088: final RefactoringArguments arguments) {
1089: fSelfInitializing = true;
1090: if (arguments instanceof JavaRefactoringArguments) {
1091: final JavaRefactoringArguments extended = (JavaRefactoringArguments) arguments;
1092: final String selection = extended
1093: .getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION);
1094: if (selection != null) {
1095: int offset = -1;
1096: int length = -1;
1097: final StringTokenizer tokenizer = new StringTokenizer(
1098: selection);
1099: if (tokenizer.hasMoreTokens())
1100: offset = Integer.valueOf(tokenizer.nextToken())
1101: .intValue();
1102: if (tokenizer.hasMoreTokens())
1103: length = Integer.valueOf(tokenizer.nextToken())
1104: .intValue();
1105: if (offset >= 0 && length >= 0) {
1106: fSelectionStart = offset;
1107: fSelectionLength = length;
1108: } else
1109: return RefactoringStatus
1110: .createFatalErrorStatus(Messages
1111: .format(
1112: RefactoringCoreMessages.InitializableRefactoring_illegal_argument,
1113: new Object[] {
1114: selection,
1115: JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION }));
1116: } else
1117: return RefactoringStatus
1118: .createFatalErrorStatus(Messages
1119: .format(
1120: RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1121: JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION));
1122: final String handle = extended
1123: .getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
1124: if (handle != null) {
1125: final IJavaElement element = JavaRefactoringDescriptorUtil
1126: .handleToElement(extended.getProject(), handle,
1127: false);
1128: if (element == null
1129: || !element.exists()
1130: || element.getElementType() != IJavaElement.COMPILATION_UNIT)
1131: return createInputFatalStatus(element,
1132: IJavaRefactorings.CONVERT_LOCAL_VARIABLE);
1133: else
1134: fCu = (ICompilationUnit) element;
1135: } else
1136: return RefactoringStatus
1137: .createFatalErrorStatus(Messages
1138: .format(
1139: RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1140: JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
1141: final String visibility = extended
1142: .getAttribute(ATTRIBUTE_VISIBILITY);
1143: if (visibility != null && !"".equals(visibility)) {//$NON-NLS-1$
1144: int flag = 0;
1145: try {
1146: flag = Integer.parseInt(visibility);
1147: } catch (NumberFormatException exception) {
1148: return RefactoringStatus
1149: .createFatalErrorStatus(Messages
1150: .format(
1151: RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1152: ATTRIBUTE_VISIBILITY));
1153: }
1154: fVisibility = flag;
1155: }
1156: final String initialize = extended
1157: .getAttribute(ATTRIBUTE_INITIALIZE);
1158: if (initialize != null && !"".equals(initialize)) {//$NON-NLS-1$
1159: int value = 0;
1160: try {
1161: value = Integer.parseInt(initialize);
1162: } catch (NumberFormatException exception) {
1163: return RefactoringStatus
1164: .createFatalErrorStatus(Messages
1165: .format(
1166: RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1167: ATTRIBUTE_INITIALIZE));
1168: }
1169: fInitializeIn = value;
1170: }
1171: final String name = extended
1172: .getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME);
1173: if (name != null && !"".equals(name)) //$NON-NLS-1$
1174: fFieldName = name;
1175: else
1176: return RefactoringStatus
1177: .createFatalErrorStatus(Messages
1178: .format(
1179: RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1180: JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME));
1181: final String declareStatic = extended
1182: .getAttribute(ATTRIBUTE_STATIC);
1183: if (declareStatic != null) {
1184: fDeclareStatic = Boolean.valueOf(declareStatic)
1185: .booleanValue();
1186: } else
1187: return RefactoringStatus
1188: .createFatalErrorStatus(Messages
1189: .format(
1190: RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1191: ATTRIBUTE_STATIC));
1192: final String declareFinal = extended
1193: .getAttribute(ATTRIBUTE_FINAL);
1194: if (declareFinal != null) {
1195: fDeclareFinal = Boolean.valueOf(declareFinal)
1196: .booleanValue();
1197: } else
1198: return RefactoringStatus
1199: .createFatalErrorStatus(Messages
1200: .format(
1201: RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1202: ATTRIBUTE_FINAL));
1203: } else
1204: return RefactoringStatus
1205: .createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
1206: return new RefactoringStatus();
1207: }
1208:
1209: public void setLinkedProposalModel(LinkedProposalModel model) {
1210: fLinkedProposalModel = model;
1211: }
1212: }
|