Eclipse 的 Code Templates 僅在建立新檔案或插入片段時套用,無法批量更新既有專案的註釋風格(如統一加入版權聲明、調整欄位/方法註釋格式)。本文提供的 Add Comment and Format 外掛,基於 JDT (Java Development Tools) 開發,可一鍵將整個工作區的 Java 原始碼依最新模板重構註釋並格式化。

IJavaProject → 取得 IPackageFragmentRoot (原始碼資料夾) → 遍歷 ICompilationUnit (.java 檔)。ICompilationUnit 轉為 Working Copy (記憶體緩衝區) 進行修改。IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (IProject p : projects) {
IJavaProject jp = JavaCore.create(p);
if (jp != null && jp.exists()) {
IPackageFragmentRoot root = jp.getPackageFragmentRoots()[0]; // source folder
for (IJavaElement pack : root.getChildren()) {
if (pack instanceof IPackageFragment) {
for (ICompilationUnit cu : ((IPackageFragment)pack).getCompilationUnits()) {
process(cu);
}
}
}
}
}
cu.becomeWorkingCopy(monitor);
IBuffer buffer = cu.getBuffer(); // 類似 StringBuffer,操作即修改原始碼
IType type = cu.getTypes()[0];
String typeBody = type.getSource();
// 移除舊 Javadoc
if (type.getJavadocRange() != null) {
typeBody = typeBody.substring(type.getJavadocRange().getOffset()
+ type.getJavadocRange().getLength() - type.getSourceRange().getOffset());
}
String lineDelim = StubUtility.getLineDelimiterUsed(jp);
String newContent = CodeGeneration.getCompilationUnitContent(cu,
CodeGeneration.getTypeComment(cu, type.getElementName(), lineDelim),
typeBody, lineDelim);
buffer.replace(0, cu.getSourceRange().getLength(), newContent);
JavaModelUtil.reconcile(cu); // 同步
// 儲存舊匯入
List imports = new ArrayList<>();
for (IImportDeclaration imp : cu.getImports()) imports.add(imp.getElementName());
// 重構後逐一加回
for (String imp : imports) {
cu.createImport(imp, null, monitor);
JavaModelUtil.reconcile(cu);
}
for (IMember m : getAllMembers(type)) { // 含 IMethod, IField
String comment = switch (m.getElementType()) {
case IJavaElement.METHOD -> getMethodComment((IMethod)m, lineDelim);
case IJavaElement.FIELD -> getFieldComment((IField)m, lineDelim);
default -> CodeGeneration.getTypeComment(cu, type.getElementName(), lineDelim);
};
if (m.getJavadocRange() != null)
buffer.replace(m.getJavadocRange().getOffset(), m.getJavadocRange().getLength(), comment);
else
buffer.replace(m.getSourceRange().getOffset(), 0, comment);
JavaModelUtil.reconcile(cu);
}
ISourceRange bodyRange = type.getSourceRange();
String original = buffer.getText(bodyRange.getOffset(), bodyRange.getLength());
String formatted = CodeFormatterUtil.format(
CodeFormatter.K_CLASS_BODY_DECLARATIONS, original, 0, lineDelim, cu.getJavaProject());
formatted = Strings.trimLeadingTabsAndSpaces(formatted);
buffer.replace(bodyRange.getOffset(), bodyRange.getLength(), formatted);
cu.commitWorkingCopy(true, monitor);
cu.discardWorkingCopy();
透過擴展 JDT,我們將 Eclipse 打造為高度可配置的開發平台。此工具大幅降低維護註釋風格一致性的人力成本,歡迎參考原始碼進一步優化或發佈為實用外掛。