【问题标题】:Formatting Source Code programmatically with JDT使用 JDT 以编程方式格式化源代码
【发布时间】:2013-04-15 12:32:00
【问题描述】:

我正在使用 JDT 生成一些类。之后我想格式化整个 ICompilationUnit,就像我在没有选择的情况下在打开的编辑器中按下 Ctrl+Shift+F(Source > Format)一样。

高度赞赏 JDT 中任何用于以编程方式格式化源代码的 API 指针。

补充:我试过这样,但代码没有改变。我在发什么消息?

private void formatUnitSourceCode(ICompilationUnit targetUnit, IProgressMonitor monitor) throws JavaModelException {
    CodeFormatter formatter = ToolFactory.createCodeFormatter(null);
    TextEdit formatEdit = formatter.format(CodeFormatter.K_COMPILATION_UNIT, targetUnit.getSource(), 0, targetUnit.getSource().length(), 0, null);
    targetUnit.applyTextEdit(formatEdit, monitor);
}

【问题讨论】:

    标签: java eclipse eclipse-jdt


    【解决方案1】:

    这可能是一个错误,但使用 Elcipse 4.2.2 中的 JDK,需要创建 ICompilationUnit 的工作副本才能将 TextEdit 应用于文件。

        targetUnit.becomeWorkingCopy(new SubProgressMonitor(monitor, 1));
        ... do work on the source file ...
        formatUnitSourceCode(targetUnit, new SubProgressMonitor(monitor, 1));
        targetUnit.commitWorkingCopy(true, new SubProgressMonitor(monitor, 1));
    

    格式化本身是这样完成的:

    public static void formatUnitSourceCode(ICompilationUnit unit, IProgressMonitor monitor) throws JavaModelException {
        CodeFormatter formatter = ToolFactory.createCodeFormatter(null);
        ISourceRange range = unit.getSourceRange();
        TextEdit formatEdit = formatter.format(CodeFormatter.K_COMPILATION_UNIT, unit.getSource(), range.getOffset(), range.getLength(), 0, null);
        if (formatEdit != null && formatEdit.hasChildren()) {
            unit.applyTextEdit(formatEdit, monitor);
        } else {
            monitor.done();
        }
    }
    

    【讨论】:

    • +1 一个小问题:SubProgressMonitor 现在已弃用。应该改用SubMonitor.convert(monitor) 之类的东西。
    【解决方案2】:

    generating some classes by using JDT 时,你可以在你的源代码中加入“\t”。或者像你所做的那样,使用代码格式化程序。我已经测试了以下代码:

    public static void main(String[] args)
    {
        String code = "public class TestFormatter{public static void main(String[] args){System.out.println(\"Hello World\");}}";
        CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(null);
    
        TextEdit textEdit = codeFormatter.format(CodeFormatter.K_UNKNOWN, code, 0,code.length(),0,null);
        IDocument doc = new Document(code);
        try {
            textEdit.apply(doc);
            System.out.println(doc.get());
        } catch (MalformedTreeException e) {
            e.printStackTrace();
        } catch (BadLocationException e) {
            e.printStackTrace();
        }   
    }
    

    apply() 方法在这里解决了问题。

    【讨论】:

    • 这有帮助,但它并不能优雅地解决所有想要的格式。 IE。您需要手动打破带有大量参数的长方法声明。
    • 非常有趣的问题。我看到你在做什么,我刚刚编辑了我的答案。谢谢。
    • 嗨 Ryan,我将上面的代码更改为使用 CodeFormatter.K_UNKNOWN,但这也不起作用。之后我在调用targetUnit.applyTextEdit 之后检查了targetUnit.getSource()(它在ICompilationUnit 的内部IDocument 上执行apply()),奇怪的是这些更改似乎已应用。但它们不适用于文件。这是一个错误,还是我错过了什么?
    • 我找到了解决方案:我似乎有必要创建workingCopyICompilationUnit 以便能够将编辑应用于文件。
    【解决方案3】:

    我使用下面的方法来格式化一个Java源文件

        public static void formatSource(ICompilationUnit cu, IProgressMonitor progressMonitor) throws JavaModelException{
        String source = cu.getSource();
        IJavaProject javaProject = cu.getJavaProject();
    
        Map options = javaProject.getOptions(true);
    
    
                // Instantiate the default code formatter with the given options
                final CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(options);
    
    
                final TextEdit edit = codeFormatter.format(
                    CodeFormatter.K_COMPILATION_UNIT, // format a compilation unit
                    source, // source to format
                    0, // starting position
                    source.length(), // length
                    0, // initial indentation
                    System.getProperty("line.separator") // line separator
                );          
    
                cu.becomeWorkingCopy(progressMonitor);
                try {
                    cu.applyTextEdit(edit, progressMonitor);
                    //cu.reconcile();
                    cu.commitWorkingCopy(true, progressMonitor);
                    //cu.save(progressMonitor, false);
    
                    JavaUI.openInEditor(cu);
    
    
                } catch (MalformedTreeException e) {
                    e.printStackTrace();
                } catch (PartInitException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }   
    
    }
    

    【讨论】:

      猜你喜欢
      • 2016-04-18
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 2023-01-20
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多