Ejemplo n.º 1
0
 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;
 }
Ejemplo n.º 3
0
  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();
 }