Index: compiler/javatests/com/google/dart/compiler/parser/TruncatedSourceParserTest.java |
=================================================================== |
--- compiler/javatests/com/google/dart/compiler/parser/TruncatedSourceParserTest.java (revision 0) |
+++ compiler/javatests/com/google/dart/compiler/parser/TruncatedSourceParserTest.java (revision 0) |
@@ -0,0 +1,153 @@ |
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+package com.google.dart.compiler.parser; |
+ |
+import com.google.dart.compiler.DartCompilationError; |
+import com.google.dart.compiler.DartCompilerListenerTest; |
+import com.google.dart.compiler.DartSourceTest; |
+import com.google.dart.compiler.ast.DartUnit; |
+ |
+public class TruncatedSourceParserTest extends AbstractParserTest { |
+ |
+ /** |
+ * Performs parsing in a separate thread such that the test can detect infinite loop. |
+ */ |
+ private class ParserThread extends Thread { |
+ private final Object lock = new Object(); |
+ private final String srcName; |
+ private int state = 0; |
+ private String srcCode; |
+ private DartUnit result; |
+ |
+ /** |
+ * Listener that ignores errors because this is a stress test |
+ */ |
+ private DartCompilerListenerTest listener = new DartCompilerListenerTest("") { |
+ @Override |
+ public void checkAllErrorsReported() { |
+ } |
+ |
+ @Override |
+ public void compilationError(DartCompilationError event) { |
+ } |
+ }; |
+ |
+ public ParserThread(String srcName) { |
+ super("Parsing " + srcName); |
+ this.srcName = srcName; |
+ } |
+ |
+ /** |
+ * Queue the specified source to be parsed on a separate thread. Wait up to 10 seconds for the |
+ * result |
+ * |
+ * @return <code>true</code> if finished parsing |
+ */ |
+ public boolean parse(String srcCode) { |
+ assert (srcCode != null); |
+ assert (state == 0); |
+ synchronized (lock) { |
+ this.srcCode = srcCode; |
+ result = null; |
+ state = 1; |
+ lock.notifyAll(); |
+ try { |
+ lock.wait(10000); |
+ } catch (InterruptedException e) { |
+ // Fall through |
+ } |
+ return state == 0; |
+ } |
+ } |
+ |
+ /** |
+ * Parse source code in the background |
+ */ |
+ @Override |
+ public void run() { |
+ while (true) { |
+ DartSourceTest src; |
+ ParserContext context; |
+ synchronized (lock) { |
+ while (state == 0) { |
+ try { |
+ lock.wait(); |
+ } catch (InterruptedException e) { |
+ // Fall through |
+ } |
+ } |
+ if (state == 2) { |
+ return; |
+ } |
+ src = new DartSourceTest(srcName, srcCode, null); |
+ context = makeParserContext(src, srcCode, listener); |
+ } |
+ DartUnit unit = makeParser(context).parseUnit(src); |
+ synchronized (lock) { |
+ if (state == 2) { |
+ return; |
+ } |
+ state = 0; |
+ result = unit; |
+ lock.notifyAll(); |
+ } |
+ } |
+ } |
+ |
+ /** |
+ * Signal the background thread to terminate |
+ */ |
+ public void stopParsing() { |
+ synchronized (lock) { |
+ state = 2; |
+ lock.notify(); |
+ } |
+ } |
+ } |
+ |
+ @Override |
+ public void testStringsErrors() { |
+ parseUnit("StringsErrorsNegativeTest.dart"); |
+ } |
+ |
+ @Override |
+ public void testTiming() { |
+ // Skip |
+ } |
+ |
+ @Override |
+ protected DartUnit parseUnit(String srcName, String srcCode) { |
+ // System.out.print(srcName); |
+ ParserThread thread = new ParserThread(srcName); |
+ thread.start(); |
+ int eol = 0; |
+ for (int index = 0; index < srcCode.length(); index++) { |
+ if (eol == index) { |
+ eol++; |
+ while (eol < srcCode.length()) { |
+ char ch = srcCode.charAt(eol); |
+ if (ch == '\r' || ch == '\n') { |
+ break; |
+ } |
+ eol++; |
+ } |
+ } |
+ String modifiedSrcCode = srcCode.substring(0, index); |
+ if (!thread.parse(modifiedSrcCode)) { |
+ // System.out.println(); |
+ fail("Failed to finish parsing " + srcName + "\n" + modifiedSrcCode); |
+ } |
+ modifiedSrcCode += srcCode.substring(eol); |
+ if (!thread.parse(modifiedSrcCode)) { |
+ // System.out.println(); |
+ fail("Failed to finish parsing " + srcName + "\n" + modifiedSrcCode); |
+ } |
+ // System.out.print('.'); |
+ } |
+ thread.stopParsing(); |
+ // System.out.println(); |
+ return thread.result; |
+ } |
+} |