public String loadSource(String pathToSource) throws IOException, UnknownSourceProviderException { for (SourceProvider sourceProvider : sourceProviders) { if (sourceProvider.isAllowed(pathToSource)) { return sourceProvider.load(pathToSource); } } throw new UnknownSourceProviderException(); }
public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { RefactoringStatus result = new RefactoringStatus(); if (fSourceProvider == null && Invocations.isInvocation(fInitialNode)) { fSourceProvider = resolveSourceProvider(result, fInitialTypeRoot, fInitialNode); if (result.hasFatalError()) return result; } result.merge(fSourceProvider.checkActivation()); result.merge(fTargetProvider.checkActivation()); return result; }
public static Set<File> getCompileClasses(File file, SourceProvider sourceProvider) throws IOException { if (!file.isDirectory()) return null; HashSet<File> out = new HashSet<>(); for (File f : file.listFiles()) { if (f.isDirectory()) { Set<File> aa = getCompileClasses(f, sourceProvider); if (aa != null) out.addAll(aa); continue; } if (!f.isFile()) continue; if (!f.getName().endsWith(".class")) continue; try (FileInputStream fis = new FileInputStream(f)) { ClassReader cr = new ClassReader(fis); ClassNode classNode = new ClassNode(); cr.accept(classNode, 0); if (classNode.visibleAnnotations != null) for (Object o : classNode.visibleAnnotations) { AnnotationNode an = (AnnotationNode) o; if (an.desc.equals("L" + JSClass.class.getName().replace('.', '/') + ";")) { if (classNode.name.contains("$")) { String cn = classNode.name.substring(0, classNode.name.indexOf("$")).replace('/', '.'); sourceProvider.getSourceForClass(cn).ifPresent(e -> out.add(e)); } else { if (sourceProvider .getSourceForClass(classNode.name.replace('/', '.')) .isPresent()) { out.add(sourceProvider.getSourceForClass(classNode.name.replace('/', '.')).get()); } } } } } } return out; }
private IFile[] getFilesToBeModified(ICompilationUnit[] units) { List result = new ArrayList(units.length + 1); IFile file; for (int i = 0; i < units.length; i++) { file = getFile(units[i]); if (file != null) result.add(file); } if (fDeleteSource) { file = getFile((ICompilationUnit) fSourceProvider.getTypeRoot()); if (file != null && !result.contains(file)) result.add(file); } return (IFile[]) result.toArray(new IFile[result.size()]); }
private void checkOverridden(RefactoringStatus status, IProgressMonitor pm) throws JavaModelException { pm.beginTask("", 9); // $NON-NLS-1$ pm.setTaskName(RefactoringCoreMessages.InlineMethodRefactoring_checking_overridden); MethodDeclaration decl = fSourceProvider.getDeclaration(); IMethod method = (IMethod) decl.resolveBinding().getJavaElement(); if (method == null || Flags.isPrivate(method.getFlags())) { pm.worked(8); return; } IType type = method.getDeclaringType(); ITypeHierarchy hierarchy = type.newTypeHierarchy(new SubProgressMonitor(pm, 6)); checkSubTypes(status, method, hierarchy.getAllSubtypes(type), new SubProgressMonitor(pm, 1)); checkSuperClasses( status, method, hierarchy.getAllSuperclasses(type), new SubProgressMonitor(pm, 1)); checkSuperInterfaces( status, method, hierarchy.getAllSuperInterfaces(type), new SubProgressMonitor(pm, 1)); pm.setTaskName(""); // $NON-NLS-1$ }
public RefactoringStatus setCurrentMode(Mode mode) throws JavaModelException { if (fCurrentMode == mode) return new RefactoringStatus(); Assert.isTrue(getInitialMode() == Mode.INLINE_SINGLE); fCurrentMode = mode; if (mode == Mode.INLINE_SINGLE) { if (fInitialNode instanceof MethodInvocation) fTargetProvider = TargetProvider.create( (ICompilationUnit) fInitialTypeRoot, (MethodInvocation) fInitialNode); else if (fInitialNode instanceof SuperMethodInvocation) fTargetProvider = TargetProvider.create( (ICompilationUnit) fInitialTypeRoot, (SuperMethodInvocation) fInitialNode); else if (fInitialNode instanceof ConstructorInvocation) fTargetProvider = TargetProvider.create( (ICompilationUnit) fInitialTypeRoot, (ConstructorInvocation) fInitialNode); else throw new IllegalStateException(String.valueOf(fInitialNode)); } else { fTargetProvider = TargetProvider.create(fSourceProvider.getDeclaration()); } return fTargetProvider.checkActivation(); }
public Change createChange(IProgressMonitor pm) throws CoreException { if (fDeleteSource && fCurrentMode == Mode.INLINE_ALL) { TextChange change = fChangeManager.get((ICompilationUnit) fSourceProvider.getTypeRoot()); TextEdit delete = fSourceProvider.getDeleteEdit(); TextEditGroup description = new TextEditGroup( RefactoringCoreMessages.InlineMethodRefactoring_edit_delete, new TextEdit[] {delete}); TextEdit root = change.getEdit(); if (root != null) { // TODO instead of finding the right insert position the call inliner should // reuse the AST & rewriter of the source provide and we should rewrite the // whole AST at the end. However, since recursive calls aren't allowed there // shouldn't be a text edit overlap. // root.addChild(delete); TextChangeCompatibility.insert(root, delete); } else { change.setEdit(delete); } change.addTextEditGroup(description); } final Map arguments = new HashMap(); String project = null; IJavaProject javaProject = fInitialTypeRoot.getJavaProject(); if (javaProject != null) project = javaProject.getElementName(); int flags = RefactoringDescriptor.STRUCTURAL_CHANGE | JavaRefactoringDescriptor.JAR_REFACTORING | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT; final IMethodBinding binding = fSourceProvider.getDeclaration().resolveBinding(); final ITypeBinding declaring = binding.getDeclaringClass(); if (!Modifier.isPrivate(binding.getModifiers())) flags |= RefactoringDescriptor.MULTI_CHANGE; final String description = Messages.format( RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description_short, BasicElementLabels.getJavaElementName(binding.getName())); final String header = Messages.format( RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description, new String[] { BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED), BindingLabelProvider.getBindingLabel(declaring, JavaElementLabels.ALL_FULLY_QUALIFIED) }); final JDTRefactoringDescriptorComment comment = new JDTRefactoringDescriptorComment(project, this, header); comment.addSetting( Messages.format( RefactoringCoreMessages.InlineMethodRefactoring_original_pattern, BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED))); if (fDeleteSource) comment.addSetting(RefactoringCoreMessages.InlineMethodRefactoring_remove_method); if (fCurrentMode == Mode.INLINE_ALL) comment.addSetting(RefactoringCoreMessages.InlineMethodRefactoring_replace_references); final InlineMethodDescriptor descriptor = RefactoringSignatureDescriptorFactory.createInlineMethodDescriptor( project, description, comment.asString(), arguments, flags); arguments.put( JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT, JavaRefactoringDescriptorUtil.elementToHandle(project, fInitialTypeRoot)); arguments.put( JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION, new Integer(fSelectionStart).toString() + " " + new Integer(fSelectionLength).toString()); // $NON-NLS-1$ arguments.put(ATTRIBUTE_DELETE, Boolean.valueOf(fDeleteSource).toString()); arguments.put(ATTRIBUTE_MODE, new Integer(fCurrentMode == Mode.INLINE_ALL ? 1 : 0).toString()); return new DynamicValidationRefactoringChange( descriptor, RefactoringCoreMessages.InlineMethodRefactoring_edit_inlineCall, fChangeManager.getAllChanges()); }
public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException { pm.beginTask("", 20); // $NON-NLS-1$ fChangeManager = new TextChangeManager(); RefactoringStatus result = new RefactoringStatus(); fSourceProvider.initialize(); fTargetProvider.initialize(); pm.setTaskName(RefactoringCoreMessages.InlineMethodRefactoring_searching); RefactoringStatus searchStatus = new RefactoringStatus(); String binaryRefsDescription = Messages.format( RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description, BasicElementLabels.getJavaElementName(fSourceProvider.getMethodName())); ReferencesInBinaryContext binaryRefs = new ReferencesInBinaryContext(binaryRefsDescription); ICompilationUnit[] units = fTargetProvider.getAffectedCompilationUnits( searchStatus, binaryRefs, new SubProgressMonitor(pm, 1)); binaryRefs.addErrorIfNecessary(searchStatus); if (searchStatus.hasFatalError()) { result.merge(searchStatus); return result; } IFile[] filesToBeModified = getFilesToBeModified(units); result.merge(Checks.validateModifiesFiles(filesToBeModified, getValidationContext())); if (result.hasFatalError()) return result; result.merge( ResourceChangeChecker.checkFilesToBeChanged( filesToBeModified, new SubProgressMonitor(pm, 1))); checkOverridden(result, new SubProgressMonitor(pm, 4)); IProgressMonitor sub = new SubProgressMonitor(pm, 15); sub.beginTask("", units.length * 3); // $NON-NLS-1$ for (int c = 0; c < units.length; c++) { ICompilationUnit unit = units[c]; sub.subTask( Messages.format( RefactoringCoreMessages.InlineMethodRefactoring_processing, BasicElementLabels.getFileName(unit))); CallInliner inliner = null; try { boolean added = false; MultiTextEdit root = new MultiTextEdit(); CompilationUnitChange change = (CompilationUnitChange) fChangeManager.get(unit); change.setEdit(root); BodyDeclaration[] bodies = fTargetProvider.getAffectedBodyDeclarations(unit, new SubProgressMonitor(pm, 1)); if (bodies.length == 0) continue; inliner = new CallInliner(unit, (CompilationUnit) bodies[0].getRoot(), fSourceProvider); for (int b = 0; b < bodies.length; b++) { BodyDeclaration body = bodies[b]; inliner.initialize(body); RefactoringStatus nestedInvocations = new RefactoringStatus(); ASTNode[] invocations = removeNestedCalls( nestedInvocations, unit, fTargetProvider.getInvocations(body, new SubProgressMonitor(sub, 2))); for (int i = 0; i < invocations.length; i++) { ASTNode invocation = invocations[i]; result.merge(inliner.initialize(invocation, fTargetProvider.getStatusSeverity())); if (result.hasFatalError()) break; if (result.getSeverity() < fTargetProvider.getStatusSeverity()) { added = true; TextEditGroup group = new TextEditGroup(RefactoringCoreMessages.InlineMethodRefactoring_edit_inline); change.addTextEditGroup(group); result.merge(inliner.perform(group)); } else { fDeleteSource = false; } } // do this after we have inlined the method calls. We still want // to generate the modifications. if (!nestedInvocations.isOK()) { result.merge(nestedInvocations); fDeleteSource = false; } } if (!added) { fChangeManager.remove(unit); } else { root.addChild(inliner.getModifications()); ImportRewrite rewrite = inliner.getImportEdit(); if (rewrite.hasRecordedChanges()) { TextEdit edit = rewrite.rewriteImports(null); if (edit instanceof MultiTextEdit ? ((MultiTextEdit) edit).getChildrenSize() > 0 : true) { root.addChild(edit); change.addTextEditGroup( new TextEditGroup( RefactoringCoreMessages.InlineMethodRefactoring_edit_import, new TextEdit[] {edit})); } } } } finally { if (inliner != null) inliner.dispose(); } sub.worked(1); if (sub.isCanceled()) throw new OperationCanceledException(); } result.merge(searchStatus); sub.done(); pm.done(); return result; }
public boolean canEnableDeleteSource() { return !(fSourceProvider.getTypeRoot() instanceof IClassFile); }
/** * Returns the method to inline, or null if the method could not be found or {@link * #checkInitialConditions(IProgressMonitor)} has not been called yet. * * @return the method, or <code>null</code> */ public IMethod getMethod() { if (fSourceProvider == null) return null; IMethodBinding binding = fSourceProvider.getDeclaration().resolveBinding(); if (binding == null) return null; return (IMethod) binding.getJavaElement(); }