]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-after/core refactoring/org/eclipse/jdt/internal/corext/refactoring/sef/SelfEncapsulateFieldRefactoring.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / core refactoring / org / eclipse / jdt / internal / corext / refactoring / sef / SelfEncapsulateFieldRefactoring.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * jens.lukowski@gmx.de - contributed code to convert prefix and postfix
11 * expressions into a combination of setter and getter calls.
12 * Dmitry Stalnov (dstalnov@fusionone.com) - contributed fix for
13 * bug Encapsulate field can fail when two variables in one variable declaration (see
14 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=51540).
15 *******************************************************************************/
16package org.eclipse.jdt.internal.corext.refactoring.sef;
17
18import java.lang.reflect.InvocationTargetException;
19import java.util.ArrayList;
20import java.util.Arrays;
21import java.util.HashMap;
22import java.util.Iterator;
23import java.util.List;
24import java.util.Map;
25
26import org.eclipse.swt.SWT;
27import org.eclipse.swt.events.ModifyEvent;
28import org.eclipse.swt.events.ModifyListener;
29import org.eclipse.swt.events.SelectionAdapter;
30import org.eclipse.swt.events.SelectionEvent;
31import org.eclipse.swt.layout.GridData;
32import org.eclipse.swt.layout.GridLayout;
33import org.eclipse.swt.widgets.Button;
34import org.eclipse.swt.widgets.Combo;
35import org.eclipse.swt.widgets.Composite;
36import org.eclipse.swt.widgets.Control;
37import org.eclipse.swt.widgets.Display;
38import org.eclipse.swt.widgets.Label;
39import org.eclipse.swt.widgets.Link;
40import org.eclipse.swt.widgets.Text;
41
42import org.eclipse.core.runtime.Assert;
43import org.eclipse.core.runtime.CoreException;
44import org.eclipse.core.runtime.IProgressMonitor;
45import org.eclipse.core.runtime.IStatus;
46import org.eclipse.core.runtime.NullProgressMonitor;
47
48import org.eclipse.text.edits.MultiTextEdit;
49import org.eclipse.text.edits.TextEditGroup;
50
51import org.eclipse.jface.window.Window;
52
53import org.eclipse.ui.IWorkbenchWindow;
54import org.eclipse.ui.PlatformUI;
55import org.eclipse.ui.dialogs.PreferencesUtil;
56
57import org.eclipse.ltk.core.refactoring.Change;
58import org.eclipse.ltk.core.refactoring.Refactoring;
59import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
60import org.eclipse.ltk.core.refactoring.RefactoringStatus;
61import org.eclipse.ltk.core.refactoring.TextChange;
62
63import org.eclipse.jdt.core.Flags;
64import org.eclipse.jdt.core.ICompilationUnit;
65import org.eclipse.jdt.core.IField;
66import org.eclipse.jdt.core.IJavaProject;
67import org.eclipse.jdt.core.ISourceRange;
68import org.eclipse.jdt.core.IType;
69import org.eclipse.jdt.core.JavaModelException;
70import org.eclipse.jdt.core.compiler.IProblem;
71import org.eclipse.jdt.core.dom.AST;
72import org.eclipse.jdt.core.dom.ASTNode;
73import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
74import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
75import org.eclipse.jdt.core.dom.ArrayType;
76import org.eclipse.jdt.core.dom.Assignment;
77import org.eclipse.jdt.core.dom.Block;
78import org.eclipse.jdt.core.dom.BodyDeclaration;
79import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
80import org.eclipse.jdt.core.dom.ClassInstanceCreation;
81import org.eclipse.jdt.core.dom.CompilationUnit;
82import org.eclipse.jdt.core.dom.Expression;
83import org.eclipse.jdt.core.dom.FieldDeclaration;
84import org.eclipse.jdt.core.dom.IMethodBinding;
85import org.eclipse.jdt.core.dom.ITypeBinding;
86import org.eclipse.jdt.core.dom.IVariableBinding;
87import org.eclipse.jdt.core.dom.Javadoc;
88import org.eclipse.jdt.core.dom.Message;
89import org.eclipse.jdt.core.dom.MethodDeclaration;
90import org.eclipse.jdt.core.dom.Modifier;
91import org.eclipse.jdt.core.dom.NodeFinder;
92import org.eclipse.jdt.core.dom.ReturnStatement;
93import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
94import org.eclipse.jdt.core.dom.Type;
95import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
96import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
97import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
98import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
99import org.eclipse.jdt.core.refactoring.descriptors.EncapsulateFieldDescriptor;
100import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
101
102import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil;
103import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
104import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
105import org.eclipse.jdt.internal.corext.dom.ASTNodes;
106import org.eclipse.jdt.internal.corext.dom.Bindings;
107import org.eclipse.jdt.internal.corext.dom.VariableDeclarationRewrite;
108import org.eclipse.jdt.internal.corext.refactoring.Checks;
109import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
110import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
111import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
112import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
113import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
114import org.eclipse.jdt.internal.corext.refactoring.scripting.SelfEncapsulateRefactoringContribution;
115import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
116import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
117import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil;
118import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
119import org.eclipse.jdt.internal.corext.util.JdtFlags;
120import org.eclipse.jdt.internal.corext.util.Messages;
121
122import org.eclipse.jdt.ui.CodeGeneration;
123import org.eclipse.jdt.ui.JavaElementLabels;
124import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper;
125
126import org.eclipse.jdt.internal.ui.JavaPlugin;
127import org.eclipse.jdt.internal.ui.dialogs.TextFieldNavigationHandler;
128import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
129import org.eclipse.jdt.internal.ui.preferences.CodeStylePreferencePage;
130import org.eclipse.jdt.internal.ui.refactoring.RefactoringExecutionHelper;
131import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages;
132import org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter;
133import org.eclipse.jdt.internal.ui.refactoring.sef.SelfEncapsulateFieldInputPage;
134import org.eclipse.jdt.internal.ui.refactoring.sef.SelfEncapsulateFieldWizard;
135import org.eclipse.jdt.internal.ui.text.correction.GetterSetterCorrectionSubProcessor.SelfEncapsulateFieldProposal;
136import org.eclipse.jdt.internal.ui.util.SWTUtil;
137import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
138import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
139
140/**
141 * Encapsulates a field into getter and setter calls.
142 */
143public class SelfEncapsulateFieldRefactoring extends Refactoring {
144
145 public static final String ATTRIBUTE_VISIBILITY= "visibility"; //$NON-NLS-1$
146 public static final String ATTRIBUTE_GETTER= "getter"; //$NON-NLS-1$
147 public static final String ATTRIBUTE_SETTER= "setter"; //$NON-NLS-1$
148 public static final String ATTRIBUTE_INSERTION= "insertion"; //$NON-NLS-1$
149 public static final String ATTRIBUTE_COMMENTS= "comments"; //$NON-NLS-1$
150 public static final String ATTRIBUTE_DECLARING= "declaring"; //$NON-NLS-1$
151
152 public IField fField;
153 public TextChangeManager fChangeManager;
154
155 public CompilationUnit fRoot;
156 public VariableDeclarationFragment fFieldDeclaration;
157 public ASTRewrite fRewriter;
158 public ImportRewrite fImportRewrite;
159
160 public int fVisibility= -1;
161 public String fGetterName;
162 public String fSetterName;
163 private String fArgName;
164 public boolean fSetterMustReturnValue;
165 public int fInsertionIndex; // -1 represents as first method.
166 public boolean fEncapsulateDeclaringClass;
167 public boolean fGenerateJavadoc;
168
169 private List<IMethodBinding> fUsedReadNames;
170 private List<IMethodBinding> fUsedModifyNames;
171 public boolean fConsiderVisibility=true;
172
173 public static final String NO_NAME= ""; //$NON-NLS-1$
174
175 /**
176 * Creates a new self encapsulate field refactoring.
177 * @param field the field, or <code>null</code> if invoked by scripting
178 * @throws JavaModelException if initialization failed
179 */
180 public SelfEncapsulateFieldRefactoring(IField field) throws JavaModelException {
181 fEncapsulateDeclaringClass= true;
182 fChangeManager= new TextChangeManager();
183 fField= field;
184 if (field != null)
185 initialize(field);
186 }
187
188 public void initialize(IField field) throws JavaModelException {
189 fGetterName= GetterSetterUtil.getGetterName(field, null);
190 fSetterName= GetterSetterUtil.getSetterName(field, null);
191 fArgName= StubUtility.getBaseName(field);
192 checkArgName();
193 }
194
195 public void reinitialize() {
196 try {
197 initialize(fField);
198 } catch (JavaModelException e) {
199 // ignore
200 }
201 }
202
203 public IField getField() {
204 return fField;
205 }
206
207 public String getGetterName() {
208 return fGetterName;
209 }
210
211 public void setGetterName(String name) {
212 fGetterName= name;
213 Assert.isNotNull(fGetterName);
214 }
215
216 public String getSetterName() {
217 return fSetterName;
218 }
219
220 public void setSetterName(String name) {
221 fSetterName= name;
222 Assert.isNotNull(fSetterName);
223 }
224
225 public void setInsertionIndex(int index) {
226 fInsertionIndex= index;
227 }
228
229 public int getVisibility() {
230 return fVisibility;
231 }
232
233 public void setVisibility(int visibility) {
234 fVisibility= visibility;
235 }
236
237 public void setEncapsulateDeclaringClass(boolean encapsulateDeclaringClass) {
238 fEncapsulateDeclaringClass= encapsulateDeclaringClass;
239 }
240
241 public boolean getEncapsulateDeclaringClass() {
242 return fEncapsulateDeclaringClass;
243 }
244
245 public boolean getGenerateJavadoc() {
246 return fGenerateJavadoc;
247 }
248
249 public void setGenerateJavadoc(boolean value) {
250 fGenerateJavadoc= value;
251 }
252
253 //----activation checking ----------------------------------------------------------
254
255 @Override
256 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
257 if (fVisibility < 0)
258 fVisibility= (fField.getFlags() & (Flags.AccPublic | Flags.AccProtected | Flags.AccPrivate));
259 RefactoringStatus result= new RefactoringStatus();
260 result.merge(Checks.checkAvailability(fField));
261 if (result.hasFatalError())
262 return result;
263 fRoot= new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(fField.getCompilationUnit(), true, pm);
264 ISourceRange sourceRange= fField.getNameRange();
265 ASTNode node= NodeFinder.perform(fRoot, sourceRange.getOffset(), sourceRange.getLength());
266 if (node == null) {
267 return mappingErrorFound(result, node);
268 }
269 fFieldDeclaration= (VariableDeclarationFragment)ASTNodes.getParent(node, VariableDeclarationFragment.class);
270 if (fFieldDeclaration == null) {
271 return mappingErrorFound(result, node);
272 }
273 if (fFieldDeclaration.resolveBinding() == null) {
274 if (!processCompilerError(result, node))
275 result.addFatalError(RefactoringCoreMessages.SelfEncapsulateField_type_not_resolveable);
276 return result;
277 }
278 computeUsedNames();
279 return result;
280 }
281
282 private RefactoringStatus mappingErrorFound(RefactoringStatus result, ASTNode node) {
283 if (node != null && (node.getFlags() & ASTNode.MALFORMED) != 0 && processCompilerError(result, node))
284 return result;
285 result.addFatalError(getMappingErrorMessage());
286 return result;
287 }
288
289 private boolean processCompilerError(RefactoringStatus result, ASTNode node) {
290 Message[] messages= ASTNodes.getMessages(node, ASTNodes.INCLUDE_ALL_PARENTS);
291 if (messages.length == 0)
292 return false;
293 result.addFatalError(Messages.format(
294 RefactoringCoreMessages.SelfEncapsulateField_compiler_errors_field,
295 new String[] { BasicElementLabels.getJavaElementName(fField.getElementName()), messages[0].getMessage()}));
296 return true;
297 }
298
299 private String getMappingErrorMessage() {
300 return Messages.format(
301 RefactoringCoreMessages.SelfEncapsulateField_cannot_analyze_selected_field,
302 BasicElementLabels.getJavaElementName(fField.getElementName()));
303 }
304
305 //---- Input checking ----------------------------------------------------------
306
307 public RefactoringStatus checkMethodNames() {
308 return checkMethodNames(isUsingLocalGetter(),isUsingLocalSetter());
309 }
310
311 public RefactoringStatus checkMethodNames(boolean usingLocalGetter, boolean usingLocalSetter) {
312 RefactoringStatus result= new RefactoringStatus();
313 IType declaringType= fField.getDeclaringType();
314 checkName(result, fGetterName, fUsedReadNames, declaringType, usingLocalGetter, fField);
315 checkName(result, fSetterName, fUsedModifyNames, declaringType, usingLocalSetter, fField);
316 return result;
317 }
318
319 private static void checkName(RefactoringStatus status, String name, List<IMethodBinding> usedNames, IType type, boolean reUseExistingField, IField field) {
320 if ("".equals(name)) { //$NON-NLS-1$
321 status.addFatalError(RefactoringCoreMessages.Checks_Choose_name);
322 return;
323 }
324 boolean isStatic=false;
325 try {
326 isStatic= Flags.isStatic(field.getFlags());
327 } catch (JavaModelException e) {
328 }
329 status.merge(Checks.checkMethodName(name, field));
330 for (Iterator<IMethodBinding> iter= usedNames.iterator(); iter.hasNext(); ) {
331 IMethodBinding method= iter.next();
332 String selector= method.getName();
333 if (selector.equals(name)) {
334 if (!reUseExistingField) {
335 status.addFatalError(Messages.format(RefactoringCoreMessages.SelfEncapsulateField_method_exists, new String[] { BindingLabelProvider.getBindingLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED), BasicElementLabels.getJavaElementName(type.getElementName()) }));
336 } else {
337 boolean methodIsStatic= Modifier.isStatic(method.getModifiers());
338 if (methodIsStatic && !isStatic)
339 status.addWarning(Messages.format(RefactoringCoreMessages.SelfEncapsulateFieldRefactoring_static_method_but_nonstatic_field, new String[] { BasicElementLabels.getJavaElementName(method.getName()), BasicElementLabels.getJavaElementName(field.getElementName()) }));
340 if (!methodIsStatic && isStatic)
341 status.addFatalError(Messages.format(RefactoringCoreMessages.SelfEncapsulateFieldRefactoring_nonstatic_method_but_static_field, new String[] { BasicElementLabels.getJavaElementName(method.getName()), BasicElementLabels.getJavaElementName(field.getElementName()) }));
342 return;
343 }
344
345 }
346 }
347 if (reUseExistingField)
348 status.addFatalError(Messages.format(
349 RefactoringCoreMessages.SelfEncapsulateFieldRefactoring_methoddoesnotexist_status_fatalError,
350 new String[] { BasicElementLabels.getJavaElementName(name), BasicElementLabels.getJavaElementName(type.getElementName())}));
351 }
352
353 @Override
354 public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
355 pm.beginTask(NO_NAME, 12);
356 pm.setTaskName(RefactoringCoreMessages.SelfEncapsulateField_checking_preconditions);
357
358 RefactoringStatus result= new RefactoringStatus();
359 return fChangeManager.generated_3483103471104219612(this, pm, result);
360 }
361
362 public void createEdits(ICompilationUnit unit, ASTRewrite rewriter, List<TextEditGroup> groups, ImportRewrite importRewrite) throws CoreException {
363 TextChange change= fChangeManager.get(unit);
364 MultiTextEdit root= new MultiTextEdit();
365 change.setEdit(root);
366 root.addChild(importRewrite.rewriteImports(null));
367 root.addChild(rewriter.rewriteAST());
368 for (Iterator<TextEditGroup> iter= groups.iterator(); iter.hasNext();) {
369 change.addTextEditGroup(iter.next());
370 }
371 }
372
373 @Override
374 public Change createChange(IProgressMonitor pm) throws CoreException {
375 final Map<String, String> arguments= new HashMap<String, String>();
376 String project= null;
377 IJavaProject javaProject= fField.getJavaProject();
378 if (javaProject != null)
379 project= javaProject.getElementName();
380 int flags= JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING | RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE;
381 final IType declaring= fField.getDeclaringType();
382 try {
383 if (declaring.isAnonymous() || declaring.isLocal())
384 flags|= JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
385 } catch (JavaModelException exception) {
386 JavaPlugin.log(exception);
387 }
388 final String description= Messages.format(RefactoringCoreMessages.SelfEncapsulateField_descriptor_description_short, BasicElementLabels.getJavaElementName(fField.getElementName()));
389 final String header= Messages.format(RefactoringCoreMessages.SelfEncapsulateFieldRefactoring_descriptor_description, new String[] { JavaElementLabels.getElementLabel(fField, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getElementLabel(declaring, JavaElementLabels.ALL_FULLY_QUALIFIED)});
390 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
391 final EncapsulateFieldDescriptor descriptor= comment.generated_9056438639731303072(arguments, project, flags, description, this);
392 arguments.put(ATTRIBUTE_GETTER, fGetterName);
393 arguments.put(ATTRIBUTE_COMMENTS, Boolean.valueOf(fGenerateJavadoc).toString());
394 arguments.put(ATTRIBUTE_DECLARING, Boolean.valueOf(fEncapsulateDeclaringClass).toString());
395 final DynamicValidationRefactoringChange result= new DynamicValidationRefactoringChange(descriptor, getName());
396 TextChange[] changes= fChangeManager.getAllChanges();
397 pm.beginTask(NO_NAME, changes.length);
398 pm.setTaskName(RefactoringCoreMessages.SelfEncapsulateField_create_changes);
399 for (int i= 0; i < changes.length; i++) {
400 result.add(changes[i]);
401 pm.worked(1);
402 }
403 pm.done();
404 return result;
405 }
406
407 @Override
408 public String getName() {
409 return RefactoringCoreMessages.SelfEncapsulateField_name;
410 }
411
412 //---- Helper methods -------------------------------------------------------------
413
414 public void checkCompileErrors(RefactoringStatus result, CompilationUnit root, ICompilationUnit element) {
415 IProblem[] messages= root.getProblems();
416 for (int i= 0; i < messages.length; i++) {
417 IProblem problem= messages[i];
418 if (!isIgnorableProblem(problem)) {
419 result.addWarning(Messages.format(
420 RefactoringCoreMessages.SelfEncapsulateField_compiler_errors_update,
421 BasicElementLabels.getFileName(element)), JavaStatusContext.create(element));
422 return;
423 }
424 }
425 }
426
427 public void checkInHierarchy(RefactoringStatus status, boolean usingLocalGetter, boolean usingLocalSetter) {
428 AbstractTypeDeclaration declaration= (AbstractTypeDeclaration)ASTNodes.getParent(fFieldDeclaration, AbstractTypeDeclaration.class);
429 ITypeBinding type= declaration.resolveBinding();
430 if (type != null) {
431 ITypeBinding fieldType= fFieldDeclaration.resolveBinding().getType();
432 checkMethodInHierarchy(type, fGetterName, fieldType, new ITypeBinding[0], status, usingLocalGetter);
433 checkMethodInHierarchy(type, fSetterName, fFieldDeclaration.getAST().resolveWellKnownType("void"), //$NON-NLS-1$
434 new ITypeBinding[] {fieldType}, status, usingLocalSetter);
435 }
436 }
437
438 public static void checkMethodInHierarchy(ITypeBinding type, String methodName, ITypeBinding returnType, ITypeBinding[] parameters, RefactoringStatus result, boolean reUseMethod) {
439 IMethodBinding method= Bindings.findMethodInHierarchy(type, methodName, parameters);
440 if (method != null) {
441 boolean returnTypeClash= false;
442 ITypeBinding methodReturnType= method.getReturnType();
443 if (returnType != null && methodReturnType != null) {
444 String returnTypeKey= returnType.getKey();
445 String methodReturnTypeKey= methodReturnType.getKey();
446 if (returnTypeKey == null && methodReturnTypeKey == null) {
447 returnTypeClash= returnType != methodReturnType;
448 } else if (returnTypeKey != null && methodReturnTypeKey != null) {
449 returnTypeClash= !returnTypeKey.equals(methodReturnTypeKey);
450 }
451 }
452 ITypeBinding dc= method.getDeclaringClass();
453 if (returnTypeClash) {
454 result.addError(Messages.format(RefactoringCoreMessages.Checks_methodName_returnTypeClash,
455 new Object[] { BasicElementLabels.getJavaElementName(methodName), BasicElementLabels.getJavaElementName(dc.getName())}),
456 JavaStatusContext.create(method));
457 } else {
458 if (!reUseMethod)
459 result.addError(Messages.format(RefactoringCoreMessages.Checks_methodName_overrides,
460 new Object[] { BasicElementLabels.getJavaElementName(methodName), BasicElementLabels.getJavaElementName(dc.getName())}),
461 JavaStatusContext.create(method));
462 }
463 } else {
464 if (reUseMethod){
465 result.addError(Messages.format(RefactoringCoreMessages.SelfEncapsulateFieldRefactoring_nosuchmethod_status_fatalError,
466 BasicElementLabels.getJavaElementName(methodName)),
467 JavaStatusContext.create(method));
468 }
469 }
470 }
471
472 private void computeUsedNames() {
473 fUsedReadNames= new ArrayList<IMethodBinding>(0);
474 fUsedModifyNames= new ArrayList<IMethodBinding>(0);
475 IVariableBinding binding= fFieldDeclaration.resolveBinding();
476 ITypeBinding type= binding.getType();
477 IMethodBinding[] methods= binding.getDeclaringClass().getDeclaredMethods();
478 for (int i= 0; i < methods.length; i++) {
479 IMethodBinding method= methods[i];
480 ITypeBinding[] parameters= methods[i].getParameterTypes();
481 if (parameters == null || parameters.length == 0) {
482 fUsedReadNames.add(method);
483 } else if (parameters.length == 1 && parameters[0] == type) {
484 fUsedModifyNames.add(method);
485 }
486 }
487 }
488
489 public List<TextEditGroup> addGetterSetterChanges(CompilationUnit root, ASTRewrite rewriter, String lineDelimiter, boolean usingLocalSetter, boolean usingLocalGetter) throws CoreException {
490 List<TextEditGroup> result= new ArrayList<TextEditGroup>(2);
491 AST ast= root.getAST();
492 FieldDeclaration decl= (FieldDeclaration)ASTNodes.getParent(fFieldDeclaration, ASTNode.FIELD_DECLARATION);
493 int position= 0;
494 int numberOfMethods= 0;
495 List<BodyDeclaration> members= ASTNodes.getBodyDeclarations(decl.getParent());
496 for (Iterator<BodyDeclaration> iter= members.iterator(); iter.hasNext();) {
497 BodyDeclaration element= iter.next();
498 if (element.getNodeType() == ASTNode.METHOD_DECLARATION) {
499 if (fInsertionIndex == -1) {
500 break;
501 } else if (fInsertionIndex == numberOfMethods) {
502 position++;
503 break;
504 }
505 numberOfMethods++;
506 }
507 position++;
508 }
509 TextEditGroup description;
510 ListRewrite rewrite= fRewriter.getListRewrite(decl.getParent(), getBodyDeclarationsProperty(decl.getParent()));
511 if (!usingLocalGetter) {
512 description= new TextEditGroup(RefactoringCoreMessages.SelfEncapsulateField_add_getter);
513 result.add(description);
514 rewrite.insertAt(createGetterMethod(ast, rewriter, lineDelimiter), position++, description);
515 }
516 if (!JdtFlags.isFinal(fField) && !usingLocalSetter) {
517 description= new TextEditGroup(RefactoringCoreMessages.SelfEncapsulateField_add_setter);
518 result.add(description);
519 rewrite.insertAt(createSetterMethod(ast, rewriter, lineDelimiter), position, description);
520 }
521 if (!JdtFlags.isPrivate(fField))
522 result.add(makeDeclarationPrivate(rewriter, decl));
523 return result;
524 }
525
526 private TextEditGroup makeDeclarationPrivate(ASTRewrite rewriter, FieldDeclaration decl) {
527 TextEditGroup description= new TextEditGroup(RefactoringCoreMessages.SelfEncapsulateField_change_visibility);
528 VariableDeclarationFragment[] vdfs= new VariableDeclarationFragment[] { fFieldDeclaration };
529 int includedModifiers= Modifier.PRIVATE;
530 int excludedModifiers= Modifier.PROTECTED | Modifier.PUBLIC;
531 VariableDeclarationRewrite.rewriteModifiers(decl, vdfs, includedModifiers, excludedModifiers, rewriter, description);
532 return description;
533 }
534
535 private ChildListPropertyDescriptor getBodyDeclarationsProperty(ASTNode declaration) {
536 if (declaration instanceof AnonymousClassDeclaration)
537 return AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;
538 else if (declaration instanceof AbstractTypeDeclaration)
539 return ((AbstractTypeDeclaration) declaration).getBodyDeclarationsProperty();
540 Assert.isTrue(false);
541 return null;
542 }
543
544 private MethodDeclaration createSetterMethod(AST ast, ASTRewrite rewriter, String lineDelimiter) throws CoreException {
545 FieldDeclaration field= (FieldDeclaration)ASTNodes.getParent(fFieldDeclaration, FieldDeclaration.class);
546 Type type= field.getType();
547 MethodDeclaration result= ast.newMethodDeclaration();
548 result.setName(ast.newSimpleName(fSetterName));
549 result.modifiers().addAll(ASTNodeFactory.newModifiers(ast, createModifiers()));
550 if (fSetterMustReturnValue) {
551 result.setReturnType2((Type)rewriter.createCopyTarget(type));
552 }
553 SingleVariableDeclaration param= ast.newSingleVariableDeclaration();
554 result.parameters().add(param);
555 param.setName(ast.newSimpleName(fArgName));
556 param.setType((Type)rewriter.createCopyTarget(type));
557 param.setExtraDimensions(fFieldDeclaration.getExtraDimensions());
558
559 Block block= ast.newBlock();
560 result.setBody(block);
561
562 String fieldAccess= createFieldAccess();
563 String body= CodeGeneration.getSetterMethodBodyContent(fField.getCompilationUnit(), getTypeName(field.getParent()), fSetterName, fieldAccess, fArgName, lineDelimiter);
564 if (body != null) {
565 ASTNode setterNode= rewriter.createStringPlaceholder(body, ASTNode.BLOCK);
566 block.statements().add(setterNode);
567 } else {
568 Assignment ass= ast.newAssignment();
569 ass.setLeftHandSide((Expression) rewriter.createStringPlaceholder(fieldAccess, ASTNode.QUALIFIED_NAME));
570 ass.setRightHandSide(ast.newSimpleName(fArgName));
571 block.statements().add(ass);
572 }
573 if (fSetterMustReturnValue) {
574 ReturnStatement rs= ast.newReturnStatement();
575 rs.setExpression(ast.newSimpleName(fArgName));
576 block.statements().add(rs);
577 }
578 if (fGenerateJavadoc) {
579 String string= CodeGeneration.getSetterComment(
580 fField.getCompilationUnit() , getTypeName(field.getParent()), fSetterName,
581 fField.getElementName(), ASTNodes.asString(type), fArgName,
582 StubUtility.getBaseName(fField),
583 lineDelimiter);
584 if (string != null) {
585 Javadoc javadoc= (Javadoc)fRewriter.createStringPlaceholder(string, ASTNode.JAVADOC);
586 result.setJavadoc(javadoc);
587 }
588 }
589 return result;
590 }
591
592 private MethodDeclaration createGetterMethod(AST ast, ASTRewrite rewriter, String lineDelimiter) throws CoreException {
593 FieldDeclaration field= (FieldDeclaration)ASTNodes.getParent(fFieldDeclaration, FieldDeclaration.class);
594 Type type= field.getType();
595 MethodDeclaration result= ast.newMethodDeclaration();
596 result.setName(ast.newSimpleName(fGetterName));
597 result.modifiers().addAll(ASTNodeFactory.newModifiers(ast, createModifiers()));
598 Type returnType;
599 if (fFieldDeclaration.getExtraDimensions() > 0) {
600 if (type instanceof ArrayType) {
601 ArrayType arrayType= (ArrayType)type;
602 returnType= (Type)rewriter.createCopyTarget(arrayType.getElementType());
603 returnType= ast.newArrayType(returnType, fFieldDeclaration.getExtraDimensions() + arrayType.getDimensions());
604
605 } else {
606 returnType= (Type)rewriter.createCopyTarget(type);
607 returnType= ast.newArrayType(returnType, fFieldDeclaration.getExtraDimensions());
608 }
609 } else
610 returnType= (Type)rewriter.createCopyTarget(type);
611 result.setReturnType2(returnType);
612
613 Block block= ast.newBlock();
614 result.setBody(block);
615
616 String body= CodeGeneration.getGetterMethodBodyContent(fField.getCompilationUnit(), getTypeName(field.getParent()), fGetterName, fField.getElementName(), lineDelimiter);
617 if (body != null) {
618 ASTNode getterNode= rewriter.createStringPlaceholder(body, ASTNode.BLOCK);
619 block.statements().add(getterNode);
620 } else {
621 ReturnStatement rs= ast.newReturnStatement();
622 rs.setExpression(ast.newSimpleName(fField.getElementName()));
623 block.statements().add(rs);
624 }
625 if (fGenerateJavadoc) {
626 String string= CodeGeneration.getGetterComment(
627 fField.getCompilationUnit() , getTypeName(field.getParent()), fGetterName,
628 fField.getElementName(), ASTNodes.asString(type),
629 StubUtility.getBaseName(fField),
630 lineDelimiter);
631 if (string != null) {
632 Javadoc javadoc= (Javadoc)fRewriter.createStringPlaceholder(string, ASTNode.JAVADOC);
633 result.setJavadoc(javadoc);
634 }
635 }
636 return result;
637 }
638
639 private int createModifiers() throws JavaModelException {
640 int result= 0;
641 if (Flags.isPublic(fVisibility))
642 result |= Modifier.PUBLIC;
643 else if (Flags.isProtected(fVisibility))
644 result |= Modifier.PROTECTED;
645 else if (Flags.isPrivate(fVisibility))
646 result |= Modifier.PRIVATE;
647 if (JdtFlags.isStatic(fField))
648 result |= Modifier.STATIC;
649 return result;
650 }
651
652 private String createFieldAccess() throws JavaModelException {
653 String fieldName= fField.getElementName();
654 boolean nameConflict= fArgName.equals(fieldName);
655
656 if (JdtFlags.isStatic(fField)) {
657 if (nameConflict) {
658 return JavaModelUtil.concatenateName(fField.getDeclaringType().getElementName(), fieldName);
659 }
660 } else {
661 if (nameConflict || StubUtility.useThisForFieldAccess(fField.getJavaProject())) {
662 return "this." + fieldName; //$NON-NLS-1$
663 }
664 }
665 return fieldName;
666 }
667
668 private void checkArgName() {
669 String fieldName= fField.getElementName();
670 boolean isStatic= true;
671 try {
672 isStatic= JdtFlags.isStatic(fField);
673 } catch(JavaModelException e) {
674 }
675 if ( (isStatic && fArgName.equals(fieldName) && fieldName.equals(fField.getDeclaringType().getElementName()))
676 || JavaConventionsUtil.validateIdentifier(fArgName, fField).getSeverity() == IStatus.ERROR) {
677 fArgName= "_" + fArgName; //$NON-NLS-1$
678 }
679 }
680
681 private String getTypeName(ASTNode type) {
682 if (type instanceof AbstractTypeDeclaration) {
683 return ((AbstractTypeDeclaration)type).getName().getIdentifier();
684 } else if (type instanceof AnonymousClassDeclaration) {
685 ClassInstanceCreation node= (ClassInstanceCreation)ASTNodes.getParent(type, ClassInstanceCreation.class);
686 return ASTNodes.asString(node.getType());
687 }
688 Assert.isTrue(false, "Should not happen"); //$NON-NLS-1$
689 return null;
690 }
691
692 public RefactoringStatus initialize(JavaRefactoringArguments arguments) {
693 return arguments.generated_6580071410129555571(this);
694 }
695
696 public boolean isUsingLocalGetter() {
697 return checkName(fGetterName, fUsedReadNames);
698 }
699
700 public boolean isUsingLocalSetter() {
701 return checkName(fSetterName, fUsedModifyNames);
702 }
703
704 private static boolean checkName(String name, List<IMethodBinding> usedNames) {
705 for (Iterator<IMethodBinding> iter= usedNames.iterator(); iter.hasNext(); ) {
706 IMethodBinding method= iter.next();
707 String selector= method.getName();
708 if (selector.equals(name)) {
709 return true;
710 }
711 }
712 return false;
713 }
714
715 private boolean isIgnorableProblem(IProblem problem) {
716 if (problem.getID() == IProblem.NotVisibleField)
717 return true;
718 return false;
719 }
720
721 public boolean isConsiderVisibility() {
722 return fConsiderVisibility;
723 }
724
725 public void setConsiderVisibility(boolean considerVisibility) {
726 fConsiderVisibility= considerVisibility;
727 }
728
729 public void generated_2018755423923014312() throws CoreException {
730 setConsiderVisibility(false);//private field references are just searched in local file
731 checkInitialConditions(new NullProgressMonitor());
732 checkFinalConditions(new NullProgressMonitor());
733 }
734
735 public void generated_6700535397952918073(SelfEncapsulateFieldProposal selfencapsulatefieldproposal) {
736 setVisibility(Flags.AccPublic);
737 setConsiderVisibility(false);//private field references are just searched in local file
738 if (selfencapsulatefieldproposal.fNoDialog) {
739 IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
740 final RefactoringExecutionHelper helper= new RefactoringExecutionHelper(this, RefactoringStatus.ERROR, RefactoringSaveHelper.SAVE_REFACTORING, JavaPlugin.getActiveWorkbenchShell(), window);
741 if (Display.getCurrent() != null) {
742 try {
743 helper.perform(false, false);
744 } catch (InterruptedException e) {
745 JavaPlugin.log(e);
746 } catch (InvocationTargetException e) {
747 JavaPlugin.log(e);
748 }
749 } else {
750 Display.getDefault().syncExec(new Runnable() {
751 public void run() {
752 try {
753 helper.perform(false, false);
754 } catch (InterruptedException e) {
755 JavaPlugin.log(e);
756 } catch (InvocationTargetException e) {
757 JavaPlugin.log(e);
758 }
759 }
760 });
761 }
762 } else {
763 new RefactoringStarter().activate(new SelfEncapsulateFieldWizard(this), JavaPlugin.getActiveWorkbenchShell(), "", RefactoringSaveHelper.SAVE_REFACTORING); //$NON-NLS-1$
764 }
765 }
766
767 public Button generated_5839747861460611149(final SelfEncapsulateFieldInputPage selfencapsulatefieldinputpage, Composite result, Composite nameComposite) {
768 Label label;
769 selfencapsulatefieldinputpage.fGetterInfo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
770 selfencapsulatefieldinputpage.updateUseGetter();
771
772 if (selfencapsulatefieldinputpage.needsSetter()) {
773 label= new Label(nameComposite, SWT.LEAD);
774 label.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_setter_name);
775
776 selfencapsulatefieldinputpage.fSetterName= new Text(nameComposite, SWT.BORDER);
777 selfencapsulatefieldinputpage.fSetterName.setText(getSetterName());
778 selfencapsulatefieldinputpage.fSetterName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
779 selfencapsulatefieldinputpage.fSetterName.addModifyListener(new ModifyListener() {
780 public void modifyText(ModifyEvent e) {
781 selfencapsulatefieldinputpage.doSetterModified();
782 }
783 });
784 TextFieldNavigationHandler.install(selfencapsulatefieldinputpage.fSetterName);
785
786 selfencapsulatefieldinputpage.fSetterInfo= new Label(nameComposite, SWT.LEAD);
787 selfencapsulatefieldinputpage.fSetterInfo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
788 selfencapsulatefieldinputpage.updateUseSetter();
789 }
790
791 Link link= new Link(nameComposite, SWT.NONE);
792 link.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_configure_link);
793 link.addSelectionListener(new SelectionAdapter() {
794 @Override
795 public void widgetSelected(SelectionEvent e) {
796 selfencapsulatefieldinputpage.doOpenPreference();
797 }
798 });
799 link.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
800
801 Label separator= new Label(result, SWT.NONE);
802 separator.setText(""); //$NON-NLS-1$
803 separator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
804
805 // createSeparator(result, layouter);
806 selfencapsulatefieldinputpage.createFieldAccessBlock(result);
807
808 label= new Label(result, SWT.LEFT);
809 label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
810 label.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_insert_after);
811 selfencapsulatefieldinputpage.fEnablements.add(label);
812
813 final Combo combo= new Combo(result, SWT.READ_ONLY);
814 SWTUtil.setDefaultVisibleItemCount(combo);
815 selfencapsulatefieldinputpage.fillWithPossibleInsertPositions(combo, getField());
816 combo.addSelectionListener(new SelectionAdapter() {
817 @Override
818 public void widgetSelected(SelectionEvent event) {
819 setInsertionIndex(combo.getSelectionIndex() - 1);
820 }
821 });
822 combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
823 selfencapsulatefieldinputpage.fEnablements.add(combo);
824
825 selfencapsulatefieldinputpage.createAccessModifier(result);
826
827 Button checkBox= new Button(result, SWT.CHECK);
828 checkBox.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_generateJavadocComment);
829 checkBox.setSelection(getGenerateJavadoc());
830 checkBox.addSelectionListener(new SelectionAdapter() {
831 @Override
832 public void widgetSelected(SelectionEvent e) {
833 selfencapsulatefieldinputpage.setGenerateJavadoc(((Button)e.widget).getSelection());
834 }
835 });
836 return checkBox;
837 }
838
839 public void generated_1120108998625713785(SelfEncapsulateFieldInputPage selfencapsulatefieldinputpage) {
840 boolean enable=!(isUsingLocalSetter()&&isUsingLocalGetter());
841 for (Iterator<Control> iter= selfencapsulatefieldinputpage.fEnablements.iterator(); iter.hasNext();) {
842 Control control= iter.next();
843 control.setEnabled(enable);
844 }
845 }
846
847 public void generated_4707012495340476777(final SelfEncapsulateFieldInputPage selfencapsulatefieldinputpage, Composite result) {
848 int visibility= getVisibility();
849 if (Flags.isPublic(visibility))
850 return;
851
852 Label label= new Label(result, SWT.NONE);
853 label.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_access_Modifiers);
854 selfencapsulatefieldinputpage.fEnablements.add(label);
855
856 Composite group= new Composite(result, SWT.NONE);
857 group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
858
859 GridLayout layout= new GridLayout(4, false);
860 layout.marginWidth= 0;
861 layout.marginHeight= 0;
862 group.setLayout(layout);
863
864 group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
865
866 Object[] info= selfencapsulatefieldinputpage.createData(visibility);
867 String[] labels= (String[])info[0];
868 Integer[] data= (Integer[])info[1];
869 for (int i= 0; i < labels.length; i++) {
870 Button radio= new Button(group, SWT.RADIO);
871 radio.setText(labels[i]);
872 radio.setData(data[i]);
873 int iData= data[i].intValue();
874 if (iData == visibility)
875 radio.setSelection(true);
876 radio.addSelectionListener(new SelectionAdapter() {
877 @Override
878 public void widgetSelected(SelectionEvent event) {
879 setVisibility(((Integer)event.widget.getData()).intValue());
880 }
881 });
882 selfencapsulatefieldinputpage.fEnablements.add(radio);
883 }
884 }
885
886 public Button generated_2737941035924666987(final SelfEncapsulateFieldInputPage selfencapsulatefieldinputpage, Composite result) {
887 Composite group= new Composite(result, SWT.NONE);
888 GridLayout layout= new GridLayout(2, false);
889 layout.marginWidth= 0;
890 layout.marginHeight= 0;
891 group.setLayout(layout);
892
893 group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
894
895 Button radio= new Button(group, SWT.RADIO);
896 radio.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_use_setter_getter);
897 radio.setSelection(true);
898 radio.addSelectionListener(new SelectionAdapter() {
899 @Override
900 public void widgetSelected(SelectionEvent e) {
901 setEncapsulateDeclaringClass(true);
902 }
903 });
904 radio.setLayoutData(new GridData());
905
906 radio= new Button(group, SWT.RADIO);
907 radio.setText(RefactoringMessages.SelfEncapsulateFieldInputPage_keep_references);
908 radio.addSelectionListener(new SelectionAdapter() {
909 @Override
910 public void widgetSelected(SelectionEvent e) {
911 setEncapsulateDeclaringClass(false);
912 }
913 });
914 return radio;
915 }
916
917 public void generated_3757629404282508122(SelfEncapsulateFieldInputPage selfencapsulatefieldinputpage) {
918 String id= CodeStylePreferencePage.PROP_ID;
919 IJavaProject project= getField().getJavaProject();
920
921 String[] relevantOptions= selfencapsulatefieldinputpage.getRelevantOptions(project);
922
923 int open= PreferencesUtil.createPropertyDialogOn(selfencapsulatefieldinputpage.getShell(), project, id, new String[] { id }, null).open();
924 if (open == Window.OK && !Arrays.equals(relevantOptions, selfencapsulatefieldinputpage.getRelevantOptions(project))) { // relevant options changes
925 reinitialize();
926 selfencapsulatefieldinputpage.fGetterName.setText(getGetterName());
927 selfencapsulatefieldinputpage.fSetterName.setText(getSetterName());
928 }
929 }
930
931 public Refactoring generated_8252411552231870148(JavaRefactoringDescriptor descriptor, RefactoringStatus status, SelfEncapsulateRefactoringContribution selfencapsulaterefactoringcontribution) {
932 status.merge(initialize(new JavaRefactoringArguments(descriptor.getProject(), selfencapsulaterefactoringcontribution.retrieveArgumentMap(descriptor))));
933 return this;
934 }
935
936 public void generated_8705836902015974464(AccessAnalyzer accessanalyzer, ICompilationUnit unit, IVariableBinding field, ITypeBinding declaringClass, ASTRewrite rewriter, ImportRewrite importRewrite) {
937 Assert.isNotNull(this);
938 Assert.isNotNull(unit);
939 Assert.isNotNull(field);
940 Assert.isNotNull(declaringClass);
941 Assert.isNotNull(rewriter);
942 Assert.isNotNull(importRewrite);
943 accessanalyzer.fCUnit= unit;
944 accessanalyzer.fFieldBinding= field.getVariableDeclaration();
945 accessanalyzer.fDeclaringClassBinding= declaringClass;
946 accessanalyzer.fRewriter= rewriter;
947 accessanalyzer.fImportRewriter= importRewrite;
948 accessanalyzer.fGroupDescriptions= new ArrayList<TextEditGroup>();
949 accessanalyzer.fGetter= getGetterName();
950 accessanalyzer.fSetter= getSetterName();
951 accessanalyzer.fEncapsulateDeclaringClass= getEncapsulateDeclaringClass();
952 try {
953 accessanalyzer.fIsFieldFinal= Flags.isFinal(getField().getFlags());
954 } catch (JavaModelException e) {
955 // assume non final field
956 }
957 accessanalyzer.fStatus= new RefactoringStatus();
958 }
959
960
961}