Another case of creating from factory constructors was not taken into account in r6619

http://code.google.com/p/dart/issues/detail?id=2282

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

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@6636 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
zundel@google.com 2012-04-17 13:36:14 +00:00
parent ddd7475724
commit 9965d546ab
2 changed files with 47 additions and 15 deletions

View file

@ -1218,17 +1218,19 @@ public class TypeAnalyzer implements DartCompilationPhase {
} else {
ClassElement cls = (ClassElement) constructorElement.getEnclosingElement();
// Add warning for instantiating abstract class.
if (cls.isAbstract() && !constructorElement.getModifiers().isFactory()) {
typeError(typeName, TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, cls.getName());
} else {
List<Element> unimplementedMembers = findUnimplementedMembers(cls);
if (unimplementedMembers.size() > 0) {
StringBuilder sb = getUnimplementedMembersMessage(cls, unimplementedMembers);
typeError(
typeName,
TypeErrorCode.INSTANTIATION_OF_CLASS_WITH_UNIMPLEMENTED_MEMBERS,
cls.getName(),
sb);
if (!constructorElement.getModifiers().isFactory()) {
if (cls.isAbstract()) {
typeError(typeName, TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, cls.getName());
} else {
List<Element> unimplementedMembers = findUnimplementedMembers(cls);
if (unimplementedMembers.size() > 0) {
StringBuilder sb = getUnimplementedMembersMessage(cls, unimplementedMembers);
typeError(
typeName,
TypeErrorCode.INSTANTIATION_OF_CLASS_WITH_UNIMPLEMENTED_MEMBERS,
cls.getName(),
sb);
}
}
}
// Check type arguments.

View file

@ -416,8 +416,9 @@ public class TypeAnalyzerCompilerTest extends CompilerTestCase {
}
/**
* Factory constructor can instantiate any class and return it non-abstract class instance, but
* spec requires warnings, so we provide it, but using different constant.
* Factory constructor can instantiate any class and return it non-abstract class instance, Even
* thought this is an abstract class, there should be no warnings for the invocation of the
* factory constructor.
*/
public void test_abstractClass_whenInstantiate_factoryConstructor()
throws Exception {
@ -425,20 +426,49 @@ public class TypeAnalyzerCompilerTest extends CompilerTestCase {
analyzeLibrary(
getName(),
makeCode(
"abstract class A {",
"abstract class A {", // explicitly abstract
" factory A() {",
" return null;",
" }",
"}",
"class C {",
" foo() {",
" return new A();",
" return new A();", // no error - factory constructor
" }",
"}"));
assertErrors(
libraryResult.getTypeErrors());
}
/**
* Factory constructor can instantiate any class and return it non-abstract class instance, Even
* thought this is an abstract class, there should be no warnings for the invocation of the
* factory constructor.
*/
public void test_abstractClass_whenInstantiate_factoryConstructor2()
throws Exception {
AnalyzeLibraryResult libraryResult =
analyzeLibrary(
getName(),
makeCode(
"class A extends B {", // class doesn't implement all abstract methods
" factory A() {",
" return null;",
" }",
"}",
"class B {",
" abstract method();",
"}",
"class C {",
" foo() {",
" return new A();", // no error, factory constructor
" }",
"}"));
assertErrors(
libraryResult.getTypeErrors(),
errEx(TypeErrorCode.ABSTRACT_CLASS_WITHOUT_ABSTRACT_MODIFIER, 1, 7, 1));
}
/**
* Spec 7.3 It is a static warning if a setter declares a return type other than void.
*/