From 115fc3df08c9252f2f434d9f78ab2816c87c36b4 Mon Sep 17 00:00:00 2001 From: "mmendez@google.com" Date: Thu, 6 Oct 2011 02:46:31 +0000 Subject: [PATCH] Revert "Revert "Eliminate retarded constructors."" This reverts r66 which was a revert of r64. The original commit failed because "optimized" mode builds won't generate NoSuchMethodErrors and that is why the release mode test won't pass. So for that issue, I updated the language.status file. The client failure appears to be test infrastructure flakiness because my rollback failed but the subsequent build succeeded and I'm unable to reproduce the failure at my desk. Review URL: https://chromereviews.googleplex.com/3508025 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@88 260f80e4-7a28-3924-810f-c04153c831b5 --- co19/tests/co19/co19-compiler.status | 2 +- .../dart/compiler/DartCompilerErrorCode.java | 2 + .../backend/js/GenerateJavascriptAST.java | 67 ++++--- .../dart/compiler/backend/js/Normalizer.java | 180 ++++++++++++++++++ .../dart/compiler/resolver/Elements.java | 7 + .../dart/compiler/resolver/Resolver.java | 118 +++++++++--- ...NegativeTest3.dart => ConstSuperTest.dart} | 2 +- .../resolver/NegativeResolverTest.java | 6 +- .../dart/compiler/resolver/ResolverTest.java | 65 +++++++ tests/language/language.status | 7 +- 10 files changed, 397 insertions(+), 59 deletions(-) rename compiler/javatests/com/google/dart/compiler/resolver/{ConstSuperNegativeTest3.dart => ConstSuperTest.dart} (84%) diff --git a/co19/tests/co19/co19-compiler.status b/co19/tests/co19/co19-compiler.status index 730d15f4ef5..e5be6848c61 100644 --- a/co19/tests/co19/co19-compiler.status +++ b/co19/tests/co19/co19-compiler.status @@ -131,6 +131,7 @@ LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A02/t02: LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A02/t03: Fail # Bug 5371670. LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A02/t04: Fail # Bug 5371670. LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A03/t01: Fail # Bug 5371670. +LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A03/t02: Fail # Bug 5371670. This will no longer valid due to language spec changes. LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A06/t04: Fail # Bug 5371670. LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A10/t01: Fail # Bug 5371670. LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A13/t01: Fail # Bug 5371670. @@ -216,7 +217,6 @@ LibTest/core/Set/every/Set/every/A01/t04: Skip LangGuideTest/02_Language_Constructs/02_11_Exceptions/A05/t01: Fail LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A05/t01: Fail -LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A12/t01: Fail LangGuideTest/02_Language_Constructs/02_1_Class/02_1_Class_Construction/A12/t02: Fail LangGuideTest/02_Language_Constructs/02_1_Class/A02/t04: Skip # Times out. LangGuideTest/02_Language_Constructs/02_5_Meaning_of_Names/A02/t02: Fail diff --git a/compiler/java/com/google/dart/compiler/DartCompilerErrorCode.java b/compiler/java/com/google/dart/compiler/DartCompilerErrorCode.java index be5171be9f8..8b52a11cdcd 100644 --- a/compiler/java/com/google/dart/compiler/DartCompilerErrorCode.java +++ b/compiler/java/com/google/dart/compiler/DartCompilerErrorCode.java @@ -33,6 +33,8 @@ public enum DartCompilerErrorCode implements ErrorCode { CANNOT_RESOLVE_LABEL("cannot resolve label %s"), CANNOT_RESOLVE_METHOD("cannot resolve method %s"), CANNOT_RESOLVE_SUPER_CONSTRUCTOR("cannot resolve method %s"), + CANNOT_RESOLVE_IMPLICIT_CALL_TO_SUPER_CONSTRUCTOR( + "super type %s does not have a default constructor"), CATCH_OR_FINALLY_EXPECTED("catch or finally clause expected."), CONSTRUCTOR_CANNOT_BE_ABSTRACT("A constructor cannot be asbstract"), CONSTRUCTOR_CANNOT_BE_STATIC("A constructor cannot be static"), diff --git a/compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java b/compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java index 30f70a66ea9..fd31b2fc2b2 100644 --- a/compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java +++ b/compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java @@ -442,6 +442,11 @@ public class GenerateJavascriptAST { for (Element element : classElement.getMembers()) { classMembers.add(element); } + + if (Elements.needsImplicitDefaultConstructor(classElement)) { + addImplicitDefaultConstructor(x, classElement, classMembers); + } + for (Element member : classMembers) { switch(ElementKind.of(member)) { case METHOD: { @@ -491,6 +496,19 @@ public class GenerateJavascriptAST { return null; } + private void addImplicitDefaultConstructor(DartClass x, ClassElement classElement, + List classElementMembers) { + for (DartNode member : x.getMembers()) { + if (member instanceof DartMethodDefinition) { + DartMethodDefinition method = (DartMethodDefinition) member; + MethodElement symbol = method.getSymbol(); + if (symbol.isConstructor() && "".equals(symbol.getName())) { + classElementMembers.add(symbol); + } + } + } + } + /** * @param classElement * @@ -846,12 +864,6 @@ public class GenerateJavascriptAST { Iterator iterator = initializers.iterator(); Iterator fieldIterator = fieldInitializers.iterator(); - if (hasConstructorInvocation) { - // skip the super call - DartInitializer first = iterator.next(); - assert first.isInvocation(); - } - List jsInitializers = initFunction.getBody().getStatements(); // Do the field inline initializers first. If there are any assignments in the initializer @@ -861,14 +873,19 @@ public class GenerateJavascriptAST { jsInitializers.add(initializer.makeStmt()); } + DartInvocation initInvocation = null; while (iterator.hasNext()) { - jsInitializers.add((JsStatement) generate(iterator.next())); + DartInitializer initializer = iterator.next(); + if (!initializer.isInvocation()) { + jsInitializers.add((JsStatement) generate(initializer)); + } else { + initInvocation = (DartInvocation) initializer.getValue(); + } } if (hasConstructorInvocation) { // Call the super initializer function in the initializer. // Compute the super constructor initializer to call. - DartInvocation initInvocation = (DartInvocation) initializers.get(0).getValue(); ConstructorElement superElement = (ConstructorElement) initInvocation.getSymbol(); // TODO(floitsch): it would be better if we had a js-name and not just a string. // This way the debugging information would be better. @@ -930,10 +947,11 @@ public class GenerateJavascriptAST { // If there are initializers, populate the initializer function. List initializers = constructor.getInitializers(); if (!initializers.isEmpty()) { - DartInitializer firstInit = initializers.get(0); - if (firstInit.isInvocation()) { - JsExprStmt statement = (JsExprStmt) generate(firstInit); - return (JsInvocation) statement.getExpression(); + for (DartInitializer init : initializers) { + if (init.isInvocation()) { + JsExprStmt statement = (JsExprStmt) generate(init); + return (JsInvocation) statement.getExpression(); + } } } return null; @@ -2141,10 +2159,6 @@ public class GenerateJavascriptAST { return expr; } - private JsNameRef nameref(JsName qualifier, String prop) { - return AstUtil.newNameRef(qualifier.makeRef(), prop); - } - private JsBinaryOperation assign(JsNameRef op1, JsExpression op2) { return AstUtil.newAssignment(op1, op2); } @@ -2157,14 +2171,6 @@ public class GenerateJavascriptAST { return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2); } - private JsPrefixOperation not(JsExpression op1) { - return new JsPrefixOperation(JsUnaryOperator.NOT, op1); - } - - private JsBinaryOperation and(JsExpression op1, JsExpression op2) { - return new JsBinaryOperation(JsBinaryOperator.AND, op1, op2); - } - private JsNumberLiteral number(double num) { return translationContext.getProgram().getNumberLiteral(num); } @@ -3028,14 +3034,23 @@ public class GenerateJavascriptAST { // Must use SuperClass.call(this, ...) to get the correct 'this' context in the callee: // .$Constructor.call(this, ...). ConstructorElement element = (ConstructorElement) x.getSymbol(); + Element classElement; + String elementName; + if (element == null) { + classElement = ((ClassElement) currentHolder).getSupertype().getElement(); + elementName = classElement.getName(); + } else { + classElement = element.getEnclosingElement(); + elementName = element.getName(); + } + // TODO(floitsch): it would be good, if we could get a js-name instead of just a string. // This way the debugging information would be better. // We need to generate the JsName (for the initializer/factory) once only and store it // in some hashtable. Then instead of reusing the mangler, we should reuse those JsNames. // The debugging information would then contain a link from the property-access to the // constructor. Without JsName the debugger just assumes we access some random property. - String name = mangler.mangleConstructor(element.getName(), unitLibrary); - Element classElement = element.getEnclosingElement(); + String name = mangler.mangleConstructor(elementName, unitLibrary); JsNameRef constructorRef = AstUtil.newNameRef(getJsName(classElement).makeRef(), name); return generateInvocation(x, constructorRef, true, null, element); } diff --git a/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java b/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java index 72914eec6b7..e049ffda084 100644 --- a/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java +++ b/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java @@ -10,6 +10,7 @@ import com.google.dart.compiler.ast.DartArrayAccess; import com.google.dart.compiler.ast.DartBinaryExpression; import com.google.dart.compiler.ast.DartBlock; import com.google.dart.compiler.ast.DartCase; +import com.google.dart.compiler.ast.DartClass; import com.google.dart.compiler.ast.DartClassMember; import com.google.dart.compiler.ast.DartContext; import com.google.dart.compiler.ast.DartDefault; @@ -35,8 +36,10 @@ import com.google.dart.compiler.ast.DartNodeTraverser; import com.google.dart.compiler.ast.DartParameter; import com.google.dart.compiler.ast.DartParenthesizedExpression; import com.google.dart.compiler.ast.DartPropertyAccess; +import com.google.dart.compiler.ast.DartRedirectConstructorInvocation; import com.google.dart.compiler.ast.DartReturnStatement; import com.google.dart.compiler.ast.DartStatement; +import com.google.dart.compiler.ast.DartSuperConstructorInvocation; import com.google.dart.compiler.ast.DartSwitchMember; import com.google.dart.compiler.ast.DartSwitchStatement; import com.google.dart.compiler.ast.DartThrowStatement; @@ -52,11 +55,17 @@ import com.google.dart.compiler.resolver.ClassElement; import com.google.dart.compiler.resolver.ConstructorElement; import com.google.dart.compiler.resolver.CoreTypeProvider; import com.google.dart.compiler.resolver.Element; +import com.google.dart.compiler.resolver.ElementKind; import com.google.dart.compiler.resolver.Elements; +import com.google.dart.compiler.resolver.EnclosingElement; import com.google.dart.compiler.resolver.FieldElement; import com.google.dart.compiler.resolver.LabelElement; import com.google.dart.compiler.resolver.MethodElement; import com.google.dart.compiler.resolver.VariableElement; +import com.google.dart.compiler.type.FunctionType; +import com.google.dart.compiler.type.InterfaceType; +import com.google.dart.compiler.type.Type; +import com.google.dart.compiler.type.Types; import java.util.ArrayList; import java.util.Arrays; @@ -579,6 +588,112 @@ public class Normalizer { } } + @Override + public DartNode visitClass(DartClass node) { + final ClassElement classElement = node.getSymbol(); + if (Elements.needsImplicitDefaultConstructor(classElement)) { + DartMethodDefinition method = createImplicitDefaultConstructor(classElement); + + // TODO - We should really normalize the class itself. + node.getMembers().add(method); + } + return super.visitClass(node); + } + + static class SyntheticDefaultConstructorElement implements ConstructorElement { + private final DartMethodDefinition method; + private final ClassElement enclosingClass; + + SyntheticDefaultConstructorElement(DartMethodDefinition method, ClassElement enclosingClass) { + this.method = method; + this.enclosingClass = enclosingClass; + } + + @Override + public String getOriginalSymbolName() { + return getName(); + } + + @Override + public DartNode getNode() { + return method; + } + + @Override + public void setNode(DartLabel node) { + } + + @Override + public boolean isDynamic() { + return false; + } + + @Override + public Type getType() { + return null; + } + + @Override + public String getName() { + return ""; + } + + @Override + public Modifiers getModifiers() { + return Modifiers.NONE; + } + + @Override + public ElementKind getKind() { + return ElementKind.CONSTRUCTOR; + } + + @Override + public EnclosingElement getEnclosingElement() { + return enclosingClass; + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public boolean isConstructor() { + return true; + } + + @Override + public Type getReturnType() { + return null; + } + + @Override + public List getParameters() { + return Collections.emptyList(); + } + + @Override + public FunctionType getFunctionType() { + return null; + } + + @Override + public ClassElement getConstructorType() { + return enclosingClass; + } + } + + private DartMethodDefinition createImplicitDefaultConstructor(final ClassElement classElement) { + assert (Elements.needsImplicitDefaultConstructor(classElement)); + DartFunction function = new DartFunction(Collections.emptyList(), + new DartBlock(Collections.emptyList()), null); + final DartMethodDefinition method = + DartMethodDefinition.create(new DartIdentifier(""), function, Modifiers.NONE, null, null); + method.setSymbol(new SyntheticDefaultConstructorElement(method, classElement)); + return method; + } + @Override public DartExpression visitBinaryExpression(DartBinaryExpression node) { node.visitChildren(this); @@ -605,15 +720,62 @@ public class Normalizer { return node; } + static class NeedsImplicitSuperInvocationDeterminant extends DartNodeTraverser { + private boolean needsSuperInvocation = true; + + @Override + public Void visitSuperConstructorInvocation(DartSuperConstructorInvocation node) { + needsSuperInvocation = false; + return super.visitSuperConstructorInvocation(node); + } + + @Override + public Void visitRedirectConstructorInvocation(DartRedirectConstructorInvocation node) { + needsSuperInvocation = false; + return super.visitRedirectConstructorInvocation(node); + } + + @Override + public Void visitMethodDefinition(DartMethodDefinition node) { + // Ignore everything except the initializers + for (DartInitializer initializer : node.getInitializers()) { + initializer.accept(this); + } + return null; + } + } + @Override public DartMethodDefinition visitMethodDefinition(DartMethodDefinition node) { super.visitMethodDefinition(node); if (Elements.isNonFactoryConstructor(node.getSymbol())) { normalizeParameterInitializer(node); } + return node; } + @Override + public DartNode visitNewExpression(DartNewExpression node) { + ConstructorElement symbol = node.getSymbol(); + if (symbol == null) { + InterfaceType constructorType = Types.constructorType(node); + + // HACK use proper normalized node + ClassElement classToInstantiate = constructorType.getElement(); + if (classToInstantiate.getDefaultClass() != null) { + classToInstantiate = classToInstantiate.getDefaultClass().getElement(); + } + + if (classToInstantiate != null && Elements.needsImplicitDefaultConstructor(classToInstantiate)) { + DartMethodDefinition implicitDefaultConstructor = createImplicitDefaultConstructor(classToInstantiate); + node.setSymbol(implicitDefaultConstructor.getSymbol()); + } + } + + return super.visitNewExpression(node); + } + @Override public DartNode visitSwitchStatement(DartSwitchStatement node) { node.getExpression().accept(this); @@ -647,10 +809,28 @@ public class Normalizer { nInit.add(di); } } + + EnclosingElement enclosingElement = node.getSymbol().getEnclosingElement(); + if (ElementKind.of(enclosingElement) == ElementKind.CLASS) { + ClassElement classElement = (ClassElement) enclosingElement; + if (!classElement.isObject()) { + NeedsImplicitSuperInvocationDeterminant superLocator = new NeedsImplicitSuperInvocationDeterminant(); + node.accept(superLocator); + if (superLocator.needsSuperInvocation) { + DartSuperConstructorInvocation superInvocation = new DartSuperConstructorInvocation( + new DartIdentifier(""), Collections.emptyList()); + superInvocation.setSymbol(new SyntheticDefaultConstructorElement(null, + classElement.getSupertype().getElement())); + nInit.add(new DartInitializer(null, superInvocation)); + } + } + } + if (!nInit.isEmpty()) { if (!node.getInitializers().isEmpty()) { nInit.addAll(0, node.getInitializers()); } + DartMethodDefinition nConstructor = DartMethodDefinition.create( node.getName(), node.getFunction(), node.getModifiers(), nInit, null); nConstructor.setSymbol(node.getSymbol()); diff --git a/compiler/java/com/google/dart/compiler/resolver/Elements.java b/compiler/java/com/google/dart/compiler/resolver/Elements.java index 9241cf7fc02..08d2f3397e7 100644 --- a/compiler/java/com/google/dart/compiler/resolver/Elements.java +++ b/compiler/java/com/google/dart/compiler/resolver/Elements.java @@ -209,4 +209,11 @@ public class Elements { public static Element voidElement() { return VoidElement.getInstance(); } + + /** + * Returns true if the class needs an implicit default constructor. + */ + public static boolean needsImplicitDefaultConstructor(ClassElement classElement) { + return !classElement.isObject() && classElement.getConstructors().isEmpty(); + } } diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java index 43e3d6e8410..0067d1ebdab 100644 --- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java +++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java @@ -237,11 +237,51 @@ public class Resolver { } checkRedirectConstructorCycle(classElement.getConstructors(), context); + if (Elements.needsImplicitDefaultConstructor(classElement)) { + checkImplicitDefaultDefaultSuperInvocation(cls, classElement); + } + context = previousContext; currentHolder = previousHolder; return classElement; } + + /** + * Returns true if the {@link ClassElement} has an implicit or a declared + * default constructor. + */ + boolean hasDefaultConstructor(ClassElement classElement) { + if (Elements.needsImplicitDefaultConstructor(classElement)) { + return true; + } + + ConstructorElement defaultCtor = Elements.lookupConstructor(classElement, ""); + if (defaultCtor != null) { + return defaultCtor.getParameters().isEmpty(); + } + + return false; + } + + private void checkImplicitDefaultDefaultSuperInvocation(DartClass cls, + ClassElement classElement) { + assert (Elements.needsImplicitDefaultConstructor(classElement)); + + InterfaceType supertype = classElement.getSupertype(); + if (supertype != null) { + ClassElement superElement = supertype.getElement(); + if (!superElement.isDynamic()) { + ConstructorElement superCtor = Elements.lookupConstructor(superElement, ""); + if (superCtor != null && !superCtor.getParameters().isEmpty()) { + resolutionError(cls.getName(), + DartCompilerErrorCode.CANNOT_RESOLVE_IMPLICIT_CALL_TO_SUPER_CONSTRUCTOR, + cls.getSuperclass()); + } + } + } + } + private Element resolve(DartNode node) { if (node == null) { return null; @@ -832,11 +872,27 @@ public class Resolver { } }); + if (ElementKind.of(element).equals(ElementKind.CLASS)) { - // Just calling the unnamed constructor. - element = Elements.lookupConstructor(((ClassElement) element), ""); + // Check for default constructor or implicit default constructor + ClassElement classElement = (ClassElement) element; + element = Elements.lookupConstructor(classElement, ""); + if (element == null) { + // Check that the class needs an implicit ctor and no extra args are passed + if (Elements.needsImplicitDefaultConstructor(classElement) && x.getArgs().isEmpty()) { + InterfaceType defaultClass = classElement.getDefaultClass(); + if (defaultClass != null) { + classElement = defaultClass.getElement(); + element = Elements.lookupConstructor(classElement, ""); + } + + if (element == null) { + return recordElement(x, element); + } + } + } } - + // If there is a default implementation, lookup the constructor in the // default class. ConstructorElement constructor = checkIsConstructor(x, element); @@ -850,7 +906,15 @@ public class Resolver { // If the constructor hasn't been found, try the constructor of the default class. // TODO(ngeoffray): check earlier if the default class implements the interface. element = Elements.lookupConstructor(defaultClass, constructor.getName()); + if (element == null && Elements.needsImplicitDefaultConstructor(defaultClass)) { + /* + * Record the element and prevent checkIsConstructor from reporting errors below + * since we know that w don't have an element. + */ + return recordElement(x, element); + } } + // Will check that element is not null. constructor = checkIsConstructor(x, element); } @@ -1106,17 +1170,30 @@ public class Resolver { } private void checkConstructor(DartMethodDefinition node, - ConstructorElement superCall, - boolean firstIsSuper) { + ConstructorElement superCall) { ClassElement currentClass = (ClassElement) currentHolder; + if (superCall == null) { + // Look for a default constructor in our super type + InterfaceType supertype = currentClass.getSupertype(); + if (supertype != null) { + superCall = Elements.lookupConstructor(supertype.getElement(), ""); + } + } + if ((superCall == null) && !currentClass.isObject() && !currentClass.isObjectChild()) { - resolutionError(node, DartCompilerErrorCode.CONSTRUCTOR_MUST_CALL_SUPER); - } else if (!firstIsSuper - && !currentClass.isObject() - && !currentClass.isObjectChild()) { - resolutionError(node, DartCompilerErrorCode.SUPER_CALL_MUST_BE_FIRST); + InterfaceType supertype = currentClass.getSupertype(); + if (supertype != null) { + ClassElement superElement = supertype.getElement(); + if (superElement != null) { + if (!hasDefaultConstructor(superElement)) { + resolutionError(node, + DartCompilerErrorCode.CANNOT_RESOLVE_IMPLICIT_CALL_TO_SUPER_CONSTRUCTOR, + superElement.getName()); + } + } + } } else if ((superCall != null) && node.getModifiers().isConstant() && !superCall.getModifiers().isConstant()) { @@ -1180,22 +1257,17 @@ public class Resolver { private void resolveInitializers(DartMethodDefinition node) { assert null != node; - Element firstElement = null; - DartNode firstNode = null; Iterator initializers = node.getInitializers().iterator(); - if (initializers.hasNext()) { - firstNode = initializers.next(); - firstElement = resolve(firstNode); - } + ConstructorElement constructorElement = null; while (initializers.hasNext()) { - resolve(initializers.next()); + DartInitializer initializer = initializers.next(); + Element element = resolve(initializer); + if (ElementKind.of(element) == ElementKind.CONSTRUCTOR) { + constructorElement = (ConstructorElement) element; + } } - boolean firstIsConstructorInvocation = - ElementKind.of(firstElement).equals(ElementKind.CONSTRUCTOR); - if (firstElement != null && !firstIsConstructorInvocation) { - firstElement = null; - } - checkConstructor(node, (ConstructorElement) firstElement, firstIsConstructorInvocation); + + checkConstructor(node, constructorElement); } private void resolutionError(DartNode node, DartCompilerErrorCode errorCode, diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperNegativeTest3.dart b/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperTest.dart similarity index 84% rename from compiler/javatests/com/google/dart/compiler/resolver/ConstSuperNegativeTest3.dart rename to compiler/javatests/com/google/dart/compiler/resolver/ConstSuperTest.dart index 617e4cfb0c1..b540dbad1e0 100644 --- a/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperNegativeTest3.dart +++ b/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperTest.dart @@ -2,7 +2,7 @@ // 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. -// expect one failure - Sub.A omits call to const super. +// expect no failures - Sub.A omits call to const super, but one will be added class Base { const Base(a); diff --git a/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java b/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java index bbcc0ba2caa..d3c10f7b780 100644 --- a/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java +++ b/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java @@ -66,15 +66,15 @@ public class NegativeResolverTest extends CompilerTestCase { } public void testConstSuperNegativeTest1() { - checkNumErrors("ConstSuperNegativeTest1.dart", 1); + checkNumErrors("ConstSuperNegativeTest1.dart", 0); } public void testConstSuperNegativeTest2() { checkNumErrors("ConstSuperNegativeTest2.dart", 1); } - public void testConstSuperNegativeTest3() { - checkNumErrors("ConstSuperNegativeTest3.dart", 1); + public void testConstSuperTest() { + checkNumErrors("ConstSuperTest.dart", 0); } public void testParameterInitializerNegativeTest1() { diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java index 30acde448a4..a87f56db464 100644 --- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java +++ b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java @@ -214,6 +214,71 @@ public class ResolverTest extends ResolverTestCase { checkExpectedErrors(); } + public void testImplicitDefaultConstructor() { + // Check that the implicit constructor is resolved correctly + resolve(parseUnit( + "class Object {}", + "class B {}", + "class C { main() { new B(); } }"), getContext()); + checkExpectedErrors(); + + /* + * We should check for signature mismatch but that is a TypeAnalyzer issue. + */ + } + + public void testImplicitDefaultConstructor_ThroughFactories() { + // Check that we generate implicit constructors through factories also. + resolve(parseUnit( + "class Object {}", + "interface B factory C {}", + "class C {}", + "class D { main() { new B(); } }"), getContext()); + checkExpectedErrors(); + } + + public void testImplicitDefaultConstructor_WithConstCtor() { + setExpectedErrors(1); + // Check that we generate an error if the implicit constructor would violate const. + resolve(parseUnit( + "class Object {}", + "class B { const B() {} }", + "class C extends B {}", + "class D { main() { new C(); } }"), getContext()); + checkExpectedErrors(); + } + + public void testImplicitSuperCall_ImplicitCtor() { + // Check that we can properly resolve the super ctor that exists. + resolve(parseUnit( + "class Object {}", + "class B { B() {} }", + "class C extends B {}", + "class D { main() { new C(); } }"), getContext()); + checkExpectedErrors(); + } + + public void testImplicitSuperCall_OnExistingCtor() { + // Check that we can properly resolve the super ctor that exists. + resolve(parseUnit( + "class Object {}", + "class B { B() {} }", + "class C extends B { C(){} }", + "class D { main() { new C(); } }"), getContext()); + checkExpectedErrors(); + } + + public void testImplicitSuperCall_NonExistentSuper() { + setExpectedErrors(1); + // Check that we generate an error if the implicit constructor would call a non-existent super. + resolve(parseUnit( + "class Object {}", + "class B { B(Object o) {} }", + "class C extends B {}", + "class D { main() { new C(); } }"), getContext()); + checkExpectedErrors(); + } + public void testCyclicSupertype() { setExpectedErrors(8); resolve(parseUnit( diff --git a/tests/language/language.status b/tests/language/language.status index 096273510bf..4c462be0812 100644 --- a/tests/language/language.status +++ b/tests/language/language.status @@ -57,6 +57,7 @@ NullPointerExceptionTest: Fail # Bug 5391976 CallThroughNullGetterTest: Fail # Bug 5391976 Private3Test: Fail # Bug 5391976 Switch3NegativeTest: Crash # Bug 5318228 +BadNamedParametersTest: Fail # Bug Bug 4202974 - release mode is not throwing NSME # Tests that pass in release mode but fail in debug mode [ ($arch == dartc || $arch == chromium) && $mode == debug ] @@ -67,7 +68,6 @@ Prefix11NegativeTest: Fail # Bug 5406175 Prefix12NegativeTest: Fail,Crash # Bug 5406175 FunctionTypeParameterNegativeTest: Fail # Bug 4568007 ImplicitScopeTest: FAIL # Nested statements can be declarations -ResolveTest: FAIL # 4254120 (implicit constructors) ConstConstructor1NegativeTest: FAIL # 5142545 ConstConstructor2NegativeTest: FAIL # 5142545 MathTest: FAIL # 5165080 @@ -75,7 +75,6 @@ StringConcatTest: FAIL # 5196164 NamedParametersTest: Fail # Implementation in progress. NamedParametersTypeTest: Fail # Implementation in progress. NamedParametersWithConversionsTest: Fail # Implementation in progress. -BadNamedParameters2Test: Fail # Implementation in progress. NamedParametersNegativeTest: Skip # Implementation in progress. NamedParameters2NegativeTest: Skip # Implementation in progress. NamedParameters3NegativeTest: Skip # Implementation in progress. @@ -91,13 +90,13 @@ RegExp3Test: Fail # 5299683 InterfaceFactory3NegativeTest: Fail # 5387405 GenericParameterizedExtendsTest: Skip # Bug 5392297 ConstObjectsAreImmutableTest: Fail # Bug 5202940 +SuperNegativeTest: Fail # Now that super calls are automatically injected this test doesn't make sense # Crashes in dartc. FunctionTypeAliasTest: Crash # Bug 4519208. # Other bugs (or unimplemented features) in dartc. GenericTest: Fail # Bug 5393302 (missing call to super constructor) -GenericInheritanceTest: Fail # Bug 4562150 (implicit constructors). Throw7NegativeTest: Fail # Bug 4208459. Throw3Test: Fail # Bug 4205624. SwitchLabelTest: Fail # Bug 4208467. @@ -108,7 +107,6 @@ PseudoKWNegativeTest: Fail # Bug 4979760. OverriddenNoSuchMethodTest: Fail # Bug 4202974. ManyOverriddenNoSuchMethodTest: Fail # Bug 4202974. NoSuchMethodTest: Fail # Bug 4202974. -BadNamedParametersTest: Fail # Bug 4202974. NumbersTest: Fail # Fails because numbers are mapped to doubles. LocalFunctionTest: Fail # Bug in test. Bug 4202989 (shadowing). LocalFunction3Test: Fail # Bug 4202974. @@ -131,7 +129,6 @@ OverrideFieldMethod3NegativeTest: Fail # Bug 5215249 OverrideFieldMethod4NegativeTest: Fail # Bug 5215249 OverrideFieldMethod5NegativeTest: Fail # Bug 5215249 OverrideFieldMethod6NegativeTest: Fail # Bug 5215249 -DeoptimizationTest: Fail # Bug 4254120 CharEscapeTest: Fail FunctionTypeParameter2NegativeTest: Fail # Bug 4568007