avm2: Add automatic linting for AS3 playerglobals

This commit is contained in:
EmperorBale 2022-09-04 16:33:35 -07:00 committed by GitHub
parent ce0752c225
commit dd2bc1ea78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 1129 additions and 87 deletions

View File

@ -69,6 +69,13 @@ jobs:
command: fmt
args: --all -- --check
- name: Lint AS3 playerglobals
if: runner.os == 'Linux' && matrix.rust_version == 'stable'
uses: actions-rs/cargo@v1
with:
command: run
args: -p build_playerglobal -- lint
- name: Check clippy
uses: actions-rs/cargo@v1
with:

27
Cargo.lock generated
View File

@ -270,9 +270,13 @@ checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7"
name = "build_playerglobal"
version = "0.1.0"
dependencies = [
"clap",
"colored",
"convert_case",
"proc-macro2",
"quote",
"serde",
"serde-xml-rs",
"swf",
]
@ -530,6 +534,17 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colored"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]]
name = "combine"
version = "4.6.4"
@ -3356,6 +3371,18 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "serde-xml-rs"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65162e9059be2f6a3421ebbb4fef3e74b7d9e7c60c50a0e292c6239f19f1edfa"
dependencies = [
"log",
"serde",
"thiserror",
"xml-rs",
]
[[package]]
name = "serde_derive"
version = "1.0.144"

View File

@ -8,3 +8,7 @@ convert_case = "0.5.0"
proc-macro2 = "1.0.43"
quote = "1.0.21"
swf = { path = "../../swf" }
clap = {version = "3.2.17", features = ["derive"]}
serde = {version = "1.0.143", features = ["derive"]}
serde-xml-rs = "0.5.1"
colored = "2.0.0"

View File

@ -0,0 +1,28 @@
Copyright (c) 2009, Adobe Systems, Incorporated
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the Adobe Systems, Incorporated. nor the names of
its contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,657 @@
<ruleset name="Ruffle Playerglobal Rules" xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd" xmlns="http://pmd.sf.net/ruleset/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<description/>
<rule since="" class="com.adobe.ac.pmd.rules.architecture.ViewComponentReferencedInModelRule" message="A view component should not be referenced in a model class">
<description/>
<priority>3</priority>
<example><![CDATA[package com.adobe.ac
{
import mx.controls.ComboBox; // VIOLATION
public class MyModelClass
{
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.architecture.MonkeyPatchingRule" message="This class looks to be duplicated with a SDK class">
<description>Monkey patching can be a risky undertaking because it is not using intended extensibility points and thus may have unintended consequences or make migration to newer versions of the SDK more difficult</description>
<priority>1</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.architecture.UseInternalClassOutsideApiClass" message="This class imports an internal class ({0}) from another function area ({1})">
<description>If you have different functionalities, you probably don't want every class of each to be accessible from any other functional areas.
So you probably want to use this packaging:
[org].[project].func1.api
[org].[project].func1.restricted
[org].[project].func2.api
[org].[project].func2.restricted
This rule makes sure that no restricted classes is accessed from outside its own function area.</description>
<priority>1</priority>
<example><![CDATA[package functional
{
import functional.func1.api.Func1ExposedClass;
import functional.func1.restricted.Func1RestrictedClass; // VIOLATION
import functional.func2.api.Func2ExposedClass;
import functional.func2.restricted.Func2RestrictedClass; // VIOLATION
public class FunctionClient
{
}
}
package functional.func1.api
{
import functional.func1.restricted.Func1RestrictedClass;
import functional.func2.api.Func2ExposedClass;
import functional.func2.restricted.Func2RestrictedClass; // VIOLATION
public class Func1ExposedClass
{
}
}
package functional.func1.restricted
{
import functional.func1.api.Func1ExposedClass;
import functional.func2.api.Func2ExposedClass;
import functional.func2.restricted.Func2RestrictedClass; // VIOLATION
public class Func1RestrictedClass
{
}
}
package functional.func2.api
{
import functional.func1.api.Func1ExposedClass;
import functional.func1.restricted.Func1RestrictedClass; // VIOLATION
import functional.func2.restricted.Func2RestrictedClass;
public class Func2ExposedClass
{
}
}
package functional.func2.restricted
{
import functional.func1.api.Func1ExposedClass;
import functional.func1.restricted.Func1RestrictedClass; // VIOLATION
import functional.func2.api.Func2ExposedClass;
public class Func2RestrictedClass
{
}
}]]></example>
</rule>
<!--<rule since="" class="com.adobe.ac.pmd.rules.asdocs.AttributeAsDocMissingRule" message="This attribute ({0}) should be documented with AsDocs.">
<description/>
<priority>3</priority>
</rule>-->
<!--<rule since="" class="com.adobe.ac.pmd.rules.asdocs.MethodAsDocMissingRule" message="This method ({0}) should be documented with AsDocs.">
<description/>
<priority>3</priority>
</rule>-->
<rule since="" class="com.adobe.ac.pmd.rules.mxml.MoreThanOneEntryPointInMxmlRule" message="There is more than 1 public variable in this MXML component">
<description/>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.mxml.MoreThanTwoEntryPointsInMxmlRule" message="There are more than 2 public variables in this MXML component">
<description/>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.mxml.TooLongScriptBlockRule" message="This script block is too long ({0} maximum, but {1} actually)">
<description/>
<priority>3</priority>
<properties>
<property name="maximum">
<value>50</value>
</property>
</properties>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.mxml.CodeBehindInMxmlRule" message="Avoid using code behind files">
<description>Code behind files are tightly coupled with the view, not unit-testable, not easy to navigate the code code base and not reusable. Try using presentation model pattern, or observer pattern</description>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.binding.BindingUtilsRule" message="BindingUtils class uses hard coded strings, which won't be picked up by the compiler if you rename this attribute. You should probably consider refactoring using events">
<description/>
<priority>1</priority>
<example><![CDATA[public class Controller extends FrontController
{
public function Controller()
{
BindingUtils.bindSetter(setContent, value, "content"); // VIOLATION
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.binding.ChangeWatcherRule" message="ChangeWatcher class uses hard coded strings to specify the attribute name, to listen to. Prefer listening to events or setters">
<description/>
<priority>1</priority>
<example><![CDATA[public final class Title
{
private var watcher : ChangeWatcher; // VIOLATION
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.binding.TooLongBindingExpressionRule" message="This binding expression is too long ({0} dots maximum, but {1} actually)">
<description>A Binding expression is executed as soon as one of the bindable attributes changed. If a binding expression contains too many expression, there could be some performance issue.</description>
<priority>3</priority>
<properties>
<property name="maximum">
<value>3</value>
</property>
</properties>
<example><![CDATA[
<mx:Label text="{ vfrfr.frfr.frf.lala }"/> <!-- Violation-->
]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.cairngorm.BindableModelLocatorRule" message="A modelLocator must not be Bindable at a class level">
<description>A bindable ModelLocator could leads to performance issues due to bindings</description>
<priority>1</priority>
<example><![CDATA[[Bindable]
public class BindableModelLocator // VIOLATION
{
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.cairngorm.ReferenceModelLocatorOutsideTheMainApplicationRule" message="The ModelLocator should be only accessible from the main application file">
<description>The ModelLocator should be only accessible from the main application file. Then sub-models should be injected to the nested views.</description>
<priority>3</priority>
<example><![CDATA[package business
{
import model.MyModelLocator; // VIOLATION
public class MyBusinessClass
{
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.cairngorm.FatControllerRule" message="A FrontController must nor add all its commands within the Controller constructor">
<description>Try split them into methods where you add commands depending on their functional area.</description>
<priority>3</priority>
<example><![CDATA[package control
{
import control.GetItems1Command;
import control.GetItems1Event;
import control.GetItems2Command;
import control.GetItems2Event;
// A lot of other imports
public class MyFrontController // VIOLATION
{
public function MyFrontController()
{
addCommand(
GetItems1Event.EVENT_NAME,
GetItems1Command );
addCommand(
GetItems2Event.EVENT_NAME,
GetItems2Command );
// A lot of other addCommand
}
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.cairngorm.BadCairngormEventNameFormatRule" message="A Cairngorm event name should contain the function area name before the actual event name">
<description>You would have something like 'productManagement.getProducts' as an event name.</description>
<priority>3</priority>
<example><![CDATA[public class UncorrectConstructorEvent extends CairngormEvent
{
public function UncorrectConstructorEvent( model : IModel )
{
super( "eventName", model ); // VIOLATION. It should be "functionalArea.eventName" instead
}
}
public class UncorrectConstantEvent extends CairngormEnterpriseEvent
{
public static const EVENT_NAME : String = "eventName";
public function UncorrectConstantEvent( model : IModel )
{
super( EVENT_NAME, model ); // VIOLATION
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.cairngorm.CairngormEventDispatcherCallExplicitlyRule" message="CairngormEventDispatcher is called explicitly. {0}">
<description/>
<priority>3</priority>
<example><![CDATA[
public function foo() : void
{
CairngormEventDispatcher.getInstance().dispatchEvent(new Event(CONSTANT)); // VIOLATION <- use cairngormEvent.dispatch();
CairngormEventDispatcher.getInstance().addEventListener(CONSTANT, onHearing); // VIOLATION <- MVC broken
}
]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.cairngorm.ModelLocatorReferencedMoreThanOncePerClassRule" message="Only one reference of ModelLocator is allowed per class">
<description/>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.component.UpdateChildrenNumberInUpdateDisplayListRule" message="Flex specific - Do not add or remove displayable children from updateDisplayList">
<description>UpdateDisplayList is called everytime a child is invalidated. So calling addChild or removeChild in this function could be really CPU consuming</description>
<priority>1</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.component.CallLaterDirectlyRule" message="Flex specific - Don't call 'callLater' explicitly">
<description>If you needed to call 'callLater' explicitly, then you probably did not extend the correct component life cycle.</description>
<priority>1</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.css.StyleBlockInMxmlRule" message="The style block is embed in the MXML file">
<description>It is not a good practice to embed style blocks inside the MXML component. Prefer using external CSS files.</description>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.css.UseCssInsteadOfEmbedMetaDataRule" message="Embed metadata detected in source code where a stylesheet may be cleaner">
<description/>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.empty.EmptyCatchStatementRule" message="This catch statement is empty">
<description/>
<priority>3</priority>
<example><![CDATA[public class Foo
{
public function bar( x : int ) : void
{
try
{
}
catch( e : Exception ) // VIOLATION
{
}
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.empty.EmptyIfStmtRule" message="No statements in this if statement">
<description>Empty If Statement finds instances where a condition is checked but nothing is done about it.</description>
<priority>3</priority>
<example><![CDATA[public class Foo
{
public function bar( x : int ) : void
{
if ( x == 0 )
{
// VIOLATION
}
}
}]]></example>
</rule>
<!-- MIKE: Disabled because many AS3 event classes do not override `clone`.
<rule since="" class="com.adobe.ac.pmd.rules.event.EventMissingCloneFunctionRule" message="The clone event must be overiden in a custom event">
<description>When creating your own custom Event class, you must override the inherited Event.clone() method in order for it to duplicate the properties of your custom class. If you do not set all the properties that you add in your event subclass, those properties will not have the correct values when the event is cloned. This is important because the Flex SDK clones events whenever redispatching takes place.</description>
<priority>3</priority>
<example><![CDATA[public class FirstCustomEvent // VIOLATION - clone method is missing
{
public var lala : String;
public function FirstCustomEvent()
{
}
}]]></example>
</rule>
-->
<rule since="" class="com.adobe.ac.pmd.rules.event.ConstructorDispatchingEventRule" message="An event is dispatched in a constructor">
<description>This is pointless, since event listeners cannot be attached to an object before it has been constructed, so nothing can ever hear the event</description>
<priority>1</priority>
<example><![CDATA[public class BigModel
{
public function BigModel()
{
dispatchEvent( new Event( "pointlessEvent" ) );
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.event.DefaultEventNameRule" message="Event name should be set explicitly">
<description/>
<priority>3</priority>
<example><![CDATA[public class DefaultNameEvent extends Event
{
public function DefaultNameEvent( type : String = "" )
{
super( type );
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.event.DispatchHardCodedEventNameRule" message="DispatchEvent function must dispatch constant strings">
<description>You should not dispatch a plain string. If you rename this string, you need to replace the string listener as well. Use constants instead</description>
<priority>1</priority>
<example><![CDATA[public class Foo
{
public function bar() : void
{
dispatch( new Event( "myHardCodedEvent" ) ); // VIOLATION
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.event.ListenForHardCodedEventNameRule" message="addEventListener must not contain hard coded strings">
<description>You should not listen for a plain string. If you rename this string, you need to replace the string listener as well. Use constants instead</description>
<priority>1</priority>
<example><![CDATA[public class Foo
{
public function bar() : void
{
addEventListener( "myHardCodedEvent", handleMyHardCodedEvent ); // VIOLATION
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.event.UnboundTypeInMetadataRule" message="This type ({0}) was not found within the scope against which PMD was run">
<description/>
<priority>1</priority>
<example><![CDATA[[Event(name="myTypeEvent",type="UnknownType")] // VIOLATION
public class UnboundMetadata
{
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.event.UntypedEventMetadataRule" message="This event type is not specified">
<description>Specifying a type will allow Flash builder and the class to have this event exposed in its API</description>
<priority>3</priority>
<example><![CDATA[[Event(name="myTypeEvent")] // VIOLATION
public class UnTypedMetadata
{
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.naming.PackageCaseRule" message="A package name should be lower case ({0})">
<description>Detects when a package definition contains upper case characters.</description>
<priority>1</priority>
<example><![CDATA[
package com.MyCompany // VIOLATION <- should be lower case name
{
public class SomeClass
{
}
}
]]></example>
</rule>
<!--
<rule since="" class="com.adobe.ac.pmd.rules.naming.PropertyHiddenByLocalVariableRule" message="A class property is hidden by this local variable ({0})">
<description/>
<priority>3</priority>
<example><![CDATA[public class SomeClass
{
public var myField : int = 0;
public function foo() : void
{
var myField : int = 9; // VIOLATION
}
}]]></example>
</rule>
-->
<rule since="" class="com.adobe.ac.pmd.rules.naming.WronglyNamedVariableRule" message="This variable ({0}) seems to be incorrectly named. Let your creativity flow">
<description/>
<priority>3</priority>
<example><![CDATA[
public class SomeClass
{
public var myField : int = 0; // VIOLATION <- my prefix is forbidden
public function tmpFoo() : void // VIOLATION <- tmp prefix is forbidden
{
var tempFoo : int = 9; // VIOLATION <- temp prefix is forbidden
}
}
]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.parsley.InaccessibleMetaDataRule" message="Parsley metadata should not be placed on inaccessible members.">
<description>Parsley can only process metadata that is placed onto public members.</description>
<priority>1</priority>
<example><![CDATA[[MessageHandler]
private function doSomething() : void // VIOLATION
{
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.parsley.MismatchedManagedEventRule" message="Managed events should have matching [Event] metadata">
<description>Each managed event should have matching [Event] metadata.</description>
<priority>1</priority>
<example><![CDATA[[Event(name="message", type="my.package.MyEvemt")]
[ManagedEvents(names="messag")] // VIOLATION
public class MyClass
{
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.parsley.MessageInterceptorSignatureRule" message="The signature of the message interceptor {0} is not correct. {1}.">
<description/>
<priority>1</priority>
<example><![CDATA[
[MessageInterceptor(type="a.b.MyMessage")]
public function messageInterceptor( processor : MessageProcessor ) : void
{
processor.proceed();
}
[MessageInterceptor(type="a.b.MyMessage")]
public function messageInterceptor() : void // VIOLATION
{
}
[MessageInterceptor(type="a.b.MyMessage")]
public function messageInterceptor( type : MyMessage ) : void // VIOLATION
{
type.something();
}
[MessageInterceptor(type="a.b.MyMessage")]
public function messageInterceptor( processor : MessageProcessor, type : MyMessage ) : void // VIOLATION
{
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.parsley.MisplacedMetaDataRule" message="This metadata {0} is misplaced">
<description/>
<priority>1</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.parsley.RedundantMessageHandlerTypeAttributeRule" message="This type metadata argument is redundant with the handler argument type">
<description/>
<priority>3</priority>
<example><![CDATA[
[MessageHandler(type="a.b.MyMessage")] // VIOLATION
public function doSomething( message : MyMessage ) : void
{
message.toString();
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.parsley.RedundantMethodAttributeRule" message="This method metadata argument is redundant with the handler name">
<description/>
<priority>3</priority>
<example><![CDATA[
[MessageHandler(method="doSomething")] // VIOLATION
public function doSomething( message : MyMessage ) : void
{
message.toString();
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.parsley.UnknownMetaDataAttributeRule" message="This metadata attribute {0} is unknown">
<description/>
<priority>1</priority>
<example><![CDATA[
[AsyncInit(x="y")] // VIOLATION
public class UnknownMetaDataAttribute
{
[Inject(x="y")] // VIOLATION
public var inject;
[MessageHandler(x="y")] // VIOLATION
public function messageHandler() : void
{
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.performance.DynamicFiltersUsedInPopup" message="A popup should not use dynamic filters">
<description>Prefer using embed filters in assets</description>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.performance.CyclomaticComplexityRule" message="This method is too complex. Maximum complexity is {0}, but its cyclomatic complexity was {1}">
<description/>
<priority>3</priority>
<properties>
<property name="maximum">
<value>15</value>
</property>
</properties>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.performance.HeavyConstructorRule" message="Constructor must be as lightweight as possible. No control statement allowed, whereas a cyclomatic complexe of {0} has been detected">
<description>The Just-In-Time compiler does not compile constructors. Make them as lightweight as possible, or move the complexity of the code to a method called by the constructor. Then the complexity will be compiled by the JIT.</description>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.performance.CreationPolicySetToAllRule" message="creationPolicy to ALL impacts the performance significantly">
<description/>
<priority>1</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.performance.BindableClassRule" message="Globally bindable classes can lead to unexpected behaviour especially when you have a setter to a property, and hits the performance of the application">
<description/>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.performance.AvoidInstanciationInLoopRule" message="Instanciating a variable in a loop can be expensive">
<description/>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.performance.DeeplyNestedIfRule" message="Nested if statements are not a good design">
<description/>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.performance.RecursiveStyleManagerRule" message="Detect calls to the StyleManager that dont pass “false” as the second parameter">
<description>A recursive style manager call can be a very expensive operation, causing parts of the UI to flicker visibly. Instead it is preferable to defer the creation of parts of the UI that depend on a runtime CSS SWF until after the SWF has been loaded. In this case a recursive call is not required.</description>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.sizing.TooLongFunctionRule" message="This function is far too long ({0} maximum, but {1} actually)">
<description>Violations of this rule usually indicate that the method has too much responsibility. Try to reduce the method size by creating helper methods and removing any copy/pasted code.</description>
<priority>3</priority>
<properties>
<property name="maximum">
<value>20</value>
</property>
</properties>
<example><![CDATA[public class Foo
{
public function doSomething() : void
{
System.out.println("Hello world!");
System.out.println("Hello world!");
// 98 copies omitted for brevity.
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.sizing.TooLongSwitchCaseRule" message="Long switch case detected ({0} lines maximum, but {1} actually)">
<description>A switch case statement should be either empty, or contain a break, or call another method.</description>
<priority>3</priority>
<properties>
<property name="maximum">
<value>3</value>
</property>
</properties>
<example><![CDATA[public class Bar
{
public function foo() : void
{
var i : int = 4;
switch( i )
{
case 1:
handleFirstCase();
break;
case 2: // VIOLATION
googleResquest.url = "";
handleSecondCaseFirstPart();
handleSecondCaseSecondPart();
break;
}
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.sizing.TooManyFieldInVORule" message="Too many field detected ({0} maximum, but {1} actually)">
<description/>
<priority>3</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.style.ConstructorNonEmptyReturnTypeRule" message="A constructor should not have a return type">
<description>Even if this is syntactically correct, there should not be a return type for a constructor.</description>
<priority>3</priority>
<example><![CDATA[public class VoidConstructor
{
public function VoidConstructor() : void // VIOLATION
{
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.style.OverLongLineRule" message="Too long line ({0} maximum, but {1} actually)">
<description/>
<priority>3</priority>
<properties>
<property name="maximum">
<value>200</value>
</property>
</properties>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.style.ImportFromSamePackageRule" message="Imports from the same package are not necessary">
<description/>
<priority>3</priority>
<example><![CDATA[package com.adobe.ac
{
import com.adobe.ac.MyModel; // VIOLATION HERE
public class BigModel
{
public var model : MyModel = null;
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.switchrules.SwitchStatementsShouldHaveDefaultRule" message="A switch statement does not contain a default statement">
<description>Switch statements should have a default label in order to detect corner cases.</description>
<priority>1</priority>
<example><![CDATA[public class Foo
{
public funciton bar() : void
{
var x : int = 2;
switch (x)
{
case 2: var j : int = 8;
}
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.switchrules.NestedSwitchRule" message="Switch must not be nested">
<description>As a general practice, switch statement should not be used. Prefer using inheritance. It is even harder to read when switch statements are nested.</description>
<priority>3</priority>
<example><![CDATA[public function foo( a : Number, b : Number ) : void
{
switch( a )
{
case 1:
break;
case 2:
switch ( b )
{
case 3 :
break;
case 4 :
break;
}
break;
}
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.switchrules.TooFewBrancheInSwitchStatementRule" message="There are too few branches in this switch statement ({0} minimum, but {1} actual)">
<description>Switch statements are designed for complex branches, and allow branches to share treatment. Using a switch for only 2 branches is ill advised, as switches are not as easy to understand as if. In this case, it's most likely is a good idea to use a if statement</description>
<priority>3</priority>
<properties>
<property name="minimum">
<value>3</value>
</property>
</properties>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.switchrules.IdenticalSwitchCasesRule" message="Two switch cases should not be identical">
<description/>
<priority>1</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.unused.UnusedLocalVariableRule" message="This variable ({0}) is not used">
<description/>
<priority>1</priority>
<example><![CDATA[public function foo() : void
{
var i : int = 0;// 1 violation
}]]></example>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.unused.UnusedPrivateMethodRule" message="This private method ({0}) does not seem to be used">
<description/>
<priority>1</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.unused.UnusedFieldRule" message="This private attribute ({0}) does not seem to be used">
<description/>
<priority>1</priority>
</rule>
<rule since="" class="com.adobe.ac.pmd.rules.unused.EmptyPrivateMethodRule" message="This private method ({0}) is used but its content is empty">
<description/>
<priority>1</priority>
</rule>
</ruleset>

View File

@ -0,0 +1,16 @@
use clap::{Parser, Subcommand};
#[derive(Parser)]
pub(crate) struct Cli {
#[clap(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub(crate) enum Commands {
Compile {
#[clap(value_parser)]
out_dir: String,
},
Lint,
}

View File

@ -5,10 +5,57 @@
//! and `out_dir` is the directory where `playerglobal.swf` should
//! be written
mod cli;
mod pmd;
use clap::Parser;
use pmd::Pmd;
use cli::Commands;
use std::io::ErrorKind;
use std::path::PathBuf;
use std::process::Command;
fn main() {
build_playerglobal::build_playerglobal(
std::env::args().nth(1).unwrap().into(),
std::env::args().nth(2).unwrap().into(),
)
.unwrap();
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let repo_root = root.join("../../");
let args = cli::Cli::parse();
match args.command {
Commands::Compile { out_dir } => {
build_playerglobal::build_playerglobal(repo_root, out_dir.into()).unwrap();
}
Commands::Lint => {
let tmp = root.join("tmp");
if let Err(e) = std::fs::create_dir(&tmp) {
if e.kind() != ErrorKind::AlreadyExists {
panic!("Failed to create temporary folder {}", e);
}
}
let classes_dir = repo_root.join("core/src/avm2/globals/");
let flexpmd = root.join("flexpmd");
let output = Command::new("java")
.arg("-jar")
.arg(flexpmd.join("flex-pmd-command-line-1.2.jar"))
.arg("-r")
.arg(flexpmd.join("ruffle-ruleset.xml"))
.arg("-s")
.arg(&classes_dir)
.arg("-o")
.arg(&tmp)
.output()
.expect("Failed to execute FlexPMD");
if !output.status.success() {
panic!("{}", String::from_utf8_lossy(&output.stderr));
}
let pmd = Pmd::open(classes_dir, tmp.join("pmd.xml")).expect("Invalid PMD xml file");
std::fs::remove_dir_all(tmp).expect("Failed to delete temp folder");
if pmd.contains_violations() {
eprintln!("{}", pmd);
std::process::exit(1);
}
}
}
}

View File

@ -0,0 +1,125 @@
use colored::Colorize;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::io::{BufRead, BufReader, Error, ErrorKind, Seek, SeekFrom};
use std::path::{Path, PathBuf};
pub struct Pmd {
root: PathBuf,
data: PmdData,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct PmdData {
#[serde(rename = "$value")]
files: Option<Vec<File>>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct File {
name: String,
#[serde(rename = "$value")]
violations: Vec<Violation>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Violation {
#[serde(rename = "beginline")]
begin_line: usize,
#[serde(rename = "endline")]
end_line: usize,
rule: String,
#[serde(rename = "$value")]
message: String,
}
impl Pmd {
pub fn open(root: impl Into<PathBuf>, path: impl Into<PathBuf>) -> std::io::Result<Self> {
let file = std::fs::File::open(path.into())?;
let data = serde_xml_rs::from_reader(file)
.map_err(|_| Error::new(ErrorKind::Other, "Failed to parse XML data"))?;
Ok(Pmd {
root: root.into(),
data,
})
}
pub fn contains_violations(&self) -> bool {
self.data.files.is_some()
}
pub fn violation_count(&self) -> usize {
let mut count = 0;
if let Some(files) = self.data.files.as_ref() {
for file in files.iter() {
count += file.violations.len();
}
}
count
}
}
impl File {
fn display(&self, root: &Path, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut file = std::fs::File::open(&self.name).map_err(|_| fmt::Error)?;
for violation in self.violations.iter() {
writeln!(f, "{}: {}", "warning".yellow(), violation.message)?;
let max_digits = violation.end_line.to_string().len();
let name = Path::new(&self.name)
.strip_prefix(root)
.map_err(|_| fmt::Error)?;
writeln!(
f,
"{}{} {}",
" ".repeat(max_digits),
"-->".blue().bold(),
name.to_string_lossy().bold()
)?;
file.seek(SeekFrom::Start(0)).map_err(|_| fmt::Error)?;
let reader = BufReader::new(&file);
for (num, text) in reader
.lines()
.enumerate()
.skip(violation.begin_line - 1)
.take(violation.end_line - violation.begin_line + 1)
{
let mut text = text.map_err(|_| fmt::Error)?;
if text.len() > 117 {
text.truncate(117);
text.push_str("...");
}
let num_str = (num + 1).to_string();
writeln!(
f,
"{}{}{} {}",
num_str.blue().bold(),
" ".repeat(max_digits - num_str.len() + 1),
"|".blue().bold(),
text
)?;
}
writeln!(
f,
"{}{} {}: rule {} is enabled\n",
" ".repeat(max_digits + 1),
"=".blue().bold(),
"note".bold(),
violation.rule.bold()
)?;
}
Ok(())
}
}
impl fmt::Display for Pmd {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(files) = self.data.files.as_ref() {
for file in files.iter() {
file.display(&self.root, f)?;
}
write!(f, "{} total warnings emitted", self.violation_count())?;
}
Ok(())
}
}

View File

@ -7,23 +7,31 @@ package flash.events
public class AccelerometerEvent extends Event
{
public static const UPDATE:String = "update"; // Defines the value of the type property of a AccelerometerEvent event object.
// Defines the value of the type property of a AccelerometerEvent event object.
public static const UPDATE:String = "update";
public var timestamp: Number; // The number of milliseconds at the time of the event since the runtime was initialized.
public var accelerationX: Number; // Acceleration along the x-axis, measured in Gs.
public var accelerationY: Number; // Acceleration along the y-axis, measured in Gs.
public var accelerationZ: Number; // Acceleration along the z-axis, measured in Gs.
// The number of milliseconds at the time of the event since the runtime was initialized.
public var timestamp:Number;
public function AccelerometerEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, timestamp:Number = 0, accelerationX:Number = 0, accelerationY:Number = 0, accelerationZ:Number = 0)
// Acceleration along the x-axis, measured in Gs.
public var accelerationX:Number;
// Acceleration along the y-axis, measured in Gs.
public var accelerationY:Number;
// Acceleration along the z-axis, measured in Gs.
public var accelerationZ:Number;
public function AccelerometerEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, timestamp:Number = 0,
accelerationX:Number = 0, accelerationY:Number = 0, accelerationZ:Number = 0)
{
super(type,bubbles,cancelable);
super(type, bubbles, cancelable);
this.timestamp = timestamp;
this.accelerationX = accelerationX;
this.accelerationY = accelerationY;
this.accelerationZ = accelerationZ;
}
// Creates a copy of an AccelerometerEvent object and sets the value of each property to match that of the original.
override public function clone():Event
{
@ -33,8 +41,10 @@ package flash.events
// Returns a string that contains all the properties of the AccelerometerEvent object.
override public function toString():String
{
return this.formatToString("AccelerometerEvent","type","bubbles","cancelable","eventPhase","timestamp","accelerationX","accelerationY","accelerationZ");
return this.formatToString("AccelerometerEvent", "type", "bubbles", "cancelable", "eventPhase", "timestamp", "accelerationX", "accelerationY", "accelerationZ");
}
}
}

View File

@ -1,5 +1,4 @@
package flash.events {
import flash.events.Event;
public class ActivityEvent extends Event {
public var activating:Boolean;

View File

@ -4,12 +4,11 @@
// It won't be regenerated in the future, so feel free to edit and/or fix
package flash.events
{
public class AudioOutputChangeEvent extends Event
{
public static const AUDIO_OUTPUT_CHANGE:String = "audioOutputChange"; // Defines the value of the type property of a AudioOutputchangeEvent event object.
public static const AUDIO_OUTPUT_CHANGE:String = "audioOutputChange"; // Defines the value of the type property of a AudioOutputChangeEvent event object.
private var _reason: String; // Reports the reason that triggers this AudioOutputchangeEvent.
private var _reason: String; // Reports the reason that triggers this AudioOutputChangeEvent.
public function AudioOutputChangeEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, reason:String = null)
{

View File

@ -9,7 +9,8 @@ package flash.events
public class DRMAuthenticationCompleteEvent extends Event
{
public static const AUTHENTICATION_COMPLETE:String = "authenticationComplete"; // The string constant to use for the authentication complete event in the type parameter when adding and removing event listeners.
// The string constant to use for the authentication complete event in the type parameter when adding and removing event listeners.
public static const AUTHENTICATION_COMPLETE:String = "authenticationComplete";
public var serverURL: String; // The URL of the media rights server.
public var domain: String; // The content domain of the media rights server.

View File

@ -7,13 +7,20 @@ package flash.events
public class DRMAuthenticationErrorEvent extends ErrorEvent
{
public static const AUTHENTICATION_ERROR:String = "authenticationError"; // The string constant to use for the authentication error event in the type parameter when adding and removing event listeners.
// The string constant to use for the authentication error event in the type parameter when adding and removing event listeners.
public static const AUTHENTICATION_ERROR:String = "authenticationError";
public var subErrorID: int; // A more detailed error code.
public var serverURL: String; // The URL of the media rights server that rejected the authentication attempt.
public var domain: String; // The content domain of the media rights server.
// A more detailed error code.
public var subErrorID: int;
public function DRMAuthenticationErrorEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, inDetail:String = "", inErrorID:int = 0, inSubErrorID:int = 0, inServerURL:String = null, inDomain:String = null)
// The URL of the media rights server that rejected the authentication attempt.
public var serverURL: String;
// The content domain of the media rights server.
public var domain: String;
public function DRMAuthenticationErrorEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, inDetail:String = "",
inErrorID:int = 0, inSubErrorID:int = 0, inServerURL:String = null, inDomain:String = null)
{
super(type,bubbles,cancelable,inDetail,inErrorID);
this.subErrorID = inSubErrorID;
@ -21,7 +28,6 @@ package flash.events
this.domain = inDomain;
}
// Creates a copy of the ErrorEvent object and sets the value of each property to match that of the original.
override public function clone():Event
{

View File

@ -7,14 +7,23 @@ package flash.events
public class DRMReturnVoucherCompleteEvent extends Event
{
public static const RETURN_VOUCHER_COMPLETE:String = "returnVoucherComplete"; // The string constant to use for the return voucher complete event in the type parameter when adding and removing event listeners.
// The string constant to use for the return voucher complete event in the type parameter when adding and removing event listeners.
public static const RETURN_VOUCHER_COMPLETE:String = "returnVoucherComplete";
public var serverURL: String; // The URL of the media rights server.
public var licenseID: String; // The license ID that was passed into the DRMManager.returnVoucher() call.
public var policyID: String; // The policyID that was passed into the DRMManager.returnVoucher() call.
public var numberOfVouchersReturned: int; // The number of vouchers that matches the criterion passed into DRMManager.returnVoucher() and subsequently returned.
// The URL of the media rights server.
public var serverURL: String;
public function DRMReturnVoucherCompleteEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, inServerURL:String = null, inLicenseID:String = null, inPolicyID:String = null, inNumberOfVouchersReturned:int = 0)
// The license ID that was passed into the DRMManager.returnVoucher() call.
public var licenseID: String;
// The policyID that was passed into the DRMManager.returnVoucher() call.
public var policyID: String;
// The number of vouchers that matches the criterion passed into DRMManager.returnVoucher() and subsequently returned.
public var numberOfVouchersReturned: int;
public function DRMReturnVoucherCompleteEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, inServerURL:String = null,
inLicenseID:String = null, inPolicyID:String = null, inNumberOfVouchersReturned:int = 0)
{
super(type,bubbles,cancelable);
this.serverURL = inServerURL;

View File

@ -7,14 +7,23 @@ package flash.events
public class DRMReturnVoucherErrorEvent extends ErrorEvent
{
public static const RETURN_VOUCHER_ERROR:String = "returnVoucherError"; // The string constant to use for the return voucher error event in the type parameter when adding and removing event listeners.
// The string constant to use for the return voucher error event in the type parameter when adding and removing event listeners.
public static const RETURN_VOUCHER_ERROR:String = "returnVoucherError";
public var subErrorID: int; // A more detailed error code.
public var serverURL: String; // The URL of the media rights server for this return Voucher attempt.
public var licenseID: String; // The license ID that was passed into the returnVoucher() call that resulted in this error.
public var policyID: String; // The policy ID that was passed into the returnVoucher() call that resulted in this error.
// A more detailed error code.
public var subErrorID: int;
public function DRMReturnVoucherErrorEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, inDetail:String = "", inErrorID:int = 0, inSubErrorID:int = 0, inServerURL:String = null, inLicenseID:String = null, inPolicyID:String = null)
// The URL of the media rights server for this return Voucher attempt.
public var serverURL: String;
// The license ID that was passed into the returnVoucher() call that resulted in this error.
public var licenseID: String;
// The policy ID that was passed into the returnVoucher() call that resulted in this error.
public var policyID: String;
public function DRMReturnVoucherErrorEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, inDetail:String = "",
inErrorID:int = 0, inSubErrorID:int = 0, inServerURL:String = null, inLicenseID:String = null, inPolicyID:String = null)
{
super(type,bubbles,cancelable,inDetail,inErrorID);
this.subErrorID = inSubErrorID;

View File

@ -9,18 +9,35 @@ package flash.events
public class FocusEvent extends Event
{
public static const FOCUS_IN:String = "focusIn"; // Defines the value of the type property of a focusIn event object.
public static const FOCUS_OUT:String = "focusOut"; // Defines the value of the type property of a focusOut event object.
public static const KEY_FOCUS_CHANGE:String = "keyFocusChange"; // Defines the value of the type property of a keyFocusChange event object.
public static const MOUSE_FOCUS_CHANGE:String = "mouseFocusChange"; // Defines the value of the type property of a mouseFocusChange event object.
// Defines the value of the type property of a focusIn event object.
public static const FOCUS_IN:String = "focusIn";
public var relatedObject: InteractiveObject; // A reference to the complementary InteractiveObject instance that is affected by the change in focus.
public var shiftKey: Boolean; // Indicates whether the Shift key modifier is activated, in which case the value is true.
public var keyCode: uint; // The key code value of the key pressed to trigger a keyFocusChange event.
public var direction: String; // Specifies direction of focus for a focusIn event.
public var isRelatedObjectInaccessible: Boolean; // If true, the relatedObject property is set to null for reasons related to security sandboxes.
// Defines the value of the type property of a focusOut event object.
public static const FOCUS_OUT:String = "focusOut";
public function FocusEvent(type:String, bubbles:Boolean = true, cancelable:Boolean = false, relatedObject:InteractiveObject = null, shiftKey:Boolean = false, keyCode:uint = 0, direction:String = "none")
// Defines the value of the type property of a keyFocusChange event object.
public static const KEY_FOCUS_CHANGE:String = "keyFocusChange";
// Defines the value of the type property of a mouseFocusChange event object.
public static const MOUSE_FOCUS_CHANGE:String = "mouseFocusChange";
// A reference to the complementary InteractiveObject instance that is affected by the change in focus.
public var relatedObject: InteractiveObject;
// Indicates whether the Shift key modifier is activated, in which case the value is true.
public var shiftKey: Boolean;
// The key code value of the key pressed to trigger a keyFocusChange event.
public var keyCode: uint;
// Specifies direction of focus for a focusIn event.
public var direction: String;
// If true, the relatedObject property is set to null for reasons related to security sandboxes.
public var isRelatedObjectInaccessible: Boolean;
public function FocusEvent(type:String, bubbles:Boolean = true, cancelable:Boolean = false, relatedObject:InteractiveObject = null,
shiftKey:Boolean = false, keyCode:uint = 0, direction:String = "none")
{
super(type,bubbles,cancelable);
this.relatedObject = relatedObject;

View File

@ -9,15 +9,29 @@ package flash.events
{
public static const GESTURE_TWO_FINGER_TAP:String = "gestureTwoFingerTap"; // Defines the value of the type property of a GESTURE_TWO_FINGER_TAP gesture event object.
public var phase: String; // A value from the GesturePhase class indicating the progress of the touch gesture.
public var localX: Number; // The horizontal coordinate at which the event occurred relative to the containing sprite.
public var localY: Number; // The vertical coordinate at which the event occurred relative to the containing sprite.
public var ctrlKey: Boolean; // On Windows or Linux, indicates whether the Ctrl key is active (true) or inactive (false).
public var altKey: Boolean; // Indicates whether the Alt key is active (true) or inactive (false).
public var shiftKey: Boolean; // Indicates whether the Shift key is active (true) or inactive (false).
public var controlKey: Boolean; // Indicates whether the Control key is activated on Mac and whether the Ctrl key is activated on Windows or Linux.
// A value from the GesturePhase class indicating the progress of the touch gesture.
public var phase: String;
public function GestureEvent(type:String, bubbles:Boolean = true, cancelable:Boolean = false, phase:String = null, localX:Number = 0, localY:Number = 0, ctrlKey:Boolean = false, altKey:Boolean = false, shiftKey:Boolean = false, controlKey:Boolean = false)
// The horizontal coordinate at which the event occurred relative to the containing sprite.
public var localX: Number;
// The vertical coordinate at which the event occurred relative to the containing sprite.
public var localY: Number;
// On Windows or Linux, indicates whether the Ctrl key is active (true) or inactive (false).
public var ctrlKey: Boolean;
// Indicates whether the Alt key is active (true) or inactive (false).
public var altKey: Boolean;
// Indicates whether the Shift key is active (true) or inactive (false).
public var shiftKey: Boolean;
// Indicates whether the Control key is activated on Mac and whether the Ctrl key is activated on Windows or Linux.
public var controlKey: Boolean;
public function GestureEvent(type:String, bubbles:Boolean = true, cancelable:Boolean = false, phase:String = null, localX:Number = 0,
localY:Number = 0, ctrlKey:Boolean = false, altKey:Boolean = false, shiftKey:Boolean = false, controlKey:Boolean = false)
{
super(type,bubbles,cancelable);
this.phase = phase;

View File

@ -7,7 +7,15 @@ package flash.events
private var _charCode:uint;
private var _keyCode:uint;
public function KeyboardEvent(type:String, bubbles:Boolean = true, cancelable:Boolean = false, charCodeValue:uint = 0, keyCodeValue:uint = 0, keyLocationValue:uint = 0, ctrlKeyValue:Boolean = false, altKeyValue:Boolean = false, shiftKeyValue:Boolean = false)
public function KeyboardEvent(type:String,
bubbles:Boolean = true,
cancelable:Boolean = false,
charCodeValue:uint = 0,
keyCodeValue:uint = 0,
keyLocationValue:uint = 0,
ctrlKeyValue:Boolean = false,
altKeyValue:Boolean = false,
shiftKeyValue:Boolean = false)
{
super(type,bubbles,cancelable);
this._charCode = charCodeValue;
@ -27,5 +35,10 @@ package flash.events
public function set keyCode(val:uint) {
this._keyCode = val;
}
override public function clone() : Event
{
return new KeyboardEvent(this.type,this.bubbles,this.cancelable);
}
}
}

View File

@ -37,7 +37,17 @@ package flash.events
public var movementX: Number;
public var movementY: Number;
public function MouseEvent(type:String, bubbles:Boolean = true, cancelable:Boolean = false, localX:Number = 0/0, localY:Number = 0/0, relatedObject:InteractiveObject = null, ctrlKey:Boolean = false, altKey:Boolean = false, shiftKey:Boolean = false, buttonDown:Boolean = false, delta:int = 0)
public function MouseEvent(type:String,
bubbles:Boolean = true,
cancelable:Boolean = false,
localX:Number = 0/0,
localY:Number = 0/0,
relatedObject:InteractiveObject = null,
ctrlKey:Boolean = false,
altKey:Boolean = false,
shiftKey:Boolean = false,
buttonDown:Boolean = false,
delta:int = 0)
{
super(type,bubbles,cancelable);
this.localX = localX;

View File

@ -7,10 +7,15 @@ package flash.events
public class NetDataEvent extends Event
{
public static const MEDIA_TYPE_DATA:String = "mediaTypeData"; // The NetDataEvent.MEDIA_TYPE_DATA constant defines the value of the type property of the NetDataEvent object dispatched when a data message in the media stream is encountered by the NetStream object.
// The NetDataEvent.MEDIA_TYPE_DATA constant defines the value of the type property of the NetDataEvent object
// dispatched when a data message in the media stream is encountered by the NetStream object.
public static const MEDIA_TYPE_DATA:String = "mediaTypeData";
private var _timestamp: Number; // The timestamp of the data message in the media stream.
private var _info: Object; // A data object describing the message.
// The timestamp of the data message in the media stream.
private var _timestamp: Number;
// A data object describing the message.
private var _info: Object;
public function NetDataEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, timestamp:Number = 0, info:Object = null)
{

View File

@ -9,12 +9,20 @@ package flash.events
public class SoftKeyboardEvent extends Event
{
public static const SOFT_KEYBOARD_ACTIVATE:String = "softKeyboardActivate"; // The SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE constant defines the value of the type property SoftKeyboardEvent object when a soft keyboard is displayed.
public static const SOFT_KEYBOARD_ACTIVATING:String = "softKeyboardActivating"; // The SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATING constant defines the value of the type property SoftKeyboardEvent object immediately before a soft keyboard is displayed.
public static const SOFT_KEYBOARD_DEACTIVATE:String = "softKeyboardDeactivate"; // The SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE constant defines the value of the type property SoftKeyboardEvent object when a soft keyboard is lowered or hidden.
// The SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE constant defines the value of the type property SoftKeyboardEvent object when a soft keyboard is displayed.
public static const SOFT_KEYBOARD_ACTIVATE:String = "softKeyboardActivate";
public var relatedObject: InteractiveObject; // A reference to a display list object that is related to the event.
private var _triggerType: String; // Indicates whether the change in keyboard status has been triggered by an application (such as programmatic use of requestSoftKeyboard()) or by the user (such as selecting a text field).
// The SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATING constant defines the value of the type property SoftKeyboardEvent object immediately before a soft keyboard is displayed.
public static const SOFT_KEYBOARD_ACTIVATING:String = "softKeyboardActivating";
// The SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE constant defines the value of the type property SoftKeyboardEvent object when a soft keyboard is lowered or hidden.
public static const SOFT_KEYBOARD_DEACTIVATE:String = "softKeyboardDeactivate";
// A reference to a display list object that is related to the event.
public var relatedObject: InteractiveObject;
// Indicates whether the change in keyboard status has been triggered by an application (such as programmatic use of requestSoftKeyboard()) or by the user (such as selecting a text field).
private var _triggerType: String;
public function SoftKeyboardEvent(type:String, bubbles:Boolean, cancelable:Boolean, relatedObjectVal:InteractiveObject, triggerTypeVal:String)
{
@ -23,7 +31,6 @@ package flash.events
this._triggerType = triggerTypeVal;
}
// Creates a copy of a SoftKeyboardEvent object and sets the value of each property to match that of the original.
override public function clone():Event
{

View File

@ -7,6 +7,10 @@ package flash.events {
super(type, bubbles, cancelable);
}
override public function clone() : Event {
return new TimerEvent(this.type,this.bubbles,this.cancelable);
}
public function updateAfterEvent():void {
// TODO - determine when we should actually force a frame to be rendered.
}

View File

@ -9,7 +9,15 @@
public var quality: int;
public var strength: Number;
public function GlowFilter(color: uint = 0xFF0000, alpha: Number = 1.0, blurX: Number = 6.0, blurY: Number = 6.0, strength: Number = 2, quality: int = 1, inner: Boolean = false, knockout: Boolean = false) {
public function GlowFilter(color: uint = 0xFF0000,
alpha: Number = 1.0,
blurX: Number = 6.0,
blurY: Number = 6.0,
strength: Number = 2,
quality: int = 1,
inner: Boolean = false,
knockout: Boolean = false)
{
this.alpha = alpha;
this.blurX = blurX;
this.blurY = blurY;

View File

@ -9,7 +9,15 @@ package flash.geom {
public var blueOffset: Number;
public var alphaOffset: Number;
public function ColorTransform(redMultiplier: Number = 1, greenMultiplier: Number = 1, blueMultiplier: Number = 1, alphaMultiplier: Number = 1, redOffset: Number = 0, greenOffset: Number = 0, blueOffset: Number = 0, alphaOffset: Number = 0) {
public function ColorTransform(redMultiplier: Number = 1,
greenMultiplier: Number = 1,
blueMultiplier: Number = 1,
alphaMultiplier: Number = 1,
redOffset: Number = 0,
greenOffset: Number = 0,
blueOffset: Number = 0,
alphaOffset: Number = 0)
{
this.redMultiplier = redMultiplier;
this.greenMultiplier = greenMultiplier;
this.blueMultiplier = blueMultiplier;
@ -45,7 +53,23 @@ package flash.geom {
}
public function toString(): String {
return "(redMultiplier=" + this.redMultiplier + ", greenMultiplier=" + this.greenMultiplier + ", blueMultiplier=" + this.blueMultiplier + ", alphaMultiplier=" + this.alphaMultiplier + ", redOffset=" + this.redOffset + ", greenOffset=" + this.greenOffset + ", blueOffset=" + this.blueOffset + ", alphaOffset=" + this.alphaOffset + ")";
return "(redMultiplier="
+ this.redMultiplier
+ ", greenMultiplier="
+ this.greenMultiplier
+ ", blueMultiplier="
+ this.blueMultiplier
+ ", alphaMultiplier="
+ this.alphaMultiplier
+ ", redOffset="
+ this.redOffset
+ ", greenOffset="
+ this.greenOffset
+ ", blueOffset="
+ this.blueOffset
+ ", alphaOffset="
+ this.alphaOffset
+ ")";
}
}
}

View File

@ -1,7 +1,4 @@
package flash.geom {
import flash.geom.Point;
import flash.geom.Vector3D;
public class Matrix {
public var a:Number;
public var b:Number;

View File

@ -1,6 +1,5 @@
package flash.system {
import flash.display.DisplayObjectContainer;
import flash.system.ApplicationDomain;
public class LoaderContext {
public var allowCodeImport : Boolean;