mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 03:22:52 +00:00
Better redirecting constructor and initializers problems reporting.
Preparation for work on http://code.google.com/p/dart/issues/detail?id=351 R=zundel@google.com BUG= TEST= Review URL: http://codereview.chromium.org//8527005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@1511 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
bd670664bb
commit
7cea876fef
|
@ -974,17 +974,18 @@ public class DartParser extends CompletionHooksParserBase {
|
|||
done(null);
|
||||
}
|
||||
|
||||
// Parse the argument definitions.
|
||||
List<DartParameter> arguments = parseFormalParameterList();
|
||||
// Parse the parameters definitions.
|
||||
List<DartParameter> parameters = parseFormalParameterList();
|
||||
|
||||
if (arity != -1 && arguments.size() != arity) {
|
||||
reportError(position(), ParserErrorCode.ILLEGAL_NUMBER_OF_ARGUMENTS);
|
||||
if (arity != -1 && parameters.size() != arity) {
|
||||
reportError(position(), ParserErrorCode.ILLEGAL_NUMBER_OF_PARAMETERS);
|
||||
}
|
||||
|
||||
// Parse initializer expressions for constructors.
|
||||
List<DartInitializer> initializers = new ArrayList<DartInitializer>();
|
||||
if (match(Token.COLON) && !(isParsingInterface || modifiers.isFactory())) {
|
||||
boolean isRedirectedConstructor = parseInitializers(initializers);
|
||||
parseInitializers(initializers);
|
||||
boolean isRedirectedConstructor = validateInitializers(parameters, initializers);
|
||||
if (isRedirectedConstructor) {
|
||||
modifiers = modifiers.makeRedirectedConstructor();
|
||||
}
|
||||
|
@ -1001,7 +1002,7 @@ public class DartParser extends CompletionHooksParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
DartFunction function = doneWithoutConsuming(new DartFunction(arguments, body, returnType));
|
||||
DartFunction function = doneWithoutConsuming(new DartFunction(parameters, body, returnType));
|
||||
return DartMethodDefinition.create(name, function, modifiers, initializers, null);
|
||||
}
|
||||
|
||||
|
@ -1054,10 +1055,10 @@ public class DartParser extends CompletionHooksParserBase {
|
|||
* : (THIS '.')? identifier '=' conditionalExpression
|
||||
* | THIS ('.' identifier)? arguments
|
||||
* ;
|
||||
* </pre>
|
||||
* </pre>
|
||||
* @return true if initializer is a redirected constructor, false otherwise.
|
||||
*/
|
||||
private boolean parseInitializers(List<DartInitializer> initializers) {
|
||||
private void parseInitializers(List<DartInitializer> initializers) {
|
||||
expect(Token.COLON);
|
||||
do {
|
||||
beginInitializer();
|
||||
|
@ -1075,13 +1076,15 @@ public class DartParser extends CompletionHooksParserBase {
|
|||
boolean hasThisPrefix = optional(Token.THIS);
|
||||
if (hasThisPrefix) {
|
||||
if (match(Token.LPAREN)) {
|
||||
return parseRedirectedConstructorInvocation(null, initializers);
|
||||
parseRedirectedConstructorInvocation(null, initializers);
|
||||
continue;
|
||||
}
|
||||
expect(Token.PERIOD);
|
||||
}
|
||||
DartIdentifier name = parseIdentifier();
|
||||
if (hasThisPrefix && match(Token.LPAREN)) {
|
||||
return parseRedirectedConstructorInvocation(name, initializers);
|
||||
parseRedirectedConstructorInvocation(name, initializers);
|
||||
continue;
|
||||
} else {
|
||||
expect(Token.ASSIGN);
|
||||
boolean save = setAllowFunctionExpression(false);
|
||||
|
@ -1091,20 +1094,87 @@ public class DartParser extends CompletionHooksParserBase {
|
|||
}
|
||||
}
|
||||
} while (optional(Token.COMMA));
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean parseRedirectedConstructorInvocation(DartIdentifier name,
|
||||
List<DartInitializer> initializers) {
|
||||
if (initializers.isEmpty()) {
|
||||
DartRedirectConstructorInvocation redirConstructor =
|
||||
private void parseRedirectedConstructorInvocation(DartIdentifier name,
|
||||
List<DartInitializer> initializers) {
|
||||
DartRedirectConstructorInvocation redirConstructor =
|
||||
new DartRedirectConstructorInvocation(name, parseArguments());
|
||||
initializers.add(done(new DartInitializer(null, doneWithoutConsuming(redirConstructor))));
|
||||
return true;
|
||||
} else {
|
||||
reportUnexpectedToken(position(), Token.ASSIGN, Token.LPAREN);
|
||||
initializers.add(done(new DartInitializer(null, doneWithoutConsuming(redirConstructor))));
|
||||
}
|
||||
|
||||
private boolean validateInitializers(List<DartParameter> parameters,
|
||||
List<DartInitializer> initializers) {
|
||||
// Try to find DartRedirectConstructorInvocation, check for multiple invocations.
|
||||
// Check for DartSuperConstructorInvocation multiple invocations.
|
||||
DartInitializer redirectInitializer = null;
|
||||
boolean firstMultipleRedirectReported = false;
|
||||
{
|
||||
DartInitializer superInitializer = null;
|
||||
boolean firstMultipleSuperReported = false;
|
||||
for (DartInitializer initializer : initializers) {
|
||||
if (initializer.isInvocation()) {
|
||||
// DartSuperConstructorInvocation
|
||||
DartExpression initializerInvocation = initializer.getValue();
|
||||
if (initializerInvocation instanceof DartSuperConstructorInvocation) {
|
||||
if (superInitializer != null) {
|
||||
if (!firstMultipleSuperReported) {
|
||||
reportError(superInitializer, ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE);
|
||||
firstMultipleSuperReported = true;
|
||||
}
|
||||
reportError(initializer, ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE);
|
||||
} else {
|
||||
superInitializer = initializer;
|
||||
}
|
||||
}
|
||||
// DartRedirectConstructorInvocation
|
||||
if (initializerInvocation instanceof DartRedirectConstructorInvocation) {
|
||||
if (redirectInitializer != null) {
|
||||
if (!firstMultipleRedirectReported) {
|
||||
reportError(redirectInitializer, ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE);
|
||||
firstMultipleRedirectReported = true;
|
||||
}
|
||||
reportError(initializer, ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE);
|
||||
} else {
|
||||
redirectInitializer = initializer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
// If there is redirecting constructor, then there should be no other initializers.
|
||||
if (redirectInitializer != null) {
|
||||
boolean shouldRedirectInvocationReported = false;
|
||||
// Implicit initializer in form of "this.id" parameter.
|
||||
for (DartParameter parameter : parameters) {
|
||||
if (parameter.getName() instanceof DartPropertyAccess) {
|
||||
DartPropertyAccess propertyAccess = (DartPropertyAccess) parameter.getName();
|
||||
if (propertyAccess.getQualifier() instanceof DartThisExpression) {
|
||||
shouldRedirectInvocationReported = true;
|
||||
reportError(
|
||||
parameter,
|
||||
ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Iterate all initializers and mark all except of DartRedirectConstructorInvocation
|
||||
for (DartInitializer initializer : initializers) {
|
||||
if (!(initializer.getValue() instanceof DartRedirectConstructorInvocation)) {
|
||||
shouldRedirectInvocationReported = true;
|
||||
reportError(
|
||||
initializer,
|
||||
ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER);
|
||||
}
|
||||
}
|
||||
// Mark DartRedirectConstructorInvocation if needed.
|
||||
if (shouldRedirectInvocationReported) {
|
||||
reportError(
|
||||
redirectInitializer,
|
||||
ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF);
|
||||
}
|
||||
}
|
||||
// Done.
|
||||
return redirectInitializer != null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,13 +39,18 @@ public enum ParserErrorCode implements ErrorCode {
|
|||
FUNCTION_TYPED_PARAMETER_IS_FINAL("Formal parameter with a function type cannot be const"),
|
||||
FUNCTION_TYPED_PARAMETER_IS_VAR("Formal parameter with a function type cannot be var"),
|
||||
ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE("Illegal assignment to non-assignable expression"),
|
||||
ILLEGAL_NUMBER_OF_ARGUMENTS("Illegal number of arguments"),
|
||||
ILLEGAL_NUMBER_OF_PARAMETERS("Illegal number of parameters"),
|
||||
INCOMPLETE_STRING_LITERAL("Incomplete string literal"),
|
||||
INVALID_FIELD_DECLARATION("Wrong syntax for field declaration"),
|
||||
INVALID_OPERATOR_CHAINING("Cannot chain '%s'"),
|
||||
MISSING_FUNCTION_NAME("a function name is required for a declaration"),
|
||||
NON_FINAL_STATIC_MEMBER_IN_INTERFACE("Non-final static members are not allowed in interfaces"),
|
||||
OPERATOR_CANNOT_BE_STATIC("Operators cannot be static"),
|
||||
REDIRECTING_CONSTRUCTOR_PARAM("Redirecting constructor can not have initializers"),
|
||||
REDIRECTING_CONSTRUCTOR_ITSELF("Redirecting constructor can not have initializers"),
|
||||
REDIRECTING_CONSTRUCTOR_MULTIPLE("Multiple redirecting constructor invocations"),
|
||||
REDIRECTING_CONSTRUCTOR_OTHER("Redirecting constructor can not have initializers"),
|
||||
SUPER_CONSTRUCTOR_MULTIPLE("'super' must be called only once in the initialization list"),
|
||||
TOP_LEVEL_IS_STATIC("Top-level field or method may not be static"),
|
||||
UNEXPECTED_TOKEN("Unexpected token '%s'"),
|
||||
UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION("Unexpected token in string interpolation: %s"),
|
||||
|
|
|
@ -1339,9 +1339,6 @@ public class Resolver {
|
|||
DartInitializer initializer = initializers.next();
|
||||
Element element = resolve(initializer);
|
||||
if ((ElementKind.of(element) == ElementKind.CONSTRUCTOR) && initializer.isInvocation()) {
|
||||
if (constructorElement != null) {
|
||||
onError(initializer, ResolverErrorCode.SUPER_INVOCATION_NOT_UNIQUE);
|
||||
}
|
||||
constructorElement = (ConstructorElement) element;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,6 @@ public enum ResolverErrorCode implements ErrorCode {
|
|||
STATIC_METHOD_ACCESS_SUPER("Cannot use 'super' in a static method"),
|
||||
STATIC_METHOD_ACCESS_THIS("Cannot use 'this' in a static method"),
|
||||
SUPER_OUTSIDE_OF_METHOD("Cannot use 'super' outside of a method"),
|
||||
SUPER_INVOCATION_NOT_UNIQUE("'super' must be called only once in the initialization list"),
|
||||
TOP_LEVEL_METHOD_ACCESS_SUPER("Cannot use 'super' in a top-level method"),
|
||||
TOP_LEVEL_METHOD_ACCESS_THIS("Cannot use 'this' in a top-level method"),
|
||||
TYPE_NOT_ASSIGNMENT_COMPATIBLE("%s is not assignable to %s"),
|
||||
|
|
|
@ -273,4 +273,57 @@ public abstract class CompilerTestCase extends TestCase {
|
|||
DartCompilerListener listener) {
|
||||
return new DartScannerParserContext(src, sourceCode, listener);
|
||||
}
|
||||
|
||||
protected static class ErrorExpectation {
|
||||
final ErrorCode errorCode;
|
||||
final int line;
|
||||
final int column;
|
||||
final int length;
|
||||
|
||||
public ErrorExpectation(ErrorCode errorCode, int line, int column, int length) {
|
||||
this.errorCode = errorCode;
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
this.length = length;
|
||||
}
|
||||
}
|
||||
|
||||
protected static ErrorExpectation errEx(ErrorCode errorCode, int line, int column, int length) {
|
||||
return new ErrorExpectation(errorCode, line, column, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that given list of {@link DartCompilationError} is exactly same as expected.
|
||||
*/
|
||||
protected static void assertErrors(List<DartCompilationError> errors,
|
||||
ErrorExpectation... expectedErrors) {
|
||||
// count of errors
|
||||
if (errors.size() != expectedErrors.length) {
|
||||
fail(String.format(
|
||||
"Expected %s errors, but got %s: %s",
|
||||
expectedErrors.length,
|
||||
errors.size(),
|
||||
errors));
|
||||
}
|
||||
// content of errors
|
||||
for (int i = 0; i < expectedErrors.length; i++) {
|
||||
ErrorExpectation expectedError = expectedErrors[i];
|
||||
DartCompilationError actualError = errors.get(i);
|
||||
if (actualError.getErrorCode() != expectedError.errorCode
|
||||
|| actualError.getLineNumber() != expectedError.line
|
||||
|| actualError.getColumnNumber() != expectedError.column
|
||||
|| actualError.getLength() != expectedError.length) {
|
||||
fail(String.format(
|
||||
"Expected %s:%d:%d/%d, but got %s:%d:%d/%d",
|
||||
expectedError.errorCode,
|
||||
expectedError.line,
|
||||
expectedError.column,
|
||||
expectedError.length,
|
||||
actualError.getErrorCode(),
|
||||
actualError.getLineNumber(),
|
||||
actualError.getColumnNumber(),
|
||||
actualError.getLength()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +1,105 @@
|
|||
// 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.CompilerTestCase;
|
||||
import com.google.dart.compiler.DartCompilationError;
|
||||
import com.google.dart.compiler.ast.DartIdentifier;
|
||||
import com.google.dart.compiler.ast.DartMethodDefinition;
|
||||
import com.google.dart.compiler.ast.DartUnit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Negative Parser/Syntax tests.
|
||||
*/
|
||||
public class NegativeParserTest extends CompilerTestCase {
|
||||
|
||||
private void parseExpectErrors(String code, int expectedErrorCount) {
|
||||
assertEquals(expectedErrorCount, DartParserRunner.parse(getName(), code).getErrorCount());
|
||||
private void parseExpectErrors(String code, ErrorExpectation... expectedErrors) {
|
||||
List<DartCompilationError> errors = getParseErrors(code);
|
||||
assertErrors(errors, expectedErrors);
|
||||
}
|
||||
|
||||
private void parseExpectErrors(String code) {
|
||||
assertTrue("expected errors.", DartParserRunner.parse(getName(), code).hasErrors());
|
||||
private List<DartCompilationError> getParseErrors(String code) {
|
||||
return DartParserRunner.parse(getName(), code, Integer.MAX_VALUE, false).getErrors();
|
||||
}
|
||||
|
||||
public void testFieldInitializerInRedirectionConstructor1() {
|
||||
parseExpectErrors("class A { A(x) { } A.foo() : this(5), y = 5; var y; }");
|
||||
parseExpectErrors(
|
||||
"class A { A(x) { } A.foo() : this(5), y = 5; var y; }",
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 39, 5),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 30, 7));
|
||||
}
|
||||
|
||||
public void testFieldInitializerInRedirectionConstructor2() {
|
||||
parseExpectErrors("class A { A(x) { } A.foo() : y = 5, this(5); var y; }");
|
||||
parseExpectErrors(
|
||||
"class A { A(x) { } A.foo() : y = 5, this(5); var y; }",
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 30, 5),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 37, 7));
|
||||
}
|
||||
|
||||
public void testFieldInitializerInRedirectionConstructor3() {
|
||||
parseExpectErrors("class A { A(x) { } A.foo(this.y) : this(5); var y; }", 1);
|
||||
parseExpectErrors(
|
||||
"class A { A.foo(x) { } A() : y = 5, this.foo(5); var y; }",
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 30, 5),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 37, 11));
|
||||
}
|
||||
|
||||
public void testFieldInitializerInRedirectionConstructor4() {
|
||||
parseExpectErrors(
|
||||
"class A { A(x) { } A.foo(this.y, this.z) : this(5); var y; var z;}",
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM, 1, 26, 6),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM, 1, 34, 6),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 44, 7));
|
||||
}
|
||||
|
||||
public void testFieldInitializerInRedirectionConstructor5() {
|
||||
parseExpectErrors(
|
||||
"class A { A(x) { } A.foo(this.y) : this(5), z = 7; var y; var z;}",
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM, 1, 26, 6),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 45, 5),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 36, 7));
|
||||
}
|
||||
|
||||
public void testSuperInRedirectionConstructor1() {
|
||||
parseExpectErrors("class A { A(x) { } A.foo(this.y) : this(5), super(); var y; }");
|
||||
parseExpectErrors(
|
||||
"class A { A(x) { } A.foo() : this(5), super(); var y; }",
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 39, 7),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 30, 7));
|
||||
}
|
||||
|
||||
public void testSuperInRedirectionConstructor2() {
|
||||
parseExpectErrors("class A { A(x) { } A.foo(this.y) : super(), this(5); var y; }", 1);
|
||||
parseExpectErrors(
|
||||
"class A { A(x) { } A.foo() : super(), this(5); var y; }",
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 30, 7),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 39, 7));
|
||||
}
|
||||
|
||||
public void testMultipleRedirectionConstructors() {
|
||||
parseExpectErrors("class A { A(x) { } A.foo(this.y) : this(1), this(2); }", 1);
|
||||
parseExpectErrors(
|
||||
"class A { A(x) { } A.foo() : this(1), this(2); }",
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE, 1, 30, 7),
|
||||
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE, 1, 39, 7));
|
||||
}
|
||||
|
||||
public void testSuperMultipleInvocationsTest() {
|
||||
String source =
|
||||
makeCode(
|
||||
"class A {",
|
||||
" int a;",
|
||||
" A(this.a);",
|
||||
" A.foo(int x, int y);",
|
||||
"}",
|
||||
"",
|
||||
"class B extends A {",
|
||||
" int b1;",
|
||||
" int b2;",
|
||||
" B(int x) : this.b1 = x, super(x), this.b2 = x, super.foo(x, x);",
|
||||
"}");
|
||||
parseExpectErrors(
|
||||
source,
|
||||
errEx(ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE, 10, 29, 8),
|
||||
errEx(ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE, 10, 52, 15));
|
||||
}
|
||||
|
||||
public void testIncompleteClassDeclaration_noLBrace() {
|
||||
|
@ -56,7 +112,9 @@ public class NegativeParserTest extends CompilerTestCase {
|
|||
DartUnit unit =
|
||||
parseSourceUnitErrors(
|
||||
sourceCode,
|
||||
ParserErrorCode.EXPECTED_CLASS_DECLARATION_LBRACE.getMessage(), 2, 1);
|
||||
ParserErrorCode.EXPECTED_CLASS_DECLARATION_LBRACE.getMessage(),
|
||||
2,
|
||||
1);
|
||||
// check structure of AST, top level Baz and Foo expected
|
||||
assertEquals(2, unit.getTopLevelNodes().size());
|
||||
assertEquals(
|
||||
|
@ -84,14 +142,16 @@ public class NegativeParserTest extends CompilerTestCase {
|
|||
DartUnit unit =
|
||||
parseSourceUnitErrors(
|
||||
"factory foo() {}",
|
||||
ParserErrorCode.DISALLOWED_FACTORY_KEYWORD.getMessage(), 1, 1);
|
||||
ParserErrorCode.DISALLOWED_FACTORY_KEYWORD.getMessage(),
|
||||
1,
|
||||
1);
|
||||
DartMethodDefinition factory = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
|
||||
assertNotNull(factory);
|
||||
// this factory has name, which is allowed for normal method
|
||||
assertEquals(true, factory.getName() instanceof DartIdentifier);
|
||||
assertEquals("foo", ((DartIdentifier) factory.getName()).getTargetName());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Language specification requires that factory should be declared in class. However declaring
|
||||
* factory on top level should not cause exceptions in compiler. To ensure this we parse top level
|
||||
|
@ -103,7 +163,9 @@ public class NegativeParserTest extends CompilerTestCase {
|
|||
DartUnit unit =
|
||||
parseSourceUnitErrors(
|
||||
"factory foo<T>() {}",
|
||||
ParserErrorCode.DISALLOWED_FACTORY_KEYWORD.getMessage(), 1, 1);
|
||||
ParserErrorCode.DISALLOWED_FACTORY_KEYWORD.getMessage(),
|
||||
1,
|
||||
1);
|
||||
DartMethodDefinition factory = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
|
||||
assertNotNull(factory);
|
||||
// normal method requires name, so we provide some name
|
||||
|
|
|
@ -22,7 +22,7 @@ public class ParserTests extends TestSetup {
|
|||
suite.addTestSuite(CPParserTest.class);
|
||||
suite.addTestSuite(ParserRoundTripTest.class);
|
||||
suite.addTestSuite(LibraryParserTest.class);
|
||||
//suite.addTestSuite(NegativeParserTest.class); TODO(scheglov) fix failures here and add again
|
||||
suite.addTestSuite(NegativeParserTest.class);
|
||||
suite.addTestSuite(ValidatingSyntaxTest.class);
|
||||
suite.addTestSuite(CommentTest.class);
|
||||
suite.addTestSuite(ErrorMessageLocationTest.class);
|
||||
|
|
|
@ -6,11 +6,9 @@ package com.google.dart.compiler.resolver;
|
|||
|
||||
import com.google.dart.compiler.CompilerTestCase;
|
||||
import com.google.dart.compiler.DartCompilationError;
|
||||
import com.google.dart.compiler.ErrorCode;
|
||||
import com.google.dart.compiler.ast.DartUnit;
|
||||
import com.google.dart.compiler.testing.TestCompilerContext;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -19,20 +17,22 @@ public class NegativeResolverTest extends CompilerTestCase {
|
|||
List<DartCompilationError> errors = new ArrayList<DartCompilationError>();
|
||||
List<DartCompilationError> typeErrors = new ArrayList<DartCompilationError>();
|
||||
|
||||
private static class ErrorExpectation {
|
||||
final ErrorCode errorCode;
|
||||
final int line;
|
||||
final int column;
|
||||
|
||||
public ErrorExpectation(ErrorCode errorCode, int line, int column) {
|
||||
this.errorCode = errorCode;
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
}
|
||||
/**
|
||||
* Parses given Dart source, runs {@link Resolver} and checks that expected errors were generated.
|
||||
*/
|
||||
public void checkSourceErrors(String source, ErrorExpectation ...expectedErrors) {
|
||||
DartUnit unit = parseUnit("Test.dart", source);
|
||||
resolve(unit);
|
||||
assertErrors(errors, expectedErrors);
|
||||
}
|
||||
|
||||
private static ErrorExpectation errEx(ErrorCode errorCode, int line, int column) {
|
||||
return new ErrorExpectation(errorCode, line, column);
|
||||
/**
|
||||
* Parses given Dart file, runs {@link Resolver} and checks that expected errors were generated.
|
||||
*/
|
||||
public void checkFileErrors(String source, ErrorExpectation ...expectedErrors) {
|
||||
DartUnit unit = parseUnit(source);
|
||||
resolve(unit);
|
||||
assertErrors(errors, expectedErrors);
|
||||
}
|
||||
|
||||
public void checkNumErrors(String fileName, int expectedErrorCount) {
|
||||
|
@ -45,28 +45,6 @@ public class NegativeResolverTest extends CompilerTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void checkNumErrors(String fileName, ErrorExpectation ...expectedErrors) {
|
||||
DartUnit unit = parseUnit(fileName);
|
||||
resolve(unit);
|
||||
assertEquals(expectedErrors.length, errors.size());
|
||||
for (int i = 0; i < expectedErrors.length; i++) {
|
||||
ErrorExpectation expectedError = expectedErrors[i];
|
||||
DartCompilationError actualError = errors.get(i);
|
||||
if (actualError.getErrorCode() != expectedError.errorCode
|
||||
|| actualError.getLineNumber() != expectedError.line
|
||||
|| actualError.getColumnNumber() != expectedError.column) {
|
||||
fail(String.format(
|
||||
"Expected %s:%s:%s, but got %s:%s:%s",
|
||||
expectedError.errorCode,
|
||||
expectedError.line,
|
||||
expectedError.column,
|
||||
actualError.getErrorCode(),
|
||||
actualError.getLineNumber(),
|
||||
actualError.getColumnNumber()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resolve(DartUnit unit) {
|
||||
unit.addTopLevelNode(ResolverTestCase.makeClass("int", null));
|
||||
unit.addTopLevelNode(ResolverTestCase.makeClass("Object", null));
|
||||
|
@ -77,39 +55,6 @@ public class NegativeResolverTest extends CompilerTestCase {
|
|||
ResolverTestCase.resolve(unit, getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses given Dart source, runs {@link Resolver} and checks that expected errors were generated.
|
||||
*/
|
||||
public void checkErrors(String source, ErrorExpectation ...expectedErrors) {
|
||||
DartUnit unit = parseUnit("Test.dart", source);
|
||||
resolve(unit);
|
||||
// count of errors
|
||||
if (errors.size() != expectedErrors.length) {
|
||||
fail(String.format(
|
||||
"Expected %s errors, but got %s: %s",
|
||||
expectedErrors.length,
|
||||
errors.size(),
|
||||
errors));
|
||||
}
|
||||
// content of errors
|
||||
for (int i = 0; i < expectedErrors.length; i++) {
|
||||
ErrorExpectation expectedError = expectedErrors[i];
|
||||
DartCompilationError actualError = errors.get(i);
|
||||
if (actualError.getErrorCode() != expectedError.errorCode
|
||||
|| actualError.getLineNumber() != expectedError.line
|
||||
|| actualError.getColumnNumber() != expectedError.column) {
|
||||
fail(String.format(
|
||||
"Expected %s:%s:%s, but got %s:%s:%s",
|
||||
expectedError.errorCode,
|
||||
expectedError.line,
|
||||
expectedError.column,
|
||||
actualError.getErrorCode(),
|
||||
actualError.getLineNumber(),
|
||||
actualError.getColumnNumber()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testInitializer1() {
|
||||
checkNumErrors("Initializer1NegativeTest.dart", 1);
|
||||
}
|
||||
|
@ -135,25 +80,25 @@ public class NegativeResolverTest extends CompilerTestCase {
|
|||
}
|
||||
|
||||
public void testArrayLiteralNegativeTest() {
|
||||
checkErrors(
|
||||
checkSourceErrors(
|
||||
makeCode(
|
||||
"class A {",
|
||||
" main() {",
|
||||
" List<int, int> ints = [1];",
|
||||
" }",
|
||||
"}"),
|
||||
errEx(TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 3, 5));
|
||||
errEx(TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 3, 5, 14));
|
||||
}
|
||||
|
||||
public void testMapLiteralNegativeTest() {
|
||||
checkErrors(
|
||||
checkSourceErrors(
|
||||
makeCode(
|
||||
"class A {",
|
||||
" main() {",
|
||||
" Map<String, int, int> map = {'foo':1};",
|
||||
" }",
|
||||
"}"),
|
||||
errEx(TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 3, 5));
|
||||
errEx(TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 3, 5, 21));
|
||||
}
|
||||
|
||||
public void testCall1() {
|
||||
|
@ -276,11 +221,6 @@ public class NegativeResolverTest extends CompilerTestCase {
|
|||
checkNumErrors("RawTypesNegativeTest.dart", 4);
|
||||
}
|
||||
|
||||
public void testSuperMultipleInvocationsTest() {
|
||||
checkNumErrors("SuperMultipleInvocationsTest.dart",
|
||||
errEx(ResolverErrorCode.SUPER_INVOCATION_NOT_UNIQUE, 14, 52));
|
||||
}
|
||||
|
||||
private TestCompilerContext getContext() {
|
||||
return new TestCompilerContext() {
|
||||
@Override
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
// 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.
|
||||
|
||||
class A {
|
||||
int a;
|
||||
A(this.a);
|
||||
A.foo(int x, int y);
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
int b1;
|
||||
int b2;
|
||||
B(int x) : this.b1 = x, super(x), this.b2 = x, super.foo(x, x);
|
||||
}
|
Loading…
Reference in a new issue