This is an automated email from the ASF dual-hosted git repository.
joshtynjala pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
The following commit(s) were added to refs/heads/develop by this push:
new 4a9426316 compiler: abstract getters/setters
4a9426316 is described below
commit 4a942631604a3adab7feafe825d3910a4589c7e5
Author: Josh Tynjala <[email protected]>
AuthorDate: Thu Mar 28 13:53:15 2024 -0700
compiler: abstract getters/setters
---
RELEASE_NOTES.md | 1 +
.../js/royale/TestRoyaleAccessorMembers.java | 48 +-
.../as/codegen/ClassDirectiveProcessor.java | 10 +
.../internal/definitions/ClassDefinition.java | 10 +-
.../semantics/MethodBodySemanticChecker.java | 15 +
.../compiler/internal/semantics/SemanticUtils.java | 3 +-
.../problems/AbstractAndOverrideProblem.java | 40 +
.../src/test/java/as/ASAbstractClassTests.java | 1319 +++++++++++++++++---
8 files changed, 1257 insertions(+), 189 deletions(-)
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 0b3311731..db78f46f5 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -4,6 +4,7 @@ Apache Royale Compiler 0.9.11
=============================
- compiler: Added new `--infer-types` compiler option that allows the compiler
to automatically detect an appropriate type for both variables and function
signatures that have omitted their declared types. Type inference is based on
either the initializer or return values.
+- compiler: Abstract classes now support abstract getter and setter methods.
- compiler: Improved type checking for `&&` and `||` binary operators and `?:`
ternary operator.
- compiler: Removed obsolete "AMD" and "Goog" JavaScript backends, and
finished some refactoring to make codebase easier to maintain.
- compiler: Now requires Java 11 or newer to run. Previously required Java 8
minimum.
diff --git
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessorMembers.java
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessorMembers.java
index 6701e08a3..afd58c396 100644
---
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessorMembers.java
+++
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessorMembers.java
@@ -46,7 +46,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testGetAccessor_withBody()
{
- IClassNode node = (IClassNode) getNode("function get foo():int{return
-1;}",
+ IClassNode node = (IClassNode) getNode("function get foo():int{return
-1;}",
IClassNode.class, WRAP_LEVEL_CLASS);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function()
{\n};\n\n\n" +
@@ -59,7 +59,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testGetAccessor_withNamespace()
{
- IClassNode node = (IClassNode) getNode("public function get
foo():int{return -1;}",
+ IClassNode node = (IClassNode) getNode("public function get
foo():int{return -1;}",
IClassNode.class, WRAP_LEVEL_CLASS);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function()
{\n};\n\n\n" +
@@ -72,7 +72,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testGetAccessor_withNamespaceOverride()
{
- IClassNode node = (IClassNode) getNode("public class B extends A {
public override function get foo():int{return super.foo;} }; public class A
{public function get foo():int {return 0;}} ",
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public override function get foo():int{return super.foo;} }; public class A
{public function get foo():int {return 0;}} ",
IClassNode.class, WRAP_LEVEL_PACKAGE);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n};\ngoog.inherits(B, A);\n\n\n" +
@@ -83,7 +83,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testGetAccessor_withGeneratedSetOverride()
{
- IClassNode node = (IClassNode) getNode("public class B extends A {
public override function get foo():int{return super.foo;} }; public class A {
public function set foo(value:int):void{} public function get foo():int {return
0;}}",
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public override function get foo():int{return super.foo;} }; public class A {
public function set foo(value:int):void{} public function get foo():int {return
0;}}",
IClassNode.class, WRAP_LEVEL_PACKAGE);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n};\ngoog.inherits(B, A);\n\n\n" +
@@ -95,7 +95,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testGetAccessor_withStatic()
{
- IClassNode node = (IClassNode) getNode("public static function get
foo():int{return -1;}",
+ IClassNode node = (IClassNode) getNode("public static function get
foo():int{return -1;}",
IClassNode.class, WRAP_LEVEL_CLASS);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function()
{\n};\n\n\n" +
@@ -121,7 +121,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testGetAccessor_withNamespace_withoutReturnType()
{
- IClassNode node = (IClassNode) getNode("public function get
foo(){return -1;}",
+ IClassNode node = (IClassNode) getNode("public function get
foo(){return -1;}",
IClassNode.class, WRAP_LEVEL_CLASS);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function()
{\n};\n\n\n" +
@@ -134,7 +134,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testSetAccessor()
{
- IClassNode node = (IClassNode) getNode("function set
foo(value:int):void{}",
+ IClassNode node = (IClassNode) getNode("function set
foo(value:int):void{}",
IClassNode.class, WRAP_LEVEL_CLASS);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function()
{\n};\n\n\n" +
@@ -146,7 +146,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testSetAccessor_withBody()
{
- IClassNode node = (IClassNode) getNode("function set
foo(value:int):void{fetch('haai');}",
+ IClassNode node = (IClassNode) getNode("function set
foo(value:int):void{fetch('haai');}",
IClassNode.class, WRAP_LEVEL_CLASS);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function()
{\n};\n\n\n" +
@@ -159,7 +159,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testSetAccessor_withNamespace()
{
- IClassNode node = (IClassNode) getNode("public function set
foo(value:int):void{}",
+ IClassNode node = (IClassNode) getNode("public function set
foo(value:int):void{}",
IClassNode.class, WRAP_LEVEL_CLASS);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function()
{\n};\n\n\n" +
@@ -172,7 +172,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testSetAccessor_withNamespaceOverride()
{
- IClassNode node = (IClassNode) getNode("public class B extends A {
public override function set foo(value:int):void {super.foo = value;} }; public
class A { public function set foo(value:int):void{}}",
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public override function set foo(value:int):void {super.foo = value;} }; public
class A { public function set foo(value:int):void{}}",
IClassNode.class, WRAP_LEVEL_PACKAGE);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n};\ngoog.inherits(B, A);\n\n\n" +
@@ -184,7 +184,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testSetAccessor_withStatic()
{
- IClassNode node = (IClassNode) getNode("public static function set
foo(value:int):void{}",
+ IClassNode node = (IClassNode) getNode("public static function set
foo(value:int):void{}",
IClassNode.class, WRAP_LEVEL_CLASS);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function()
{\n};\n\n\n" +
@@ -196,7 +196,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testSetAccessor_withGeneratedGetOverride()
{
- IClassNode node = (IClassNode) getNode("public class B extends A {
public override function set foo(value:int):void {super.foo = value;} }; public
class A { public function set foo(value:int):void{} public function get
foo():int { return 0;}}",
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public override function set foo(value:int):void {super.foo = value;} }; public
class A { public function set foo(value:int):void{} public function get
foo():int { return 0;}}",
IClassNode.class, WRAP_LEVEL_PACKAGE);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n};\ngoog.inherits(B, A);\n\n\n" +
@@ -207,7 +207,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testSetAccessorWithSuperSet()
{
- IClassNode node = (IClassNode) getNode("public class B extends A {
public override function set foo(value:int):void {super.foo = value;} }; public
class A { public function set foo(value:int):void{} public function get
foo():int { return 0;}}",
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public override function set foo(value:int):void {super.foo = value;} }; public
class A { public function set foo(value:int):void{} public function get
foo():int { return 0;}}",
IClassNode.class, WRAP_LEVEL_PACKAGE);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n};\ngoog.inherits(B, A);\n\n\n" +
@@ -218,7 +218,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testSetAccessorWithSuperSetAndPropagatedValue()
{
- IClassNode node = (IClassNode) getNode("public class B extends A {
public override function set foo(value:int):void {var z:int = super.foo =
value;} }; public class A { public function set foo(value:int):void{} public
function get foo():int { return 0;}}",
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public override function set foo(value:int):void {var z:int = super.foo =
value;} }; public class A { public function set foo(value:int):void{} public
function get foo():int { return 0;}}",
IClassNode.class, WRAP_LEVEL_PACKAGE);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n};\ngoog.inherits(B, A);\n\n\n" +
@@ -230,7 +230,7 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
@Test
public void testSetAccessor_withoutParameterType()
{
- IClassNode node = (IClassNode) getNode("function set foo(value):void{}",
+ IClassNode node = (IClassNode) getNode("function set
foo(value):void{}",
IClassNode.class, WRAP_LEVEL_CLASS);
asBlockWalker.visitClass(node);
assertOut("/**\n * @constructor\n */\nRoyaleTest_A = function()
{\n};\n\n\n" +
@@ -238,6 +238,24 @@ public class TestRoyaleAccessorMembers extends
TestAccessorMembers
"RoyaleTest_A.prototype.set__foo =
function(value) {\n};\n\n\n" +
"Object.defineProperties(RoyaleTest_A.prototype, /**
@lends {RoyaleTest_A.prototype} */ {\n/**\n * @type {*}\n */\nfoo: {\nset:
RoyaleTest_A.prototype.set__foo}}\n);");
}
+
+ @Test
+ public void testGetAccessorWithAbstract()
+ {
+ IClassNode node = (IClassNode) getNode("public abstract class A {
public abstract function get foo():int; }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n};\n\n\n/**\n
* @nocollapse\n * @export\n * @type {number}\n
*/\nA.prototype.foo;\n\n\nA.prototype.get__foo = function()
{\n};\n\n\nObject.defineProperties(A.prototype, /** @lends {A.prototype} */
{\n/**\n * @type {number}\n */\nfoo: {\nget: A.prototype.get__foo}}\n);");
+ }
+
+ @Test
+ public void testSetAccessorWithAbstract()
+ {
+ IClassNode node = (IClassNode) getNode("public abstract class A {
public abstract function set foo(value:int):void; }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n};\n\n\n/**\n
* @nocollapse\n * @export\n * @type {number}\n
*/\nA.prototype.foo;\n\n\nA.prototype.set__foo = function(value)
{\n};\n\n\nObject.defineProperties(A.prototype, /** @lends {A.prototype} */
{\n/**\n * @type {number}\n */\nfoo: {\nset: A.prototype.set__foo}}\n);");
+ }
@Override
protected IBackend createBackend()
diff --git
a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ClassDirectiveProcessor.java
b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ClassDirectiveProcessor.java
index 281a97393..3512f0734 100644
---
a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ClassDirectiveProcessor.java
+++
b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/ClassDirectiveProcessor.java
@@ -1216,6 +1216,16 @@ class ClassDirectiveProcessor extends DirectiveProcessor
{
classScope.addProblem(new
AbstractOutsideClassProblem(site) );
}
+ else
+ {
+ if (modifiersSet != null)
+ {
+ if( modifiersSet.hasModifier(ASModifier.OVERRIDE) )
+ {
+ classScope.addProblem(new
AbstractAndOverrideProblem(site) );
+ }
+ }
+ }
}
else
{
diff --git
a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinition.java
b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinition.java
index 1b07a5592..a103ee132 100644
---
a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinition.java
+++
b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinition.java
@@ -1504,7 +1504,7 @@ public class ClassDefinition extends ClassDefinitionBase
implements IClassDefini
for (int i = 0, l = defSet.getSize(); i < l; ++i)
{
IDefinition def = defSet.getDefinition(i);
- if (def instanceof FunctionDefinition && !(def instanceof
IAccessorDefinition))
+ if (def instanceof FunctionDefinition)
{
FunctionDefinition abstractMethod =
(FunctionDefinition)def;
@@ -1534,8 +1534,14 @@ public class ClassDefinition extends ClassDefinitionBase
implements IClassDefini
if (c == null || c.isAbstract())
{
// Error, didn't implement the method
+ String methodName = abstractMethod.getBaseName();
+ if (abstractMethod instanceof IGetterDefinition) {
+ methodName = "get " + methodName;
+ } else if (abstractMethod instanceof
ISetterDefinition) {
+ methodName = "set " + methodName;
+ }
problems.add(new
UnimplementedAbstractMethodProblem(cls,
- abstractMethod.getBaseName(),
+ methodName,
this.getBaseName(),
cls.getBaseName()));
}
diff --git
a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
index 7ce307905..d0a0801e1 100644
---
a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
+++
b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/MethodBodySemanticChecker.java
@@ -2187,6 +2187,21 @@ public class MethodBodySemanticChecker
}
// For super.f(...), check whether f is deprecated.
+ if (iNode instanceof IMemberAccessExpressionNode)
+ {
+ IMemberAccessExpressionNode mae =
(IMemberAccessExpressionNode)iNode;
+ IExpressionNode rightNode = mae.getRightOperandNode();
+ IDefinition rightDef = rightNode.resolve(project);
+ if (rightDef instanceof IAccessorDefinition)
+ {
+ if (rightDef.isAbstract())
+ {
+ addProblem(new AccessUndefinedPropertyProblem(
+ iNode, rightDef.getBaseName()
+ ));
+ }
+ }
+ }
if (iNode instanceof IFunctionCallNode)
{
IExpressionNode nameNode =
((IFunctionCallNode)iNode).getNameNode();
diff --git
a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
index 678c047a9..23d3a6bfc 100644
---
a/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
+++
b/compiler/src/main/java/org/apache/royale/compiler/internal/semantics/SemanticUtils.java
@@ -3237,8 +3237,7 @@ public class SemanticUtils
return parentDef.isAbstract()
&& !funcDef.isStatic()
&& !funcDef.isFinal()
- && !funcDef.isConstructor()
- && !(funcDef instanceof IAccessorDefinition);
+ && !funcDef.isConstructor();
}
return false;
}
diff --git
a/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractAndOverrideProblem.java
b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractAndOverrideProblem.java
new file mode 100644
index 000000000..4e8f2e558
--- /dev/null
+++
b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractAndOverrideProblem.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.royale.compiler.problems;
+
+import org.apache.royale.compiler.tree.as.IASNode;
+
+/**
+ * Diagnostic emitted when a function is declared "abstract" and "override"
+ */
+public final class AbstractAndOverrideProblem extends CodegenProblem
+{
+ public static final String DESCRIPTION =
+ "Functions cannot be both ${ABSTRACT} and ${OVERRIDE}.";
+
+ public AbstractAndOverrideProblem(IASNode site)
+ {
+ super(site);
+ }
+
+ // Prevent these from being localized.
+ public final String ABSTRACT = "abstract";
+ public final String OVERRIDE = "override";
+}
diff --git a/compiler/src/test/java/as/ASAbstractClassTests.java
b/compiler/src/test/java/as/ASAbstractClassTests.java
index d98c12242..34fb2fbf9 100644
--- a/compiler/src/test/java/as/ASAbstractClassTests.java
+++ b/compiler/src/test/java/as/ASAbstractClassTests.java
@@ -136,8 +136,8 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\n");
}
- @Test
- public void
testAbstractNotAllowedOnStaticMethodError_withAllowAbstractClassesDisabled()
+ @Test
+ public void
testAbstractNotAllowedOnInterfaceStaticMethodError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -150,9 +150,9 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
};
String[] extra = new String[]
{
- "class A {",
+ "interface A {",
//error because abstract classes have
not been enabled
- "public static abstract function
a():void",
+ "static abstract function a():void",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -161,11 +161,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=false"
};
- compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nFunction does not have a body.\n");
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nThe static attribute may be used only on definitions
inside a class.\n");
}
@Test
- public void
testAbstractNotAllowedOnGetterError_withAllowAbstractClassesDisabled()
+ public void
testAbstractNotAllowedOnStaticMethodError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -180,7 +180,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
{
"class A {",
//error because abstract classes have
not been enabled
- "public abstract function get
a():Object;",
+ "public static abstract function
a():void",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -189,11 +189,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=false"
};
- compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nFunction does not have a body.\nFunction does not return a
value.\n");
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nFunction does not have a body.\n");
}
@Test
- public void
testAbstractNotAllowedOnSetterError_withAllowAbstractClassesDisabled()
+ public void
testAbstractNotAllowedOnGetterError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -208,7 +208,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
{
"class A {",
//error because abstract classes have
not been enabled
- "public abstract function set
a(value:Object):void;",
+ "public abstract function get
a():String;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -217,11 +217,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=false"
};
- compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nFunction does not have a body.\n");
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nFunction does not have a body.\nFunction does not return a
value.\n");
}
@Test
- public void
testAbstractNotAllowedOnVariableError_withAllowAbstractClassesDisabled()
+ public void
testAbstractNotAllowedOnSetterError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -236,7 +236,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
{
"class A {",
//error because abstract classes have
not been enabled
- "public abstract var a:Object;",
+ "public abstract function set
a(value:String):void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -245,11 +245,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=false"
};
- compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\n");
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nFunction does not have a body.\n");
}
@Test
- public void
testAbstractNotAllowedOnStaticVariableError_withAllowAbstractClassesDisabled()
+ public void
testAbstractNotAllowedOnStaticGetterError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -264,7 +264,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
{
"class A {",
//error because abstract classes have
not been enabled
- "public static abstract var a:Object;",
+ "public static abstract function get
a():String;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -273,11 +273,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=false"
};
- compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\n");
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nFunction does not have a body.\nFunction does not return a
value.\n");
}
- @Test
- public void
testAbstractNotAllowedOnInterfaceGetterError_withAllowAbstractClassesDisabled()
+ @Test
+ public void
testAbstractNotAllowedOnStaticSetterError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -290,9 +290,9 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
};
String[] extra = new String[]
{
- "interface A {",
+ "class A {",
//error because abstract classes have
not been enabled
- "abstract function get a():Object;",
+ "public static abstract function set
a(value:String):void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -301,11 +301,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=false"
};
- compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\n");
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nFunction does not have a body.\n");
}
- @Test
- public void
testAbstractNotAllowedOnInterfaceSetterError_withAllowAbstractClassesDisabled()
+ @Test
+ public void
testAbstractNotAllowedOnVariableError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -318,9 +318,9 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
};
String[] extra = new String[]
{
- "interface A {",
+ "class A {",
//error because abstract classes have
not been enabled
- "abstract function set
a(value:Object):void;",
+ "public abstract var a:Object;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -333,7 +333,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
}
@Test
- public void testAbstractClassNoErrors_withAllowAbstractClassesEnabled()
+ public void
testAbstractNotAllowedOnStaticVariableError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -346,22 +346,22 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
+ "class A {",
+ //error because abstract classes have
not been enabled
+ "public static abstract var a:Object;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
String[] options = new String[]
{
- "-allow-abstract-classes=true"
+ "-allow-abstract-classes=false"
};
- File tempASFile = generateTempFile(source);
- String result = compile(tempASFile, source, false,false,false,
options, true);
- Assert.assertEquals("", result);
- }
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\n");
+ }
- @Test
- public void
testAbstractMethodOnClassNoErrors_withAllowAbstractClassesEnabled()
+ @Test
+ public void
testAbstractNotAllowedOnInterfaceGetterError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -374,23 +374,22 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- "public abstract function a():void;",
+ "interface A {",
+ //error because abstract classes have
not been enabled
+ "abstract function get a():String;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
String[] options = new String[]
{
- "-allow-abstract-classes=true"
+ "-allow-abstract-classes=false"
};
- File tempASFile = generateTempFile(source);
- String result = compile(tempASFile, source, false,false,false,
options, true);
- Assert.assertEquals("", result);
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\n");
}
- @Test
- public void
testAbstractMethodWithParametersAndReturnOnClassNoErrors_withAllowAbstractClassesEnabled()
+ @Test
+ public void
testAbstractNotAllowedOnInterfaceSetterError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -403,23 +402,22 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- "public abstract function
a(arg0:String, arg1:Number):Boolean;",
+ "interface A {",
+ //error because abstract classes have
not been enabled
+ "abstract function set
a(value:String):void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
String[] options = new String[]
{
- "-allow-abstract-classes=true"
+ "-allow-abstract-classes=false"
};
- File tempASFile = generateTempFile(source);
- String result = compile(tempASFile, source, false,false,false,
options, true);
- Assert.assertEquals("", result);
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\n");
}
- @Test
- public void
testAbstractMethodOnInterfaceError_withAllowAbstractClassesEnabled()
+ @Test
+ public void
testAbstractNotAllowedOnInterfaceStaticGetterError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -433,20 +431,21 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
String[] extra = new String[]
{
"interface A {",
- "abstract function a():void;",
+ //error because abstract classes have
not been enabled
+ "static abstract function get
a():String;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
String[] options = new String[]
{
- "-allow-abstract-classes=true"
+ "-allow-abstract-classes=false"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nThe static attribute may be used only on definitions
inside a class.\n");
}
- @Test
- public void
testAbstractGetterOnInterfaceError_withAllowAbstractClassesEnabled()
+ @Test
+ public void
testAbstractNotAllowedOnInterfaceStaticSetterError_withAllowAbstractClassesDisabled()
{
String[] imports = new String[]
{
@@ -460,20 +459,21 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
String[] extra = new String[]
{
"interface A {",
- "abstract function get a():Object;",
+ //error because abstract classes have
not been enabled
+ "static abstract function set
a(value:String):void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
String[] options = new String[]
{
- "-allow-abstract-classes=true"
+ "-allow-abstract-classes=false"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
+ compileAndExpectErrors(source, false,false,false, options,"'abstract'
is not allowed here\nThe static attribute may be used only on definitions
inside a class.\n");
}
@Test
- public void
testAbstractSetterOnInterfaceError_withAllowAbstractClassesEnabled()
+ public void testAbstractClassNoErrors_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -486,8 +486,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
};
String[] extra = new String[]
{
- "interface A {",
- "abstract function set
a(value:Object):void;",
+ "abstract class A {",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -496,11 +495,13 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
- }
+ File tempASFile = generateTempFile(source);
+ String result = compile(tempASFile, source, false,false,false,
options, true);
+ Assert.assertEquals("", result);
+ }
@Test
- public void
testAbstractProtectedMethodNoErrors_withAllowAbstractClassesEnabled()
+ public void
testAbstractMethodOnClassNoErrors_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -514,7 +515,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
String[] extra = new String[]
{
"abstract class A {",
- "protected abstract function a():void;",
+ "public abstract function a():void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -529,7 +530,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
}
@Test
- public void
testAbstractInternalMethodNoErrors_withAllowAbstractClassesEnabled()
+ public void
testAbstractMethodWithParametersAndReturnOnClassNoErrors_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -543,7 +544,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
String[] extra = new String[]
{
"abstract class A {",
- "internal abstract function a():void;",
+ "public abstract function
a(arg0:String, arg1:Number):Boolean;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -558,7 +559,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
}
@Test
- public void
testAbstractPrivateMethodError_withAllowAbstractClassesEnabled()
+ public void
testAbstractMethodOnInterfaceError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -571,8 +572,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- "private abstract function a():void;",
+ "interface A {",
+ //error because an abstract method may
only be defined on an
+ //abstract class (not an interface)
+ "abstract function a():void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -581,11 +584,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options, "Methods
that are abstract cannot be declared private.\n");
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
}
@Test
- public void testAbstractFinalClassError_withAllowAbstractClassesEnabled()
+ public void
testAbstractGetterOnInterfaceError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -598,7 +601,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract final class A {",
+ "interface A {",
+ //error because an abstract method may
only be defined on an
+ //abstract class (not an interface)
+ "abstract function get a():String;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -611,7 +617,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
}
@Test
- public void testAbstractFinalMethodError_withAllowAbstractClassesEnabled()
+ public void
testAbstractSetterOnInterfaceError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -624,8 +630,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- "public final abstract function
a():void;",
+ "interface A {",
+ //error because an abstract method may
only be defined on an
+ //abstract class (not an interface)
+ "abstract function set
a(value:String):void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -634,11 +642,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
}
@Test
- public void
testAbstractMethodNotInAbstractClassError_withAllowAbstractClassesEnabled()
+ public void
testAbstractStaticMethodOnInterfaceError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -651,10 +659,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "class A {",
+ "interface A {",
//error because an abstract method may
only be defined on an
- //abstract class
- "public abstract function a():void;",
+ //abstract class (not an interface)
+ "static abstract function a():void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -663,11 +671,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
+ compileAndExpectErrors(source, false,false,false, options, "The static
attribute may be used only on definitions inside a class.\nThe abstract
attribute can only be used on a class definition or a non-static, non-final
method defined on an abstract class.\n");
}
@Test
- public void testAbstractStaticMethodError_withAllowAbstractClassesEnabled()
+ public void
testAbstractStaticGetterOnInterfaceError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -680,9 +688,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- //error because a static function
cannot be abstract
- "public static abstract function
a():void;",
+ "interface A {",
+ //error because an abstract method may
only be defined on an
+ //abstract class (not an interface)
+ "static abstract function get
a():String;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -691,11 +700,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
+ compileAndExpectErrors(source, false,false,false, options, "The static
attribute may be used only on definitions inside a class.\nThe abstract
attribute can only be used on a class definition or a non-static, non-final
method defined on an abstract class.\n");
}
@Test
- public void testAbstractGetterError_withAllowAbstractClassesEnabled()
+ public void
testAbstractStaticSetterOnInterfaceError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -708,9 +717,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- //error because a getter cannot be
abstract
- "public abstract function get
a():Object;",
+ "interface A {",
+ //error because an abstract method may
only be defined on an
+ //abstract class (not an interface)
+ "static abstract function set
a(value:String):void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -719,11 +729,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\nFunction does not return a value.\n");
+ compileAndExpectErrors(source, false,false,false, options, "The static
attribute may be used only on definitions inside a class.\nThe abstract
attribute can only be used on a class definition or a non-static, non-final
method defined on an abstract class.\n");
}
@Test
- public void testAbstractSetterError_withAllowAbstractClassesEnabled()
+ public void
testAbstractProtectedMethodNoErrors_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -737,8 +747,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
String[] extra = new String[]
{
"abstract class A {",
- //error because a setter cannot be
abstract
- "public abstract function set
a(value:Object):void;",
+ "protected abstract function a():void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -747,11 +756,13 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
+ File tempASFile = generateTempFile(source);
+ String result = compile(tempASFile, source, false,false,false,
options, true);
+ Assert.assertEquals("", result);
}
@Test
- public void testAbstractVariableError_withAllowAbstractClassesEnabled()
+ public void
testAbstractInternalMethodNoErrors_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -765,8 +776,7 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
String[] extra = new String[]
{
"abstract class A {",
- //error because a variable cannot be
abstract
- "public abstract var a:Object;",
+ "internal abstract function a():void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -775,11 +785,13 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
+ File tempASFile = generateTempFile(source);
+ String result = compile(tempASFile, source, false,false,false,
options, true);
+ Assert.assertEquals("", result);
}
@Test
- public void
testAbstractStaticVariableError_withAllowAbstractClassesEnabled()
+ public void
testAbstractPrivateMethodError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -793,8 +805,8 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
String[] extra = new String[]
{
"abstract class A {",
- //error because a static variable
cannot be abstract
- "public static abstract var a:Object;",
+ //error because an abstract method
cannot be private
+ "private abstract function a():void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -803,11 +815,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
+ compileAndExpectErrors(source, false,false,false, options, "Methods
that are abstract cannot be declared private.\n");
}
@Test
- public void testAbstractMethodBodyError_withAllowAbstractClassesEnabled()
+ public void testAbstractFinalClassError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -820,9 +832,8 @@ public class ASAbstractClassTests extends ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- //error because an abstract method has
a body
- "public abstract function a():void {}",
+ //error because an abstract class cannot be final
+ "abstract final class A {",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -831,11 +842,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options,
"Method marked abstract must not have a body.\n");
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
}
@Test
- public void
testAbstractClassNewOperatorError_withAllowAbstractClassesEnabled()
+ public void testAbstractFinalMethodError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -845,13 +856,12 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] testCode = new String[]
{
- //error because the class is abstract
and cannot be
- //instantiated with new
- "var obj:A = new A();",
};
String[] extra = new String[]
{
"abstract class A {",
+ //error because an abstract method
cannot be final
+ "public final abstract function
a():void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -860,11 +870,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options,
"Abstract classes cannot be instantiated with the new operator.\n");
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
}
@Test
- public void
testConcreteClassExtendsAbstractNewOperatorNoErrors_withAllowAbstractClassesEnabled()
+ public void
testAbstractMethodNotInAbstractClassError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -874,13 +884,13 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] testCode = new String[]
{
- "var obj:A = new B();",
};
String[] extra = new String[]
{
- "abstract class A {",
- "}",
- "class B extends A {",
+ "class A {",
+ //error because an abstract method may
only be defined on an
+ //abstract class
+ "public abstract function a():void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -889,13 +899,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- File tempASFile = generateTempFile(source);
- String result = compile(tempASFile, source, false,false,false,
options, true);
- Assert.assertEquals("", result);
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
}
@Test
- public void testAbstractClassSuperError_withAllowAbstractClassesEnabled()
+ public void
testAbstractStaticMethodNotInAbstractClassError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -908,14 +916,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- "public abstract function a():void;",
- "}",
- "class B extends A {",
- "override public function a():void {",
- //error because the the super method is
abstract
- "super.a();",
- "};",
+ "class A {",
+ //error because an abstract method may
only be defined on an
+ //abstract class
+ "public static abstract function
a():void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -924,11 +928,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options,
"Call to a possibly undefined method a.\n");
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
}
@Test
- public void
testAbstractClassNotImplementedError_withAllowAbstractClassesEnabled()
+ public void
testAbstractGetterNotInAbstractClassError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -941,12 +945,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- "public abstract function a():void;",
- "}",
- "class B extends A {",
- //error because we did not implement
the abstract method in
- //a concrete subclass
+ "class A {",
+ //error because an abstract getter may
only be defined on an
+ //abstract class
+ "public abstract function get
a():String;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -955,11 +957,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options,
"Method a in abstract class A not implemented by class B\n");
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\nFunction does not return a value.\n");
}
@Test
- public void
testAbstractClassNotImplementedErrorOneTimeForTwoConcreteSubclasses_withAllowAbstractClassesEnabled()
+ public void
testAbstractSetterNotInAbstractClassError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -972,15 +974,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- "public abstract function a():void;",
- "}",
- "class B extends A {",
- //error because we did not implement
the abstract method in
- //a concrete subclass
- "}",
- "class C extends B {",
- //no duplicate error here!
+ "class A {",
+ //error because an abstract setter may
only be defined on an
+ //abstract class
+ "public abstract function set
a(value:String):void;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -989,11 +986,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options,
"Method a in abstract class A not implemented by class B\n");
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
}
@Test
- public void
testAbstractClassMissingOverrideError_withAllowAbstractClassesEnabled()
+ public void
testAbstractStaticGetterNotInAbstractClassError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -1006,12 +1003,10 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- "public abstract function a():void;",
- "}",
- "class B extends A {",
- //error because we did not use the
override keyword
- "public function a():void {}",
+ "class A {",
+ //error because an abstract getter may
only be defined on an
+ //abstract class
+ "public static abstract function get
a():String;",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -1020,11 +1015,11 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"-allow-abstract-classes=true"
};
- compileAndExpectErrors(source, false,false,false, options,
"Overriding a function that is not marked for override\n");
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\nFunction does not return a value.\n");
}
@Test
- public void
testAbstractClassExtendsAbstractWithoutImplementingNoError_withAllowAbstractClassesEnabled()
+ public void
testAbstractStaticSetterNotInAbstractClassError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -1037,11 +1032,734 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
};
String[] extra = new String[]
{
- "abstract class A {",
- "public abstract function a():void;",
- "}",
- "abstract class B extends A {",
- //we don't want an error for
unimplemented methods because
+ "class A {",
+ //error because an abstract setter may
only be defined on an
+ //abstract class
+ "public static abstract function set
a(value:String):void;",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
+ }
+
+ @Test
+ public void testAbstractStaticMethodError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ //error because a static method cannot
be abstract
+ "public static abstract function
a():void;",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
+ }
+
+ @Test
+ public void testAbstractGetterNoError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function get
a():String;",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ File tempASFile = generateTempFile(source);
+ String result = compile(tempASFile, source, false,false,false,
options, true);
+ Assert.assertEquals("", result);
+ }
+
+ @Test
+ public void testAbstractStaticGetterError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ //error because a static getter cannot
be abstract
+ "public static abstract function get
a():String;",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\nFunction does not return a value.\n");
+ }
+
+ @Test
+ public void testAbstractSetterNoError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function set
a(value:String):void;",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ File tempASFile = generateTempFile(source);
+ String result = compile(tempASFile, source, false,false,false,
options, true);
+ Assert.assertEquals("", result);
+ }
+
+ @Test
+ public void testAbstractStaticSetterError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ //error because a static setter cannot
be abstract
+ "public static abstract function set
a(value:String):void;",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\nFunction does not have a
body.\n");
+ }
+
+ @Test
+ public void testAbstractVariableError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ //error because a variable cannot be
abstract
+ "public abstract var a:Object;",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
+ }
+
+ @Test
+ public void
testAbstractStaticVariableError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ //error because a static variable
cannot be abstract
+ "public static abstract var a:Object;",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
+ }
+
+ @Test
+ public void testAbstractMethodBodyError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ //error because an abstract method has
a body
+ "public abstract function a():void {}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Method marked abstract must not have a body.\n");
+ }
+
+ @Test
+ public void testAbstractGetterBodyError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ //error because an abstract getter has
a body
+ "public abstract function get
a():String {}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Method marked abstract must not have a body.\n");
+ }
+
+ @Test
+ public void testAbstractSetterBodyError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ //error because an abstract getter has
a body
+ "public abstract function set
a(value:String):void {}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Method marked abstract must not have a body.\n");
+ }
+
+ @Test
+ public void
testAbstractClassNewOperatorError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ //error because the class is abstract
and cannot be
+ //instantiated with new
+ "var obj:A = new A();",
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Abstract classes cannot be instantiated with the new operator.\n");
+ }
+
+ @Test
+ public void
testConcreteClassExtendsAbstractNewOperatorNoErrors_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ "var obj:A = new B();",
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "}",
+ "class B extends A {",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ File tempASFile = generateTempFile(source);
+ String result = compile(tempASFile, source, false,false,false,
options, true);
+ Assert.assertEquals("", result);
+ }
+
+ @Test
+ public void
testAbstractClassSuperMethodError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function a():void;",
+ "}",
+ "class B extends A {",
+ "override public function a():void {",
+ //error because the super method is
abstract
+ "super.a();",
+ "}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Call to a possibly undefined method a.\n");
+ }
+
+ @Test
+ public void testAbstractMethodOverride_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function a():void;",
+ "}",
+ "abstract class B extends A {",
+ //error because the method already
exists and is already abstract
+ "override public abstract function
a():void;",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Functions cannot be both abstract and override.\n");
+ }
+
+ @Test
+ public void
testAbstractClassSuperGetterError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function get
a():String;",
+ "}",
+ "class B extends A {",
+ "override public function get
a():String {",
+ //error because the super getter is
abstract
+ "return super.a;",
+ "}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Access of possibly undefined property a.\n");
+ }
+
+ @Test
+ public void
testAbstractClassSuperSetterError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function set
a(value:String):void;",
+ "}",
+ "class B extends A {",
+ "override public function set
a(value:String):void {",
+ //error because the super setter is
abstract
+ "super.a = value;",
+ "}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Access of possibly undefined property a.\n");
+ }
+
+ @Test
+ public void
testAbstractClassMethodNotImplementedError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function a():void;",
+ "}",
+ "class B extends A {",
+ //error because we did not implement
the abstract method in
+ //a concrete subclass
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Method a in abstract class A not implemented by class B\n");
+ }
+
+ @Test
+ public void
testAbstractClassGetterNotImplementedError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function get
a():String;",
+ "}",
+ "class B extends A {",
+ //error because we did not implement
the abstract getter in
+ //a concrete subclass
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Method get a in abstract class A not implemented by class B\n");
+ }
+
+ @Test
+ public void
testAbstractClassSetterNotImplementedError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function set
a(value:String):void;",
+ "}",
+ "class B extends A {",
+ //error because we did not implement
the abstract setter in
+ //a concrete subclass
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Method set a in abstract class A not implemented by class B\n");
+ }
+
+ @Test
+ public void
testAbstractClassNotImplementedErrorOneTimeForTwoConcreteSubclasses_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function a():void;",
+ "}",
+ "class B extends A {",
+ //error because we did not implement
the abstract method in
+ //a concrete subclass
+ "}",
+ "class C extends B {",
+ //no duplicate error here!
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Method a in abstract class A not implemented by class B\n");
+ }
+
+ @Test
+ public void
testAbstractMethodMissingOverrideError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function a():void;",
+ "}",
+ "class B extends A {",
+ //error because we did not use the
override keyword
+ "public function a():void {}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Overriding a function that is not marked for override\n");
+ }
+
+ @Test
+ public void
testAbstractGetterMissingOverrideError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function get
a():String;",
+ "}",
+ "class B extends A {",
+ //error because we did not use the
override keyword
+ "public function get a():String {return
null;}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Overriding a function that is not marked for override\n");
+ }
+
+ @Test
+ public void
testAbstractSetterMissingOverrideError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function set
a(value:String):void;",
+ "}",
+ "class B extends A {",
+ //error because we did not use the
override keyword
+ "public function set
a(value:String):void {}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options,
"Overriding a function that is not marked for override\n");
+ }
+
+ @Test
+ public void
testAbstractClassExtendsAbstractWithoutImplementingNoError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function a():void;",
+ "public abstract function get
b():String;",
+ "public abstract function set
b(value:String):void;",
+ "}",
+ "abstract class B extends A {",
+ //we don't want an error for
unimplemented methods because
//this class is also abstract
"}"
};
@@ -1057,7 +1775,7 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
}
@Test
- public void
testConcreteClassExtendsAbstractExtendsAbstractNotImplementedError_withAllowAbstractClassesEnabled()
+ public void
testConcreteClassExtendsAbstractExtendsAbstractMethodNotImplementedError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -1091,7 +1809,75 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
}
@Test
- public void
testConcreteClassExtendsAbstractExtendsAbstractMultipleNotImplementedErrors_withAllowAbstractClassesEnabled()
+ public void
testConcreteClassExtendsAbstractExtendsAbstractGetterNotImplementedError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function get
a():String;",
+ "}",
+ "abstract class B extends A {",
+ //we don't want an error for
unimplemented methods because
+ //this class is also abstract
+ "}",
+ "class C extends B {",
+ //but we do want an error here for
unimplemented methods
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "Method get
a in abstract class A not implemented by class C\n");
+ }
+
+ @Test
+ public void
testConcreteClassExtendsAbstractExtendsAbstractSetterNotImplementedError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function set
a(value:String):void;",
+ "}",
+ "abstract class B extends A {",
+ //we don't want an error for
unimplemented methods because
+ //this class is also abstract
+ "}",
+ "class C extends B {",
+ //but we do want an error here for
unimplemented methods
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "Method set
a in abstract class A not implemented by class C\n");
+ }
+
+ @Test
+ public void
testConcreteClassExtendsAbstractExtendsAbstractMultipleMethodNotImplementedErrors_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -1111,7 +1897,7 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
"public abstract function b():void;",
"}",
"class C extends B {",
- //mulitple errors because more than one
method is not implemented
+ //multiple errors because more than one
method is not implemented
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -1124,7 +1910,73 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
}
@Test
- public void
testAbstractClassExtendsAbstractAndImplementsNoError_withAllowAbstractClassesEnabled()
+ public void
testConcreteClassExtendsAbstractExtendsAbstractMultipleGetterNotImplementedErrors_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function get
a():String;",
+ "}",
+ "abstract class B extends A {",
+ "public abstract function get
b():String;",
+ "}",
+ "class C extends B {",
+ //multiple errors because more than one
method is not implemented
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "Method get
b in abstract class B not implemented by class C\nMethod get a in abstract
class A not implemented by class C\n");
+ }
+
+ @Test
+ public void
testConcreteClassExtendsAbstractExtendsAbstractMultipleSetterNotImplementedErrors_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function set
a(value:String):void;",
+ "}",
+ "abstract class B extends A {",
+ "public abstract function set
b(value:String):void;",
+ "}",
+ "class C extends B {",
+ //multiple errors because more than one
method is not implemented
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "Method set
b in abstract class B not implemented by class C\nMethod set a in abstract
class A not implemented by class C\n");
+ }
+
+ @Test
+ public void
testAbstractClassExtendsAbstractAndImplementsMethodNoError_withAllowAbstractClassesEnabled()
{
String[] imports = new String[]
{
@@ -1157,6 +2009,74 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
Assert.assertEquals("", result);
}
+ @Test
+ public void
testAbstractClassExtendsAbstractAndImplementsGetterNoError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function get
a():String;",
+ "}",
+ "abstract class B extends A {",
+ //it's okay for an abstract subclass to
implement any
+ //abstract getters from the superclass
+ "override public function get
a():String {return null;}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ File tempASFile = generateTempFile(source);
+ String result = compile(tempASFile, source, false,false,false,
options, true);
+ Assert.assertEquals("", result);
+ }
+
+ @Test
+ public void
testAbstractClassExtendsAbstractAndImplementsSetterNoError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ "abstract class A {",
+ "public abstract function set
a(value:String):void;",
+ "}",
+ "abstract class B extends A {",
+ //it's okay for an abstract subclass to
implement any
+ //abstract setters from the superclass
+ "override public function set
a(value:String):void {}",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ File tempASFile = generateTempFile(source);
+ String result = compile(tempASFile, source, false,false,false,
options, true);
+ Assert.assertEquals("", result);
+ }
+
@Test
public void
testConcreteClassExtendsAbstractNoError_withAllowAbstractClassesEnabled()
{
@@ -1173,11 +2093,15 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
{
"abstract class A {",
"public abstract function a():void;",
+ "public abstract function get
b():String;",
+ "public abstract function set
b(value:String):void;",
"}",
"class B extends A {",
//no errors because we've implemented
all of the methods
//that are abstract
"override public function a():void {}",
+ "override public function get
b():String {return null;}",
+ "override public function set
b(value:String):void {}",
"}"
};
String source = getAS(imports, declarations, testCode, extra);
@@ -1190,4 +2114,59 @@ public class ASAbstractClassTests extends
ASFeatureTestsBase
String result = compile(tempASFile, source, false,false,false,
options, true);
Assert.assertEquals("", result);
}
+
+ @Test
+ public void
testAbstractNotAllowedOnInterfaceError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ //error because abstract cannot be used with interfaces (only
classes)
+ "abstract interface A {",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
+ }
+
+ @Test
+ public void
testAbstractNotAllowedOnFunctionNotMethodError_withAllowAbstractClassesEnabled()
+ {
+ String[] imports = new String[]
+ {
+ };
+ String[] declarations = new String[]
+ {
+ };
+ String[] testCode = new String[]
+ {
+ };
+ String[] extra = new String[]
+ {
+ //error because abstract cannot be used with standalone functions
+ //that are not class methods
+ "abstract function a():void {",
+ "}"
+ };
+ String source = getAS(imports, declarations, testCode, extra);
+
+ String[] options = new String[]
+ {
+ "-allow-abstract-classes=true"
+ };
+ compileAndExpectErrors(source, false,false,false, options, "The
abstract attribute can only be used on a class definition or a non-static,
non-final method defined on an abstract class.\n");
+ }
}
\ No newline at end of file