1 11 package org.eclipse.jdt.core.formatter; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Map ; 16 17 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; 18 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; 19 import org.eclipse.jdt.internal.compiler.util.Util; 20 import org.eclipse.jface.text.BadLocationException; 21 import org.eclipse.jface.text.DefaultLineTracker; 22 import org.eclipse.jface.text.ILineTracker; 23 import org.eclipse.jface.text.IRegion; 24 25 import org.eclipse.text.edits.ReplaceEdit; 26 27 32 public final class IndentManipulation { 33 34 private IndentManipulation() { 35 } 37 38 45 public static boolean isIndentChar(char ch) { 46 return ScannerHelper.isWhitespace(ch) && !isLineDelimiterChar(ch); 47 } 48 49 55 public static boolean isLineDelimiterChar(char ch) { 56 return ch == '\n' || ch == '\r'; 57 } 58 59 75 public static int measureIndentUnits(CharSequence line, int tabWidth, int indentWidth) { 76 if (indentWidth <= 0 || tabWidth < 0 || line == null) { 77 throw new IllegalArgumentException (); 78 } 79 80 int visualLength= measureIndentInSpaces(line, tabWidth); 81 return visualLength / indentWidth; 82 } 83 84 100 public static int measureIndentInSpaces(CharSequence line, int tabWidth) { 101 if (tabWidth < 0 || line == null) { 102 throw new IllegalArgumentException (); 103 } 104 105 int length= 0; 106 int max= line.length(); 107 for (int i= 0; i < max; i++) { 108 char ch= line.charAt(i); 109 if (ch == '\t') { 110 int reminder= length % tabWidth; 111 length += tabWidth - reminder; 112 } else if (isIndentChar(ch)) { 113 length++; 114 } else { 115 return length; 116 } 117 } 118 return length; 119 } 120 121 137 public static String extractIndentString(String line, int tabWidth, int indentWidth) { 138 if (tabWidth < 0 || indentWidth <= 0 || line == null) { 139 throw new IllegalArgumentException (); 140 } 141 142 int size= line.length(); 143 int end= 0; 144 145 int spaceEquivs= 0; 146 int characters= 0; 147 for (int i= 0; i < size; i++) { 148 char c= line.charAt(i); 149 if (c == '\t') { 150 int remainder= spaceEquivs % tabWidth; 151 spaceEquivs += tabWidth - remainder; 152 characters++; 153 } else if (isIndentChar(c)) { 154 spaceEquivs++; 155 characters++; 156 } else { 157 break; 158 } 159 if (spaceEquivs >= indentWidth) { 160 end += characters; 161 characters= 0; 162 spaceEquivs= spaceEquivs % indentWidth; 163 } 164 } 165 if (end == 0) { 166 return Util.EMPTY_STRING; 167 } else if (end == size) { 168 return line; 169 } else { 170 return line.substring(0, end); 171 } 172 } 173 174 175 191 public static String trimIndent(String line, int indentUnitsToRemove, int tabWidth, int indentWidth) { 192 if (tabWidth < 0 || indentWidth <= 0 || line == null) { 193 throw new IllegalArgumentException (); 194 } 195 196 if (indentUnitsToRemove <= 0) 197 return line; 198 199 final int spaceEquivalentsToRemove= indentUnitsToRemove * indentWidth; 200 201 int start= 0; 202 int spaceEquivalents= 0; 203 int size= line.length(); 204 String prefix= null; 205 for (int i= 0; i < size; i++) { 206 char c= line.charAt(i); 207 if (c == '\t') { 208 int remainder= spaceEquivalents % tabWidth; 209 spaceEquivalents += tabWidth - remainder; 210 } else if (isIndentChar(c)) { 211 spaceEquivalents++; 212 } else { 213 start= i; 215 break; 216 } 217 if (spaceEquivalents == spaceEquivalentsToRemove) { 218 start= i + 1; 219 break; 220 } 221 if (spaceEquivalents > spaceEquivalentsToRemove) { 222 start= i + 1; char[] missing= new char[spaceEquivalents - spaceEquivalentsToRemove]; 227 Arrays.fill(missing, ' '); 228 prefix= new String (missing); 229 break; 230 } 231 } 232 String trimmed; 233 if (start == size) 234 trimmed= Util.EMPTY_STRING; 235 else 236 trimmed= line.substring(start); 237 238 if (prefix == null) 239 return trimmed; 240 return prefix + trimmed; 241 } 242 243 266 public static String changeIndent(String code, int indentUnitsToRemove, int tabWidth, int indentWidth, String newIndentString, String lineDelim) { 267 if (tabWidth < 0 || indentWidth <= 0 || code == null || indentUnitsToRemove < 0 || newIndentString == null || lineDelim == null) { 268 throw new IllegalArgumentException (); 269 } 270 271 try { 272 ILineTracker tracker= new DefaultLineTracker(); 273 tracker.set(code); 274 int nLines= tracker.getNumberOfLines(); 275 if (nLines == 1) { 276 return code; 277 } 278 279 StringBuffer buf= new StringBuffer (); 280 281 for (int i= 0; i < nLines; i++) { 282 IRegion region= tracker.getLineInformation(i); 283 int start= region.getOffset(); 284 int end= start + region.getLength(); 285 String line= code.substring(start, end); 286 287 if (i == 0) { buf.append(line); 289 } else { buf.append(lineDelim); 291 buf.append(newIndentString); 292 buf.append(trimIndent(line, indentUnitsToRemove, tabWidth, indentWidth)); 293 } 294 } 295 return buf.toString(); 296 } catch (BadLocationException e) { 297 return code; 299 } 300 } 301 302 324 public static ReplaceEdit[] getChangeIndentEdits(String source, int indentUnitsToRemove, int tabWidth, int indentWidth, String newIndentString) { 325 if (tabWidth < 0 || indentWidth <= 0 || source == null || indentUnitsToRemove < 0 || newIndentString == null) { 326 throw new IllegalArgumentException (); 327 } 328 329 ArrayList result= new ArrayList (); 330 try { 331 ILineTracker tracker= new DefaultLineTracker(); 332 tracker.set(source); 333 int nLines= tracker.getNumberOfLines(); 334 if (nLines == 1) 335 return (ReplaceEdit[])result.toArray(new ReplaceEdit[result.size()]); 336 for (int i= 1; i < nLines; i++) { 337 IRegion region= tracker.getLineInformation(i); 338 int offset= region.getOffset(); 339 String line= source.substring(offset, offset + region.getLength()); 340 int length= indexOfIndent(line, indentUnitsToRemove, tabWidth, indentWidth); 341 if (length >= 0) { 342 result.add(new ReplaceEdit(offset, length, newIndentString)); 343 } else { 344 length= measureIndentUnits(line, tabWidth, indentWidth); 345 result.add(new ReplaceEdit(offset, length, "")); } 347 } 348 } catch (BadLocationException cannotHappen) { 349 } 351 return (ReplaceEdit[])result.toArray(new ReplaceEdit[result.size()]); 352 } 353 354 359 private static int indexOfIndent(CharSequence line, int numberOfIndentUnits, int tabWidth, int indentWidth) { 360 361 int spaceEquivalents= numberOfIndentUnits * indentWidth; 362 363 int size= line.length(); 364 int result= -1; 365 int blanks= 0; 366 for (int i= 0; i < size && blanks < spaceEquivalents; i++) { 367 char c= line.charAt(i); 368 if (c == '\t') { 369 int remainder= blanks % tabWidth; 370 blanks += tabWidth - remainder; 371 } else if (isIndentChar(c)) { 372 blanks++; 373 } else { 374 break; 375 } 376 result= i; 377 } 378 if (blanks < spaceEquivalents) 379 return -1; 380 return result + 1; 381 } 382 383 392 public static int getTabWidth(Map options) { 393 if (options == null) { 394 throw new IllegalArgumentException (); 395 } 396 return getIntValue(options, DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, 4); 397 } 398 399 408 public static int getIndentWidth(Map options) { 409 if (options == null) { 410 throw new IllegalArgumentException (); 411 } 412 int tabWidth=getTabWidth(options); 413 boolean isMixedMode= DefaultCodeFormatterConstants.MIXED.equals(options.get(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR)); 414 if (isMixedMode) { 415 return getIntValue(options, DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, tabWidth); 416 } 417 return tabWidth; 418 } 419 420 private static int getIntValue(Map options, String key, int def) { 421 try { 422 return Integer.parseInt((String ) options.get(key)); 423 } catch (NumberFormatException e) { 424 return def; 425 } 426 } 427 } 428 429 | Popular Tags |