Terminate parsing any single compilation unit if we encounter more then 100 parse errors.

Review URL: https://chromiumcodereview.appspot.com//10704068

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@9445 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
devoncarew@google.com
2012-07-06 16:20:40 +00:00
parent 25f88de46d
commit 4efd5000c1
2 changed files with 51 additions and 9 deletions
@@ -124,7 +124,8 @@ public class DartParser extends CompletionHooksParserBase {
private boolean isTopLevelAbstract;
private DartScanner.Position topLevelAbstractModifierPosition;
private boolean isParsingClass;
private int errorCount = 0;
/**
* Determines the maximum number of errors before terminating the parser. See
* {@link #reportError(com.google.dart.compiler.parser.DartScanner.Position, ErrorCode,
@@ -286,6 +287,9 @@ public class DartParser extends CompletionHooksParserBase {
Token.RESOURCE, Token.NATIVE})
public DartUnit parseUnit() {
DartSource dartSource = (DartSource) source;
errorCount = 0;
try {
beginCompilationUnit();
ctx.unitAboutToCompile(dartSource, isDietParse);
@@ -4575,15 +4579,52 @@ public class DartParser extends CompletionHooksParserBase {
}
}
/**
* Increment the number of errors encountered while parsing this compilation unit. Returns whether
* the current error should be reported.
*
* @return whether the current error should be reported
*/
private boolean incErrorCount() {
errorCount++;
if (errorCount >= MAX_DEFAULT_ERRORS) {
if (errorCount == MAX_DEFAULT_ERRORS) {
// Create a 'too many errors' error.
DartCompilationError dartError = new DartCompilationError(ctx.getSource(),
ctx.getTokenLocation(), ParserErrorCode.NO_SOUP_FOR_YOU);
ctx.error(dartError);
}
// Consume the rest of the input stream. Throwing an exception - as suggested elsewhere in
// this file - is not ideal.
Token next = next();
while (next != null && next != Token.EOS) {
next = next();
}
}
return errorCount < MAX_DEFAULT_ERRORS;
}
@Override
protected void reportError(Position position, ErrorCode errorCode, Object... arguments) {
if (incErrorCount()) {
super.reportError(position, errorCode, arguments);
}
}
@Override
protected void reportErrorAtPosition(Position startPosition, Position endPosition,
ErrorCode errorCode, Object... arguments) {
if (incErrorCount()) {
super.reportErrorAtPosition(startPosition, endPosition, errorCode, arguments);
}
}
private void reportError(DartCompilationError dartError) {
if ((errorHistory.size() > MAX_DEFAULT_ERRORS) ||
errorHistory.contains(dartError.hashCode())) {
// Force parser termination if one of the conditions are observed:
// 1) We have already reported the same error at the same location; This
// is an indication that the parser is not making progress.
// 2) If we reached the absolute maximum number of errors.
// TODO (fabiomfv) consider throwing AssertionError to terminate parsing.
} else {
if (incErrorCount()) {
ctx.error(dartError);
errorHistory.add(dartError.hashCode());
}
@@ -92,6 +92,7 @@ public enum ParserErrorCode implements ErrorCode {
MISSING_FUNCTION_NAME(ErrorSeverity.WARNING, "a function name is required for a declaration"),
NAMED_PARAMETER_NOT_ALLOWED("Named parameter is not allowed for operator or setter method"),
NO_SPACE_AFTER_PLUS("Cannot have space between plus and numeric literal"),
NO_SOUP_FOR_YOU("Too many errors"),
NO_UNARY_PLUS_OPERATOR("No unary plus operator in Dart"),
NON_FINAL_STATIC_MEMBER_IN_INTERFACE("Non-final static members are not allowed in interfaces"),
ONLY_ONE_LIBRARY_DIRECTIVE("Only one library directive may be declared in a file"),