1 19 20 package org.netbeans.modules.lexer.demo; 21 22 import java.util.List ; 23 import java.util.ArrayList ; 24 import java.util.Arrays ; 25 import javax.swing.text.BadLocationException ; 26 import javax.swing.text.Document ; 27 import javax.swing.text.PlainDocument ; 28 import javax.swing.event.DocumentListener ; 29 import javax.swing.event.DocumentEvent ; 30 import org.netbeans.api.lexer.Language; 31 import org.netbeans.api.lexer.LexerInput; 32 import org.netbeans.api.lexer.TokenUpdater; 33 import org.netbeans.api.lexer.Token; 34 import org.netbeans.api.lexer.Lexer; 35 import org.netbeans.spi.lexer.util.LexerTestDescription; 36 import org.netbeans.spi.lexer.util.LexerUtilities; 37 38 52 53 public class LexerRandomTest extends DemoTokenUpdater { 54 55 private LexerTestDescription td; 56 57 private int debugLevel; 58 59 public LexerRandomTest(LexerTestDescription td, boolean maintainLookbacks) { 60 super(new PlainDocument (), td.getLanguage(), maintainLookbacks); 61 62 this.td = td; 63 debugLevel = td.getDebugLevel(); 64 } 65 66 public void test() { 67 LexerTestDescription.TestRound[] rounds = td.getTestRounds(); 68 69 List insertItems = new ArrayList (); 71 LexerTestDescription.TestChar[] testChars = td.getTestChars(); 72 if (testChars != null) { 73 insertItems.addAll(Arrays.asList(testChars)); 74 } 75 LexerTestDescription.TestCharInterval[] testCharIntervals = td.getTestCharIntervals(); 76 if (testCharIntervals != null) { 77 insertItems.addAll(Arrays.asList(testCharIntervals)); 78 } 79 LexerTestDescription.TestString[] testStrings = td.getTestStrings(); 80 if (testStrings != null) { 81 insertItems.addAll(Arrays.asList(testStrings)); 82 } 83 84 double insertItemsRatioSum = 0; 86 int insertItemsLength = insertItems.size(); 87 for (int i = 0; i < insertItemsLength; i++) { 88 insertItemsRatioSum += getInsertRatio(insertItems.get(i)); 89 } 90 91 int maxDocumentLength = td.getMaxDocumentLength(); 92 93 Thread.currentThread().setPriority(Thread.MIN_PRIORITY); 94 System.err.println("Test started ..."); 95 long tm = System.currentTimeMillis(); 96 97 for (int i = 0; i < rounds.length; i++) { 98 LexerTestDescription.TestRound r = rounds[i]; 99 100 System.out.println("Test round: " + r); 101 102 int operationCount = r.getOperationCount(); 103 double insertRatio = r.getInsertRatio(); 104 int maxInsertLength = r.getMaxInsertLength(); 105 double removeRatio = r.getRemoveRatio(); 106 int maxRemoveLength = r.getMaxRemoveLength(); 107 108 double operationRatioSum = r.getInsertRatio() + r.getRemoveRatio(); 109 110 String incompleteString = null; 112 int incompleteStringRemainLength = 0; 113 int incompleteStringInsertOffset = 0; 114 115 boolean forceRemove = false; 117 118 int moduloOperationCount = operationCount / 10; 119 while (--operationCount >= 0) { 120 double operationRatio = Math.random() * operationRatioSum; 121 operationRatio -= insertRatio; 122 if (forceRemove || getDocument().getLength() > maxDocumentLength) { 123 operationRatio = 0; 124 } 125 126 if (operationRatio < 0 || incompleteString != null) { StringBuffer insertBuffer = new StringBuffer (); 128 int insertLength = (int)(maxInsertLength * Math.random()) + 1; 129 int insertOffset = (int)((getDocument().getLength() + 1) * Math.random()); 130 if (incompleteString != null && operationRatio >= 0) { insertLength = Math.min(insertLength, incompleteStringRemainLength); 132 } 133 134 if (incompleteString != null) { 135 insertOffset = incompleteStringInsertOffset; 136 137 int isLen = incompleteString.length(); 138 139 if (incompleteStringRemainLength <= insertLength) { 140 insertLength -= incompleteStringRemainLength; 141 insertBuffer.append(incompleteString.substring( 142 isLen - incompleteStringRemainLength)); 143 144 insertLength -= incompleteStringRemainLength; 145 incompleteString = null; 146 incompleteStringRemainLength = 0; 147 148 } else { insertBuffer.append(incompleteString.substring( 150 isLen - incompleteStringRemainLength, 151 isLen - incompleteStringRemainLength + insertLength 152 )); 153 154 incompleteStringRemainLength -= insertLength; 155 insertLength = 0; 156 } 157 } 158 159 160 while (insertLength > 0) { 161 double insertItemsRatio = Math.random() * insertItemsRatioSum; 162 for (int j = 0; j < insertItemsLength; j++) { 163 Object item = insertItems.get(j); 164 insertItemsRatio -= getInsertRatio(item); 165 if (insertItemsRatio < 0) { 166 if (item instanceof LexerTestDescription.TestChar) { 168 LexerTestDescription.TestChar tc = (LexerTestDescription.TestChar)item; 169 insertBuffer.append(tc.getChar()); 170 insertLength--; 171 172 } else if (item instanceof LexerTestDescription.TestCharInterval) { 173 LexerTestDescription.TestCharInterval tci 174 = (LexerTestDescription.TestCharInterval)item; 175 insertBuffer.append((char)(tci.getChar() 176 + ((tci.getLastChar() - tci.getChar() + 1) * Math.random()))); 177 insertLength--; 178 179 } else if (item instanceof LexerTestDescription.TestString) { 180 LexerTestDescription.TestString ts = (LexerTestDescription.TestString)item; 181 String s = ts.getString(); 182 int sLen = s.length(); 183 if (sLen <= insertLength) { 184 insertBuffer.append(s); 185 insertLength -= insertLength; 186 187 } else { insertBuffer.append(s.substring(0, insertLength)); 189 incompleteString = s; 190 incompleteStringRemainLength = sLen - insertLength; 191 insertLength = 0; 192 } 193 194 } else { throw new IllegalStateException (); 196 } 197 198 break; 199 } 200 } 201 } 202 203 String text = insertBuffer.toString(); 204 try { 205 if (debugLevel > 0) { 206 System.err.print("+Insert"); 207 208 if (debugLevel >= 2) { System.err.print(" \"" + LexerUtilities.toSource(text) + '"'); 210 } 211 212 System.err.print(" at offset=" + insertOffset 213 + "(" + getDocument().getLength() + "), length=" 214 + text.length() 215 ); 216 } 217 218 getDocument().insertString(insertOffset, text, null); 219 220 if (debugLevel >= 3) { System.err.print(", docText=\"" + LexerUtilities.toSource(getDocText(getDocument())) + "\""); 222 } 223 224 incompleteStringInsertOffset = insertOffset + text.length(); 225 } catch (BadLocationException e) { 226 throw new IllegalStateException (e.toString()); 227 } 228 229 } else { operationRatio -= removeRatio; 231 if (operationRatio < 0 || forceRemove) { forceRemove = false; 233 234 int removeLength = (int)(maxRemoveLength * Math.random()) + 1; 235 removeLength = Math.min(removeLength, getDocument().getLength()); 236 237 int removeOffset = (int)((getDocument().getLength() - removeLength + 1) * Math.random()); 238 try { 239 if (debugLevel > 0) { 240 System.err.print("-Remove"); 241 242 if (debugLevel >= 2) { 243 String text = getDocument().getText(removeOffset, removeLength); 244 System.err.print(" \"" + LexerUtilities.toSource(text) + '"'); 245 } 246 247 System.err.print(" at offset=" + removeOffset 248 + "(" + getDocument().getLength() + "), length=" + removeLength); 249 250 } 251 252 getDocument().remove(removeOffset, removeLength); 253 254 if (debugLevel >= 3) { 255 System.err.print(", docText=\"" + LexerUtilities.toSource(getDocText(getDocument())) + "\""); 256 } 257 } catch (BadLocationException e) { 258 throw new IllegalStateException (e.toString()); 259 } 260 } 261 } 262 263 int tokenIndex = 0; try { 267 ArrayList lbList = new ArrayList (); 268 String docText; 269 try { 270 docText = getDocument().getText(0, getDocument().getLength()); 271 } catch (BadLocationException e) { 272 throw new IllegalStateException (e.toString()); 273 } 274 LexerInput input = new StringLexerInput(docText); 275 Lexer lexer = getLanguage().createLexer(); 276 lexer.restart(input, null); 277 278 int shift = relocate(0); 279 if (shift != 0) { 280 throw new IllegalStateException ("Invalid relocate shift=" 281 + shift); 282 } 283 284 int tokenTotalLength = 0; 285 int lbOffset = 0; 286 while (true) { 287 Token token = lexer.nextToken(); 288 if (token != null) { 289 Token itToken = next(); 290 checkTokensEqual(itToken, token); 291 int tokenLength = token.getText().length(); 292 tokenTotalLength += tokenLength; 293 294 int la = getLookahead(); 295 if (input.getReadLookahead() != la) { 296 throw new IllegalStateException ("incremental environment lookahead=" + la 297 + ", batch lexer lookahead=" + input.getReadLookahead()); 298 } 299 300 Object state = getState(); 301 Object lexerState = lexer.getState(); 302 if (!((state == null && lexerState == null) 303 || (state != null && state.equals(lexerState)) 304 )) { 305 throw new IllegalStateException ( 306 "States do not match incremental environment lexer-state=" + state 307 + ", batch lexer state=" + lexerState); 308 } 309 310 lbList.add(new Integer (tokenLength)); 311 lbList.add(new Integer (la)); 312 313 while (lbList.size() > 0) { 314 int tlen = ((Integer )lbList.get(0)).intValue(); 315 int tla = ((Integer )lbList.get(1)).intValue(); 316 if (lbOffset + tlen + tla <= tokenTotalLength) { 317 lbOffset += tlen; 318 lbList.remove(0); lbList.remove(0); } else { 321 break; 322 } 323 } 324 325 int lb = getLookback(); 326 if (lb >= 0) { 327 if (lb != lbList.size() / 2) { 328 throw new IllegalStateException ("iterator-lb=" 329 + lb 330 + ", lexer-lb=" + (lbList.size() / 2) 331 ); 332 } 333 } 334 335 tokenIndex++; 336 337 } else { if (hasNext()) { 339 throw new IllegalStateException (); 340 } 341 if (tokenTotalLength != docText.length()) { 342 throw new IllegalStateException (); 343 } 344 break; 345 } 346 } 347 348 if (debugLevel > 0) { 349 System.err.println(", " + tokenIndex + " tokens"); 350 } 351 352 if (operationCount > 0 && (operationCount % moduloOperationCount) == 0) { 353 System.err.println(operationCount 354 + " operations remain. docLength=" + getDocument().getLength() 355 + ", tokenCount=" + tokenIndex 356 ); 357 } 358 359 } catch (RuntimeException e) { 360 try { 361 System.err.println("\n\nException thrown - document text=\"" 362 + LexerUtilities.toSource(getDocument().getText( 363 0, getDocument().getLength())) 364 + "\"\ntokens:\n" + allTokensToString() 365 + "tokenIndex=" + tokenIndex); 366 367 } catch (BadLocationException ex) { 368 throw new IllegalStateException (ex.toString()); 369 } 370 throw e; } 372 373 } } 375 376 System.err.println("Test finished in " 377 + (System.currentTimeMillis() - tm) / 1000 378 + " seconds." 379 ); 380 } 381 382 private static double getInsertRatio(Object o) { 383 if (o instanceof LexerTestDescription.TestChar) { 384 return ((LexerTestDescription.TestChar)o).getInsertRatio(); 385 } else if (o instanceof LexerTestDescription.TestCharInterval) { 386 return ((LexerTestDescription.TestCharInterval)o).getInsertRatio(); 387 } else if (o instanceof LexerTestDescription.TestString) { 388 return ((LexerTestDescription.TestString)o).getInsertRatio(); 389 } else { 390 throw new IllegalArgumentException (); 391 } 392 } 393 394 private void dump() { 395 System.err.println("Dump of token iterator\n" 396 + allTokensToString()); 397 } 398 399 private static void checkTokensEqual(Token t1, Token t2) { 400 if (t1.getId() != t2.getId()) { 401 throw new IllegalStateException ("t1.id=" + t1.getId() 402 + ", t2.id=" + t2.getId()); 403 } 404 405 CharSequence t1Text = t1.getText(); 406 CharSequence t2Text = t2.getText(); 407 if (t1Text.length() != t2Text.length()) { 408 throw new IllegalStateException ( 409 "t1=\"" + LexerUtilities.toSource(t1Text.toString()) 410 + "\", t2=\"" + LexerUtilities.toSource(t2Text.toString()) 411 + '"' 412 ); 413 } 414 for (int i = t1Text.length() - 1; i >= 0; i--) { 415 if (t1Text.charAt(i) != t2Text.charAt(i)) { 416 throw new IllegalStateException (); 417 } 418 } 419 } 420 421 private static String getDocText(Document doc) { 422 try { 423 return doc.getText(0, doc.getLength()); 424 } catch (BadLocationException e) { 425 throw new IllegalStateException (); 426 } 427 } 428 429 public static void main (String [] args) { 430 try { 431 if (args.length == 0) { 432 System.err.println("Usage: java " + LexerRandomTest.class.getName () 433 + " <test-description-class-name>"); 434 System.exit(1); 435 } 436 437 Class langCls = Class.forName(args[0]); 438 LexerTestDescription td = (LexerTestDescription)langCls.newInstance(); 439 440 new LexerRandomTest(td, false).test(); 441 442 } catch (Exception ex) { 443 ex.printStackTrace(); 444 } 445 } 446 447 } 448 449 | Popular Tags |