public static fields should be constant
There is no good reason to declare a field “public” and “static” without also declaring it “const”. Most of the time this is a kludge to share a state among several objects. But with this approach, any object can do whatever it wants with the shared state, such as setting it to null
.
Classes that extend Event should override Event.clone()
Overriding Event.clone() is a required part of the API contract:
Alert.show(...) should not be used
Alert.show(…)
can be useful for debugging during development, but in production mode this kind of pop-up could expose sensitive information to attackers, and should never be displayed.
The element type of an array field should be specified
Quoted from the Flex documentation :
Only while, do and for statements should be labelled
Any statement or block of statements can be identified by a label, but those labels should be used only on while, do-while and for
statements. Using labels in any other context leads to unstructured, confusing code.
Statements should end with semicolons
In Flex, the semicolon is optional as a statement separator, but omitting semicolons can be confusing.
The flash.system.Security.exactSettings property should never be set to false
The Security.exactSettings value should remain set at the default value of true. Setting this value to false could make the SWF vulnerable to cross-domain attacks.
The special star type should not be used
According to the ActionScript language reference, the star type:
But deferring type checking to runtime can highly impact the robustness of the application because the compiler is unable to assist the developer.
Function call arguments should not start on new lines
Because semicolons at the ends of statements are optional, starting function call arguments on a separate line makes the code confusing. It could lead to errors and most likely will lead to questions for maintainers.
What was the initial intent of the developer?
Define a function and then execute some unrelated code inside a closure ?
Pass the second function as a parameter to the first one ?
The first option will be the one chosen by the JavaScript interpreter.
By extension, and to improve readability, any kind of function call argument should not start on new line.
Event names should not be hardcoded in event listeners
Using plain string event names in even listeners is an anti-pattern; if the event is renamed, the application can start behaving unexpectedly. A constant variable should be used instead.
Method visibility should be explicitly declared
Access modifiers define which classes can access properties, variables, methods, and other classes. If an access modifier is not specified, the access level defaults to `internal, which grants access to all classes in the same package. This may be what is intended, but it should be specified explicitly to avoid confusion.
Available access modifiers are:
internal - access allowed within the same package
private - access allowed only within the same class
protected - access allowed to the class and its child classes
public` - unfettered access by all
ManagedEvents tags should have companion Event tags
with statements should not be used
Never use with
statements, since they decrease readability. When you do not specify a variable’s scope, you do not always know where you are setting properties, so your code can be confusing.
Objects should not be instantiated inside a loop
It can be expensive to instantiate a new object, and doing so inside a loop is typically an error. Instead, create the object once, before the loop.
The trace function should not be used
The trace() function outputs debug statements, which can be read by anyone with a debug version of the Flash player. Because sensitive information could easily be exposed in this manner, trace()
should never appear in production code.
Package definition should be separate from Class definition
Declaring the package and class together has been deprecated since ActionScript 3. The package definition should be declared outside of the class definition even if the old syntax is still supported.
Loggers should be private static const and should share naming convention
Function names should comply with a naming convention
For example, with the default provided regular expression ^[a-z][a-zA-Z0-9]*$
, the function:
Multiple ++ or -- unary operators should not be used in a single arithmetic expression
Using several ”—” or ”++” unary operators in the same arithmetic expression can quickly make the expression unreadable.
Control flow statements if, for, while and switch should not be nested too deeply
Nested control flow statements if, for, while, do while and switch
are often key ingredients in creating
what’s known as “Spaghetti code”. This code smell can make your program difficult to understand and maintain.
When numerous control structures are placed inside one another, the code becomes a tangled, complex web. This significantly reduces the code’s readability and maintainability, and it also complicates the testing process.
Overriding methods should do more than simply call the same method in the super class
Overriding a method just to call the same method from the super class without performing any other actions is useless and misleading.
Constructors should not dispatch events
A listener can be attached to an object only after it has been constructed. So dispatching an event in a constructor is useless and error prone.
Constructor bodies should be as lightweight as possible
In ActionScript 3, constructor code is always interpreted rather than compiled by the JIT at runtime, which is why the body of a constructor should be as lightweight as possible. As soon as a constructor contains branches (“if”, “for”, “switch”, …) an issue is logged.
Statements, operators and keywords specific to ActionScript 2 should not be used
Usage of statements, operators and keywords specific to ActionScript 2 does not allow to migrate to ActionScript 3. This includes “intrinsic” keyword, set variable statement and following list of operators:
`<> (inequality) - use != instead
add (concatenation (strings)) - use + instead
eq (equality (strings)) - use == instead
ne (not equal (strings)) - use != instead
lt (less than (strings)) - use < instead
le (less than or equal to (strings)) - use <= instead
gt (greater than (strings)) - use > instead
ge (greater than or equal to (strings)) - use >= instead
and (logical and) - use && instead
or (logical or) - use || instead
not (logical not) - use !` instead
Cases in a switch should not have the same condition
Having multiple cases in a switch
with the same condition is confusing at best. At worst, it’s a bug that is likely to induce further bugs as the code is maintained.
If the first case ends with a break, the second case will never be executed, rendering it dead code. Worse there is the risk in this situation that future maintenance will be done on the dead case, rather than on the one that’s actually used.
On the other hand, if the first case does not end with a break, both cases will be executed, but future maintainers may not notice that.
Variables of the Object type should not be used
Creating a new variable with the type “Object” means that it may be used to store any kind of object. This feature may be required in some specific contexts, but it leaves the compiler unable to do any kind of type checking, and is therefore a hazardous practice.
LocalConnection should be configured to narrowly specify the domains with which local connections to other Flex application are allowed
A LocalConnection object is used to invoke a method in another LocalConnection
object, either within a single SWF file or between multiple SWF files. This kind of local connection should be authorized only when the origin (domain) of the other Flex applications is perfectly defined.
Event types should be defined in metadata tags
Constructors should not have a void return type
Even though this is syntactically correct, the void
return type should not be used in the signature of a constructor. Indeed some developers might be confused by this syntax, believing that the constructor is in fact a standard function.
MovieClip.onEnterFrame event handler should not be used
The onEnterFrame event handler is continually invoked at the frame rate of the SWF file, regardless of which individual movie frame it is set for. Having too many onEnterFrame
handlers can seriously degrade performance.
If the use of this event handler cannot be avoided entirely, then it should be created as close to its use as possible, and then destroyed as soon as possible afterward.
Public constants and fields initialized at declaration should be const static rather than merely const
Making a public constant just const as opposed to static const
leads to duplicating its value for every instance of the class, uselessly increasing the amount of memory required to execute the application.
Dynamic classes should not be used
A dynamic class defines an object that can be altered at run time by adding or changing properties and methods. This extremely powerful mechanism should be used very carefully, and only in very limited use cases.
Indeed, by definition dynamic classes make refactoring difficult and prevent the compiler from raising potential errors at compile time.
Security.allowDomain(...) should only be used in a tightly focused manner
Calling Security.allowDomain(”*”) lets any domain cross-script into the domain of this SWF and exercise its functionality.
A function should have a single point of exit at the end of the function
This is required by IEC 61508, under good programming style.
Octal values should not be used
Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.
Mergeable if statements should be combined
Nested code - blocks of code inside blocks of code - is eventually necessary, but increases complexity. This is why keeping the code as flat as possible, by avoiding unnecessary nesting, is considered a good practice.
Merging if statements when possible will decrease the nesting of the code and improve its readability.
Methods should not be empty
An empty {operationName} is generally considered bad practice and can lead to confusion, readability, and maintenance issues. Empty {operationName}s bring no functionality and are misleading to others as they might think the {operationName} implementation fulfills a specific and identified requirement.
There are several reasons for a {operationName} not to have a body:
It is an unintentional omission, and should be fixed to prevent an unexpected behavior in production.
It is not yet, or never will be, supported. In this case an exception should be thrown.
The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.
Unused private fields should be removed
If a private field is declared but not used locally, its limited visibility makes it dead code.
This is either a sign that some logic is missing or that the code should be cleaned.
Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand and preventing bugs from being introduced.
Unused function parameters should be removed
A typical code smell known as unused function parameters refers to parameters declared in a function but not used anywhere within the function’s body. While this might seem harmless at first glance, it can lead to confusion and potential errors in your code. Disregarding the values passed to such parameters, the function’s behavior will be the same, but the programmer’s intention won’t be clearly expressed anymore. Therefore, removing function parameters that are not being utilized is considered best practice.
Package names should comply with a naming convention
Shared naming conventions improve readability and allow teams to collaborate efficiently. This rule checks that all package names match a provided regular expression.
Class names should comply with a naming convention
Shared naming conventions allow teams to collaborate efficiently.
This rule raises an issue when a class name does not match a provided regular expression.
for loop stop conditions should be invariant
A `for loop stop condition should test the loop counter against an invariant value (i.e. one that is true at both the beginning and ending of every loop iteration). Ideally, this means that the stop condition is set to a local variable just before the loop begins.
Stop conditions that are not invariant are slightly less efficient, as well as being difficult to understand and maintain, and likely lead to the introduction of errors in the future.
This rule tracks three types of non-invariant stop conditions:
When the loop counters are updated in the body of the for` loop
When the stop condition depend upon a method call
When the stop condition depends on an object property, since such properties could change during the execution of the loop.
Functions should not contain too many return statements
Having too many return statements in a function increases the function’s essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the function.
switch case clauses should not have too many lines of code
The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case
clause should be extracted into a dedicated method.
Track uses of TODO tags
Field names should comply with a naming convention
A naming convention in software development is a set of guidelines for naming code elements like variables, functions, and classes.
The goal of a naming convention is to make the code more readable and understandable, which makes it easier to maintain and debug. It also ensures consistency in the code, especially when multiple developers are working on the same project.
This rule checks that field names match a provided regular expression.
Unused private functions should be removed
This rule raises an issue when a {visibility} {operationName} is never referenced in the code.
Useless if(true) {...} and if(false){...} blocks should be removed
`if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.
There are three possible causes for the presence of such code:
An if statement was changed during debugging and that debug code has been committed.
Some value was left unset.
Some logic is not doing what the programmer thought it did.
In any of these cases, unconditional if` statements should be removed.
Empty statements should be removed
Empty statements represented by a semicolon ; are statements that do not perform any operation. They are often the result of a typo or a misunderstanding of the language syntax. It is a good practice to remove empty statements since they don’t add value and lead to confusion and errors.
switch statements should have default clauses
The requirement for a final default
clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.
switch statements should not be nested
Nested `switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.
Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch` to another function.
Unused local variables should be removed
An unused local variable is a variable that has been declared but is not used anywhere in the block of code where it is defined. It is dead code, contributing to unnecessary complexity and leading to confusion when reading the code. Therefore, it should be removed from your code to maintain clarity and efficiency.
Local variable and function parameter names should comply with a naming convention
A naming convention in software development is a set of guidelines for naming code elements like variables, functions, and classes. {identifier_capital_plural} hold the meaning of the written code. Their names should be meaningful and follow a consistent and easily recognizable pattern. Adhering to a consistent naming convention helps to make the code more readable and understandable, which makes it easier to maintain and debug. It also ensures consistency in the code, especially when multiple developers are working on the same project.
This rule checks that {identifier} names match a provided regular expression.
Public classes, methods, properties and metadata should be documented with ASDoc
Undocumented APIs pose significant challenges in software development for several reasons:
Lack of Clarity: developers struggling to understand how to use the API correctly. This can lead to misuse and unexpected results.
Increased Development Time: developers spending extra time reading and understanding the source code, which slows down the development process.
Error Prone: developers are more likely to make mistakes that lead to bugs or system crashes when the intent or the error handling of an API is not clear.
Difficult Maintenance and Updates: developers may not understand the existing functionality well enough to add new features without breaking the existing ones.
Poor Collaboration: collaboration, when there is lack of documentation, leads to confusion and inconsistencies.
Local variables should not shadow class fields
Local variables should not shadow class fields