You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by jo...@apache.org on 2022/10/05 17:32:36 UTC

[royale-compiler] branch develop updated (a447f32c0 -> dc79c93d4)

This is an automated email from the ASF dual-hosted git repository.

joshtynjala pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git


    from a447f32c0 update release notes
     new 1b4b87534 linter: extract utility functions
     new dc79c93d4 linter: add ILinterProblem interface to allow for easier detection of linter problems

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../main/java/org/apache/royale/linter/LINTER.java | 191 +----------------
 .../java/org/apache/royale/linter/LinterUtils.java | 225 +++++++++++++++++++++
 .../royale/linter/problems/ILinterProblem.java     |  14 +-
 .../apache/royale/linter/rules/ClassNameRule.java  |   3 +-
 .../royale/linter/rules/ConstantNameRule.java      |   3 +-
 .../royale/linter/rules/EmptyCommentRule.java      |   3 +-
 .../royale/linter/rules/EmptyFunctionBodyRule.java |   3 +-
 .../royale/linter/rules/EmptyNestedBlockRule.java  |   3 +-
 .../royale/linter/rules/EmptyStatementRule.java    |   3 +-
 .../apache/royale/linter/rules/FieldNameRule.java  |   3 +-
 .../royale/linter/rules/FunctionNameRule.java      |   3 +-
 .../royale/linter/rules/InterfaceNameRule.java     |   3 +-
 .../linter/rules/LineCommentPositionRule.java      |   3 +-
 .../linter/rules/LocalVarAndParameterNameRule.java |   5 +-
 .../linter/rules/LocalVarShadowsFieldRule.java     |   3 +-
 .../linter/rules/MXMLEmptyAttributeRule.java       |   3 +-
 .../org/apache/royale/linter/rules/MXMLIDRule.java |   3 +-
 .../royale/linter/rules/MaxBlockDepthRule.java     |   3 +-
 .../royale/linter/rules/MaxParametersRule.java     |   3 +-
 .../royale/linter/rules/MissingASDocRule.java      |   5 +-
 .../linter/rules/MissingConstructorSuperRule.java  |   3 +-
 .../royale/linter/rules/MissingNamespaceRule.java  |  13 +-
 .../royale/linter/rules/MissingSemicolonRule.java  |   3 +-
 .../royale/linter/rules/MissingTypeRule.java       |   7 +-
 .../apache/royale/linter/rules/NoAnyTypeRule.java  |   7 +-
 .../royale/linter/rules/NoBooleanEqualityRule.java |   3 +-
 .../rules/NoConstructorDispatchEventRule.java      |   5 +-
 .../linter/rules/NoConstructorReturnTypeRule.java  |   3 +-
 .../linter/rules/NoDuplicateObjectKeysRule.java    |   3 +-
 .../royale/linter/rules/NoDynamicClassRule.java    |   3 +-
 .../linter/rules/NoIfBooleanLiteralRule.java       |   3 +-
 .../royale/linter/rules/NoLeadingZeroesRule.java   |   3 +-
 .../royale/linter/rules/NoSparseArrayRule.java     |   3 +-
 .../royale/linter/rules/NoStringEventNameRule.java |   7 +-
 .../royale/linter/rules/NoThisInClosureRule.java   |   3 +-
 .../apache/royale/linter/rules/NoTraceRule.java    |   3 +-
 .../royale/linter/rules/NoVoidOperatorRule.java    |   3 +-
 .../royale/linter/rules/NoWildcardImportRule.java  |   3 +-
 .../org/apache/royale/linter/rules/NoWithRule.java |   4 +-
 .../rules/OverrideContainsOnlySuperCallRule.java   |   3 +-
 .../royale/linter/rules/PackageNameRule.java       |   3 +-
 .../royale/linter/rules/StaticConstantsRule.java   |   3 +-
 .../royale/linter/rules/StrictEqualityRule.java    |   4 +-
 .../linter/rules/SwitchWithoutDefaultRule.java     |   3 +-
 .../royale/linter/rules/UnsafeNegationRule.java    |   3 +-
 .../royale/linter/rules/ValidTypeofRule.java       |   3 +-
 .../royale/linter/rules/VariablesOnTopRule.java    |   3 +-
 47 files changed, 334 insertions(+), 258 deletions(-)
 create mode 100644 linter/src/main/java/org/apache/royale/linter/LinterUtils.java
 copy compiler/src/test/royale/custom/Label.as => linter/src/main/java/org/apache/royale/linter/problems/ILinterProblem.java (85%)


[royale-compiler] 01/02: linter: extract utility functions

Posted by jo...@apache.org.
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

commit 1b4b875345262e1ca65a02c89e1709cb9e7c1f23
Author: Josh Tynjala <jo...@apache.org>
AuthorDate: Wed Oct 5 10:08:24 2022 -0700

    linter: extract utility functions
---
 .../main/java/org/apache/royale/linter/LINTER.java | 191 +----------------
 .../java/org/apache/royale/linter/LinterUtils.java | 225 +++++++++++++++++++++
 2 files changed, 227 insertions(+), 189 deletions(-)

diff --git a/linter/src/main/java/org/apache/royale/linter/LINTER.java b/linter/src/main/java/org/apache/royale/linter/LINTER.java
index 0a55f116e..2abc08db8 100644
--- a/linter/src/main/java/org/apache/royale/linter/LINTER.java
+++ b/linter/src/main/java/org/apache/royale/linter/LINTER.java
@@ -47,51 +47,6 @@ import org.apache.royale.linter.config.ConfigurationBuffer;
 import org.apache.royale.linter.config.ConfigurationValue;
 import org.apache.royale.linter.config.Configurator;
 import org.apache.royale.linter.config.ILinterSettingsConstants;
-import org.apache.royale.linter.config.LineCommentPosition;
-import org.apache.royale.linter.rules.NoAnyTypeRule;
-import org.apache.royale.linter.rules.NoBooleanEqualityRule;
-import org.apache.royale.linter.rules.ClassNameRule;
-import org.apache.royale.linter.rules.ConstantNameRule;
-import org.apache.royale.linter.rules.NoConstructorDispatchEventRule;
-import org.apache.royale.linter.rules.NoConstructorReturnTypeRule;
-import org.apache.royale.linter.rules.NoDuplicateObjectKeysRule;
-import org.apache.royale.linter.rules.NoDynamicClassRule;
-import org.apache.royale.linter.rules.EmptyCommentRule;
-import org.apache.royale.linter.rules.EmptyFunctionBodyRule;
-import org.apache.royale.linter.rules.EmptyNestedBlockRule;
-import org.apache.royale.linter.rules.EmptyStatementRule;
-import org.apache.royale.linter.rules.FieldNameRule;
-import org.apache.royale.linter.rules.FunctionNameRule;
-import org.apache.royale.linter.rules.NoIfBooleanLiteralRule;
-import org.apache.royale.linter.rules.InterfaceNameRule;
-import org.apache.royale.linter.rules.LineCommentPositionRule;
-import org.apache.royale.linter.rules.LocalVarAndParameterNameRule;
-import org.apache.royale.linter.rules.LocalVarShadowsFieldRule;
-import org.apache.royale.linter.rules.MXMLEmptyAttributeRule;
-import org.apache.royale.linter.rules.MXMLIDRule;
-import org.apache.royale.linter.rules.MaxBlockDepthRule;
-import org.apache.royale.linter.rules.MaxParametersRule;
-import org.apache.royale.linter.rules.MissingASDocRule;
-import org.apache.royale.linter.rules.MissingConstructorSuperRule;
-import org.apache.royale.linter.rules.MissingNamespaceRule;
-import org.apache.royale.linter.rules.MissingSemicolonRule;
-import org.apache.royale.linter.rules.MissingTypeRule;
-import org.apache.royale.linter.rules.NoLeadingZeroesRule;
-import org.apache.royale.linter.rules.OverrideContainsOnlySuperCallRule;
-import org.apache.royale.linter.rules.PackageNameRule;
-import org.apache.royale.linter.rules.NoSparseArrayRule;
-import org.apache.royale.linter.rules.StaticConstantsRule;
-import org.apache.royale.linter.rules.StrictEqualityRule;
-import org.apache.royale.linter.rules.NoStringEventNameRule;
-import org.apache.royale.linter.rules.SwitchWithoutDefaultRule;
-import org.apache.royale.linter.rules.NoThisInClosureRule;
-import org.apache.royale.linter.rules.NoTraceRule;
-import org.apache.royale.linter.rules.UnsafeNegationRule;
-import org.apache.royale.linter.rules.ValidTypeofRule;
-import org.apache.royale.linter.rules.VariablesOnTopRule;
-import org.apache.royale.linter.rules.NoVoidOperatorRule;
-import org.apache.royale.linter.rules.NoWildcardImportRule;
-import org.apache.royale.linter.rules.NoWithRule;
 import org.apache.royale.utils.FilenameNormalization;
 
 /**
@@ -246,150 +201,8 @@ public class LINTER {
 				return false;
 			}
 
-			settings = new LinterSettings();
-			settings.ignoreProblems = configuration.getIgnoreParsingProblems();
-
-			List<LinterRule> rules = new ArrayList<LinterRule>();
-			if (configuration.getClassName()) {
-				rules.add(new ClassNameRule());
-			}
-			if (configuration.getConstantName()) {
-				rules.add(new ConstantNameRule());
-			}
-			if (configuration.getEmptyFunctionBody()) {
-				rules.add(new EmptyFunctionBodyRule());
-			}
-			if (configuration.getEmptyNestedBlock()) {
-				rules.add(new EmptyNestedBlockRule());
-			}
-			if (configuration.getFunctionName()) {
-				rules.add(new FunctionNameRule());
-			}
-			if (configuration.getFieldName()) {
-				rules.add(new FieldNameRule());
-			}
-			if (configuration.getOverrideSuper()) {
-				rules.add(new OverrideContainsOnlySuperCallRule());
-			}
-			if (configuration.getEmptyComment()) {
-				rules.add(new EmptyCommentRule());
-			}
-			if (configuration.getEmptyStatement()) {
-				rules.add(new EmptyStatementRule());
-			}
-			if (configuration.getInterfaceName()) {
-				rules.add(new InterfaceNameRule());
-			}
-			if (configuration.getLineCommentPosition() != null) {
-				LineCommentPositionRule rule = new LineCommentPositionRule();
-				rule.position = LineCommentPosition.valueOf(configuration.getLineCommentPosition().toUpperCase());
-				rules.add(rule);
-			}
-			if (configuration.getLocalVarParamName()) {
-				rules.add(new LocalVarAndParameterNameRule());
-			}
-			if (configuration.getLocalVarShadowsField()) {
-				rules.add(new LocalVarShadowsFieldRule());
-			}
-			if (configuration.getMaxParams() > 0) {
-				MaxParametersRule rule = new MaxParametersRule();
-				rule.maximum = configuration.getMaxParams();
-				rules.add(rule);
-			}
-			if (configuration.getMaxBlockDepth() > 0) {
-				MaxBlockDepthRule rule = new MaxBlockDepthRule();
-				rule.maximum = configuration.getMaxBlockDepth();
-				rules.add(rule);
-			}
-			if (configuration.getMissingAsdoc()) {
-				rules.add(new MissingASDocRule());
-			}
-			if (configuration.getMissingConstructorSuper()) {
-				rules.add(new MissingConstructorSuperRule());
-			}
-			if (configuration.getMissingNamespace()) {
-				rules.add(new MissingNamespaceRule());
-			}
-			if (configuration.getMissingSemicolon()) {
-				rules.add(new MissingSemicolonRule());
-			}
-			if (configuration.getMissingType()) {
-				rules.add(new MissingTypeRule());
-			}
-			if (configuration.getMxmlId()) {
-				rules.add(new MXMLIDRule());
-			}
-			if (configuration.getMxmlEmptyAttr()) {
-				rules.add(new MXMLEmptyAttributeRule());
-			}
-			if (configuration.getNoAnyType()) {
-				rules.add(new NoAnyTypeRule());
-			}
-			if (configuration.getNoBooleanEquality()) {
-				rules.add(new NoBooleanEqualityRule());
-			}
-			if (configuration.getNoConstructorDispatch()) {
-				rules.add(new NoConstructorDispatchEventRule());
-			}
-			if (configuration.getNoConstructorReturnType()) {
-				rules.add(new NoConstructorReturnTypeRule());
-			}
-			if (configuration.getNoDuplicateKeys()) {
-				rules.add(new NoDuplicateObjectKeysRule());
-			}
-			if (configuration.getNoDynamicClass()) {
-				rules.add(new NoDynamicClassRule());
-			}
-			if (configuration.getNoIfBoolean()) {
-				rules.add(new NoIfBooleanLiteralRule());
-			}
-			if (configuration.getNoLeadingZero()) {
-				rules.add(new NoLeadingZeroesRule());
-			}
-			if (configuration.getNoSparseArray()) {
-				rules.add(new NoSparseArrayRule());
-			}
-			if (configuration.getNoStringEvent()) {
-				rules.add(new NoStringEventNameRule());
-			}
-			if (configuration.getNoThisClosure()) {
-				rules.add(new NoThisInClosureRule());
-			}
-			if (configuration.getNoTrace()) {
-				rules.add(new NoTraceRule());
-			}
-			if (configuration.getNoVoidOperator()) {
-				rules.add(new NoVoidOperatorRule());
-			}
-			if (configuration.getNoWildcardImport()) {
-				rules.add(new NoWildcardImportRule());
-			}
-			if (configuration.getNoWith()) {
-				rules.add(new NoWithRule());
-			}
-			if (configuration.getPackageName()) {
-				rules.add(new PackageNameRule());
-			}
-			if (configuration.getStaticConstants()) {
-				rules.add(new StaticConstantsRule());
-			}
-			if (configuration.getStrictEquality()) {
-				rules.add(new StrictEqualityRule());
-			}
-			if (configuration.getSwitchDefault()) {
-				rules.add(new SwitchWithoutDefaultRule());
-			}
-			if (configuration.getUnsafeNegation()) {
-				rules.add(new UnsafeNegationRule());
-			}
-			if (configuration.getValidTypeof()) {
-				rules.add(new ValidTypeofRule());
-			}
-			if (configuration.getVarsOnTop()) {
-				rules.add(new VariablesOnTopRule());
-			}
-			settings.rules = rules;
-			if (rules.size() == 0) {
+			settings = LinterUtils.configurationToLinterSettings(configuration);
+			if (settings.rules.size() == 0) {
 				ICompilerProblem problem = new ConfigurationProblem(null, -1, -1, -1, -1, "No linter rules were specified");
 				problems.add(problem);
 				return false;
diff --git a/linter/src/main/java/org/apache/royale/linter/LinterUtils.java b/linter/src/main/java/org/apache/royale/linter/LinterUtils.java
new file mode 100644
index 000000000..d7a4542c3
--- /dev/null
+++ b/linter/src/main/java/org/apache/royale/linter/LinterUtils.java
@@ -0,0 +1,225 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.linter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.royale.linter.config.Configuration;
+import org.apache.royale.linter.config.LineCommentPosition;
+import org.apache.royale.linter.rules.ClassNameRule;
+import org.apache.royale.linter.rules.ConstantNameRule;
+import org.apache.royale.linter.rules.EmptyCommentRule;
+import org.apache.royale.linter.rules.EmptyFunctionBodyRule;
+import org.apache.royale.linter.rules.EmptyNestedBlockRule;
+import org.apache.royale.linter.rules.EmptyStatementRule;
+import org.apache.royale.linter.rules.FieldNameRule;
+import org.apache.royale.linter.rules.FunctionNameRule;
+import org.apache.royale.linter.rules.InterfaceNameRule;
+import org.apache.royale.linter.rules.LineCommentPositionRule;
+import org.apache.royale.linter.rules.LocalVarAndParameterNameRule;
+import org.apache.royale.linter.rules.LocalVarShadowsFieldRule;
+import org.apache.royale.linter.rules.MXMLEmptyAttributeRule;
+import org.apache.royale.linter.rules.MXMLIDRule;
+import org.apache.royale.linter.rules.MaxBlockDepthRule;
+import org.apache.royale.linter.rules.MaxParametersRule;
+import org.apache.royale.linter.rules.MissingASDocRule;
+import org.apache.royale.linter.rules.MissingConstructorSuperRule;
+import org.apache.royale.linter.rules.MissingNamespaceRule;
+import org.apache.royale.linter.rules.MissingSemicolonRule;
+import org.apache.royale.linter.rules.MissingTypeRule;
+import org.apache.royale.linter.rules.NoAnyTypeRule;
+import org.apache.royale.linter.rules.NoBooleanEqualityRule;
+import org.apache.royale.linter.rules.NoConstructorDispatchEventRule;
+import org.apache.royale.linter.rules.NoConstructorReturnTypeRule;
+import org.apache.royale.linter.rules.NoDuplicateObjectKeysRule;
+import org.apache.royale.linter.rules.NoDynamicClassRule;
+import org.apache.royale.linter.rules.NoIfBooleanLiteralRule;
+import org.apache.royale.linter.rules.NoLeadingZeroesRule;
+import org.apache.royale.linter.rules.NoSparseArrayRule;
+import org.apache.royale.linter.rules.NoStringEventNameRule;
+import org.apache.royale.linter.rules.NoThisInClosureRule;
+import org.apache.royale.linter.rules.NoTraceRule;
+import org.apache.royale.linter.rules.NoVoidOperatorRule;
+import org.apache.royale.linter.rules.NoWildcardImportRule;
+import org.apache.royale.linter.rules.NoWithRule;
+import org.apache.royale.linter.rules.OverrideContainsOnlySuperCallRule;
+import org.apache.royale.linter.rules.PackageNameRule;
+import org.apache.royale.linter.rules.StaticConstantsRule;
+import org.apache.royale.linter.rules.StrictEqualityRule;
+import org.apache.royale.linter.rules.SwitchWithoutDefaultRule;
+import org.apache.royale.linter.rules.UnsafeNegationRule;
+import org.apache.royale.linter.rules.ValidTypeofRule;
+import org.apache.royale.linter.rules.VariablesOnTopRule;
+
+public class LinterUtils {
+	public static LinterSettings configurationToLinterSettings(Configuration configuration) {
+		LinterSettings settings = new LinterSettings();
+		settings.ignoreProblems = configuration.getIgnoreParsingProblems();
+
+		List<LinterRule> rules = LinterUtils.configurationToRules(configuration);
+		settings.rules = rules;
+
+		return settings;
+	}
+
+	public static List<LinterRule> configurationToRules(Configuration configuration) {
+		List<LinterRule> rules = new ArrayList<LinterRule>();
+		if (configuration.getClassName()) {
+			rules.add(new ClassNameRule());
+		}
+		if (configuration.getConstantName()) {
+			rules.add(new ConstantNameRule());
+		}
+		if (configuration.getEmptyFunctionBody()) {
+			rules.add(new EmptyFunctionBodyRule());
+		}
+		if (configuration.getEmptyNestedBlock()) {
+			rules.add(new EmptyNestedBlockRule());
+		}
+		if (configuration.getFunctionName()) {
+			rules.add(new FunctionNameRule());
+		}
+		if (configuration.getFieldName()) {
+			rules.add(new FieldNameRule());
+		}
+		if (configuration.getOverrideSuper()) {
+			rules.add(new OverrideContainsOnlySuperCallRule());
+		}
+		if (configuration.getEmptyComment()) {
+			rules.add(new EmptyCommentRule());
+		}
+		if (configuration.getEmptyStatement()) {
+			rules.add(new EmptyStatementRule());
+		}
+		if (configuration.getInterfaceName()) {
+			rules.add(new InterfaceNameRule());
+		}
+		if (configuration.getLineCommentPosition() != null) {
+			LineCommentPositionRule rule = new LineCommentPositionRule();
+			rule.position = LineCommentPosition.valueOf(configuration.getLineCommentPosition().toUpperCase());
+			rules.add(rule);
+		}
+		if (configuration.getLocalVarParamName()) {
+			rules.add(new LocalVarAndParameterNameRule());
+		}
+		if (configuration.getLocalVarShadowsField()) {
+			rules.add(new LocalVarShadowsFieldRule());
+		}
+		if (configuration.getMaxParams() > 0) {
+			MaxParametersRule rule = new MaxParametersRule();
+			rule.maximum = configuration.getMaxParams();
+			rules.add(rule);
+		}
+		if (configuration.getMaxBlockDepth() > 0) {
+			MaxBlockDepthRule rule = new MaxBlockDepthRule();
+			rule.maximum = configuration.getMaxBlockDepth();
+			rules.add(rule);
+		}
+		if (configuration.getMissingAsdoc()) {
+			rules.add(new MissingASDocRule());
+		}
+		if (configuration.getMissingConstructorSuper()) {
+			rules.add(new MissingConstructorSuperRule());
+		}
+		if (configuration.getMissingNamespace()) {
+			rules.add(new MissingNamespaceRule());
+		}
+		if (configuration.getMissingSemicolon()) {
+			rules.add(new MissingSemicolonRule());
+		}
+		if (configuration.getMissingType()) {
+			rules.add(new MissingTypeRule());
+		}
+		if (configuration.getMxmlId()) {
+			rules.add(new MXMLIDRule());
+		}
+		if (configuration.getMxmlEmptyAttr()) {
+			rules.add(new MXMLEmptyAttributeRule());
+		}
+		if (configuration.getNoAnyType()) {
+			rules.add(new NoAnyTypeRule());
+		}
+		if (configuration.getNoBooleanEquality()) {
+			rules.add(new NoBooleanEqualityRule());
+		}
+		if (configuration.getNoConstructorDispatch()) {
+			rules.add(new NoConstructorDispatchEventRule());
+		}
+		if (configuration.getNoConstructorReturnType()) {
+			rules.add(new NoConstructorReturnTypeRule());
+		}
+		if (configuration.getNoDuplicateKeys()) {
+			rules.add(new NoDuplicateObjectKeysRule());
+		}
+		if (configuration.getNoDynamicClass()) {
+			rules.add(new NoDynamicClassRule());
+		}
+		if (configuration.getNoIfBoolean()) {
+			rules.add(new NoIfBooleanLiteralRule());
+		}
+		if (configuration.getNoLeadingZero()) {
+			rules.add(new NoLeadingZeroesRule());
+		}
+		if (configuration.getNoSparseArray()) {
+			rules.add(new NoSparseArrayRule());
+		}
+		if (configuration.getNoStringEvent()) {
+			rules.add(new NoStringEventNameRule());
+		}
+		if (configuration.getNoThisClosure()) {
+			rules.add(new NoThisInClosureRule());
+		}
+		if (configuration.getNoTrace()) {
+			rules.add(new NoTraceRule());
+		}
+		if (configuration.getNoVoidOperator()) {
+			rules.add(new NoVoidOperatorRule());
+		}
+		if (configuration.getNoWildcardImport()) {
+			rules.add(new NoWildcardImportRule());
+		}
+		if (configuration.getNoWith()) {
+			rules.add(new NoWithRule());
+		}
+		if (configuration.getPackageName()) {
+			rules.add(new PackageNameRule());
+		}
+		if (configuration.getStaticConstants()) {
+			rules.add(new StaticConstantsRule());
+		}
+		if (configuration.getStrictEquality()) {
+			rules.add(new StrictEqualityRule());
+		}
+		if (configuration.getSwitchDefault()) {
+			rules.add(new SwitchWithoutDefaultRule());
+		}
+		if (configuration.getUnsafeNegation()) {
+			rules.add(new UnsafeNegationRule());
+		}
+		if (configuration.getValidTypeof()) {
+			rules.add(new ValidTypeofRule());
+		}
+		if (configuration.getVarsOnTop()) {
+			rules.add(new VariablesOnTopRule());
+		}
+		return rules;
+	}
+}


[royale-compiler] 02/02: linter: add ILinterProblem interface to allow for easier detection of linter problems

Posted by jo...@apache.org.
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

commit dc79c93d41ce08257d4d04b5eae865040473299a
Author: Josh Tynjala <jo...@apache.org>
AuthorDate: Wed Oct 5 10:32:15 2022 -0700

    linter: add ILinterProblem interface to allow for easier detection of linter problems
---
 .../ILinterProblem.java}                           | 32 ++--------------------
 .../apache/royale/linter/rules/ClassNameRule.java  |  3 +-
 .../royale/linter/rules/ConstantNameRule.java      |  3 +-
 .../royale/linter/rules/EmptyCommentRule.java      |  3 +-
 .../royale/linter/rules/EmptyFunctionBodyRule.java |  3 +-
 .../royale/linter/rules/EmptyNestedBlockRule.java  |  3 +-
 .../royale/linter/rules/EmptyStatementRule.java    |  3 +-
 .../apache/royale/linter/rules/FieldNameRule.java  |  3 +-
 .../royale/linter/rules/FunctionNameRule.java      |  3 +-
 .../royale/linter/rules/InterfaceNameRule.java     |  3 +-
 .../linter/rules/LineCommentPositionRule.java      |  3 +-
 .../linter/rules/LocalVarAndParameterNameRule.java |  5 ++--
 .../linter/rules/LocalVarShadowsFieldRule.java     |  3 +-
 .../linter/rules/MXMLEmptyAttributeRule.java       |  3 +-
 .../org/apache/royale/linter/rules/MXMLIDRule.java |  3 +-
 .../royale/linter/rules/MaxBlockDepthRule.java     |  3 +-
 .../royale/linter/rules/MaxParametersRule.java     |  3 +-
 .../royale/linter/rules/MissingASDocRule.java      |  5 ++--
 .../linter/rules/MissingConstructorSuperRule.java  |  3 +-
 .../royale/linter/rules/MissingNamespaceRule.java  | 13 +++++----
 .../royale/linter/rules/MissingSemicolonRule.java  |  3 +-
 .../royale/linter/rules/MissingTypeRule.java       |  7 +++--
 .../apache/royale/linter/rules/NoAnyTypeRule.java  |  7 +++--
 .../royale/linter/rules/NoBooleanEqualityRule.java |  3 +-
 .../rules/NoConstructorDispatchEventRule.java      |  5 ++--
 .../linter/rules/NoConstructorReturnTypeRule.java  |  3 +-
 .../linter/rules/NoDuplicateObjectKeysRule.java    |  3 +-
 .../royale/linter/rules/NoDynamicClassRule.java    |  3 +-
 .../linter/rules/NoIfBooleanLiteralRule.java       |  3 +-
 .../royale/linter/rules/NoLeadingZeroesRule.java   |  3 +-
 .../royale/linter/rules/NoSparseArrayRule.java     |  3 +-
 .../royale/linter/rules/NoStringEventNameRule.java |  7 +++--
 .../royale/linter/rules/NoThisInClosureRule.java   |  3 +-
 .../apache/royale/linter/rules/NoTraceRule.java    |  3 +-
 .../royale/linter/rules/NoVoidOperatorRule.java    |  3 +-
 .../royale/linter/rules/NoWildcardImportRule.java  |  3 +-
 .../org/apache/royale/linter/rules/NoWithRule.java |  4 ++-
 .../rules/OverrideContainsOnlySuperCallRule.java   |  3 +-
 .../royale/linter/rules/PackageNameRule.java       |  3 +-
 .../royale/linter/rules/StaticConstantsRule.java   |  3 +-
 .../royale/linter/rules/StrictEqualityRule.java    |  4 ++-
 .../linter/rules/SwitchWithoutDefaultRule.java     |  3 +-
 .../royale/linter/rules/UnsafeNegationRule.java    |  3 +-
 .../royale/linter/rules/ValidTypeofRule.java       |  3 +-
 .../royale/linter/rules/VariablesOnTopRule.java    |  3 +-
 45 files changed, 107 insertions(+), 87 deletions(-)

diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoWithRule.java b/linter/src/main/java/org/apache/royale/linter/problems/ILinterProblem.java
similarity index 51%
copy from linter/src/main/java/org/apache/royale/linter/rules/NoWithRule.java
copy to linter/src/main/java/org/apache/royale/linter/problems/ILinterProblem.java
index 388bd7a94..31eed863a 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoWithRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/problems/ILinterProblem.java
@@ -17,36 +17,10 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 
-package org.apache.royale.linter.rules;
+package org.apache.royale.linter.problems;
 
-import java.util.HashMap;
-import java.util.Map;
+import org.apache.royale.compiler.problems.ICompilerProblem;
 
-import org.apache.royale.compiler.internal.parsing.as.ASTokenTypes;
-import org.apache.royale.compiler.parsing.IASToken;
-import org.apache.royale.compiler.problems.CompilerProblem;
-import org.apache.royale.linter.LinterRule;
-import org.apache.royale.linter.TokenVisitor;
+public interface ILinterProblem extends ICompilerProblem {
 
-/**
- * Checks for uses of 'with(x)'.
- */
-public class NoWithRule extends LinterRule {
-	@Override
-	public Map<Integer, TokenVisitor> getTokenVisitors() {
-		Map<Integer, TokenVisitor> result = new HashMap<>();
-		result.put(ASTokenTypes.TOKEN_KEYWORD_WITH, (token, tokenQuery, problems) -> {
-			problems.add(new NoWithLinterProblem(token));
-		});
-		return result;
-	}
-
-	public static class NoWithLinterProblem extends CompilerProblem {
-		public static final String DESCRIPTION = "Must not use 'with' statement";
-
-		public NoWithLinterProblem(IASToken token)
-		{
-			super(token);
-		}
-	}
 }
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/ClassNameRule.java b/linter/src/main/java/org/apache/royale/linter/rules/ClassNameRule.java
index 462f28a6c..b0b208df7 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/ClassNameRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/ClassNameRule.java
@@ -32,6 +32,7 @@ import org.apache.royale.compiler.tree.as.IClassNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that class names match a specific pattern.
@@ -63,7 +64,7 @@ public class ClassNameRule extends LinterRule {
 		problems.add(new ClassNameLinterProblem(classNode, thePattern));
 	}
 
-	public static class ClassNameLinterProblem extends CompilerProblem {
+	public static class ClassNameLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Class name does not match the pattern '${pattern}'";
 
 		public ClassNameLinterProblem(IClassNode node, Pattern pattern)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/ConstantNameRule.java b/linter/src/main/java/org/apache/royale/linter/rules/ConstantNameRule.java
index 16f8b1cec..24798269e 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/ConstantNameRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/ConstantNameRule.java
@@ -32,6 +32,7 @@ import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that constant names match a specific pattern.
@@ -66,7 +67,7 @@ public class ConstantNameRule extends LinterRule {
 		problems.add(new ConstantNameLinterProblem(variableNode, thePattern));
 	}
 
-	public static class ConstantNameLinterProblem extends CompilerProblem {
+	public static class ConstantNameLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Constant name does not match the pattern '${pattern}'";
 
 		public ConstantNameLinterProblem(IVariableNode node, Pattern pattern)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/EmptyCommentRule.java b/linter/src/main/java/org/apache/royale/linter/rules/EmptyCommentRule.java
index 177c45b6c..31679040b 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/EmptyCommentRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/EmptyCommentRule.java
@@ -35,6 +35,7 @@ import org.apache.royale.linter.MXMLTokenQuery;
 import org.apache.royale.linter.MXMLTokenVisitor;
 import org.apache.royale.linter.TokenQuery;
 import org.apache.royale.linter.TokenVisitor;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for line or block comments that are empty.
@@ -95,7 +96,7 @@ public class EmptyCommentRule extends LinterRule {
 		problems.add(new EmptyCommentLinterProblem(comment));
 	}
 
-	public static class EmptyCommentLinterProblem extends CompilerProblem {
+	public static class EmptyCommentLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Comment must not be empty";
 
 		public EmptyCommentLinterProblem(IASToken token) {
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/EmptyFunctionBodyRule.java b/linter/src/main/java/org/apache/royale/linter/rules/EmptyFunctionBodyRule.java
index bfa04a6f0..bf357d633 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/EmptyFunctionBodyRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/EmptyFunctionBodyRule.java
@@ -32,6 +32,7 @@ import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for function bodies that are empty.
@@ -81,7 +82,7 @@ public class EmptyFunctionBodyRule extends LinterRule {
 		return true;
 	}
 
-	public static class EmptyFunctionBodyLinterProblem extends CompilerProblem {
+	public static class EmptyFunctionBodyLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Function body must not be empty";
 
 		public EmptyFunctionBodyLinterProblem(IBlockNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/EmptyNestedBlockRule.java b/linter/src/main/java/org/apache/royale/linter/rules/EmptyNestedBlockRule.java
index 87319ce99..d168c2a6e 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/EmptyNestedBlockRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/EmptyNestedBlockRule.java
@@ -34,6 +34,7 @@ import org.apache.royale.compiler.tree.as.ITypeNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for empty blocks, as long as they aren't the bodies of classes,
@@ -77,7 +78,7 @@ public class EmptyNestedBlockRule extends LinterRule {
 		return true;
 	}
 
-	public static class EmptyNestedBlockLinterProblem extends CompilerProblem {
+	public static class EmptyNestedBlockLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Block must not be empty";
 
 		public EmptyNestedBlockLinterProblem(IBlockNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/EmptyStatementRule.java b/linter/src/main/java/org/apache/royale/linter/rules/EmptyStatementRule.java
index ccfb3f841..62159539c 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/EmptyStatementRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/EmptyStatementRule.java
@@ -30,6 +30,7 @@ import org.apache.royale.compiler.problems.ICompilerProblem;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.TokenQuery;
 import org.apache.royale.linter.TokenVisitor;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for empty statements. An empty statement consists of only a semicolon
@@ -59,7 +60,7 @@ public class EmptyStatementRule extends LinterRule {
 		problems.add(new EmptyStatementLinterProblem(semicolon));
 	}
 
-	public static class EmptyStatementLinterProblem extends CompilerProblem {
+	public static class EmptyStatementLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Statement must not be empty";
 
 		public EmptyStatementLinterProblem(IASToken token)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/FieldNameRule.java b/linter/src/main/java/org/apache/royale/linter/rules/FieldNameRule.java
index 974613e1c..68c26a093 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/FieldNameRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/FieldNameRule.java
@@ -35,6 +35,7 @@ import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that field names match a specific pattern.
@@ -77,7 +78,7 @@ public class FieldNameRule extends LinterRule {
 		problems.add(new FieldNameLinterProblem(variableNode, thePattern));
 	}
 
-	public static class FieldNameLinterProblem extends CompilerProblem {
+	public static class FieldNameLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Field name '${varName}' does not match the pattern '${pattern}'";
 
 		public FieldNameLinterProblem(IVariableNode node, Pattern pattern)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/FunctionNameRule.java b/linter/src/main/java/org/apache/royale/linter/rules/FunctionNameRule.java
index 9cb10db3e..66618bb11 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/FunctionNameRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/FunctionNameRule.java
@@ -32,6 +32,7 @@ import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that function names match a specific pattern.
@@ -70,7 +71,7 @@ public class FunctionNameRule extends LinterRule {
 		problems.add(new FunctionNameLinterProblem(functionNode, thePattern));
 	}
 
-	public static class FunctionNameLinterProblem extends CompilerProblem {
+	public static class FunctionNameLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Function name '${functionName}' does not match the pattern '${pattern}'";
 
 		public FunctionNameLinterProblem(IFunctionNode node, Pattern pattern)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/InterfaceNameRule.java b/linter/src/main/java/org/apache/royale/linter/rules/InterfaceNameRule.java
index 23a4d2770..8629d8fae 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/InterfaceNameRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/InterfaceNameRule.java
@@ -32,6 +32,7 @@ import org.apache.royale.compiler.tree.as.IInterfaceNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that interface names match a specific pattern.
@@ -63,7 +64,7 @@ public class InterfaceNameRule extends LinterRule {
 		problems.add(new InterfaceNameLinterProblem(interfaceNode, thePattern));
 	}
 
-	public static class InterfaceNameLinterProblem extends CompilerProblem {
+	public static class InterfaceNameLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Interface name does not match the pattern '${pattern}'";
 
 		public InterfaceNameLinterProblem(IInterfaceNode node, Pattern pattern)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/LineCommentPositionRule.java b/linter/src/main/java/org/apache/royale/linter/rules/LineCommentPositionRule.java
index ae3fc4b0f..6a58c927c 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/LineCommentPositionRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/LineCommentPositionRule.java
@@ -31,6 +31,7 @@ import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.TokenQuery;
 import org.apache.royale.linter.TokenVisitor;
 import org.apache.royale.linter.config.LineCommentPosition;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks if line comments appear beside code on the same line, or on a
@@ -65,7 +66,7 @@ public class LineCommentPositionRule extends LinterRule {
 		}
 	}
 
-	public static class LineCommentPositionLinterProblem extends CompilerProblem {
+	public static class LineCommentPositionLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Comment must be ${position} code";
 
 		public LineCommentPositionLinterProblem(IASToken token, LineCommentPosition position)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/LocalVarAndParameterNameRule.java b/linter/src/main/java/org/apache/royale/linter/rules/LocalVarAndParameterNameRule.java
index 6a1be14de..589d385cd 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/LocalVarAndParameterNameRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/LocalVarAndParameterNameRule.java
@@ -37,6 +37,7 @@ import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that local variable and parameter names match a specific pattern.
@@ -95,7 +96,7 @@ public class LocalVarAndParameterNameRule extends LinterRule {
 		problems.add(new ParameterNameLinterProblem(paramNode, thePattern));
 	}
 
-	public static class LocalVarNameLinterProblem extends CompilerProblem {
+	public static class LocalVarNameLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Variable name '${varName}' does not match the pattern '${pattern}'";
 
 		public LocalVarNameLinterProblem(IVariableNode node, Pattern pattern)
@@ -109,7 +110,7 @@ public class LocalVarAndParameterNameRule extends LinterRule {
 		public String varName;
 	}
 
-	public static class ParameterNameLinterProblem extends CompilerProblem {
+	public static class ParameterNameLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Parameter name '${paramName}' does not match the pattern '${pattern}'";
 
 		public ParameterNameLinterProblem(IVariableNode node, Pattern pattern)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/LocalVarShadowsFieldRule.java b/linter/src/main/java/org/apache/royale/linter/rules/LocalVarShadowsFieldRule.java
index 4fce9ce8c..125034139 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/LocalVarShadowsFieldRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/LocalVarShadowsFieldRule.java
@@ -35,6 +35,7 @@ import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 public class LocalVarShadowsFieldRule extends LinterRule {
 	@Override
@@ -72,7 +73,7 @@ public class LocalVarShadowsFieldRule extends LinterRule {
 		}
 	}
 
-	public static class LocalVarShadowsFieldLinterProblem extends CompilerProblem {
+	public static class LocalVarShadowsFieldLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Local variable '${varName}' has the same name as field in class '${className}'";
 
 		public LocalVarShadowsFieldLinterProblem(IVariableNode variableNode, IClassNode classNode)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MXMLEmptyAttributeRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MXMLEmptyAttributeRule.java
index 147ea2b56..3594e58d9 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/MXMLEmptyAttributeRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/MXMLEmptyAttributeRule.java
@@ -30,6 +30,7 @@ import org.apache.royale.compiler.problems.ICompilerProblem;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.MXMLTagVisitor;
 import org.apache.royale.linter.MXMLTokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that MXML attribute values are not empty.
@@ -52,7 +53,7 @@ public class MXMLEmptyAttributeRule extends LinterRule {
 		}
 	}
 
-	public static class MXMLEmptyAttributeLinterProblem extends CompilerProblem {
+	public static class MXMLEmptyAttributeLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "MXML attribute '${attributeName}' value is empty";
 
 		public MXMLEmptyAttributeLinterProblem(IMXMLTagAttributeData attribute) {
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MXMLIDRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MXMLIDRule.java
index 428704443..d5dbe68f1 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/MXMLIDRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/MXMLIDRule.java
@@ -32,6 +32,7 @@ import org.apache.royale.compiler.problems.ICompilerProblem;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.MXMLTagVisitor;
 import org.apache.royale.linter.MXMLTokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that MXML id attribute values match a specific pattern.
@@ -66,7 +67,7 @@ public class MXMLIDRule extends LinterRule {
 		problems.add(new MXMLIDLinterProblem(idAttribute, thePattern));
 	}
 
-	public static class MXMLIDLinterProblem extends CompilerProblem {
+	public static class MXMLIDLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "MXML id '${idValue}' does not match the pattern '${pattern}'";
 
 		public MXMLIDLinterProblem(IMXMLTagAttributeData attribute, Pattern pattern)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MaxBlockDepthRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MaxBlockDepthRule.java
index 49aa594eb..b8e195391 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/MaxBlockDepthRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/MaxBlockDepthRule.java
@@ -34,6 +34,7 @@ import org.apache.royale.compiler.tree.as.IStatementNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks the number of nested blocks in a function.
@@ -95,7 +96,7 @@ public class MaxBlockDepthRule extends LinterRule {
 		return maxDepth;
 	}
 
-	public static class MaxBlockDepthLinterProblem extends CompilerProblem {
+	public static class MaxBlockDepthLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Function '${functionName}' has blocks nested ${depth} levels deep, but expected no deeper than ${maxDepth} levels";
 
 		public MaxBlockDepthLinterProblem(IFunctionNode node, int depth, int maxDepth)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MaxParametersRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MaxParametersRule.java
index b2005b30a..13acef074 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/MaxParametersRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/MaxParametersRule.java
@@ -30,6 +30,7 @@ import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks the number of function parameters.
@@ -53,7 +54,7 @@ public class MaxParametersRule extends LinterRule {
 		problems.add(new MaxParametersLinterProblem(functionNode, maximum));
 	}
 
-	public static class MaxParametersLinterProblem extends CompilerProblem {
+	public static class MaxParametersLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Function '${functionName}' has ${params} parameters, but expected no more than ${maxParams} parameters";
 
 		public MaxParametersLinterProblem(IFunctionNode node, int maxParams)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MissingASDocRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MissingASDocRule.java
index 5459afd60..5c8e3ba86 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/MissingASDocRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/MissingASDocRule.java
@@ -37,6 +37,7 @@ import org.apache.royale.linter.MXMLTokenQuery;
 import org.apache.royale.linter.MXMLTokenVisitor;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for missing or empty ASDoc comments.
@@ -115,7 +116,7 @@ public class MissingASDocRule extends LinterRule {
 		problems.add(new EmptyASDocLinterProblem(comment));
 	}
 
-	public static class MissingASDocLinterProblem extends CompilerProblem {
+	public static class MissingASDocLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Public APIs must have ASDoc comments";
 
 		public MissingASDocLinterProblem(IDocumentableDefinitionNode node)
@@ -124,7 +125,7 @@ public class MissingASDocRule extends LinterRule {
 		}
 	}
 
-	public static class EmptyASDocLinterProblem extends CompilerProblem {
+	public static class EmptyASDocLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "ASDoc comments must not be empty";
 
 		public EmptyASDocLinterProblem(IASToken token)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MissingConstructorSuperRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MissingConstructorSuperRule.java
index f2863b768..1d186c788 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/MissingConstructorSuperRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/MissingConstructorSuperRule.java
@@ -35,6 +35,7 @@ import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode.LanguageIdenti
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that all constructors include a call to super().
@@ -79,7 +80,7 @@ public class MissingConstructorSuperRule extends LinterRule {
 		return false;
 	}
 
-	public static class MissingConstructorSuperLinterProblem extends CompilerProblem {
+	public static class MissingConstructorSuperLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Constructor '${functionName}' does not include 'super()' call";
 
 		public MissingConstructorSuperLinterProblem(IFunctionNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MissingNamespaceRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MissingNamespaceRule.java
index 1d0262680..13d032757 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/MissingNamespaceRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/MissingNamespaceRule.java
@@ -41,6 +41,7 @@ import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that symbols in package or class scopes have a namespace.
@@ -145,7 +146,7 @@ public class MissingNamespaceRule extends LinterRule {
 		return ns != null;
 	}
 
-	public static class MissingNamespaceOnClassLinterProblem extends CompilerProblem {
+	public static class MissingNamespaceOnClassLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing namespace on class '${className}'";
 
 		public MissingNamespaceOnClassLinterProblem(IClassNode node)
@@ -157,7 +158,7 @@ public class MissingNamespaceRule extends LinterRule {
 		public String className;
 	}
 
-	public static class MissingNamespaceOnInterfaceLinterProblem extends CompilerProblem {
+	public static class MissingNamespaceOnInterfaceLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing namespace on interface '${interfaceName}'";
 
 		public MissingNamespaceOnInterfaceLinterProblem(IInterfaceNode node)
@@ -169,7 +170,7 @@ public class MissingNamespaceRule extends LinterRule {
 		public String interfaceName;
 	}
 
-	public static class MissingNamespaceOnPackageFunctionLinterProblem extends CompilerProblem {
+	public static class MissingNamespaceOnPackageFunctionLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing namespace on package function '${functionName}'";
 
 		public MissingNamespaceOnPackageFunctionLinterProblem(IFunctionNode node)
@@ -181,7 +182,7 @@ public class MissingNamespaceRule extends LinterRule {
 		public String functionName;
 	}
 
-	public static class MissingNamespaceOnMethodLinterProblem extends CompilerProblem {
+	public static class MissingNamespaceOnMethodLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing namespace on method '${functionName}'";
 
 		public MissingNamespaceOnMethodLinterProblem(IFunctionNode node)
@@ -193,7 +194,7 @@ public class MissingNamespaceRule extends LinterRule {
 		public String functionName;
 	}
 
-	public static class MissingNamespaceOnPackageVariableLinterProblem extends CompilerProblem {
+	public static class MissingNamespaceOnPackageVariableLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing namespace on package variable '${variableName}'";
 
 		public MissingNamespaceOnPackageVariableLinterProblem(IVariableNode node)
@@ -205,7 +206,7 @@ public class MissingNamespaceRule extends LinterRule {
 		public String variableName;
 	}
 
-	public static class MissingNamespaceOnFieldLinterProblem extends CompilerProblem {
+	public static class MissingNamespaceOnFieldLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing namespace on field '${variableName}'";
 
 		public MissingNamespaceOnFieldLinterProblem(IVariableNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MissingSemicolonRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MissingSemicolonRule.java
index 50a5371f9..9aa1368c1 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/MissingSemicolonRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/MissingSemicolonRule.java
@@ -30,6 +30,7 @@ import org.apache.royale.compiler.problems.ICompilerProblem;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.TokenQuery;
 import org.apache.royale.linter.TokenVisitor;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for statements with missing semicolons.
@@ -51,7 +52,7 @@ public class MissingSemicolonRule extends LinterRule {
 		problems.add(new MissingSemicolonLinterProblem(semicolon));
 	}
 
-	public static class MissingSemicolonLinterProblem extends CompilerProblem {
+	public static class MissingSemicolonLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Semicolon is required";
 
 		public MissingSemicolonLinterProblem(IASToken token)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/MissingTypeRule.java b/linter/src/main/java/org/apache/royale/linter/rules/MissingTypeRule.java
index 1b1903475..70227b73b 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/MissingTypeRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/MissingTypeRule.java
@@ -34,6 +34,7 @@ import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks that a type has been declared for all variables, function parameters,
@@ -94,7 +95,7 @@ public class MissingTypeRule extends LinterRule {
 		return true;
 	}
 
-	public static class MissingVariableTypeLinterProblem extends CompilerProblem {
+	public static class MissingVariableTypeLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing type for variable '${varName}'";
 
 		public MissingVariableTypeLinterProblem(IVariableNode node)
@@ -106,7 +107,7 @@ public class MissingTypeRule extends LinterRule {
 		public String varName;
 	}
 
-	public static class MissingFunctionParameterTypeLinterProblem extends CompilerProblem {
+	public static class MissingFunctionParameterTypeLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing type for function parameter '${paramName}'";
 
 		public MissingFunctionParameterTypeLinterProblem(IParameterNode node)
@@ -118,7 +119,7 @@ public class MissingTypeRule extends LinterRule {
 		public String paramName;
 	}
 
-	public static class MissingFunctionReturnTypeLinterProblem extends CompilerProblem {
+	public static class MissingFunctionReturnTypeLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing function return type";
 
 		public MissingFunctionReturnTypeLinterProblem(IFunctionNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoAnyTypeRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoAnyTypeRule.java
index f1879710a..ac5b58bc7 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoAnyTypeRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoAnyTypeRule.java
@@ -36,6 +36,7 @@ import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for uses of the * type.
@@ -92,7 +93,7 @@ public class NoAnyTypeRule extends LinterRule {
 		return true;
 	}
 
-	public static class NoAnyTypeOnVariableLinterProblem extends CompilerProblem {
+	public static class NoAnyTypeOnVariableLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must not use the * type for variable '${varName}'";
 
 		public NoAnyTypeOnVariableLinterProblem(IVariableNode node)
@@ -104,7 +105,7 @@ public class NoAnyTypeRule extends LinterRule {
 		public String varName;
 	}
 
-	public static class NoAnyTypeOnParameterLinterProblem extends CompilerProblem {
+	public static class NoAnyTypeOnParameterLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must not use the * type for function parameter '${paramName}'";
 
 		public NoAnyTypeOnParameterLinterProblem(IParameterNode node)
@@ -116,7 +117,7 @@ public class NoAnyTypeRule extends LinterRule {
 		public String paramName;
 	}
 
-	public static class NoAnyTypeReturnLinterProblem extends CompilerProblem {
+	public static class NoAnyTypeReturnLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must not use the * type for function return type";
 
 		public NoAnyTypeReturnLinterProblem(IFunctionNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoBooleanEqualityRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoBooleanEqualityRule.java
index 8209e554c..5768718f5 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoBooleanEqualityRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoBooleanEqualityRule.java
@@ -31,6 +31,7 @@ import org.apache.royale.compiler.tree.as.IExpressionNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for redundant equality comparisons with 'true' and 'false' boolean
@@ -64,7 +65,7 @@ public class NoBooleanEqualityRule extends LinterRule {
 		}
 	}
 
-	public static class NoBooleanEqualityLinterProblem extends CompilerProblem {
+	public static class NoBooleanEqualityLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must simplify statement to remove redundant comparison with true or false";
 
 		public NoBooleanEqualityLinterProblem(IExpressionNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoConstructorDispatchEventRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoConstructorDispatchEventRule.java
index 6ab9109f4..50bb49668 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoConstructorDispatchEventRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoConstructorDispatchEventRule.java
@@ -31,11 +31,12 @@ import org.apache.royale.compiler.tree.as.IFunctionCallNode;
 import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.compiler.tree.as.IIdentifierNode;
 import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode;
-import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
 import org.apache.royale.compiler.tree.as.ILanguageIdentifierNode.LanguageIdentifierKind;
+import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that a constructor does not call `dispatchEvent` because it's likely
@@ -84,7 +85,7 @@ public class NoConstructorDispatchEventRule extends LinterRule {
 		}
 	}
 
-	public static class NoConstructorDispatchEventLinterProblem extends CompilerProblem {
+	public static class NoConstructorDispatchEventLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Constructor '${functionName}' must not call 'dispatchEvent'";
 
 		public NoConstructorDispatchEventLinterProblem(IFunctionNode functionNode, IExpressionNode dispatchEventNode) {
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoConstructorReturnTypeRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoConstructorReturnTypeRule.java
index e3d547544..12c72a6d1 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoConstructorReturnTypeRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoConstructorReturnTypeRule.java
@@ -31,6 +31,7 @@ import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that a constructor does not specify a return type (not even `void`).
@@ -56,7 +57,7 @@ public class NoConstructorReturnTypeRule extends LinterRule {
 		problems.add(new NoConstructorReturnTypeLinterProblem(functionNode));
 	}
 
-	public static class NoConstructorReturnTypeLinterProblem extends CompilerProblem {
+	public static class NoConstructorReturnTypeLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Constructor '${functionName}' must not specify '${returnType}' return type";
 
 		public NoConstructorReturnTypeLinterProblem(IFunctionNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoDuplicateObjectKeysRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoDuplicateObjectKeysRule.java
index 601af9f01..48befed34 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoDuplicateObjectKeysRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoDuplicateObjectKeysRule.java
@@ -39,6 +39,7 @@ import org.apache.royale.compiler.tree.as.IObjectLiteralValuePairNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that each key in an object literal is unique.
@@ -90,7 +91,7 @@ public class NoDuplicateObjectKeysRule extends LinterRule {
 		}
 	}
 
-	public static class NoDuplicateObjectKeysLinterProblem extends CompilerProblem {
+	public static class NoDuplicateObjectKeysLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Object literal contains duplicate key '${keyName}'";
 
 		public NoDuplicateObjectKeysLinterProblem(IExpressionNode node, String keyName)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoDynamicClassRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoDynamicClassRule.java
index f56b11e11..cb2af9d34 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoDynamicClassRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoDynamicClassRule.java
@@ -31,6 +31,7 @@ import org.apache.royale.compiler.tree.as.IClassNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that symbols in package or class scopes have a namespace.
@@ -52,7 +53,7 @@ public class NoDynamicClassRule extends LinterRule {
 		problems.add(new NoDynamicClassLinterProblem(classNode));
 	}
 
-	public static class NoDynamicClassLinterProblem extends CompilerProblem {
+	public static class NoDynamicClassLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Class '${className}' must not be dynamic";
 
 		public NoDynamicClassLinterProblem(IClassNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoIfBooleanLiteralRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoIfBooleanLiteralRule.java
index 457520f7d..dd171c174 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoIfBooleanLiteralRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoIfBooleanLiteralRule.java
@@ -33,6 +33,7 @@ import org.apache.royale.compiler.tree.as.ILiteralNode.LiteralType;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that a boolean literal value is not used as an 'if' condition.
@@ -59,7 +60,7 @@ public class NoIfBooleanLiteralRule extends LinterRule {
 		problems.add(new NoIfBooleanLiteralLinterProblem(literalNode));
 	}
 
-	public static class NoIfBooleanLiteralLinterProblem extends CompilerProblem {
+	public static class NoIfBooleanLiteralLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Condition is always '${value}'";
 
 		public NoIfBooleanLiteralLinterProblem(ILiteralNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoLeadingZeroesRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoLeadingZeroesRule.java
index d5470755d..c860e990b 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoLeadingZeroesRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoLeadingZeroesRule.java
@@ -31,6 +31,7 @@ import org.apache.royale.compiler.tree.as.INumericLiteralNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for use of numeric literals with leading zeroes, except when it starts
@@ -65,7 +66,7 @@ public class NoLeadingZeroesRule extends LinterRule {
 		problems.add(new NoLeadingZeroesLinterProblem(numberNode));
 	}
 
-	public static class NoLeadingZeroesLinterProblem extends CompilerProblem {
+	public static class NoLeadingZeroesLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must remove leading zeros from numeric literal '${value}'";
 
 		public NoLeadingZeroesLinterProblem(INumericLiteralNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoSparseArrayRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoSparseArrayRule.java
index 3420b55c3..91238b65d 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoSparseArrayRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoSparseArrayRule.java
@@ -33,6 +33,7 @@ import org.apache.royale.compiler.tree.as.ILiteralNode.LiteralType;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that an array literal contains no empty slots (multiple repeating commas with no values).
@@ -64,7 +65,7 @@ public class NoSparseArrayRule extends LinterRule {
 		}
 	}
 
-	public static class NoSparseArrayLinterProblem extends CompilerProblem {
+	public static class NoSparseArrayLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Array literals must not be sparse";
 
 		public NoSparseArrayLinterProblem(ILiteralContainerNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoStringEventNameRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoStringEventNameRule.java
index c4541bbf1..f3e5ec7e2 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoStringEventNameRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoStringEventNameRule.java
@@ -36,6 +36,7 @@ import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that calls to event dispatcher methods don't use string values for
@@ -90,13 +91,13 @@ public class NoStringEventNameRule extends LinterRule {
 		if (!LiteralType.STRING.equals(literalNode.getLiteralType())) {
 			return;
 		}
-		problems.add(new NoStringEventNameProblem(functionCallNode, functionName));
+		problems.add(new NoStringEventNameLinterProblem(functionCallNode, functionName));
 	}
 
-	public static class NoStringEventNameProblem extends CompilerProblem {
+	public static class NoStringEventNameLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Calls to '${functionName}' must use constant value instead of string literal for event name";
 
-		public NoStringEventNameProblem(IFunctionCallNode node, String functionName)
+		public NoStringEventNameLinterProblem(IFunctionCallNode node, String functionName)
 		{
 			super(node.getArgumentNodes()[0]);
 			this.functionName = functionName;
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoThisInClosureRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoThisInClosureRule.java
index 38db15c16..fa9dfbd0c 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoThisInClosureRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoThisInClosureRule.java
@@ -34,6 +34,7 @@ import org.apache.royale.compiler.tree.as.IFunctionNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for use of the 'this' keyword in closures.
@@ -75,7 +76,7 @@ public class NoThisInClosureRule extends LinterRule {
 		return null;
 	}
 
-	public static class NoThisInClosureLinterProblem extends CompilerProblem {
+	public static class NoThisInClosureLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Closure must not contain 'this' keyword";
 
 		public NoThisInClosureLinterProblem(IASToken token)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoTraceRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoTraceRule.java
index 39ee54e5d..daf7f5543 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoTraceRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoTraceRule.java
@@ -32,6 +32,7 @@ import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check for calls to the 'trace()' function.
@@ -57,7 +58,7 @@ public class NoTraceRule extends LinterRule {
 		problems.add(new NoTraceLinterProblem(functionCallNode));
 	}
 
-	public static class NoTraceLinterProblem extends CompilerProblem {
+	public static class NoTraceLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must not call trace() function";
 
 		public NoTraceLinterProblem(IFunctionCallNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoVoidOperatorRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoVoidOperatorRule.java
index 76e7e7d13..5f4c71bdf 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoVoidOperatorRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoVoidOperatorRule.java
@@ -31,6 +31,7 @@ import org.apache.royale.compiler.tree.as.IUnaryOperatorNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for uses of 'void' operator. Using 'void' as return type is allowed.
@@ -53,7 +54,7 @@ public class NoVoidOperatorRule extends LinterRule {
 		problems.add(new NoVoidOperatorLinterProblem(unaryOperatorNode));
 	}
 
-	public static class NoVoidOperatorLinterProblem extends CompilerProblem {
+	public static class NoVoidOperatorLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must not use 'void' operator";
 
 		public NoVoidOperatorLinterProblem(IUnaryOperatorNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoWildcardImportRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoWildcardImportRule.java
index 62b479112..6ed33246b 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoWildcardImportRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoWildcardImportRule.java
@@ -30,6 +30,7 @@ import org.apache.royale.compiler.tree.as.IImportNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check for import statements that import the entire package.
@@ -51,7 +52,7 @@ public class NoWildcardImportRule extends LinterRule {
 		problems.add(new NoWildcardImportLinterProblem(importNode));
 	}
 
-	public static class NoWildcardImportLinterProblem extends CompilerProblem {
+	public static class NoWildcardImportLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must not use wildcard import";
 
 		public NoWildcardImportLinterProblem(IImportNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/NoWithRule.java b/linter/src/main/java/org/apache/royale/linter/rules/NoWithRule.java
index 388bd7a94..5301d3c1e 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/NoWithRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/NoWithRule.java
@@ -27,6 +27,8 @@ import org.apache.royale.compiler.parsing.IASToken;
 import org.apache.royale.compiler.problems.CompilerProblem;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.TokenVisitor;
+import org.apache.royale.linter.problems.ILinterProblem;
+import org.apache.royale.linter.rules.NoWithRule.NoWithLinterProblem;
 
 /**
  * Checks for uses of 'with(x)'.
@@ -41,7 +43,7 @@ public class NoWithRule extends LinterRule {
 		return result;
 	}
 
-	public static class NoWithLinterProblem extends CompilerProblem {
+	public static class NoWithLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must not use 'with' statement";
 
 		public NoWithLinterProblem(IASToken token)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/OverrideContainsOnlySuperCallRule.java b/linter/src/main/java/org/apache/royale/linter/rules/OverrideContainsOnlySuperCallRule.java
index 2138aed72..1b0d9a13a 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/OverrideContainsOnlySuperCallRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/OverrideContainsOnlySuperCallRule.java
@@ -39,6 +39,7 @@ import org.apache.royale.compiler.tree.as.IScopedNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that an overridden function contains more than a call to super.
@@ -89,7 +90,7 @@ public class OverrideContainsOnlySuperCallRule extends LinterRule {
 		problems.add(new OverrideContainsOnlySuperCallLinterProblem(functionNode));
 	}
 
-	public static class OverrideContainsOnlySuperCallLinterProblem extends CompilerProblem {
+	public static class OverrideContainsOnlySuperCallLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Method override '${functionName}' must contain more than call to 'super.${functionName}'";
 
 		public OverrideContainsOnlySuperCallLinterProblem(IFunctionNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/PackageNameRule.java b/linter/src/main/java/org/apache/royale/linter/rules/PackageNameRule.java
index de50e9a4d..9aaf7a8dd 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/PackageNameRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/PackageNameRule.java
@@ -32,6 +32,7 @@ import org.apache.royale.compiler.tree.as.IPackageNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that package names match a specific pattern.
@@ -66,7 +67,7 @@ public class PackageNameRule extends LinterRule {
 		problems.add(new PackageNameLinterProblem(packageNode, thePattern));
 	}
 
-	public static class PackageNameLinterProblem extends CompilerProblem {
+	public static class PackageNameLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Package name '${packageName}' does not match the pattern '${pattern}'";
 
 		public PackageNameLinterProblem(IPackageNode node, Pattern pattern)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/StaticConstantsRule.java b/linter/src/main/java/org/apache/royale/linter/rules/StaticConstantsRule.java
index 59ddba9a9..bab41c9c6 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/StaticConstantsRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/StaticConstantsRule.java
@@ -34,6 +34,7 @@ import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Checks for constants that are declared on a class, but are not static.
@@ -63,7 +64,7 @@ public class StaticConstantsRule extends LinterRule {
 		problems.add(new StaticConstantsLinterProblem(variableNode));
 	}
 
-	public static class StaticConstantsLinterProblem extends CompilerProblem {
+	public static class StaticConstantsLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Constant must be static";
 
 		public StaticConstantsLinterProblem(IVariableNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/StrictEqualityRule.java b/linter/src/main/java/org/apache/royale/linter/rules/StrictEqualityRule.java
index 457617cbf..4ba214e8a 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/StrictEqualityRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/StrictEqualityRule.java
@@ -28,6 +28,8 @@ import org.apache.royale.compiler.problems.CompilerProblem;
 import org.apache.royale.compiler.tree.as.IOperatorNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.TokenVisitor;
+import org.apache.royale.linter.problems.ILinterProblem;
+import org.apache.royale.linter.rules.StrictEqualityRule.StrictEqualityLinterProblem;
 
 /**
  * Checks for uses of the '==' and '!='' operators instead of the stricter '==='
@@ -46,7 +48,7 @@ public class StrictEqualityRule extends LinterRule {
 		return result;
 	}
 
-	public static class StrictEqualityLinterProblem extends CompilerProblem {
+	public static class StrictEqualityLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must use ${requiredTokenText} instead of ${tokenText}";
 
 		public StrictEqualityLinterProblem(IASToken token)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/SwitchWithoutDefaultRule.java b/linter/src/main/java/org/apache/royale/linter/rules/SwitchWithoutDefaultRule.java
index 3a9a7b667..fa30f1546 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/SwitchWithoutDefaultRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/SwitchWithoutDefaultRule.java
@@ -31,6 +31,7 @@ import org.apache.royale.compiler.tree.as.ITerminalNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check for 'switch' statements that are missing a 'default' clause.
@@ -53,7 +54,7 @@ public class SwitchWithoutDefaultRule extends LinterRule {
 		problems.add(new SwitchWithoutDefaultLinterProblem(switchNode));
 	}
 
-	public static class SwitchWithoutDefaultLinterProblem extends CompilerProblem {
+	public static class SwitchWithoutDefaultLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Missing 'default' clause in 'switch' statement";
 
 		public SwitchWithoutDefaultLinterProblem(ISwitchNode node)
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/UnsafeNegationRule.java b/linter/src/main/java/org/apache/royale/linter/rules/UnsafeNegationRule.java
index ab766f584..9f74ad101 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/UnsafeNegationRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/UnsafeNegationRule.java
@@ -34,6 +34,7 @@ import org.apache.royale.compiler.tree.as.IUnaryOperatorNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that the left side of in, is, and instanceof is not negated unsafely.
@@ -67,7 +68,7 @@ public class UnsafeNegationRule extends LinterRule {
 		problems.add(new UnsafeNegationLinterProblem(binaryOperatorNode));
 	}
 
-	public static class UnsafeNegationLinterProblem extends CompilerProblem {
+	public static class UnsafeNegationLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Must not use negation on left side of in, is, and instanceof operators. Did you mean to use parentheses?";
 
 		public UnsafeNegationLinterProblem(IASNode node) {
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/ValidTypeofRule.java b/linter/src/main/java/org/apache/royale/linter/rules/ValidTypeofRule.java
index 0e3821597..1eb9eeb89 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/ValidTypeofRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/ValidTypeofRule.java
@@ -38,6 +38,7 @@ import org.apache.royale.compiler.tree.as.IUnaryOperatorNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that an array literal contains no empty slots (multiple repeating
@@ -97,7 +98,7 @@ public class ValidTypeofRule extends LinterRule {
 		problems.add(new ValidTypeofLinterProblem(stringLiteral));
 	}
 
-	public static class ValidTypeofLinterProblem extends CompilerProblem {
+	public static class ValidTypeofLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "String '${value}' is not a valid result for typeof operator";
 
 		public ValidTypeofLinterProblem(ILiteralNode node) {
diff --git a/linter/src/main/java/org/apache/royale/linter/rules/VariablesOnTopRule.java b/linter/src/main/java/org/apache/royale/linter/rules/VariablesOnTopRule.java
index a6ae31f94..7ef51d642 100644
--- a/linter/src/main/java/org/apache/royale/linter/rules/VariablesOnTopRule.java
+++ b/linter/src/main/java/org/apache/royale/linter/rules/VariablesOnTopRule.java
@@ -33,6 +33,7 @@ import org.apache.royale.compiler.tree.as.IVariableNode;
 import org.apache.royale.linter.LinterRule;
 import org.apache.royale.linter.NodeVisitor;
 import org.apache.royale.linter.TokenQuery;
+import org.apache.royale.linter.problems.ILinterProblem;
 
 /**
  * Check that variables are always declared at the top of a function.
@@ -75,7 +76,7 @@ public class VariablesOnTopRule extends LinterRule {
 		return afterNonVariable;
 	}
 
-	public static class VariablesOnTopLinterProblem extends CompilerProblem {
+	public static class VariablesOnTopLinterProblem extends CompilerProblem implements ILinterProblem {
 		public static final String DESCRIPTION = "Variable name '${varName}' must be declared at the top of this function";
 
 		public VariablesOnTopLinterProblem(IVariableNode node)