Source Code Cross Referenced for InlineMethodRefactoring.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » corext » refactoring » code » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.corext.refactoring.code 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *     Dmitry Stalnov (dstalnov@fusionone.com) - contributed fixes for:
011:         *       o inline call that is used in a field initializer 
012:         *         (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38137)
013:         *       o Allow 'this' constructor to be inlined  
014:         *         (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38093)
015:         *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.code;
016:
017:        import java.util.ArrayList;
018:        import java.util.HashMap;
019:        import java.util.List;
020:        import java.util.Map;
021:
022:        import org.eclipse.text.edits.MultiTextEdit;
023:        import org.eclipse.text.edits.TextEdit;
024:        import org.eclipse.text.edits.TextEditGroup;
025:
026:        import org.eclipse.core.runtime.Assert;
027:        import org.eclipse.core.runtime.CoreException;
028:        import org.eclipse.core.runtime.IProgressMonitor;
029:        import org.eclipse.core.runtime.OperationCanceledException;
030:        import org.eclipse.core.runtime.SubProgressMonitor;
031:
032:        import org.eclipse.core.resources.IFile;
033:        import org.eclipse.core.resources.IResource;
034:
035:        import org.eclipse.ltk.core.refactoring.Change;
036:        import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
037:        import org.eclipse.ltk.core.refactoring.RefactoringStatus;
038:        import org.eclipse.ltk.core.refactoring.TextChange;
039:        import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
040:        import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;
041:
042:        import org.eclipse.jdt.core.Flags;
043:        import org.eclipse.jdt.core.IClassFile;
044:        import org.eclipse.jdt.core.ICompilationUnit;
045:        import org.eclipse.jdt.core.IJavaElement;
046:        import org.eclipse.jdt.core.IJavaProject;
047:        import org.eclipse.jdt.core.IMethod;
048:        import org.eclipse.jdt.core.IType;
049:        import org.eclipse.jdt.core.ITypeHierarchy;
050:        import org.eclipse.jdt.core.ITypeRoot;
051:        import org.eclipse.jdt.core.JavaModelException;
052:        import org.eclipse.jdt.core.dom.AST;
053:        import org.eclipse.jdt.core.dom.ASTNode;
054:        import org.eclipse.jdt.core.dom.BodyDeclaration;
055:        import org.eclipse.jdt.core.dom.CompilationUnit;
056:        import org.eclipse.jdt.core.dom.ConstructorInvocation;
057:        import org.eclipse.jdt.core.dom.ExpressionStatement;
058:        import org.eclipse.jdt.core.dom.IMethodBinding;
059:        import org.eclipse.jdt.core.dom.ITypeBinding;
060:        import org.eclipse.jdt.core.dom.MethodDeclaration;
061:        import org.eclipse.jdt.core.dom.MethodInvocation;
062:        import org.eclipse.jdt.core.dom.Modifier;
063:        import org.eclipse.jdt.core.dom.SuperMethodInvocation;
064:        import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
065:        import org.eclipse.jdt.core.refactoring.descriptors.InlineMethodDescriptor;
066:        import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
067:
068:        import org.eclipse.jdt.internal.corext.dom.NodeFinder;
069:        import org.eclipse.jdt.internal.corext.refactoring.Checks;
070:        import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
071:        import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
072:        import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
073:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
074:        import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
075:        import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
076:        import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
077:        import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
078:        import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
079:        import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
080:        import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
081:        import org.eclipse.jdt.internal.corext.util.Messages;
082:
083:        import org.eclipse.jdt.ui.JavaElementLabels;
084:
085:        import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
086:
087:        /*
088:         * Open items:
089:         *  - generate import statements for newly generated local variable declarations.
090:         *  - forbid cases like foo(foo(10)) when inlining foo().
091:         *  - case ref.foo(); and we want to inline foo. Inline a method in a different context;
092:         *  - optimize code when the method to be inlined returns an argument and that one is
093:         *    assigned to a parameter again. No need for a separate local (important to be able
094:         *    to reverse extract method correctly).
095:         */
096:        public class InlineMethodRefactoring extends ScriptableRefactoring {
097:
098:            private static final String ATTRIBUTE_MODE = "mode"; //$NON-NLS-1$
099:            private static final String ATTRIBUTE_DELETE = "delete"; //$NON-NLS-1$
100:
101:            public static class Mode {
102:                private Mode() {
103:                }
104:
105:                public static final Mode INLINE_ALL = new Mode();
106:                public static final Mode INLINE_SINGLE = new Mode();
107:            }
108:
109:            private ITypeRoot fInitialTypeRoot;
110:            private ASTNode fInitialNode;
111:            private TextChangeManager fChangeManager;
112:            private SourceProvider fSourceProvider;
113:            private TargetProvider fTargetProvider;
114:            /**
115:             * must never be true if fInitialUnit instanceof IClassFile
116:             */
117:            private boolean fDeleteSource;
118:            private Mode fCurrentMode;
119:            private Mode fInitialMode;
120:            private int fSelectionStart;
121:            private int fSelectionLength;
122:
123:            private InlineMethodRefactoring(ITypeRoot typeRoot, ASTNode node,
124:                    int offset, int length) {
125:                Assert.isNotNull(typeRoot);
126:                Assert.isTrue(JavaElementUtil.isSourceAvailable(typeRoot));
127:                Assert.isNotNull(node);
128:                fInitialTypeRoot = typeRoot;
129:                fInitialNode = node;
130:                fSelectionStart = offset;
131:                fSelectionLength = length;
132:            }
133:
134:            private InlineMethodRefactoring(ICompilationUnit unit,
135:                    MethodInvocation node, int offset, int length) {
136:                this (unit, (ASTNode) node, offset, length);
137:                fTargetProvider = TargetProvider.create(unit, node);
138:                fInitialMode = fCurrentMode = Mode.INLINE_SINGLE;
139:                fDeleteSource = false;
140:            }
141:
142:            private InlineMethodRefactoring(ICompilationUnit unit,
143:                    SuperMethodInvocation node, int offset, int length) {
144:                this (unit, (ASTNode) node, offset, length);
145:                fTargetProvider = TargetProvider.create(unit, node);
146:                fInitialMode = fCurrentMode = Mode.INLINE_SINGLE;
147:                fDeleteSource = false;
148:            }
149:
150:            private InlineMethodRefactoring(ICompilationUnit unit,
151:                    ConstructorInvocation node, int offset, int length) {
152:                this (unit, (ASTNode) node, offset, length);
153:                fTargetProvider = TargetProvider.create(unit, node);
154:                fInitialMode = fCurrentMode = Mode.INLINE_SINGLE;
155:                fDeleteSource = false;
156:            }
157:
158:            private InlineMethodRefactoring(ITypeRoot typeRoot,
159:                    MethodDeclaration node, int offset, int length) {
160:                this (typeRoot, (ASTNode) node, offset, length);
161:                fSourceProvider = new SourceProvider(typeRoot, node);
162:                fTargetProvider = TargetProvider.create(node);
163:                fInitialMode = fCurrentMode = Mode.INLINE_ALL;
164:                fDeleteSource = canEnableDeleteSource();
165:            }
166:
167:            /**
168:             * Creates a new inline method refactoring
169:             * @param unit the compilation unit or class file
170:             * @param node the compilation unit node
171:             * @param selectionStart
172:             * @param selectionLength
173:             * @return returns the refactoring
174:             */
175:            public static InlineMethodRefactoring create(ITypeRoot unit,
176:                    CompilationUnit node, int selectionStart,
177:                    int selectionLength) {
178:                ASTNode target = getTargetNode(unit, node, selectionStart,
179:                        selectionLength);
180:                if (target == null)
181:                    return null;
182:                if (target.getNodeType() == ASTNode.METHOD_DECLARATION) {
183:
184:                    return new InlineMethodRefactoring(unit,
185:                            (MethodDeclaration) target, selectionStart,
186:                            selectionLength);
187:                } else {
188:                    ICompilationUnit cu = (ICompilationUnit) unit;
189:                    if (target.getNodeType() == ASTNode.METHOD_INVOCATION) {
190:                        return new InlineMethodRefactoring(cu,
191:                                (MethodInvocation) target, selectionStart,
192:                                selectionLength);
193:                    } else if (target.getNodeType() == ASTNode.SUPER_METHOD_INVOCATION) {
194:                        return new InlineMethodRefactoring(cu,
195:                                (SuperMethodInvocation) target, selectionStart,
196:                                selectionLength);
197:                    } else if (target.getNodeType() == ASTNode.CONSTRUCTOR_INVOCATION) {
198:                        return new InlineMethodRefactoring(cu,
199:                                (ConstructorInvocation) target, selectionStart,
200:                                selectionLength);
201:                    }
202:                }
203:                return null;
204:            }
205:
206:            public String getName() {
207:                return RefactoringCoreMessages.InlineMethodRefactoring_name;
208:            }
209:
210:            public boolean canEnableDeleteSource() {
211:                return !(fSourceProvider.getTypeRoot() instanceof  IClassFile);
212:            }
213:
214:            public boolean getDeleteSource() {
215:                return fDeleteSource;
216:            }
217:
218:            public void setDeleteSource(boolean remove) {
219:                if (remove)
220:                    Assert.isTrue(canEnableDeleteSource());
221:                fDeleteSource = remove;
222:            }
223:
224:            public Mode getInitialMode() {
225:                return fInitialMode;
226:            }
227:
228:            public RefactoringStatus setCurrentMode(Mode mode)
229:                    throws JavaModelException {
230:                if (fCurrentMode == mode)
231:                    return new RefactoringStatus();
232:                Assert.isTrue(getInitialMode() == Mode.INLINE_SINGLE);
233:                fCurrentMode = mode;
234:                if (mode == Mode.INLINE_SINGLE) {
235:                    if (fInitialNode instanceof  MethodInvocation)
236:                        fTargetProvider = TargetProvider.create(
237:                                (ICompilationUnit) fInitialTypeRoot,
238:                                (MethodInvocation) fInitialNode);
239:                    else if (fInitialNode instanceof  SuperMethodInvocation)
240:                        fTargetProvider = TargetProvider.create(
241:                                (ICompilationUnit) fInitialTypeRoot,
242:                                (SuperMethodInvocation) fInitialNode);
243:                    else if (fInitialNode instanceof  ConstructorInvocation)
244:                        fTargetProvider = TargetProvider.create(
245:                                (ICompilationUnit) fInitialTypeRoot,
246:                                (ConstructorInvocation) fInitialNode);
247:                    else
248:                        throw new IllegalStateException(String
249:                                .valueOf(fInitialNode));
250:                } else {
251:                    fTargetProvider = TargetProvider.create(fSourceProvider
252:                            .getDeclaration());
253:                }
254:                return fTargetProvider.checkActivation();
255:            }
256:
257:            public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
258:                    throws CoreException {
259:                RefactoringStatus result = new RefactoringStatus();
260:                if (fSourceProvider == null
261:                        && Invocations.isInvocation(fInitialNode)) {
262:                    fSourceProvider = resolveSourceProvider(result,
263:                            fInitialTypeRoot, fInitialNode);
264:                    if (result.hasFatalError())
265:                        return result;
266:                }
267:                fTargetProvider.setSourceProvider(fSourceProvider);
268:                result.merge(fSourceProvider.checkActivation());
269:                result.merge(fTargetProvider.checkActivation());
270:                return result;
271:            }
272:
273:            public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
274:                    throws CoreException {
275:                pm.beginTask("", 20); //$NON-NLS-1$
276:                fChangeManager = new TextChangeManager();
277:                RefactoringStatus result = new RefactoringStatus();
278:                fSourceProvider.initialize();
279:                fTargetProvider.initialize();
280:                pm
281:                        .setTaskName(RefactoringCoreMessages.InlineMethodRefactoring_searching);
282:                RefactoringStatus searchStatus = new RefactoringStatus();
283:                ICompilationUnit[] units = fTargetProvider
284:                        .getAffectedCompilationUnits(searchStatus,
285:                                new SubProgressMonitor(pm, 1));
286:                if (searchStatus.hasFatalError()) {
287:                    result.merge(searchStatus);
288:                    return result;
289:                }
290:                IFile[] filesToBeModified = getFilesToBeModified(units);
291:                result.merge(Checks.validateModifiesFiles(filesToBeModified,
292:                        getValidationContext()));
293:                if (result.hasFatalError())
294:                    return result;
295:                result.merge(ResourceChangeChecker.checkFilesToBeChanged(
296:                        filesToBeModified, new SubProgressMonitor(pm, 1)));
297:                checkOverridden(result, new SubProgressMonitor(pm, 4));
298:                IProgressMonitor sub = new SubProgressMonitor(pm, 15);
299:                sub.beginTask("", units.length * 3); //$NON-NLS-1$
300:                for (int c = 0; c < units.length; c++) {
301:                    ICompilationUnit unit = units[c];
302:                    sub
303:                            .subTask(Messages
304:                                    .format(
305:                                            RefactoringCoreMessages.InlineMethodRefactoring_processing,
306:                                            unit.getElementName()));
307:                    CallInliner inliner = null;
308:                    try {
309:                        boolean added = false;
310:                        MultiTextEdit root = new MultiTextEdit();
311:                        CompilationUnitChange change = (CompilationUnitChange) fChangeManager
312:                                .get(unit);
313:                        change.setEdit(root);
314:                        BodyDeclaration[] bodies = fTargetProvider
315:                                .getAffectedBodyDeclarations(unit,
316:                                        new SubProgressMonitor(pm, 1));
317:                        if (bodies.length == 0)
318:                            continue;
319:                        inliner = new CallInliner(unit,
320:                                (CompilationUnit) bodies[0].getRoot(),
321:                                fSourceProvider);
322:                        for (int b = 0; b < bodies.length; b++) {
323:                            BodyDeclaration body = bodies[b];
324:                            inliner.initialize(body);
325:                            RefactoringStatus nestedInvocations = new RefactoringStatus();
326:                            ASTNode[] invocations = removeNestedCalls(
327:                                    nestedInvocations, unit, fTargetProvider
328:                                            .getInvocations(body,
329:                                                    new SubProgressMonitor(sub,
330:                                                            2)));
331:                            for (int i = 0; i < invocations.length; i++) {
332:                                ASTNode invocation = invocations[i];
333:                                result.merge(inliner.initialize(invocation,
334:                                        fTargetProvider.getStatusSeverity()));
335:                                if (result.hasFatalError())
336:                                    break;
337:                                if (result.getSeverity() < fTargetProvider
338:                                        .getStatusSeverity()) {
339:                                    added = true;
340:                                    TextEditGroup group = new TextEditGroup(
341:                                            RefactoringCoreMessages.InlineMethodRefactoring_edit_inline);
342:                                    change.addTextEditGroup(group);
343:                                    result.merge(inliner.perform(group));
344:                                } else {
345:                                    fDeleteSource = false;
346:                                }
347:                            }
348:                            // do this after we have inlined the method calls. We still want
349:                            // to generate the modifications.
350:                            if (!nestedInvocations.isOK()) {
351:                                result.merge(nestedInvocations);
352:                                fDeleteSource = false;
353:                            }
354:                        }
355:                        if (!added) {
356:                            fChangeManager.remove(unit);
357:                        } else {
358:                            root.addChild(inliner.getModifications());
359:                            ImportRewrite rewrite = inliner.getImportEdit();
360:                            if (rewrite.hasRecordedChanges()) {
361:                                TextEdit edit = rewrite.rewriteImports(null);
362:                                if (edit instanceof  MultiTextEdit ? ((MultiTextEdit) edit)
363:                                        .getChildrenSize() > 0
364:                                        : true) {
365:                                    root.addChild(edit);
366:                                    change
367:                                            .addTextEditGroup(new TextEditGroup(
368:                                                    RefactoringCoreMessages.InlineMethodRefactoring_edit_import,
369:                                                    new TextEdit[] { edit }));
370:                                }
371:                            }
372:                        }
373:                    } finally {
374:                        if (inliner != null)
375:                            inliner.dispose();
376:                    }
377:                    sub.worked(1);
378:                    if (sub.isCanceled())
379:                        throw new OperationCanceledException();
380:                }
381:                result.merge(searchStatus);
382:                sub.done();
383:                pm.done();
384:                return result;
385:            }
386:
387:            public Change createChange(IProgressMonitor pm)
388:                    throws CoreException {
389:                if (fDeleteSource && fCurrentMode == Mode.INLINE_ALL) {
390:                    TextChange change = fChangeManager
391:                            .get((ICompilationUnit) fSourceProvider
392:                                    .getTypeRoot());
393:                    TextEdit delete = fSourceProvider.getDeleteEdit();
394:                    TextEditGroup description = new TextEditGroup(
395:                            RefactoringCoreMessages.InlineMethodRefactoring_edit_delete,
396:                            new TextEdit[] { delete });
397:                    TextEdit root = change.getEdit();
398:                    if (root != null) {
399:                        // TODO instead of finding the right insert position the call inliner should
400:                        // reuse the AST & rewriter of the source provide and we should rewrite the
401:                        // whole AST at the end. However, since recursive calls aren't allowed there
402:                        // shouldn't be a text edit overlap.
403:                        // root.addChild(delete);
404:                        TextChangeCompatibility.insert(root, delete);
405:                    } else {
406:                        change.setEdit(delete);
407:                    }
408:                    change.addTextEditGroup(description);
409:                }
410:                final Map arguments = new HashMap();
411:                String project = null;
412:                IJavaProject javaProject = fInitialTypeRoot.getJavaProject();
413:                if (javaProject != null)
414:                    project = javaProject.getElementName();
415:                int flags = RefactoringDescriptor.STRUCTURAL_CHANGE
416:                        | JavaRefactoringDescriptor.JAR_REFACTORING
417:                        | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
418:                final IMethodBinding binding = fSourceProvider.getDeclaration()
419:                        .resolveBinding();
420:                final ITypeBinding declaring = binding.getDeclaringClass();
421:                if (!Modifier.isPrivate(binding.getModifiers()))
422:                    flags |= RefactoringDescriptor.MULTI_CHANGE;
423:                final String description = Messages
424:                        .format(
425:                                RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description_short,
426:                                binding.getName());
427:                final String header = Messages
428:                        .format(
429:                                RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description,
430:                                new String[] {
431:                                        BindingLabelProvider
432:                                                .getBindingLabel(
433:                                                        binding,
434:                                                        JavaElementLabels.ALL_FULLY_QUALIFIED),
435:                                        BindingLabelProvider
436:                                                .getBindingLabel(
437:                                                        declaring,
438:                                                        JavaElementLabels.ALL_FULLY_QUALIFIED) });
439:                final JDTRefactoringDescriptorComment comment = new JDTRefactoringDescriptorComment(
440:                        project, this , header);
441:                comment
442:                        .addSetting(Messages
443:                                .format(
444:                                        RefactoringCoreMessages.InlineMethodRefactoring_original_pattern,
445:                                        BindingLabelProvider
446:                                                .getBindingLabel(
447:                                                        binding,
448:                                                        JavaElementLabels.ALL_FULLY_QUALIFIED)));
449:                if (fDeleteSource)
450:                    comment
451:                            .addSetting(RefactoringCoreMessages.InlineMethodRefactoring_remove_method);
452:                if (fCurrentMode == Mode.INLINE_ALL)
453:                    comment
454:                            .addSetting(RefactoringCoreMessages.InlineMethodRefactoring_replace_references);
455:                final InlineMethodDescriptor descriptor = new InlineMethodDescriptor(
456:                        project, description, comment.asString(), arguments,
457:                        flags);
458:                arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT,
459:                        JavaRefactoringDescriptorUtil.elementToHandle(project,
460:                                fInitialTypeRoot));
461:                arguments
462:                        .put(
463:                                JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION,
464:                                new Integer(fSelectionStart).toString()
465:                                        + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$
466:                arguments.put(ATTRIBUTE_DELETE, Boolean.valueOf(fDeleteSource)
467:                        .toString());
468:                arguments.put(ATTRIBUTE_MODE, new Integer(
469:                        fCurrentMode == Mode.INLINE_ALL ? 1 : 0).toString());
470:                return new DynamicValidationRefactoringChange(
471:                        descriptor,
472:                        RefactoringCoreMessages.InlineMethodRefactoring_edit_inlineCall,
473:                        fChangeManager.getAllChanges());
474:            }
475:
476:            private static SourceProvider resolveSourceProvider(
477:                    RefactoringStatus status, ITypeRoot typeRoot,
478:                    ASTNode invocation) throws JavaModelException {
479:                CompilationUnit root = (CompilationUnit) invocation.getRoot();
480:                IMethodBinding methodBinding = Invocations
481:                        .resolveBinding(invocation);
482:                if (methodBinding == null) {
483:                    status
484:                            .addFatalError(RefactoringCoreMessages.InlineMethodRefactoring_error_noMethodDeclaration);
485:                    return null;
486:                }
487:                MethodDeclaration declaration = (MethodDeclaration) root
488:                        .findDeclaringNode(methodBinding);
489:                if (declaration != null) {
490:                    return new SourceProvider(typeRoot, declaration);
491:                }
492:                IMethod method = (IMethod) methodBinding.getJavaElement();
493:                if (method != null) {
494:                    CompilationUnit methodDeclarationAstRoot;
495:                    ICompilationUnit methodCu = method.getCompilationUnit();
496:                    if (methodCu != null) {
497:                        methodDeclarationAstRoot = new RefactoringASTParser(
498:                                AST.JLS3).parse(methodCu, true);
499:                    } else {
500:                        IClassFile classFile = method.getClassFile();
501:                        if (!JavaElementUtil.isSourceAvailable(classFile)) {
502:                            String methodLabel = JavaElementLabels
503:                                    .getTextLabel(
504:                                            method,
505:                                            JavaElementLabels.M_FULLY_QUALIFIED
506:                                                    | JavaElementLabels.M_PARAMETER_TYPES);
507:                            status
508:                                    .addFatalError(Messages
509:                                            .format(
510:                                                    RefactoringCoreMessages.InlineMethodRefactoring_error_classFile,
511:                                                    methodLabel));
512:                            return null;
513:                        }
514:                        methodDeclarationAstRoot = new RefactoringASTParser(
515:                                AST.JLS3).parse(classFile, true);
516:                    }
517:                    ASTNode node = methodDeclarationAstRoot
518:                            .findDeclaringNode(methodBinding
519:                                    .getMethodDeclaration().getKey());
520:                    if (node instanceof  MethodDeclaration) {
521:                        return new SourceProvider(methodDeclarationAstRoot
522:                                .getTypeRoot(), (MethodDeclaration) node);
523:                    }
524:                }
525:                status
526:                        .addFatalError(RefactoringCoreMessages.InlineMethodRefactoring_error_noMethodDeclaration);
527:                return null;
528:            }
529:
530:            private static ASTNode getTargetNode(ITypeRoot typeRoot,
531:                    CompilationUnit root, int offset, int length) {
532:                ASTNode node = null;
533:                try {
534:                    node = checkNode(NodeFinder.perform(root, offset, length,
535:                            typeRoot), typeRoot);
536:                } catch (JavaModelException e) {
537:                    // Do nothing
538:                }
539:                if (node != null)
540:                    return node;
541:                return checkNode(NodeFinder.perform(root, offset, length),
542:                        typeRoot);
543:            }
544:
545:            private static ASTNode checkNode(ASTNode node, IJavaElement unit) {
546:                if (node == null)
547:                    return null;
548:                if (node.getNodeType() == ASTNode.SIMPLE_NAME) {
549:                    node = node.getParent();
550:                } else if (node.getNodeType() == ASTNode.EXPRESSION_STATEMENT) {
551:                    node = ((ExpressionStatement) node).getExpression();
552:                }
553:                switch (node.getNodeType()) {
554:                case ASTNode.METHOD_DECLARATION:
555:                    return node;
556:                case ASTNode.METHOD_INVOCATION:
557:                case ASTNode.SUPER_METHOD_INVOCATION:
558:                case ASTNode.CONSTRUCTOR_INVOCATION:
559:                    return unit instanceof  ICompilationUnit ? node : null; // don't start on invocations in binary
560:                }
561:                return null;
562:            }
563:
564:            private IFile[] getFilesToBeModified(ICompilationUnit[] units) {
565:                List result = new ArrayList(units.length + 1);
566:                IFile file;
567:                for (int i = 0; i < units.length; i++) {
568:                    file = getFile(units[i]);
569:                    if (file != null)
570:                        result.add(file);
571:                }
572:                if (fDeleteSource) {
573:                    file = getFile((ICompilationUnit) fSourceProvider
574:                            .getTypeRoot());
575:                    if (file != null && !result.contains(file))
576:                        result.add(file);
577:                }
578:                return (IFile[]) result.toArray(new IFile[result.size()]);
579:            }
580:
581:            private IFile getFile(ICompilationUnit unit) {
582:                unit = unit.getPrimary();
583:                IResource resource = unit.getResource();
584:                if (resource != null && resource.getType() == IResource.FILE)
585:                    return (IFile) resource;
586:                return null;
587:            }
588:
589:            private void checkOverridden(RefactoringStatus status,
590:                    IProgressMonitor pm) throws JavaModelException {
591:                pm.beginTask("", 9); //$NON-NLS-1$
592:                pm
593:                        .setTaskName(RefactoringCoreMessages.InlineMethodRefactoring_checking_overridden);
594:                MethodDeclaration decl = fSourceProvider.getDeclaration();
595:                IMethod method = (IMethod) decl.resolveBinding()
596:                        .getJavaElement();
597:                if (method == null || Flags.isPrivate(method.getFlags())) {
598:                    pm.worked(8);
599:                    return;
600:                }
601:                IType type = method.getDeclaringType();
602:                ITypeHierarchy hierarchy = type
603:                        .newTypeHierarchy(new SubProgressMonitor(pm, 6));
604:                checkSubTypes(status, method, hierarchy.getAllSubtypes(type),
605:                        new SubProgressMonitor(pm, 1));
606:                checkSuperClasses(status, method, hierarchy
607:                        .getAllSuperclasses(type),
608:                        new SubProgressMonitor(pm, 1));
609:                checkSuperInterfaces(status, method, hierarchy
610:                        .getAllSuperInterfaces(type), new SubProgressMonitor(
611:                        pm, 1));
612:                pm.setTaskName(""); //$NON-NLS-1$
613:            }
614:
615:            private void checkSubTypes(RefactoringStatus result,
616:                    IMethod method, IType[] types, IProgressMonitor pm) {
617:                checkTypes(
618:                        result,
619:                        method,
620:                        types,
621:                        RefactoringCoreMessages.InlineMethodRefactoring_checking_overridden_error,
622:                        pm);
623:            }
624:
625:            private void checkSuperClasses(RefactoringStatus result,
626:                    IMethod method, IType[] types, IProgressMonitor pm) {
627:                checkTypes(
628:                        result,
629:                        method,
630:                        types,
631:                        RefactoringCoreMessages.InlineMethodRefactoring_checking_overrides_error,
632:                        pm);
633:            }
634:
635:            private void checkSuperInterfaces(RefactoringStatus result,
636:                    IMethod method, IType[] types, IProgressMonitor pm) {
637:                checkTypes(
638:                        result,
639:                        method,
640:                        types,
641:                        RefactoringCoreMessages.InlineMethodRefactoring_checking_implements _error,
642:                        pm);
643:            }
644:
645:            private void checkTypes(RefactoringStatus result, IMethod method,
646:                    IType[] types, String key, IProgressMonitor pm) {
647:                pm.beginTask("", types.length); //$NON-NLS-1$
648:                for (int i = 0; i < types.length; i++) {
649:                    pm.worked(1);
650:                    IMethod[] overridden = types[i].findMethods(method);
651:                    if (overridden != null && overridden.length > 0) {
652:                        result.addError(Messages.format(key, types[i]
653:                                .getElementName()), JavaStatusContext
654:                                .create(overridden[0]));
655:                    }
656:                }
657:            }
658:
659:            private ASTNode[] removeNestedCalls(RefactoringStatus status,
660:                    ICompilationUnit unit, ASTNode[] invocations) {
661:                if (invocations.length <= 1)
662:                    return invocations;
663:                ASTNode[] parents = new ASTNode[invocations.length];
664:                for (int i = 0; i < invocations.length; i++) {
665:                    parents[i] = invocations[i].getParent();
666:                }
667:                for (int i = 0; i < invocations.length; i++) {
668:                    removeNestedCalls(status, unit, parents, invocations, i);
669:                }
670:                List result = new ArrayList();
671:                for (int i = 0; i < invocations.length; i++) {
672:                    if (invocations[i] != null)
673:                        result.add(invocations[i]);
674:                }
675:                return (ASTNode[]) result.toArray(new ASTNode[result.size()]);
676:            }
677:
678:            private void removeNestedCalls(RefactoringStatus status,
679:                    ICompilationUnit unit, ASTNode[] parents,
680:                    ASTNode[] invocations, int index) {
681:                ASTNode invocation = invocations[index];
682:                for (int i = 0; i < parents.length; i++) {
683:                    ASTNode parent = parents[i];
684:                    while (parent != null) {
685:                        if (parent == invocation) {
686:                            status
687:                                    .addError(
688:                                            RefactoringCoreMessages.InlineMethodRefactoring_nestedInvocation,
689:                                            JavaStatusContext.create(unit,
690:                                                    parent));
691:                            invocations[index] = null;
692:                        }
693:                        parent = parent.getParent();
694:                    }
695:                }
696:            }
697:
698:            public RefactoringStatus initialize(
699:                    final RefactoringArguments arguments) {
700:                if (arguments instanceof  JavaRefactoringArguments) {
701:                    final JavaRefactoringArguments generic = (JavaRefactoringArguments) arguments;
702:                    final String delete = generic
703:                            .getAttribute(ATTRIBUTE_DELETE);
704:                    if (delete != null) {
705:                        fDeleteSource = Boolean.valueOf(delete).booleanValue();
706:                    } else
707:                        return RefactoringStatus
708:                                .createFatalErrorStatus(Messages
709:                                        .format(
710:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
711:                                                ATTRIBUTE_DELETE));
712:                    final String value = generic.getAttribute(ATTRIBUTE_MODE);
713:                    if (value != null && !"".equals(value)) {//$NON-NLS-1$
714:                        int mode = 0;
715:                        try {
716:                            mode = Integer.parseInt(value);
717:                        } catch (NumberFormatException exception) {
718:                            return RefactoringStatus
719:                                    .createFatalErrorStatus(Messages
720:                                            .format(
721:                                                    RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
722:                                                    ATTRIBUTE_MODE));
723:                        }
724:                        try {
725:                            setCurrentMode(mode == 1 ? Mode.INLINE_ALL
726:                                    : Mode.INLINE_SINGLE);
727:                        } catch (JavaModelException exception) {
728:                            return RefactoringStatus
729:                                    .createFatalErrorStatus(exception
730:                                            .getLocalizedMessage());
731:                        }
732:                    }
733:                } else
734:                    return RefactoringStatus
735:                            .createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
736:                return new RefactoringStatus();
737:            }
738:        }
w_w_w__._java2_s.co___m___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.