### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java,v retrieving revision 1.26 diff -u -r1.26 ImportRewriteAnalyzer.java --- dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java 13 Apr 2010 18:53:21 -0000 1.26 +++ dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java 19 Aug 2011 17:36:42 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -58,6 +58,8 @@ private boolean useContextToFilterImplicitImports; private boolean findAmbiguousImports; + private IRegion[] preserveExistingCommentsRanges; + private int flags= 0; private static final int F_NEEDS_LEADING_DELIM= 2; @@ -89,6 +91,9 @@ this.replaceRange= evaluateReplaceRange(root); if (restoreExistingImports) { addExistingImports(root); + } else { + // collect all existing comments inside imports and concatenate them + this.preserveExistingCommentsRanges = retrieveExistingCommentsInImports(root); } PackageEntry[] order= new PackageEntry[importOrder.length]; @@ -261,12 +266,30 @@ int nextLength= next.getLength(); int nextOffsetLine= root.getLineNumber(nextOffset); + int extendedStart = root.getExtendedStartPosition(next); + int extendedLength = root.getExtendedLength(next); // if next import is on a different line, modify the end position to the next line begin offset if (currEndLine < nextOffsetLine) { currEndLine++; nextOffset= root.getPosition(currEndLine, 0); } - currPackage.add(new ImportDeclEntry(packName.length(), name, isStatic, new Region(currOffset, nextOffset - currOffset))); + // retrieve preceding and trailing comments if any + IRegion rangeBefore = null; + IRegion rangeAfter = null; + if (nextOffset != extendedStart) { + rangeBefore = new Region(extendedStart, extendedStart - nextOffset + 1); + } + if (nextLength != extendedLength) { + rangeAfter = new Region(nextOffset + nextLength, extendedLength - nextLength + 1); + } + currPackage.add( + new ImportDeclEntry( + packName.length(), + name, + isStatic, + new Region(currOffset, nextOffset - currOffset), + rangeBefore, + rangeAfter)); currOffset= nextOffset; curr= next; @@ -294,6 +317,39 @@ currPackage.add(new ImportDeclEntry(packName.length(), name, isStatic, new Region(curr.getStartPosition(), length))); } + private IRegion[] retrieveExistingCommentsInImports(CompilationUnit root) { + List/*ImportDeclaration*/ decls= root.imports(); + if (decls.isEmpty()) { + return null; + } + + List regions = new ArrayList(); + + for (int i= 0; i < decls.size(); i++) { + ImportDeclaration next= (ImportDeclaration) decls.get(i); + int nextOffset= next.getStartPosition(); + int nextLength= next.getLength(); + + int extendedStart = root.getExtendedStartPosition(next); + int extendedLength = root.getExtendedLength(next); + if (nextOffset != extendedStart) { + // preceding comment + int lengthOfPrecedingComment = nextOffset - extendedStart; + regions.add(new Region(extendedStart, lengthOfPrecedingComment)); + + if (extendedLength != (nextLength + lengthOfPrecedingComment)) { + // Preceding and trailing comments + int regionLength = extendedLength - (nextLength + lengthOfPrecedingComment); + regions.add(new Region(nextOffset + nextLength, regionLength)); + } + } else if (nextLength != extendedLength) { + // no extended start - only trailing comment + int regionLength = extendedLength - nextLength; + regions.add(new Region(nextOffset + nextLength, regionLength)); + } + } + return (IRegion[]) regions.toArray(new IRegion[regions.size()]); + } /** * Specifies that implicit imports (for types in java.lang, types in the same package as the rewrite * compilation unit and types in the compilation unit's main type) should not be created, except if necessary to @@ -550,6 +606,8 @@ } } } + // concatenate existing comments inside the imports + return new Region(startPos, endPos - startPos); } else { int start= getPackageStatementEndPos(root); @@ -617,7 +675,7 @@ boolean doStarImport= pack.hasStarImport(threshold, onDemandConflicts); if (doStarImport && (pack.find("*") == null)) { //$NON-NLS-1$ - String[] imports = getNewImportStrings(pack, isStatic, lineDelim); + String[] imports = getNewImportStrings(buffer, pack, isStatic, lineDelim); for (int j = 0, max = imports.length; j < max; j++) { stringsToInsert.add(imports[j]); } @@ -648,7 +706,16 @@ } else if (doStarImport && !currDecl.isOnDemand()) { String simpleName = currDecl.getTypeQualifiedName(); if (simpleName.indexOf('.') != -1) { - String str= getNewImportString(currDecl.getElementName(), isStatic, lineDelim); + IRegion rangeBefore = currDecl.getPrecedingCommentRage(); + if (rangeBefore != null) { + stringsToInsert.add(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength())); + } + IRegion rangeAfter = currDecl.getTrailingCommentRange(); + String trailingComment = null; + if (rangeAfter != null) { + trailingComment = buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength()); + } + String str= getNewImportString(currDecl.getElementName(), isStatic, trailingComment, lineDelim); if (stringsToInsert.indexOf(str) == -1) { stringsToInsert.add(str); } @@ -657,6 +724,17 @@ } } + // insert back all existing imports comments since existing imports were not preserved + if (this.preserveExistingCommentsRanges != null) { + for (int i = 0, max = this.preserveExistingCommentsRanges.length; i < max; i++) { + IRegion region = this.preserveExistingCommentsRanges[i]; + String text = buffer.getText(region.getOffset(), region.getLength()); + if (!text.endsWith(lineDelim)) { + text += lineDelim; + } + stringsToInsert.add(text); + } + } int end= importsStart + importsLen; removeAndInsertNew(buffer, currPos, end, stringsToInsert, resEdit); @@ -787,6 +865,10 @@ } private String getNewImportString(String importName, boolean isStatic, String lineDelim) { + return getNewImportString(importName, isStatic, null, lineDelim); + } + + private String getNewImportString(String importName, boolean isStatic, String trailingComment, String lineDelim) { StringBuffer buf= new StringBuffer(); buf.append("import "); //$NON-NLS-1$ if (isStatic) { @@ -795,6 +877,9 @@ buf.append(importName); if (insertSpaceBeforeSemicolon()) buf.append(' '); buf.append(';'); + if (trailingComment != null) { + buf.append(trailingComment); + } buf.append(lineDelim); if (isStatic) { @@ -805,22 +890,51 @@ return buf.toString(); } - private String[] getNewImportStrings(PackageEntry packageEntry, boolean isStatic, String lineDelim) { + private String[] getNewImportStrings(IBuffer buffer, PackageEntry packageEntry, boolean isStatic, String lineDelim) { boolean isStarImportAdded = false; List allImports = new ArrayList(); int nImports = packageEntry.getNumberOfImports(); + StringBuffer allComments = null; for (int i= 0; i < nImports; i++) { ImportDeclEntry curr= packageEntry.getImportAt(i); String simpleName = curr.getTypeQualifiedName(); if (simpleName.indexOf('.') != -1) { // member type imports - we preserve it - allImports.add(getNewImportString(curr.getElementName(), isStatic, lineDelim)); + IRegion rangeBefore = curr.getPrecedingCommentRage(); + if (rangeBefore != null) { + allImports.add(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength())); + } + IRegion rangeAfter = curr.getTrailingCommentRange(); + String trailingComment = null; + if (rangeAfter != null) { + trailingComment = buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength()); + } + allImports.add(getNewImportString(curr.getElementName(), isStatic, trailingComment, lineDelim)); } else if (!isStarImportAdded) { String starImportString= packageEntry.getName() + ".*"; //$NON-NLS-1$ allImports.add(getNewImportString(starImportString, isStatic, lineDelim)); isStarImportAdded = true; + } else { + // collect all comments + IRegion rangeBefore = curr.getPrecedingCommentRage(); + if (rangeBefore != null) { + if (allComments == null) { + allComments = new StringBuffer(); + } + allComments.append(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength())).append(lineDelim); + } + IRegion rangeAfter = curr.getTrailingCommentRange(); + if (rangeAfter != null) { + if (allComments == null) { + allComments = new StringBuffer(); + } + allComments.append(buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength())).append(lineDelim); + } } } + if (allComments != null) { + allImports.add(0, String.valueOf(allComments)); + } return (String[]) allImports.toArray(new String[allImports.size()]); } @@ -879,6 +993,20 @@ private IRegion sourceRange; private final boolean isStatic; private int containerNameLength; + private IRegion precedingCommentRange; + private IRegion trailingCommentRange; + + public ImportDeclEntry( + int containerNameLength, + String elementName, + boolean isStatic, + IRegion sourceRange, + IRegion precedingCommentRange, + IRegion trailingCommentRange) { + this(containerNameLength, elementName, isStatic, sourceRange); + this.precedingCommentRange = precedingCommentRange; + this.trailingCommentRange = trailingCommentRange; + } public ImportDeclEntry(int containerNameLength, String elementName, boolean isStatic, IRegion sourceRange) { this.elementName= elementName; @@ -929,7 +1057,14 @@ public IRegion getSourceRange() { return this.sourceRange; } + + public IRegion getPrecedingCommentRage() { + return this.precedingCommentRange; + } + public IRegion getTrailingCommentRange() { + return this.trailingCommentRange; + } } /*