- Object initializer, just as in JavaScript, translates to plain objects whose constructor is
Object
, regardless of its associated type. If the object implements an interface, it is not considered an implementor anymore after translated to ABC. - Whenever a signature type is known, output unused parameters to the ABC. This avoids bugs such as
map()
receiving a callback that accepts only one parameter (o.map(a => v)
vs.o.map((a, i, arr) => v)
). - Optional parameters are optimized if their type supports a constant value and a proper default (e.g.
NaN
,null
orundefined
); otherwise they'll translate to an untyped parameter, which is converted to its expected type later in the same function. - airsdk/Adobe-Runtime-Support#2595
- As for FFI matters: instead of a comment, use a separate file
srcName.ffi.json
with a content like{"Q.f": {"exportAs": "q_f"}}
and also decide how to resolve to static or instance properties in this FFI meta-data.
- As for FFI matters: instead of a comment, use a separate file
- The
number[]
type should not be optimized into aVector.<Number>
. for..in
does not iterate keys from class instance properties.- If a class duplicates a name, it should have another name, by appending a dollar sign. Loop appending different suffixes such as
$1
,$2
or$90
until it is not a duplicate. The global objects should be priorized, thus they should not have these suffixes. - The target ECMAScript edition is ES5, since ES3 is deprecated.
for...of
over a statically-typedArray
should iterate the values likefor each
.for...of
over an untyped value should iterate based on a map that maps constructor (obj.constructor
) to its equivalent generator.for...of
should use generator.
- Generators are useful for iterators and
for...of
. When TypeScript emits JavaScript for an edition prior to ES2015, it emits special code instead of usingyield
; this meansts4air
can use a similiar approach, taking care to not break the control flow graph.
async
-await
should be outputted based on whattsc
outputs for them in the ES5 target.Promise
should wrap another type,com.asprelude.util.Promise
, from the SWF of theactionscript-prelude
project.- Add
"then"
,"catch"
and"finally"
as keywords are available in the ABC format.
- Add
- Symbols won't be supported, so it must be unallowed to use them, but it should be possible to define a
Symbol.iterator
iterator by internally creating global static maps usingDictionary
with weak keys. Thus allowSymbol.iterator
definitions, but don't allow use of symbols anywhere else.
- Consider, e.g., no return after
throw
in a function that doesn't returnvoid
.
Globals should be defined in some file global.d.ts.
declare global {
class Array {
// ...
}
// declare import.meta.embedT() methods here
interface ImportMeta {
}
// declare assertion functions to use
// from actionscript-extra.swf
}
Typings for globals and built-ins (including Adobe AIR API) should be included in compilerOptions.types
: com.adobe.air
. Globals like Math
, Infinity
and isFinite()
should translate to public::Math
, public::Infinity
and public::isFinite
respectively, where public
is the global package's namespace (namespace('packageNamespace', '')
).
Definitions inside declare global
should be connected to their ActionScript global equivalents.
Look at FFDec or swfdump to see what is the name of e.g. Vector.<uint>
: is it the global Vector$uint
or something like?
Definitions other than declare global
should have a suffix to not conflict with them.
Promise
,Map
,WeakMap
,Set
andWeakSet
should be wrappers around their equivalents incom.asprelude.util
.- These types can use keyword in ABC; e.g.
delete
,try
andfinally
. - Iterating these requires careful mapping.
- These types can use keyword in ABC; e.g.
Internal tweaks may be neccessary since there is no int
and uint
in TypeScript.
import.meta.embedBytes
, must output DefineBinaryData
and SymbolClass
tags to the SWF without conflicting with existing ones from previously merged SWFs.
Properties (including functions) in the top-level of a source file map to top-level package properties. If a property has a non-constant initializer, its initializer should be post-poned (taking in consideration statements that execute before and after it).
let o: number | undefined = undefined
o! // throw a ReferenceError
Using exports
might not be supported as it is not a priority.