1 11 package org.eclipse.jdt.internal.ui.compare; 12 13 import org.eclipse.core.runtime.Assert; 14 15 import org.eclipse.compare.contentmergeviewer.ITokenComparator; 16 import org.eclipse.compare.rangedifferencer.IRangeComparator; 17 18 import org.eclipse.jdt.core.ToolFactory; 19 import org.eclipse.jdt.core.compiler.IScanner; 20 import org.eclipse.jdt.core.compiler.ITerminalSymbols; 21 import org.eclipse.jdt.core.compiler.InvalidInputException; 22 23 import org.eclipse.jdt.internal.corext.dom.TokenScanner; 24 25 26 29 public class JavaTokenComparator implements ITokenComparator { 30 31 35 public static interface ITokenComparatorFactory { 36 40 public ITokenComparator createTokenComparator(String text); 41 } 42 43 private static final boolean DEBUG= false; 44 45 private final String fText; 46 private final ITokenComparatorFactory fTextTokenComparatorFactory; 47 private int fCount; 48 private int[] fStarts; 49 private int[] fLengths; 50 51 56 public JavaTokenComparator(String text) { 57 this(text, null); 58 } 59 60 66 public JavaTokenComparator(String text, ITokenComparatorFactory textTokenComparatorFactory) { 67 68 fTextTokenComparatorFactory= textTokenComparatorFactory; 69 Assert.isLegal(text != null); 70 71 fText= text; 72 73 int length= fText.length(); 74 fStarts= new int[length]; 75 fLengths= new int[length]; 76 fCount= 0; 77 78 IScanner scanner= ToolFactory.createScanner(true, true, false, false); scanner.setSource(fText.toCharArray()); 80 int endPos= 0; 81 try { 82 int tokenType; 83 while ((tokenType= scanner.getNextToken()) != ITerminalSymbols.TokenNameEOF) { 84 int start= scanner.getCurrentTokenStartPosition(); 85 int end= scanner.getCurrentTokenEndPosition()+1; 86 if (TokenScanner.isComment(tokenType) || tokenType == ITerminalSymbols.TokenNameStringLiteral) { 88 int dl= fTextTokenComparatorFactory == null ? getCommentStartTokenLength(tokenType) : 0; 89 recordTokenRange(start, dl); 90 parseText(start + dl, text.substring(start + dl, end)); 91 } else { 92 recordTokenRange(start, end - start); 93 } 94 endPos= end; 95 } 96 } catch (InvalidInputException ex) { 97 } 99 if (endPos < length) { 101 recordTokenRange(endPos, length - endPos); 102 } 103 } 104 105 112 private void recordTokenRange(int start, int length) { 113 fStarts[fCount]= start; 114 fLengths[fCount]= length; 115 fCount++; 116 if (DEBUG) 117 System.out.println(fText.substring(start, start + length)); 118 } 119 120 private void parseText(int start, String text) { 121 ITokenComparator subTokenizer= fTextTokenComparatorFactory == null 122 ? new JavaTokenComparator(text) 123 : fTextTokenComparatorFactory.createTokenComparator(text); 124 int count= subTokenizer.getRangeCount(); 125 for (int i= 0; i < count; i++) { 126 int subStart= subTokenizer.getTokenStart(i); 127 int subLength= subTokenizer.getTokenLength(i); 128 recordTokenRange(start + subStart, subLength); 129 } 130 } 131 132 140 private static int getCommentStartTokenLength(int tokenType) { 141 if (tokenType == ITerminalSymbols.TokenNameCOMMENT_JAVADOC) { 142 return 3; 143 } else if (tokenType == ITerminalSymbols.TokenNameStringLiteral) { 144 return 1; 145 } else { 146 return 2; 147 } 148 } 149 150 155 public int getRangeCount() { 156 return fCount; 157 } 158 159 162 public int getTokenStart(int index) { 163 if (index >= 0 && index < fCount) 164 return fStarts[index]; 165 if (fCount > 0) 166 return fStarts[fCount-1] + fLengths[fCount-1]; 167 return 0; 168 } 169 170 173 public int getTokenLength(int index) { 174 if (index < fCount) 175 return fLengths[index]; 176 return 0; 177 } 178 179 188 public boolean rangesEqual(int thisIndex, IRangeComparator other, int otherIndex) { 189 if (other != null && getClass() == other.getClass()) { 190 JavaTokenComparator tc= (JavaTokenComparator) other; int thisLen= getTokenLength(thisIndex); 192 int otherLen= tc.getTokenLength(otherIndex); 193 if (thisLen == otherLen) 194 return fText.regionMatches(false, getTokenStart(thisIndex), tc.fText, tc.getTokenStart(otherIndex), thisLen); 195 } 196 return false; 197 } 198 199 209 public boolean skipRangeComparison(int length, int maxLength, IRangeComparator other) { 210 211 if (getRangeCount() < 50 || other.getRangeCount() < 50) 212 return false; 213 214 if (maxLength < 100) 215 return false; 216 217 if (length < 100) 218 return false; 219 220 if (maxLength > 800) 221 return true; 222 223 if (length < maxLength / 4) 224 return false; 225 226 return true; 227 } 228 } 229 | Popular Tags |