While I'm excited to see new language features, I think we really need to think this stuff through before making changes to the framework.
I would never occur to me to use abstract for static-method-only classes. In fact, to me, it makes those classes look like base classes that should be subclassed before using. In Java they allow private constructors instead and I believe that is the recommended pattern for static-method-only classes. We also need to figure out how to document these new features, especially since I think they will all be compile-time only and thus have limitations. There are many cases where 'abstract' will not help you, like declaring an abstract class as a bead in a ClassReference in CSS. That's because the instantiation code does: var c:Class = ValuesManager.valuesImpl.getValue(...); var instance:Object = new c(); The same will likely be true for classes specified as ItemRenderers and other factories. My 2 cents, -Alex On 1/25/19, 3:41 AM, "Harbs" <[email protected]> wrote: Is there any reason to not enable this option by default? I can’t think of a downside to having this enabled. > On Jan 24, 2019, at 6:51 PM, Piotr Zarzycki <[email protected]> wrote: > > It's a great starting point - Thank you for doing that! > > czw., 24 sty 2019 o 17:49 Josh Tynjala <[email protected]> napisał(a): > >> Right now, only classes may be abstract. If you try to make a method >> abstract, you'll get a compiler error: >> >>> The abstract attribute may be used only class property definitions. >> >> It's probably possible to support abstract methods too, but I wanted to >> start with something simpler. >> >> - Josh >> >> On 2019/01/24 16:40:58, Piotr Zarzycki <[email protected]> wrote: >>> Josh, >>> >>> Do we have also ability to declare abstract methods ? >>> >>> Thanks, >>> Piotr >>> >>> czw., 24 sty 2019 o 16:59 Carlos Rovira <[email protected]> >>> napisał(a): >>> >>>> So cool! :) >>>> >>>> Think is time to tweet it! :) >>>> >>>> El jue., 24 ene. 2019 a las 16:50, Harbs (<[email protected]>) >>>> escribió: >>>> >>>>> Perfect! Thanks! >>>>> >>>>>> On Jan 24, 2019, at 5:39 PM, Josh Tynjala <[email protected]> >>>>> wrote: >>>>>> >>>>>> Following the suggestion from Harbs, I created a Github issue for >>>>> abstract classes: >>>>>> >>>>>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Froyale-compiler%2Fissues%2F73&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=36h3uyIYjL%2F01lFCEsS5FskTH1XElBwig22Br5QEnYk%3D&reserved=0 >>>>>> >>>>>> There's a code example in the description. >>>>>> >>>>>> - Josh >>>>>> >>>>>> On 2019/01/24 09:13:34, Piotr Zarzycki <[email protected]> >>>>> wrote: >>>>>>> Wow! <3 >>>>>>> How does that class looks like ? Is it follow similar principle >> as it >>>>> is in >>>>>>> C# language ? >>>>>>> >>>>>>> czw., 24 sty 2019 o 10:09 Harbs <[email protected]> >> napisał(a): >>>>>>> >>>>>>>> Great addition! Love it! >>>>>>>> >>>>>>>> Suggestion: When you add features, it’s a good idea to add a >> Github >>>>> issue >>>>>>>> to make it easier to track changes for release notes. >>>>>>>> >>>>>>>> Thanks, >>>>>>>> Harbs >>>>>>>> >>>>>>>>> On Jan 24, 2019, at 12:58 AM, [email protected] wrote: >>>>>>>>> >>>>>>>>> This is an automated email from the ASF dual-hosted git >> repository. >>>>>>>>> >>>>>>>>> joshtynjala pushed a commit to branch develop >>>>>>>>> in repository >>>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-compiler.git&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=PH6b3PM6%2FFquMfQ%2Fbcs%2BW3b%2FISZCwIHSne4K9FKDllo%3D&reserved=0 >>>>>>>>> >>>>>>>>> >>>>>>>>> The following commit(s) were added to refs/heads/develop by this >>>> push: >>>>>>>>> new 6a85bc1 compiler: added support for abstract classes in >>>>>>>> ActionScript >>>>>>>>> 6a85bc1 is described below >>>>>>>>> >>>>>>>>> commit 6a85bc1cd0c09e4ca07cf221a55ec9dd13e5d63c >>>>>>>>> Author: Josh Tynjala <[email protected]> >>>>>>>>> AuthorDate: Wed Jan 23 14:51:00 2019 -0800 >>>>>>>>> >>>>>>>>> compiler: added support for abstract classes in ActionScript >>>>>>>>> >>>>>>>>> When a developer attempts to instantiate an abstract class >> with >>>> the >>>>>>>> "new" keyword, the compiler will report an error. This is a >> compile >>>>> time >>>>>>>> check for now, but emitters could hypothetically add runtime >> checks >>>>> too. >>>>>>>>> >>>>>>>>> The abstract modifier is allowed on classes only at this >> time, and >>>>>>>> trying to use it on other definitions, like interfaces, methods, >> and >>>>>>>> variables results in a syntax problem. >>>>>>>>> >>>>>>>>> To enable abstract classes, use the new allow-abstract-classes >>>>>>>> compiler option. Support for abstract classes is disabled by >> default, >>>>>>>> meaning using this experimental new syntax is completely opt-in. >> Even >>>>> if >>>>>>>> the syntax widely adopted, we should keep it disabled by default >> in >>>> the >>>>>>>> compiler to avoid syntax conflicts when using the compiler for >> code >>>>>>>> intelligence with other SDKs. To enable it by default for a >>>> particular >>>>> SDK, >>>>>>>> modify the appropriate frameworks/*-config.xml file. >>>>>>>>> >>>>>>>>> Behind the scenes, When the "abstract" keyword is encountered >> as a >>>>>>>> modifier on a class, [RoyaleAbstract] metadata is created. This >>>> allows >>>>>>>> bytecode to store whether a class is abstract, without actually >>>> having >>>>> to >>>>>>>> update the bytecode format and runtimes that support it. The >> metadata >>>>> also >>>>>>>> allows classes in libraries to remain abstract when compiled to >> SWC. >>>>>>>>> --- >>>>>>>>> .../apache/royale/compiler/common/ASModifier.java | 8 +++- >>>>>>>>> .../royale/compiler/config/Configuration.java | 22 >> +++++++++++ >>>>>>>>> .../compiler/constants/IASKeywordConstants.java | 1 + >>>>>>>>> .../royale/compiler/definitions/IDefinition.java | 7 ++++ >>>>>>>>> .../royale/compiler/projects/ICompilerProject.java | 5 +++ >>>>>>>>> .../royale/compiler/internal/parsing/as/ASParser.g | 3 +- >>>>>>>>> .../constants/IMetaAttributeConstants.java | 4 ++ >>>>>>>>> .../as/codegen/ClassDirectiveProcessor.java | 9 +++++ >>>>>>>>> .../as/codegen/GlobalDirectiveProcessor.java | 19 >> +++++++++- >>>>>>>>> .../as/codegen/InterfaceDirectiveProcessor.java | 5 +++ >>>>>>>>> .../internal/definitions/ClassDefinitionBase.java | 26 >>>> +++++++++++++ >>>>>>>>> .../internal/definitions/DefinitionBase.java | 24 >> ++++++++++++ >>>>>>>>> .../compiler/internal/parsing/as/ASToken.java | 4 ++ >>>>>>>>> .../compiler/internal/parsing/as/BaseASParser.java | 3 +- >>>>>>>>> .../internal/parsing/as/ConfigProcessor.java | 6 +++ >>>>>>>>> .../internal/parsing/as/StreamingASTokenizer.java | 4 ++ >>>>>>>>> .../compiler/internal/projects/ASCProject.java | 6 +++ >>>>>>>>> .../compiler/internal/projects/RoyaleProject.java | 15 ++++++++ >>>>>>>>> .../projects/RoyaleProjectConfigurator.java | 1 + >>>>>>>>> .../semantics/MethodBodySemanticChecker.java | 11 ++++++ >>>>>>>>> .../internal/tree/as/BaseDefinitionNode.java | 2 + >>>>>>>>> .../AbstractClassCannotBeInstantiatedProblem.java | 42 >>>>>>>> +++++++++++++++++++++ >>>>>>>>> .../problems/AbstractOutsideClassProblem.java | 43 >>>>>>>> ++++++++++++++++++++++ >>>>>>>>> 23 files changed, 265 insertions(+), 5 deletions(-) >>>>>>>>> >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/common/ASModifier.java >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/common/ASModifier.java >>>>>>>>> index bb686ea..a601f80 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/common/ASModifier.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/common/ASModifier.java >>>>>>>>> @@ -60,6 +60,11 @@ public class ASModifier >>>>>>>>> * Represents the <code>virtual</code> modifier. >>>>>>>>> */ >>>>>>>>> public static final ASModifier VIRTUAL = new >>>>>>>> ASModifier(IASKeywordConstants.VIRTUAL, 1 << 6); >>>>>>>>> + >>>>>>>>> + /** >>>>>>>>> + * Represents the <code>abstract</code> modifier. >>>>>>>>> + */ >>>>>>>>> + public static final ASModifier ABSTRACT = new >>>>>>>> ASModifier(IASKeywordConstants.ABSTRACT, 1 << 7); >>>>>>>>> >>>>>>>>> /** >>>>>>>>> * A list of all the modifiers that exist within AS3 >>>>>>>>> @@ -71,7 +76,8 @@ public class ASModifier >>>>>>>>> NATIVE, >>>>>>>>> OVERRIDE, >>>>>>>>> STATIC, >>>>>>>>> - VIRTUAL >>>>>>>>> + VIRTUAL, >>>>>>>>> + ABSTRACT >>>>>>>>> }; >>>>>>>>> >>>>>>>>> /** >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java >>>>>>>>> index 5f8a3e0..478d346 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/config/Configuration.java >>>>>>>>> @@ -1508,6 +1508,28 @@ public class Configuration >>>>>>>>> } >>>>>>>>> >>>>>>>>> // >>>>>>>>> + // 'compiler.allow-abstract-classes' option >>>>>>>>> + // >>>>>>>>> + >>>>>>>>> + private boolean allowAbstractClasses = false; >>>>>>>>> + >>>>>>>>> + public boolean getCompilerAllowAbstractClasses() >>>>>>>>> + { >>>>>>>>> + return allowAbstractClasses; >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + /** >>>>>>>>> + * Whether the compiler will allow classes to be abstract. >>>>>>>>> + */ >>>>>>>>> + @Config >>>>>>>>> + @Mapping({ "compiler", "allow-abstract-classes" }) >>>>>>>>> + @RoyaleOnly >>>>>>>>> + public void >> setCompilerAllowAbstractClasses(ConfigurationValue >>>>> cv, >>>>>>>> boolean allow) >>>>>>>>> + { >>>>>>>>> + this.allowAbstractClasses = allow; >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + // >>>>>>>>> // 'compiler.actionscript-file-encoding' option >>>>>>>>> // >>>>>>>>> >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASKeywordConstants.java >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASKeywordConstants.java >>>>>>>>> index b45cea2..54e17ac 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASKeywordConstants.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/constants/IASKeywordConstants.java >>>>>>>>> @@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableSet; >>>>>>>>> */ >>>>>>>>> public interface IASKeywordConstants >>>>>>>>> { >>>>>>>>> + static final String ABSTRACT = "abstract"; >>>>>>>>> static final String AS = "as"; >>>>>>>>> static final String BREAK = "break"; >>>>>>>>> static final String CASE = "case"; >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/definitions/IDefinition.java >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/definitions/IDefinition.java >>>>>>>>> index 21f225b..89bfd78 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/definitions/IDefinition.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/definitions/IDefinition.java >>>>>>>>> @@ -268,6 +268,13 @@ public interface IDefinition >>>>>>>>> boolean isStatic(); >>>>>>>>> >>>>>>>>> /** >>>>>>>>> + * Is this definition marked as <code>abstract</code>? >>>>>>>>> + * >>>>>>>>> + * @return <code>true</code> if the definition is >>>>>>>> <code>abstract</code>. >>>>>>>>> + */ >>>>>>>>> + boolean isAbstract(); >>>>>>>>> + >>>>>>>>> + /** >>>>>>>>> * Determines whether the specified modifier is present on >> this >>>>>>>> definition. >>>>>>>>> * See {@link ASModifier} for the list of modifiers. >>>>>>>>> * >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java >>>>>>>>> index b3eea14..61d7489 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler-common/src/main/java/org/apache/royale/compiler/projects/ICompilerProject.java >>>>>>>>> @@ -271,5 +271,10 @@ public interface ICompilerProject >>>>>>>>> * @return True if import aliases are allowed. >>>>>>>>> */ >>>>>>>>> boolean getAllowImportAliases(); >>>>>>>>> + >>>>>>>>> + /** >>>>>>>>> + * @return True if abstract classes are allowed. >>>>>>>>> + */ >>>>>>>>> + boolean getAllowAbstractClasses(); >>>>>>>>> >>>>>>>>> } >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g >>>>>>>> >>>>> >>>> >> b/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g >>>>>>>>> index b4839ce..8a6a299 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g >>>>>>>>> @@ -212,7 +212,7 @@ attributedDefinition[ContainerNode c] >>>>>>>>> >>>>>>>>> /** >>>>>>>>> * Matches an attribute such as: >>>>>>>>> - * - Modifiers: dynamic, final, native, override, static, >> virtual. >>>>>>>>> + * - Modifiers: dynamic, final, native, override, static, >> virtual, >>>>>>>> abstract. >>>>>>>>> * - Namespace names. >>>>>>>>> * - Reserved namespace names: internal, private, public, >> protected. >>>>>>>>> * >>>>>>>>> @@ -580,6 +580,7 @@ modifierAttribute returns [ModifierNode >>>>> modifierNode] >>>>>>>>> | TOKEN_MODIFIER_STATIC >>>>>>>>> | TOKEN_MODIFIER_NATIVE >>>>>>>>> | TOKEN_MODIFIER_VIRTUAL >>>>>>>>> + | TOKEN_MODIFIER_ABSTRACT >>>>>>>>> ) >>>>>>>>> { modifierNode = new ModifierNode((ASToken) modifierT); >>>> } >>>>>>>>> ; >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/constants/IMetaAttributeConstants.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/constants/IMetaAttributeConstants.java >>>>>>>>> index dee1690..189f8ea 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/constants/IMetaAttributeConstants.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/constants/IMetaAttributeConstants.java >>>>>>>>> @@ -210,6 +210,9 @@ public interface IMetaAttributeConstants >>>>>>>>> static final String NAME_MIN_VALUE_EXCLUSIVE = >>>> "minValueExclusive"; >>>>>>>>> static final String NAME_MAX_VALUE = "maxValue"; >>>>>>>>> static final String NAME_MAX_VALUE_EXCLUSIVE = >>>> "maxValueExclusive"; >>>>>>>>> + >>>>>>>>> + // [RoyaleAbstract] >>>>>>>>> + static final String ATTRIBUTE_ABSTRACT = "RoyaleAbstract"; >>>>>>>>> >>>>>>>>> /** >>>>>>>>> * List of metadata tags that do not inherit >>>>>>>>> @@ -222,6 +225,7 @@ public interface IMetaAttributeConstants >>>>>>>>> ATTRIBUTE_DEPRECATED, >>>>>>>>> ATTRIBUTE_DISCOURAGED_FOR_PROFILE, >>>>>>>>> ATTRIBUTE_EXCLUDECLASS, >>>>>>>>> + ATTRIBUTE_ABSTRACT, >>>>>>>>> }))); >>>>>>>>> } >>>>>>>>> >>>>>>>>> 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 cc1fef1..ff3a627 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 >>>>>>>>> @@ -58,6 +58,7 @@ import >>>>>>>> org.apache.royale.compiler.definitions.IInterfaceDefinition; >>>>>>>>> import org.apache.royale.compiler.definitions.metadata.IMetaTag; >>>>>>>>> import >>>>> org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute; >>>>>>>>> import >>>>> org.apache.royale.compiler.exceptions.CodegenInterruptedException; >>>>>>>>> +import >>>>> org.apache.royale.compiler.problems.AbstractOutsideClassProblem; >>>>>>>>> import >>>>> org.apache.royale.compiler.problems.CircularTypeReferenceProblem; >>>>>>>>> import >>>>>>>> >>>>> >>>> >> org.apache.royale.compiler.problems.ConstructorCannotHaveReturnTypeProblem; >>>>>>>>> import >>>>>>>> >> org.apache.royale.compiler.problems.ConstructorIsGetterSetterProblem; >>>>>>>>> @@ -1091,6 +1092,10 @@ class ClassDirectiveProcessor extends >>>>>>>> DirectiveProcessor >>>>>>>>> { >>>>>>>>> classScope.addProblem(new >>>>>>>> VirtualOutsideClassProblem(site) ); >>>>>>>>> } >>>>>>>>> + if( modifiersSet.hasModifier(ASModifier.ABSTRACT) ) >>>>>>>>> + { >>>>>>>>> + classScope.addProblem(new >>>>>>>> AbstractOutsideClassProblem(site) ); >>>>>>>>> + } >>>>>>>>> } >>>>>>>>> >>>>>>>> >>>>> >> classScope.getMethodBodySemanticChecker().checkForDuplicateModifiers(f); >>>>>>>>> // Functions in a class allow all modifiers >>>>>>>>> @@ -1127,6 +1132,10 @@ class ClassDirectiveProcessor extends >>>>>>>> DirectiveProcessor >>>>>>>>> { >>>>>>>>> classScope.addProblem(new >>>>>>>> VirtualOutsideClassProblem(site)); >>>>>>>>> } >>>>>>>>> + else if( modifier == ASModifier.ABSTRACT ) >>>>>>>>> + { >>>>>>>>> + classScope.addProblem(new >>>>>>>> AbstractOutsideClassProblem(site)); >>>>>>>>> + } >>>>>>>>> } >>>>>>>>> >>>>>>>> >>>>> >> classScope.getMethodBodySemanticChecker().checkForDuplicateModifiers(v); >>>>>>>>> } >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/GlobalDirectiveProcessor.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/GlobalDirectiveProcessor.java >>>>>>>>> index 0f4f3c8..ca63800 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/GlobalDirectiveProcessor.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/GlobalDirectiveProcessor.java >>>>>>>>> @@ -30,6 +30,7 @@ import >> org.apache.royale.compiler.tree.as.IASNode; >>>>>>>>> import org.apache.royale.compiler.tree.as.IExpressionNode; >>>>>>>>> import org.apache.royale.compiler.common.ASModifier; >>>>>>>>> import org.apache.royale.compiler.common.ModifiersSet; >>>>>>>>> +import >> org.apache.royale.compiler.constants.IASKeywordConstants; >>>>>>>>> import >> org.apache.royale.compiler.constants.IMetaAttributeConstants; >>>>>>>>> import org.apache.royale.compiler.definitions.IDefinition; >>>>>>>>> import >>>>> org.apache.royale.compiler.internal.definitions.ClassDefinition; >>>>>>>>> @@ -45,6 +46,7 @@ import >>>> org.apache.royale.compiler.internal.tree.as >>>>>>>> .NamespaceIdentifierNode; >>>>>>>>> import org.apache.royale.compiler.internal.tree.as.PackageNode; >>>>>>>>> import org.apache.royale.compiler.internal.tree.as.VariableNode; >>>>>>>>> import >>>> org.apache.royale.compiler.internal.tree.mxml.MXMLDocumentNode; >>>>>>>>> +import >>>>> org.apache.royale.compiler.problems.AbstractOutsideClassProblem; >>>>>>>>> import >> org.apache.royale.compiler.problems.DynamicNotOnClassProblem; >>>>>>>>> import >>>>>>>> >> org.apache.royale.compiler.problems.EmbedOnlyOnClassesAndVarsProblem; >>>>>>>>> import >> org.apache.royale.compiler.problems.FinalOutsideClassProblem; >>>>>>>>> @@ -54,6 +56,7 @@ import >>>>>>>> org.apache.royale.compiler.problems.NativeNotOnFunctionProblem; >>>>>>>>> import >> org.apache.royale.compiler.problems.NativeVariableProblem; >>>>>>>>> import >>>>> org.apache.royale.compiler.problems.OverrideOutsideClassProblem; >>>>>>>>> import >>>> org.apache.royale.compiler.problems.StaticOutsideClassProblem; >>>>>>>>> +import org.apache.royale.compiler.problems.SyntaxProblem; >>>>>>>>> import >>>> org.apache.royale.compiler.problems.VirtualOutsideClassProblem; >>>>>>>>> import org.apache.royale.compiler.projects.ICompilerProject; >>>>>>>>> import org.apache.royale.compiler.tree.mxml.IMXMLDocumentNode; >>>>>>>>> @@ -320,6 +323,16 @@ class GlobalDirectiveProcessor extends >>>>>>>> DirectiveProcessor >>>>>>>>> */ >>>>>>>>> protected void verifyClassModifiers(ClassNode c) >>>>>>>>> { >>>>>>>>> + >> if(!currentScope.getProject().getAllowAbstractClasses() && >>>>>>>> c.getDefinition().isAbstract()) >>>>>>>>> + { >>>>>>>>> + IASNode problemNode = c.getNameExpressionNode(); >>>>>>>>> + if (problemNode == null) >>>>>>>>> + { >>>>>>>>> + problemNode = c; >>>>>>>>> + } >>>>>>>>> + currentScope.addProblem(new >> SyntaxProblem(problemNode, >>>>>>>> IASKeywordConstants.ABSTRACT)); >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> ModifiersSet modifiersSet = c.getModifiers(); >>>>>>>>> if (modifiersSet == null) >>>>>>>>> return; >>>>>>>>> @@ -328,8 +341,8 @@ class GlobalDirectiveProcessor extends >>>>>>>> DirectiveProcessor >>>>>>>>> IExpressionNode site = c.getNameExpressionNode(); >>>>>>>>> for (ASModifier modifier : modifiers) >>>>>>>>> { >>>>>>>>> - // final allowed on a class >>>>>>>>> - if( modifier == ASModifier.FINAL || modifier == >>>>>>>> ASModifier.DYNAMIC) >>>>>>>>> + // final, dynamic, and abstract allowed on a class >>>>>>>>> + if( modifier == ASModifier.FINAL || modifier == >>>>>>>> ASModifier.DYNAMIC || modifier == ASModifier.ABSTRACT) >>>>>>>>> { >>>>>>>>> continue; >>>>>>>>> } >>>>>>>>> @@ -408,6 +421,8 @@ class GlobalDirectiveProcessor extends >>>>>>>> DirectiveProcessor >>>>>>>>> currentScope.addProblem(new >>>>>>>> OverrideOutsideClassProblem(site)); >>>>>>>>> else if( modifier == ASModifier.VIRTUAL ) >>>>>>>>> currentScope.addProblem(new >>>>>>>> VirtualOutsideClassProblem(site)); >>>>>>>>> + else if( modifier == ASModifier.ABSTRACT ) >>>>>>>>> + currentScope.addProblem(new >>>>>>>> AbstractOutsideClassProblem(site)); >>>>>>>>> } >>>>>>>>> >>>>>>>>> /** >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InterfaceDirectiveProcessor.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InterfaceDirectiveProcessor.java >>>>>>>>> index f564c1b..46cfd3d 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InterfaceDirectiveProcessor.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/InterfaceDirectiveProcessor.java >>>>>>>>> @@ -55,6 +55,7 @@ import >>>>>>>> org.apache.royale.compiler.internal.tree.as.ImportNode; >>>>>>>>> import org.apache.royale.compiler.internal.tree.as >> .InterfaceNode; >>>>>>>>> import org.apache.royale.compiler.internal.tree.as >>>>>>>> .NamespaceIdentifierNode; >>>>>>>>> import org.apache.royale.compiler.internal.tree.as.VariableNode; >>>>>>>>> +import >>>>> org.apache.royale.compiler.problems.AbstractOutsideClassProblem; >>>>>>>>> import >>>> org.apache.royale.compiler.problems.AmbiguousReferenceProblem; >>>>>>>>> import >> org.apache.royale.compiler.problems.CannotExtendClassProblem; >>>>>>>>> import >>>>> org.apache.royale.compiler.problems.ConstructorInInterfaceProblem; >>>>>>>>> @@ -456,6 +457,10 @@ public class InterfaceDirectiveProcessor >>>> extends >>>>>>>> DirectiveProcessor >>>>>>>>> { >>>>>>>>> interfaceScope.addProblem(new >>>>>>>> VirtualOutsideClassProblem(site)); >>>>>>>>> } >>>>>>>>> + else if( modifier == ASModifier.ABSTRACT ) >>>>>>>>> + { >>>>>>>>> + interfaceScope.addProblem(new >>>>>>>> AbstractOutsideClassProblem(site)); >>>>>>>>> + } >>>>>>>>> else if ( modifier == ASModifier.DYNAMIC ) >>>>>>>>> { >>>>>>>>> // Allow this and continue. >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinitionBase.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinitionBase.java >>>>>>>>> index e00eda3..2dcf3ed 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinitionBase.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/ClassDefinitionBase.java >>>>>>>>> @@ -32,8 +32,10 @@ import >>>>>>>> org.apache.royale.compiler.definitions.IDefinition; >>>>>>>>> import >> org.apache.royale.compiler.definitions.IInterfaceDefinition; >>>>>>>>> import org.apache.royale.compiler.definitions.ITypeDefinition; >>>>>>>>> import org.apache.royale.compiler.definitions.metadata.IMetaTag; >>>>>>>>> +import >>>>>>>> >> org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute; >>>>>>>>> import >> org.apache.royale.compiler.definitions.references.IReference; >>>>>>>>> import >>>> org.apache.royale.compiler.internal.as.codegen.BindableHelper; >>>>>>>>> +import >>>>> org.apache.royale.compiler.internal.definitions.metadata.MetaTag; >>>>>>>>> import >> org.apache.royale.compiler.internal.projects.CompilerProject; >>>>>>>>> import >> org.apache.royale.compiler.internal.scopes.ASProjectScope; >>>>>>>>> import org.apache.royale.compiler.internal.scopes.ASScope; >>>>>>>>> @@ -536,6 +538,30 @@ public abstract class ClassDefinitionBase >>>> extends >>>>>>>> TypeDefinitionBase implements >>>>>>>>> return interfaces; >>>>>>>>> } >>>>>>>>> >>>>>>>>> + @Override >>>>>>>>> + public boolean isAbstract() >>>>>>>>> + { >>>>>>>>> + if(super.isAbstract()) >>>>>>>>> + { >>>>>>>>> + return true; >>>>>>>>> + } >>>>>>>>> + IMetaTag[] metaTags = >>>>>>>> getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_ABSTRACT); >>>>>>>>> + return metaTags != null && metaTags.length > 0; >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + /** >>>>>>>>> + * Utility to mark a definition as abstract. This method >> should >>>>>>>> only ever be >>>>>>>>> + * called during construction or initialization of a >>>> definition. >>>>>>>>> + */ >>>>>>>>> + @Override >>>>>>>>> + public void setAbstract() >>>>>>>>> + { >>>>>>>>> + super.setAbstract(); >>>>>>>>> + >>>>>>>>> + MetaTag abstractMetaTag = new MetaTag(this, >>>>>>>> IMetaAttributeConstants.ATTRIBUTE_ABSTRACT, new >>>> IMetaTagAttribute[0]); >>>>>>>>> + addMetaTag(abstractMetaTag); >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> /* >>>>>>>>> * This inner class implements an iterator that enumerates >> all of >>>>>>>> this >>>>>>>>> * ClassDefinition's superclasses. <p> It will stop iterating >>>> when >>>>> it >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/DefinitionBase.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/DefinitionBase.java >>>>>>>>> index 2e4c859..a219328 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/DefinitionBase.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/definitions/DefinitionBase.java >>>>>>>>> @@ -701,6 +701,21 @@ public abstract class DefinitionBase >> implements >>>>>>>> IDocumentableDefinition, IDefini >>>>>>>>> flags |= FLAG_STATIC; >>>>>>>>> } >>>>>>>>> >>>>>>>>> + // instead of increasing the size of "flags" from a short >> to >>>>> int, I >>>>>>>> added >>>>>>>>> + // a boolean variable instead. feel free to change this, if >>>>>>>> desired. -JT >>>>>>>>> + private boolean abstractFlag = false; >>>>>>>>> + >>>>>>>>> + @Override >>>>>>>>> + public boolean isAbstract() >>>>>>>>> + { >>>>>>>>> + return abstractFlag; >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + public void setAbstract() >>>>>>>>> + { >>>>>>>>> + abstractFlag = true; >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> @Override >>>>>>>>> public boolean hasModifier(ASModifier modifier) >>>>>>>>> { >>>>>>>>> @@ -731,6 +746,10 @@ public abstract class DefinitionBase >> implements >>>>>>>> IDocumentableDefinition, IDefini >>>>>>>>> // Ignore "virtual" modifier. >>>>>>>>> return false; >>>>>>>>> } >>>>>>>>> + else if (modifier == ASModifier.ABSTRACT) >>>>>>>>> + { >>>>>>>>> + return abstractFlag; >>>>>>>>> + } >>>>>>>>> else >>>>>>>>> { >>>>>>>>> assert false : "Unknown modifier: " + modifier; >>>>>>>>> @@ -752,6 +771,8 @@ public abstract class DefinitionBase >> implements >>>>>>>> IDocumentableDefinition, IDefini >>>>>>>>> result.addModifier(ASModifier.DYNAMIC); >>>>>>>>> if ((flags & FLAG_NATIVE) != 0) >>>>>>>>> result.addModifier(ASModifier.NATIVE); >>>>>>>>> + if (abstractFlag) >>>>>>>>> + result.addModifier(ASModifier.ABSTRACT); >>>>>>>>> return result; >>>>>>>>> } >>>>>>>>> >>>>>>>>> @@ -774,6 +795,9 @@ public abstract class DefinitionBase >> implements >>>>>>>> IDocumentableDefinition, IDefini >>>>>>>>> else if (modifier == ASModifier.NATIVE) >>>>>>>>> flags |= FLAG_NATIVE; >>>>>>>>> >>>>>>>>> + else if (modifier == ASModifier.ABSTRACT) >>>>>>>>> + setAbstract(); >>>>>>>>> + >>>>>>>>> else >>>>>>>>> assert false; >>>>>>>>> } >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ASToken.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ASToken.java >>>>>>>>> index 52f2040..fa8b149 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ASToken.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ASToken.java >>>>>>>>> @@ -463,6 +463,7 @@ public class ASToken extends TokenBase >>>> implements >>>>>>>> IASToken, ASTokenTypes >>>>>>>>> case TOKEN_MODIFIER_NATIVE: >>>>>>>>> case TOKEN_MODIFIER_OVERRIDE: >>>>>>>>> case TOKEN_MODIFIER_STATIC: >>>>>>>>> + case TOKEN_MODIFIER_ABSTRACT: >>>>>>>>> return true; >>>>>>>>> } >>>>>>>>> return false; >>>>>>>>> @@ -514,6 +515,7 @@ public class ASToken extends TokenBase >>>> implements >>>>>>>> IASToken, ASTokenTypes >>>>>>>>> case TOKEN_MODIFIER_OVERRIDE: >>>>>>>>> case TOKEN_MODIFIER_STATIC: >>>>>>>>> case TOKEN_MODIFIER_VIRTUAL: >>>>>>>>> + case TOKEN_MODIFIER_ABSTRACT: >>>>>>>>> case TOKEN_RESERVED_WORD_GET: >>>>>>>>> case TOKEN_RESERVED_WORD_SET: >>>>>>>>> case TOKEN_RESERVED_WORD_NAMESPACE: >>>>>>>>> @@ -655,6 +657,7 @@ public class ASToken extends TokenBase >>>> implements >>>>>>>> IASToken, ASTokenTypes >>>>>>>>> case TOKEN_MODIFIER_NATIVE: >>>>>>>>> case TOKEN_MODIFIER_OVERRIDE: >>>>>>>>> case TOKEN_MODIFIER_STATIC: >>>>>>>>> + case TOKEN_MODIFIER_ABSTRACT: >>>>>>>>> return true; >>>>>>>>> } >>>>>>>>> return false; >>>>>>>>> @@ -918,6 +921,7 @@ public class ASToken extends TokenBase >>>> implements >>>>>>>> IASToken, ASTokenTypes >>>>>>>>> case TOKEN_MODIFIER_NATIVE: >>>>>>>>> case TOKEN_MODIFIER_OVERRIDE: >>>>>>>>> case TOKEN_MODIFIER_STATIC: >>>>>>>>> + case TOKEN_MODIFIER_ABSTRACT: >>>>>>>>> return ASTokenKind.MODIFIER; >>>>>>>>> case HIDDEN_TOKEN_BUILTIN_NS: >>>>>>>>> case TOKEN_NAMESPACE_ANNOTATION: >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java >>>>>>>>> index a8c3d7f..c247c89 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java >>>>>>>>> @@ -2329,7 +2329,7 @@ abstract class BaseASParser extends >> LLkParser >>>>>>>> implements IProblemReporter >>>>>>>>> } >>>>>>>>> >>>>>>>>> private static final ImmutableSet<String> >>>>>>>> CONTEXTUAL_RESERVED_KEYWORD_MODIFIERS = >>>>>>>>> - ImmutableSet.of("dynamic", "final", "native", >> "static", >>>>>>>> "override"); >>>>>>>>> + ImmutableSet.of("dynamic", "final", "native", >> "static", >>>>>>>> "override", "abstract"); >>>>>>>>> >>>>>>>>> /** >>>>>>>>> * Recover from {@link CanNotInsertSemicolonProblem} after an >>>>>>>> expression >>>>>>>>> @@ -2854,6 +2854,7 @@ abstract class BaseASParser extends >> LLkParser >>>>>>>> implements IProblemReporter >>>>>>>>> case TOKEN_MODIFIER_OVERRIDE: >>>>>>>>> case TOKEN_MODIFIER_STATIC: >>>>>>>>> case TOKEN_MODIFIER_VIRTUAL: >>>>>>>>> + case TOKEN_MODIFIER_ABSTRACT: >>>>>>>>> return true; >>>>>>>>> } >>>>>>>>> } >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java >>>>>>>>> index 1cf7922..af2dd3b 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/ConfigProcessor.java >>>>>>>>> @@ -164,6 +164,12 @@ public class ConfigProcessor >>>>>>>>> // TODO Auto-generated method stub >>>>>>>>> return false; >>>>>>>>> } >>>>>>>>> + >>>>>>>>> + @Override >>>>>>>>> + public boolean getAllowAbstractClasses() { >>>>>>>>> + // TODO Auto-generated method stub >>>>>>>>> + return false; >>>>>>>>> + } >>>>>>>>> } >>>>>>>>> >>>>>>>>> /** >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/StreamingASTokenizer.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/StreamingASTokenizer.java >>>>>>>>> index 2cb8e99..32017a4 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/StreamingASTokenizer.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/StreamingASTokenizer.java >>>>>>>>> @@ -101,6 +101,7 @@ public class StreamingASTokenizer implements >>>>>>>> ASTokenTypes, IASTokenizer, Closeab >>>>>>>>> .put(IASKeywordConstants.OVERRIDE, >>>> TOKEN_MODIFIER_OVERRIDE) >>>>>>>>> .put(IASKeywordConstants.STATIC, >> TOKEN_MODIFIER_STATIC) >>>>>>>>> .put(IASKeywordConstants.VIRTUAL, >> TOKEN_MODIFIER_VIRTUAL) >>>>>>>>> + .put(IASKeywordConstants.ABSTRACT, >>>>> TOKEN_MODIFIER_ABSTRACT) >>>>>>>>> .put(IASKeywordConstants.SET, >> TOKEN_RESERVED_WORD_SET) >>>>>>>>> // Keywords with special token types that affect >>>> subsequent >>>>>>>> blocks >>>>>>>>> .put(IASKeywordConstants.CATCH, TOKEN_KEYWORD_CATCH) >>>>>>>>> @@ -917,6 +918,7 @@ public class StreamingASTokenizer implements >>>>>>>> ASTokenTypes, IASTokenizer, Closeab >>>>>>>>> case TOKEN_MODIFIER_OVERRIDE: >>>>>>>>> case TOKEN_MODIFIER_STATIC: >>>>>>>>> case TOKEN_MODIFIER_VIRTUAL: >>>>>>>>> + case TOKEN_MODIFIER_ABSTRACT: >>>>>>>>> { >>>>>>>>> // previous token is either a modifier or a >>>>>>>> namespace, or if >>>>>>>>> // null, assume keyword >>>>>>>>> @@ -938,6 +940,7 @@ public class StreamingASTokenizer implements >>>>>>>> ASTokenTypes, IASTokenizer, Closeab >>>>>>>>> case TOKEN_MODIFIER_OVERRIDE: >>>>>>>>> case TOKEN_MODIFIER_STATIC: >>>>>>>>> case TOKEN_MODIFIER_VIRTUAL: >>>>>>>>> + case TOKEN_MODIFIER_ABSTRACT: >>>>>>>>> case TOKEN_NAMESPACE_ANNOTATION: >>>>>>>>> case TOKEN_NAMESPACE_NAME: >>>>>>>>> case HIDDEN_TOKEN_BUILTIN_NS: >>>>>>>>> @@ -1773,6 +1776,7 @@ public class StreamingASTokenizer >> implements >>>>>>>> ASTokenTypes, IASTokenizer, Closeab >>>>>>>>> case TOKEN_MODIFIER_OVERRIDE: >>>>>>>>> case TOKEN_MODIFIER_STATIC: >>>>>>>>> case TOKEN_MODIFIER_VIRTUAL: >>>>>>>>> + case TOKEN_MODIFIER_ABSTRACT: >>>>>>>>> case TOKEN_KEYWORD_CLASS: >>>>>>>>> case TOKEN_KEYWORD_INTERFACE: >>>>>>>>> case TOKEN_NAMESPACE_ANNOTATION: >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java >>>>>>>>> index d229ca3..de04bb2 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/ASCProject.java >>>>>>>>> @@ -86,4 +86,10 @@ public class ASCProject extends >> CompilerProject >>>>>>>> implements IASCProject >>>>>>>>> // TODO Auto-generated method stub >>>>>>>>> return false; >>>>>>>>> } >>>>>>>>> + >>>>>>>>> + @Override >>>>>>>>> + public boolean getAllowAbstractClasses() { >>>>>>>>> + // TODO Auto-generated method stub >>>>>>>>> + return false; >>>>>>>>> + } >>>>>>>>> } >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java >>>>>>>>> index 6a03191..c99f5bb 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProject.java >>>>>>>>> @@ -2445,6 +2445,21 @@ public class RoyaleProject extends >> ASProject >>>>>>>> implements IRoyaleProject, ICompile >>>>>>>>> allowImportAliases = allow; >>>>>>>>> } >>>>>>>>> >>>>>>>>> + private boolean allowAbstractClasses = false; >>>>>>>>> + >>>>>>>>> + /** >>>>>>>>> + * Indicates if abstract classes are allowed. >>>>>>>>> + */ >>>>>>>>> + @Override >>>>>>>>> + public boolean getAllowAbstractClasses() >>>>>>>>> + { >>>>>>>>> + return allowAbstractClasses; >>>>>>>>> + } >>>>>>>>> + public void setAllowAbstractClasses(boolean allow) >>>>>>>>> + { >>>>>>>>> + allowAbstractClasses = allow; >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> @Override >>>>>>>>> public boolean isPlatformRule(ICSSRule rule) { >>>>>>>>> return true; >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java >>>>>>>>> index 409dfd9..cb3a35b 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/projects/RoyaleProjectConfigurator.java >>>>>>>>> @@ -264,6 +264,7 @@ public class RoyaleProjectConfigurator >> extends >>>>>>>> Configurator >>>>>>>>> >>>>>>>> >>>>> >>>> >> project.setAllowPrivateNameConflicts(configuration.getCompilerAllowPrivateNameConflicts()); >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>> >>>> >> project.setAllowImportAliases(configuration.getCompilerAllowImportAliases()); >>>>>>>>> + >>>>>>>> >>>>> >>>> >> project.setAllowAbstractClasses(configuration.getCompilerAllowAbstractClasses()); >>>>>>>>> >>>>>>>>> DataTranscoder.embedClassName = >>>>>>>> configuration.getByteArrayEmbedClass(); >>>>>>>>> } >>>>>>>>> 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 0e009fe..c142116 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 >>>>>>>>> @@ -2089,6 +2089,13 @@ public class MethodBodySemanticChecker >>>>>>>>> { >>>>>>>>> ClassDefinition class_def = (ClassDefinition)def; >>>>>>>>> >>>>>>>>> + if ( project.getAllowAbstractClasses() && >>>>>>>> class_def.isAbstract() ) >>>>>>>>> + { >>>>>>>>> + addProblem(new >>>>> AbstractClassCannotBeInstantiatedProblem( >>>>>>>>> + roundUpUsualSuspects(class_binding, iNode) >>>>>>>>> + )); >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> IFunctionDefinition ctor = >> class_def.getConstructor(); >>>>>>>>> >>>>>>>>> if ( ctor instanceof FunctionDefinition ) >>>>>>>>> @@ -2456,6 +2463,10 @@ public class MethodBodySemanticChecker >>>>>>>>> { >>>>>>>>> currentScope.addProblem(new >>>>>>>> StaticOutsideClassProblem(site)); >>>>>>>>> } >>>>>>>>> + else if( modifier == ASModifier.ABSTRACT ) >>>>>>>>> + { >>>>>>>>> + currentScope.addProblem(new >>>>>>>> AbstractOutsideClassProblem(site)); >>>>>>>>> + } >>>>>>>>> } >>>>>>>>> } >>>>>>>>> >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseDefinitionNode.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseDefinitionNode.java >>>>>>>>> index a1d9609..c45def6 100644 >>>>>>>>> --- >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseDefinitionNode.java >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/as/BaseDefinitionNode.java >>>>>>>>> @@ -401,6 +401,8 @@ public abstract class BaseDefinitionNode >> extends >>>>>>>> TreeNode implements IDocumentab >>>>>>>>> db.setOverride(); >>>>>>>>> if (hasModifier(ASModifier.STATIC)) >>>>>>>>> db.setStatic(); >>>>>>>>> + if (hasModifier(ASModifier.ABSTRACT)) >>>>>>>>> + db.setAbstract(); >>>>>>>>> } >>>>>>>>> >>>>>>>>> protected void fillInMetadata(DefinitionBase definition) >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractClassCannotBeInstantiatedProblem.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractClassCannotBeInstantiatedProblem.java >>>>>>>>> new file mode 100644 >>>>>>>>> index 0000000..e9d34d1 >>>>>>>>> --- /dev/null >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractClassCannotBeInstantiatedProblem.java >>>>>>>>> @@ -0,0 +1,42 @@ >>>>>>>>> +/* >>>>>>>>> + * >>>>>>>>> + * 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 >>>>>>>>> + * >>>>>>>>> + * https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=dxFeYUCG4Cqh5fMFJooUHeiAOkILDH2FWHtiIYhyNKs%3D&reserved=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; >>>>>>>>> + >>>>>>>>> +/** >>>>>>>>> + * Semantics diagnostic emitted when the method body >>>>>>>>> + * semantic checker detects an attempt to instantiate an >> abstract >>>>>>>> class. >>>>>>>>> + */ >>>>>>>>> +public final class AbstractClassCannotBeInstantiatedProblem >> extends >>>>>>>> SemanticProblem >>>>>>>>> +{ >>>>>>>>> + public static final String DESCRIPTION = >>>>>>>>> + "Abstract classes cannot be instantiated with the >> ${NEW} >>>>>>>> operator."; >>>>>>>>> + >>>>>>>>> + public static final int errorCode = 1156; >>>>>>>>> + >>>>>>>>> + public AbstractClassCannotBeInstantiatedProblem(IASNode >> site) >>>>>>>>> + { >>>>>>>>> + super(site); >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + // Prevent these from being localized. >>>>>>>>> + public final String NEW = "new"; >>>>>>>>> +} >>>>>>>>> diff --git >>>>>>>> >>>>> >>>> >> a/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractOutsideClassProblem.java >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractOutsideClassProblem.java >>>>>>>>> new file mode 100644 >>>>>>>>> index 0000000..4fea9f1 >>>>>>>>> --- /dev/null >>>>>>>>> +++ >>>>>>>> >>>>> >>>> >> b/compiler/src/main/java/org/apache/royale/compiler/problems/AbstractOutsideClassProblem.java >>>>>>>>> @@ -0,0 +1,43 @@ >>>>>>>>> +/* >>>>>>>>> + * >>>>>>>>> + * 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 >>>>>>>>> + * >>>>>>>>> + * https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=dxFeYUCG4Cqh5fMFJooUHeiAOkILDH2FWHtiIYhyNKs%3D&reserved=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; >>>>>>>>> + >>>>>>>>> +/** >>>>>>>>> + * Problem generated when 'abstract' is used outside of a class >>>>>>>>> + */ >>>>>>>>> +public final class AbstractOutsideClassProblem extends >>>> CodegenProblem >>>>>>>>> +{ >>>>>>>>> + // TODO ErrorMSG: not specific to methods >>>>>>>>> + public static final String DESCRIPTION = >>>>>>>>> + "The ${ABSTRACT} attribute may be used only >> ${CLASS} >>>>>>>> property definitions."; >>>>>>>>> + >>>>>>>>> + public static final int errorCode = 1011; >>>>>>>>> + >>>>>>>>> + public AbstractOutsideClassProblem(IASNode site) >>>>>>>>> + { >>>>>>>>> + super(site); >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + // Prevent these from being localized. >>>>>>>>> + public final String ABSTRACT = "abstract"; >>>>>>>>> + public final String CLASS = "class"; >>>>>>>>> +} >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> >>>>>>> Piotr Zarzycki >>>>>>> >>>>>>> Patreon: *https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.patreon.com%2Fpiotrzarzycki&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=fbKecT8tqEeQqjzX2mGhwB0xRZ3bjrNJhi%2FGCklNiLI%3D&reserved=0 >>>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.patreon.com%2Fpiotrzarzycki&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=fbKecT8tqEeQqjzX2mGhwB0xRZ3bjrNJhi%2FGCklNiLI%3D&reserved=0>* >>>>>>> >>>>> >>>>> >>>>> >>>> >>>> -- >>>> Carlos Rovira >>>> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=hgAS23NQY%2Fgxhyrvhpv%2FOTGdozGj7327pVNTDQuKTv8%3D&reserved=0 >>>> >>> >>> >>> -- >>> >>> Piotr Zarzycki >>> >>> Patreon: *https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.patreon.com%2Fpiotrzarzycki&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=fbKecT8tqEeQqjzX2mGhwB0xRZ3bjrNJhi%2FGCklNiLI%3D&reserved=0 >>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.patreon.com%2Fpiotrzarzycki&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=fbKecT8tqEeQqjzX2mGhwB0xRZ3bjrNJhi%2FGCklNiLI%3D&reserved=0>* >>> >> > > > -- > > Piotr Zarzycki > > Patreon: *https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.patreon.com%2Fpiotrzarzycki&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=fbKecT8tqEeQqjzX2mGhwB0xRZ3bjrNJhi%2FGCklNiLI%3D&reserved=0 > <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.patreon.com%2Fpiotrzarzycki&data=02%7C01%7Caharui%40adobe.com%7C526cca921dab4090311a08d682ba098d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636840132872652648&sdata=fbKecT8tqEeQqjzX2mGhwB0xRZ3bjrNJhi%2FGCklNiLI%3D&reserved=0>*
