haxefoundation / as3hx Goto Github PK
View Code? Open in Web Editor NEWConvert AS3 sources to their Haxe equivalent
License: MIT License
Convert AS3 sources to their Haxe equivalent
License: MIT License
Script reports not converting due to parse error on missing semicolon.
When I'm trying to convert AS3 file with dictionary class inside got error:
ERRORS: These files were not written due to source parsing errors:
In /home/lexys/test/TestManger.as(9) : Unexpected =
Using :
as3hx: [1.0.0]
actuate: [1.7.2] 1.7.0
format: [3.0.5] 3.0.4
hxcpp: [3.1.30]
hxlibc: 1.0.0 [1.1.4]
hxtools: [1.1.6]
lime-tools: 1.3.0 [1.4.0] 1.3.2 1.2.9
lime: [0.9.7] 0.9.6 0.9.5
openfl-html5-dom: 1.2.1 [1.2.2] 1.1.1
openfl-html5: 1.1.0-beta [1.4.2-beta]
openfl-native: 1.2.3 1.3.0 [1.4.0] 1.1.4
openfl-samples: 1.2.1 [1.3.0] 1.1.0
openfl-tiled: [0.4.2]
openfl: 1.2.3 1.3.0 [1.4.0] 1.1.1
svg: [1.0.7]
Example class:
package
{
import flash.utils.Dictionary;
public class TestManger
{
public var _dic:Dictionary = new Dictionary();
public function TestManger()
{
}
}
}
package{
//注释
import B;
import flash.display.Sprite;
public class Kaosillator extends Sprite{
//注释
public function Kaosillator(){
// 单行注释
var i:int = 100;
args(1,2,3);
}
/**
* ...args 的参数会被清除
*/
private function args(...args):void {
trace(args);
}
}
}
//注释import B;import flash.display.Sprite;class Kaosillator extends Sprite
{ //注释 public function new()
{
super(); // 单行注释 var i : Int = 100;args(1, 2, 3);
} /**
* ...args 的参数会被清除
*/ private function args() : Void{trace(args);
}
}
Conversion to setField creates broken expressions when field access occurs on same line. Example:
guiById[prefix].visible = partyMember != null;
becomes
Reflect.setField(guiById, prefix, partyMember != null).visible;
// as3
subTextureRegion.x = int(subTextureObject[ConstValues.A_X]) / scale;
// Haxe
subTextureRegion.x = as3hx.Compat.parseInt(subTextureObject[ConstValues.A_X]) / scale;
Implicit cast to int (e.g. var myInt:int = myNumber;) does not add Std.int() wrapper for conversion. This occurs especially frequently as result of Math.min() and Math.max() of two ints, which in Haxe returns a Float
Hello, The tools is very impressive and worked for the most part except that I am getting two errors that I am not able to fix. Any help with this is greatly appreciated.
ERROR: type must be determined for 'as array' cast for:
C:/HaxeToolkit/as3hx/./out/com/flashdynamix/motion/TweensyTimeline.hx
ERRORS: These files were not written due to source parsing errors:
In C:/HaxeToolkit/as3hx/projects/flash/com/adobe/serialization/json/JSONEncoder.as(278) : Unexpected *
In C:/HaxeToolkit/as3hx/projects/flash/com/adobe/serialization/json/JSONTokenizer.as(101) : Unexpected :
attached are the two files that are causing the issues. content is tagged with "file start" and "file end" for attachment reasons.
Thank you,
sam
--------------- file start TweensyTimeline.as -----------------------
/**
.______ __ ___
/__ \ /'__\ /'___
\
//\ / __ __ __ __ __ ___ ____ __ __ /\ /\ \ /\ /\ \
...\ \ \ /\ /\ /\ \ /'**\ /'**
\ /' \ /',**\ /\ \/\ \ \ \ \ \ \ \/_/// /** ....\ \ \ \ _/ _/ \/\ **/ /\ __/ /\ \/\ \ /\**,
\ \ _\ \ \ \ _\ \ __ // /\
.....\ _\ _x/'\ _\ _\ _\ _\/_/ /____ \ \ _**_//\_\/____**/ ......\/_/ \/__//**/ \/__**/ \/____/ \/_/\/_/ \/**_/
/**/> \ /**/ ///__**/
............................................................//
............................................................//
................. Tweening since 1998 ......................
............................................................
/
package com.flashdynamix.motion {
import com.flashdynamix.motion.plugins.AbstractTween;
import com.flashdynamix.motion.plugins.TweensyPluginList;
/*
* TweensyTimeline groups instances of tweens which are animating for the same duration. It's important
* to know that these Tweens can be animating their own unique properties and from to targets
*
* TweensyTimelines are especially efficient for bulk tweening (1000+ Objects) because of their
* capability of grouping instances with a common timeline.
*
* The TweensyTimeline Class has events for:
*
timeline.to([item1, item2], {x:50, y:50});
{x:50, y:25}
{x:'-50, 50', y:'-25, 25'}
timeline.to(new DropShadowFilter(), {alpha:0}, myDisplayItem);
'myDisplayItem'
. if(instance is Array) {
var i : int = 0;
var len : int = (instance as Array).length;
for(i < 0;i < len; i++) {
if(instance[i] is Number || instance[i] is String) {
if(!tween) tween = add(instance, update);
tween.add(i.toString(), to[i], false);
} else {
this.to(instance[i], to, update);
}
}
} else {
tween = add(instance, update);
tween.toTarget(to);
}
}
/**
* Adds a from based tween to the properties defined in the target Object.
*
* @param instance The instance Object to be tweened or multiple _instances if using the type Array e.g. <code>timeline.from([item1, item2], {x:50, y:50})</code>;
* @param from An Object containing the properties you would like to tween from e.g. <code>{x:50, y:25}</code>
* or this can be relative e.g. {x:'50', y:'-25'} or can be a random position e.g. <code>{x:'-50, 50', y:'-25, 25'}</code>
* @param update This param is used when tweening a property in a Object which needs to be applied onto another Object each time
* the tween occurs.<BR>
* For example <code>timeline.from(new DropShadowFilter(), {alpha:0}, myDisplayItem);</code><BR>
* Will apply the tweening DropShadowFilter onto the DisplayObject <code>'myDisplayItem'</code>.
*/
public function from(instance : Object, from : Object, update : Object = null) : void {
var tween : AbstractTween;
if(instance is Array) {
var i : int = 0;
var len : int = (instance as Array).length;
for(i < 0;i < len; i++) {
if(instance[i] is Number || instance[i] is String) {
if(!tween) tween = add(instance, update);
tween.add(i.toString(), from[i], true);
} else {
this.from(instance[i], from, update);
}
}
} else {
tween = add(instance, update);
tween.fromTarget(from);
tween.apply();
}
}
/**
* Adds a from to based tween to the properties defined in the target Object.
*
* @param instance The instance Object to be tweened or multiple _instances if using the type Array e.g. <code>timeline.fromTo([item1, item2], {x:50, y:50});</code>
* @param from An Object containing the properties you would like to tween from e.g. <code>{x:50, y:25}</code>
* or this can be relative e.g. {x:'50', y:'-25'} or can be a random position e.g. <code>{x:'-50, 50', y:'-25, 25'}</code>
* @param to An Object containing the properties you would like to tween to e.g. <code>{x:50, y:25}</code>
* or this can be relative e.g. {x:'50', y:'-25'} or can be a random position e.g. <code>{x:'-50, 50', y:'-25, 25'}</code>
* @param update This param is used when tweening a property in a Object which needs to be applied onto another Object each time
* the tween occurs.<BR>
* For example <code>timeline.fromTo(new DropShadowFilter(), {alpha:0}, {alpha:1}, myDisplayItem)</code><BR>
* Will apply the tweening DropShadowFilter onto the DisplayObject <code>'myDisplayItem'</code>
*/
public function fromTo(instance : Object, from : Object, to : Object, update : Object = null) : void {
var tween : AbstractTween;
if(instance is Array) {
var i : int = 0;
var len : int = (instance as Array).length;
for(i < 0;i < len; i++) {
if(instance[i] is Number || instance[i] is String) {
if(!tween) tween = add(instance, update);
tween.add(i.toString(), from[i], true);
tween.add(i.toString(), to[i], false);
} else {
this.fromTo(instance[i], from, to, update);
}
}
} else {
tween = add(instance, update);
tween.fromTarget(from);
tween.toTarget(to);
tween.apply();
}
}
/**
* Updates a tween for the instance Object to the new target properties defined in the to Object.<BR>
* The value of this instance depends on wether the 'update' param is used i.e.<BR>
* <code>timeline.to(new DropShadowFilter(), {alpha:0}, myDisplayItem);</code> the instance parameter will be myDisplayItem.<BR>
* <code>timeline.to(new DropShadowFilter(), {alpha:0});</code> the instance parameter will be the filter
*/
public function updateTo(instance : Object, to : Object) : void {
var position : Number = ease.apply(null, args);
var tween : AbstractTween;
for each(tween in list) {
if(tween.instance == instance) tween.updateTo(position, to);
}
}
/**
* Allows for removing tweens via an instance or tween props by the following methods :
* <ul>
* <li><code>timeline.stop(instance);</code> - stops all property tweens for this instance.</li>
* <li><code>timeline.stop(instance, "x", "y");</code> - stops all x,y property tweens for this instance.</li>
* <li><code>timeline.stop([instance1, instance2]);</code> - stops all property tweens for these _instances.</li>
* <li><code>timeline.stop([instance1, instance2], "x", "y");</code> - stops all x,y property tweens for these _instances.</li>
* <li><code>timeline.stop(null, "x", "y");</code> - stops all x,y property tweens.</li>
* <li><code>timeline.stop();</code> - stops all tweens though it is recommended to use the stopAll method as this is more efficient.</li>
* </ul>
*/
public function stop(instance : * = null, ...props : Array) : void {
var _instances : Array = (instance is Array) ? instance : (instance == null) ? null : [instance];
var tween : AbstractTween;
var i : int;
for (i = _tweens - 1;i >= 0; i--) {
tween = list[i];
if(_instances == null || _instances.indexOf(tween.instance) != -1) {
if(props.length == 0) {
tween.stopAll();
} else {
tween.stop.apply(null, props);
}
if(!tween.hasAnimations) {
remove(tween);
list.splice(i, 1);
}
}
}
if(!hasTweens && manager) manager.remove(this);
}
public function stopAll() : void {
removeAll();
if(manager) manager.remove(this);
}
/**
* Updates the TweensyTimeline by the specified amout of time in seconds.<BR>
* This function is intended for use by the Tweensy class which is controlling this timeline animation.<BR>
* Though calling this function will update the timeline independtly of the mananger allowing for custom control
* over timelines.
*
* @return Whether the TweensyTimeline animation has finished playing.
*/
public function update(secs : Number) : Boolean {
if(paused) return false;
_time += secs;
var played : Number = _time - delayStart;
var done : Boolean = false;
if(played > 0) {
done = finished;
played = (played > _duration) ? _duration : played;
args[0] = played;
var position : Number = ease.apply(null, args);
var tween : AbstractTween;
var i : int;
for (i = 0;i < _tweens; i++) {
tween = list[i];
tween.update(position);
}
if(onUpdate != null) {
onUpdate.apply(null, onUpdateParams);
done = finished;
}
if(done) {
if(canRepeat) {
if(repeatType == YOYO) {
yoyo();
} else if(repeatType == REPLAY) {
replay();
} else if(repeatType == LOOP) {
loop();
}
if(onRepeat != null) onRepeat.apply(null, onRepeatParams);
done = finished;
}
if(done) {
if(onComplete != null) onComplete.apply(null, onCompleteParams);
done = finished && !canRepeat;
if(done && _onComplete != null) _onComplete();
}
}
}
return done;
}
/**
* Pauses a playing TweensyTimeline
*/
public function pause() : void {
if(paused) return;
_paused = true;
}
/**
* Resumes a paused TweensyTimeline
*/
public function resume() : void {
if(!paused) return;
_paused = false;
}
/**
* Forces a timeline tween to loop the animation.<BR>
* A looped animation will swap the delays (delayStart & delayEnd) so that the to and from animations have the same delays.
*
* @see com.flashdynamix.motion.TweensyTimeline#repeats
* @see com.flashdynamix.motion.TweensyTimeline#repeatCount
* @see com.flashdynamix.motion.TweensyTimeline#NONE
* @see com.flashdynamix.motion.TweensyTimeline#YOYO
* @see com.flashdynamix.motion.TweensyTimeline#REPLAY
* @see com.flashdynamix.motion.TweensyTimeline#LOOP
*/
public function loop() : void {
var tween : AbstractTween;
for each(tween in list) tween.swapToFrom();
var oldStart : Number = delayStart;
delayStart = delayEnd;
delayEnd = oldStart;
doRepeat();
}
/**
* Forces a timeline tween to do a yoyo animation.<BR>
* A yoyo will use the same delayStart and delayEnd on the to and fro animation.
*
* @see com.flashdynamix.motion.TweensyTimeline#repeats
* @see com.flashdynamix.motion.TweensyTimeline#repeatCount
* @see com.flashdynamix.motion.TweensyTimeline#NONE
* @see com.flashdynamix.motion.TweensyTimeline#YOYO
* @see com.flashdynamix.motion.TweensyTimeline#REPLAY
* @see com.flashdynamix.motion.TweensyTimeline#LOOP
*/
public function yoyo() : void {
var tween : AbstractTween;
for each(tween in list) tween.swapToFrom();
doRepeat();
}
/**
* Plays a timeline animation at its start position on each repeat.
*
* @see com.flashdynamix.motion.TweensyTimeline#repeats
* @see com.flashdynamix.motion.TweensyTimeline#repeatCount
* @see com.flashdynamix.motion.TweensyTimeline#NONE
* @see com.flashdynamix.motion.TweensyTimeline#YOYO
* @see com.flashdynamix.motion.TweensyTimeline#REPLAY
* @see com.flashdynamix.motion.TweensyTimeline#LOOP
*/
public function replay() : void {
var tween : AbstractTween;
for each(tween in list) tween.update(0);
doRepeat();
}
/**
* Defines whether the TweensyTimeline repeats.
*/
public function get canRepeat() : Boolean {
return (repeatType != NONE && (repeats == -1 || repeatCount < repeats));
}
public function set position(index : Number) : void {
var dif : Number = (index * totalDuration) - _time;
update(dif);
}
/**
* Seeks and returns the animation to a position from 0 to 1, start to end.
*/
public function get position() : Number {
return (_time / totalDuration);
}
/**
* Determines whether or not the TweensyTimeline animation has finished.
*/
public function get finished() : Boolean {
return (_time >= totalDuration);
}
/**
* The total duration of the TweensyTimeline animation in seconds.<BR>
* This is the sum of delayStart, duration and delayEnd.
*/
public function get totalDuration() : Number {
return (delayStart + _duration + delayEnd);
}
public function set time(seconds : Number) : void {
_time = seconds;
}
/**
* The time in seconds the TweensyTimeline has been running for
*/
public function get time() : Number {
return _time;
}
public function set duration(secs : Number) : void {
args[3] = secs;
_duration = secs;
}
/**
* Sets and gets the current tween duration for the TweensyTimeline in seconds.
*/
public function get duration() : Number {
return _duration;
}
/**
* Sets the ease params. These params are used on Back, Bounce and Elastic ease functions.<BR>
* These parameters lessen or exaggerate the effect of these particular ease functions.<BR>
* i.e. [0.7] will lessen the effect of a Back equation
*/
public function set easeParams(value : Array) : void {
args = args.slice(0, 4).concat(value);
}
/**
* Whether the TweensyTimeline is paused.
*/
public function get paused() : Boolean {
return (_paused);
}
/**
* This is when the animation is after the delay start and before its delay end.
*
* @return Whether the TweensyTimeline is playing.
*/
public function get playing() : Boolean {
return (_time > delayStart && _time < delayEnd);
}
/**
* Number of tweens added to the TweensyTimeline Class.
*/
public function get tweens() : int {
return _tweens;
}
/**
* Whether the TweensyTimeline has any animations.
*/
public function get hasTweens() : Boolean {
return (_tweens > 0);
}
public function get instances() : Array {
return _instances;
}
/** @private */
internal function removeAll() : void {
var tween : AbstractTween;
for each(tween in list) remove(tween);
list.length = 0;
_instances.length = 0;
}
/** @private */
internal function removeOverlap(timeline : TweensyTimeline) : void {
if(this != timeline && intersects(timeline)) {
var i : int;
var tweenA : AbstractTween;
var tweenB : AbstractTween;
for each(tweenA in timeline.list) {
for (i = _tweens - 1;i >= 0; i--) {
tweenB = list[i];
tweenB.removeOverlap(tweenA);
if(!tweenB.hasAnimations) {
remove(tweenB);
list.splice(i, 1);
}
}
}
if(!hasTweens) manager.remove(this);
}
}
/** @private */
internal function clear() : void {
removeAll();
next = null;
previous = null;
args = defaultArgs.concat();
manager = null;
onUpdate = null;
onUpdateParams = null;
onComplete = null;
onCompleteParams = null;
onRepeat = null;
onRepeatParams = null;
_onComplete = null;
ease = defaultTween;
delayStart = 0;
delayEnd = 0;
repeatType = NONE;
repeats = -1;
repeatEase = null;
disposed = false;
_time = 0;
_paused = false;
repeatCount = 0;
}
private function add(instance : Object, update : Object = null) : AbstractTween {
var tween : AbstractTween = TweensyPluginList.checkOut(instance);
tween.timeline = this;
tween.construct(instance, update);
_instances.push(tween.instance);
list[_tweens++] = tween;
return tween;
}
private function remove(tween : AbstractTween) : void {
tween.clear();
TweensyPluginList.checkIn(tween);
if(manager) manager.removeInstance(tween.instance, this);
_instances.splice(_instances.indexOf(tween.instance));
_tweens--;
}
private function intersects(timeline : TweensyTimeline) : Boolean {
return (timeline.delayStart < (totalDuration - time));
}
private function doRepeat() : void {
_time = 0;
repeatCount++;
if(repeatEase) ease = repeatEase[repeatCount % repeatEase.length];
}
public static function empty() : void {
TweensyPluginList.empty();
}
private static function easeOut(t : Number, b : Number, c : Number, d : Number) : Number {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
}
/**
* Disposes the TweensyTimeline Class instance ready for garbage collection.
*/
public function dispose() : void {
if(disposed) return;
disposed = true;
stopAll();
next = null;
previous = null;
args = null;
list = null;
manager = null;
ease = null;
repeatEase = null;
onUpdate = null;
onUpdateParams = null;
onComplete = null;
onCompleteParams = null;
onRepeat = null;
onRepeatParams = null;
}
public function toString() : String {
return "TweensyTimeline " + Tweensy.version + " {tweens:" + _tweens + "}";
}
}
}
--------------file end TweensyTimeline.as -------------------
------------------file start jsonencoder.as --------------------------
/*
Copyright (c) 2008, 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 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 OWNER 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.
*/
package com.adobe.serialization.json
{
import flash.utils.describeType;
public class JSONEncoder {
/** The string that is going to represent the object we're encoding */
private var jsonString:String;
/**
* Creates a new JSONEncoder.
*
* @param o The object to encode as a JSON string
* @langversion ActionScript 3.0
* @playerversion Flash 9.0
* @tiptext
*/
public function JSONEncoder( value:* ) {
jsonString = convertToString( value );
}
/**
* Gets the JSON string from the encoder.
*
* @return The JSON string representation of the object
* that was passed to the constructor
* @langversion ActionScript 3.0
* @playerversion Flash 9.0
* @tiptext
*/
public function getString():String {
return jsonString;
}
/**
* Converts a value to it's JSON string equivalent.
*
* @param value The value to convert. Could be any
* type (object, number, array, etc)
*/
private function convertToString( value:* ):String {
// determine what value is and convert it based on it's type
if ( value is String ) {
// escape the string so it's formatted correctly
return escapeString( value as String );
} else if ( value is Number ) {
// only encode numbers that finate
return isFinite( value as Number) ? value.toString() : "null";
} else if ( value is Boolean ) {
// convert boolean to string easily
return value ? "true" : "false";
} else if ( value is Array ) {
// call the helper method to convert an array
return arrayToString( value as Array );
} else if ( value is Object && value != null ) {
// call the helper method to convert an object
return objectToString( value );
}
return "null";
}
/**
* Escapes a string accoding to the JSON specification.
*
* @param str The string to be escaped
* @return The string with escaped special characters
* according to the JSON specification
*/
private function escapeString( str:String ):String {
// create a string to store the string's jsonstring value
var s:String = "";
// current character in the string we're processing
var ch:String;
// store the length in a local variable to reduce lookups
var len:Number = str.length;
// loop over all of the characters in the string
for ( var i:int = 0; i < len; i++ ) {
// examine the character to determine if we have to escape it
ch = str.charAt( i );
switch ( ch ) {
case '"': // quotation mark
s += "\\\"";
break;
//case '/': // solidus
// s += "\\/";
// break;
case '\\': // reverse solidus
s += "\\\\";
break;
case '\b': // bell
s += "\\b";
break;
case '\f': // form feed
s += "\\f";
break;
case '\n': // newline
s += "\\n";
break;
case '\r': // carriage return
s += "\\r";
break;
case '\t': // horizontal tab
s += "\\t";
break;
default: // everything else
// check for a control character and escape as unicode
if ( ch < ' ' ) {
// get the hex digit(s) of the character (either 1 or 2 digits)
var hexCode:String = ch.charCodeAt( 0 ).toString( 16 );
// ensure that there are 4 digits by adjusting
// the # of zeros accordingly.
var zeroPad:String = hexCode.length == 2 ? "00" : "000";
// create the unicode escape sequence with 4 hex digits
s += "\\u" + zeroPad + hexCode;
} else {
// no need to do any special encoding, just pass-through
s += ch;
}
} // end switch
} // end for loop
return "\"" + s + "\"";
}
/**
* Converts an array to it's JSON string equivalent
*
* @param a The array to convert
* @return The JSON string representation of <code>a</code>
*/
private function arrayToString( a:Array ):String {
// create a string to store the array's jsonstring value
var s:String = "";
// loop over the elements in the array and add their converted
// values to the string
for ( var i:int = 0; i < a.length; i++ ) {
// when the length is 0 we're adding the first element so
// no comma is necessary
if ( s.length > 0 ) {
// we've already added an element, so add the comma separator
s += ","
}
// convert the value to a string
s += convertToString( a[i] );
}
// KNOWN ISSUE: In ActionScript, Arrays can also be associative
// objects and you can put anything in them, ie:
// myArray["foo"] = "bar";
//
// These properties aren't picked up in the for loop above because
// the properties don't correspond to indexes. However, we're
// sort of out luck because the JSON specification doesn't allow
// these types of array properties.
//
// So, if the array was also used as an associative object, there
// may be some values in the array that don't get properly encoded.
//
// A possible solution is to instead encode the Array as an Object
// but then it won't get decoded correctly (and won't be an
// Array instance)
// close the array and return it's string value
return "[" + s + "]";
}
/**
* Converts an object to it's JSON string equivalent
*
* @param o The object to convert
* @return The JSON string representation of <code>o</code>
*/
private function objectToString( o:Object ):String
{
// create a string to store the object's jsonstring value
var s:String = "";
// determine if o is a class instance or a plain object
var classInfo:XML = describeType( o );
if ( [email protected]() == "Object" )
{
// the value of o[key] in the loop below - store this
// as a variable so we don't have to keep looking up o[key]
// when testing for valid values to convert
var value:Object;
// loop over the keys in the object and add their converted
// values to the string
for ( var key:String in o )
{
// assign value to a variable for quick lookup
value = o[key];
// don't add function's to the JSON string
if ( value is Function )
{
// skip this key and try another
continue;
}
// when the length is 0 we're adding the first item so
// no comma is necessary
if ( s.length > 0 ) {
// we've already added an item, so add the comma separator
s += ","
}
s += escapeString( key ) + ":" + convertToString( value );
}
}
else // o is a class instance
{
// Loop over all of the variables and accessors in the class and
// serialize them along with their values.
for each ( var v:XML in classInfo..*.(
name() == "variable"
||
(
name() == "accessor"
// Issue #116 - Make sure accessors are readable
&& attribute( "access" ).charAt( 0 ) == "r" )
) )
{
// Issue #110 - If [Transient] metadata exists, then we should skip
if ( v.metadata && v.metadata.( @name == "Transient" ).length() > 0 )
{
continue;
}
// When the length is 0 we're adding the first item so
// no comma is necessary
if ( s.length > 0 ) {
// We've already added an item, so add the comma separator
s += ","
}
s += escapeString( [email protected]() ) + ":"
+ convertToString( o[ v.@name ] );
}
}
return "{" + s + "}";
}
}
}
------------------file end jsonencoder.as ---------------------------
as3 version:
for (var i:int=0; i < _tracks.length; i++) {
var current:TrackEntry = _tracks[i];
if (!current) continue;
}
haxe version:
for (i in 0..._tracks.length)
{
var current:TrackEntry = _tracks[i];
if (current == null)
{
i++;
continue;
}
If an included function declaration is last in the class:
public class Foo {
public function Foo():void { }
include "shared_function.as";
}
It throws: Foo.as(4) : Unexpected }
If there is a function after it, it works fine:
public class Foo {
public function Foo():void { }
include "shared_function.as";
public function bar() { ... }
}
Workaround: don't let an included function be last in the class.
Look at Loops.hx
for example:
for (i in 0..._numButtons){
var btn : ArcButton = new ArcButton();
btn.id = i;
if (btn.name != null) {i++;continue;
};
trace(i);
}
In haxe, you can only call your class's static functions implicitly without a typename. In as3, you can call your superclass's static functions in this manner as well. So static functions called implicitly on superclasses need to have their class name explicitly specified. (e.g. staticMethod(); becomes SuperClass.staticMethod();)
A preincrement before a block gives incorrect output:
Input:
if (expression) {
something();
}
++value;
Output:
if (expression) {
something();
}++;value;
It currently gets converted to while()
.
When AS3 class member level variable has no type, the script crashes.
When I run as3hx on the test folder, a lot of the output is strung together on the same line. I am using the following windows command line:
neko as3hx.n -vector2array -uint2int test\ out\
For example, the contents of the outputted Ifs.hx is:
/**
* Tests of assertions in if statements
**/ import Sprite;
class Ifs
{public function single(a : Sprite){if (a != null) {a.x = 15;
}
}public function singleInv(a : Sprite){if (a == null) {a = new Sprite();
}
}public function binops(a : Sprite, b : Sprite){if (a != null && b != null) trace("We have two sprites");if (a != null || b != null) trace("We have at least one sprite");if (a != null && b == null) trace("a is ok, b is null");if (a == null && b != null) trace("a is null, b is ok");
}public function aBool(b : Bool){ // should parse to if(b) if (b) { } // should parse to if(!b) if (!b) { } // should be left alone as if(b == null) if (b == null) { }
}public function maths(a : Int){ // should parse to if(a++ != 0) if (a++ != 0) { } // should parse to if(a++ == 0) if (a++ == 0) { } // should parse to if(++a++ != 0) if (++a++ != 0) { } // should parse to if(++a++ == 0) if (++a++ == 0) { }
}
public function new()
{
}
}
It seems that some newlines are missing
I am running:
Windows 7
Haxe 3.1.3
as3hx rev: ab16d76
Haxe arrays has not property length which can be writen to, but while converting as3 code as3hx trying to use it.
var a:Vector.<Nuber> = new Vector.<Number>();
a.length = 10;
translates to
var a:Array<Float> = [];
a.length = 10;
neko run.n swf_src/ out/
Called from sys.io.FileOutput::$statics line 1
Called from Run::main line 102
Called from Run::loop line 33
Called from sys.FileSystem::readDirectory line 85
Uncaught exception - std@sys_read_dir
Versions:
NekoVM 2.0.0
Haxe Compiler 3.1.3
Dir permissions:
drwxr-xr-x 3 jadbox jadbox 4096 Mar 14 20:32 out
drwxr-xr-x 3 jadbox jadbox 4096 Mar 14 20:32 swf_src
My OS: Debian Jessie
swf_src/ folder contains regular AS3 class files
For example: if i do parse code
package {
import flash.display.Sprite;
/**
* @author SlavaRa
*/
public class Main extends Sprite {
public function Main() {
if(CONFIG::debug) {
trace("debug");
} else {
trace("release");
}
}
}
}
i get result:
ERRORS: These files were not written due to source parsing errors:
In D:/projects/fd-dev-as3/./src/Main.as(10) : Unexpected debug
i think that this code can be parsed to
trace("debug");
trace("release");
getters and setters seem to be slightly wrong so instead of
get_x you get getX and set_x is instead setX
I expect this maybe a relatively simple fix, probably historical reason for the issue, but really a pain to manually fix in every class... this really suggests this library is completely out of date :(
casting string to xml in flash Xml(myString) should translate to FastXML.parse(myString)
Sometimes @:allow() ends up on the line after the override keyword but before other access modifiers like private, causing a syntax error.
An object literal (like this one) with a newline between the {
and the first key dies with Unexpected :
var pnt = {
x:10,
y:10
};
By contrast, this one works fine, indicating it's probably just a whitespace issue:
var pnt = { x:10,
y:10
};
In code that had the following:
public function get selectedLevel():int { return _selectedLevel; }
The following was generated:
public var selectedLevel(get, never) : Int;
and:
private function get_SelectedLevel() : Int{return _selectedLevel;
}
Other than the format being mangled, it does not compile due to the capitalized "SelectedLevel" 😄
Almost exactly the same setup as #46
neko run.n source/as3/ out/
Called from sys.io.FileOutput::$statics line 1
Called from Run::main line 102
Called from Run::loop line 33
Called from sys.FileSystem::readDirectory line 85
Uncaught exception - std@sys_read_dir
I tried to leave out the out/ I get:
Usage: as3tohx [options] sourceDir [outdir]
Options:
-no-cast-guess as3tohx will not try to handle MyClass(obj) casts
-no-func2dyn will not change Function types to Dynamic
-uint2int transforms all uint to Int
-vector2array will convert Vectors to haxe Arrays
-debug-expr will output debug information
-debug-inferred-type will output inferred type debug information
-convert-flexunit will convert FlexUnit metadata and calls to munit form
outdir defaults to './out'
Do you know any other solution that could help? When I use the haxelib released version (1.0.2) it works.
Input:
if (expression) something();
// A comment
Output:
if (expression) something() // A comment ;
as3 code:
for (var i = 0;; i++) {
if (i == 10)
break;
}
should translate to:
var i = 0;
while (true){
if (i == 10)
break;
i++;
}
now such as3 code is not converted
When dictionary is used code is full of Reflection this should be replaced with StringMap? and get set functions.
for inline struct data the opening brace { has to be on same line as first entry or the whole app crashes
When have [ in regular expression I get the error:
RegularExpressions.as(6) : Unexpected ]
Example code below:
package {
public class RegularExpressions {
private var _regEx:RegExp = /[\/]/g;
public function RegularExpressions() {
var regEx:RegExp = /[\/]/g;
}
}
}
as3 version:
for (var i:int=0; n:int = timelines.length; i<n;i++)
timelienes[i].apply(skeleton, lastTime, time, events, 1);
haxe version:
// n variable nowhere defined
for(i in 0...n)
timelienes[i].apply(skeleton, lastTime, time, events, 1);
does not convert packages to start with lowercase
Normal cast to int() or Number() from a Number or int are improperly converted to Std.parseInt or Std.parseFloat when they should be converted to Std.int() and nothing, respectively.
It appears that the letter after get_ and set_ is being capitalized:
public var rotation(get, never):Float;
private function get_Rotation():Float { };
But the compiler is looking for get_rotation
so it cannot find it.
/* often gets put on prior line, and if the prior line had a // that makes the block comment get commented out!
multiple // comments in a row often (always?) come out in inverted order
comments // and first line of /* are indented even if they weren't originally
comments // are often put on same line as end of prior scope end }
Code like this
private var _displayDataDictionary:Dictionary = new Dictionary();
and this
function parseSkeletonData(outputAnimationDictionary:Dictionary = null):DragonBonesData
prints
ERRORS: These files were not written due to source parsing errors:
In C:/HaxeToolkit/dragonbones-as3hx/as3/dragonBones/factories/BaseFactory.as(37): Unexpected =
In C:/HaxeToolkit/dragonbones-as3hx/as3/dragonBones/objects/DragonBonesData.as(13) :Unexpected =
and other similar errors with "=" and Dictionary
Is Dictionary parsing not supported? dictionaryToHash
param is true, but seems it's not working.
I'm not familiar with the origins of this project, but it's on HaxeFoundation github and there's no specific team for this repository. Who is supposed to maintain it, i.e. handle issues and pull requests?
switch statements still contain some breaks (esp after default)
if(a) where a is an object type should convert to if(a != null)
AS3 / mxmlc supports conditional compiler variables / expressions: http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7abd.html
(Issue #45 mentions these but only one specific use case.)
You can use booleans to conditionally include entire blocks of code:
CONFIG::FOO {
...
}
The doc says you can tag definitions at the package-level (without curly braces):
CONFIG::debugging
public class MyButton extends Button {
...
CONFIG::release
public class MyButton extends Button {
...
I know that you can also enclose those definitions in `{}.
You can also make conditional things like import statements and inline classes, though the latter could be rare:
CONFIG::AIR { // This import doesn't exist for non-AIR target
import flash.desktop.NativeApplication;
}
You can use constants, both booleans and Strings:
if (CONFIG::FOO) { ... }
var host:String = CONFIG::HOSTNAME;
trace("The host is: "+host);
The docs state you can pass expressions "a > b", though this one seems odd, I can't think of a good use case / reason you'd do that.
Syntax: Note that I've used the prefix CONFIG
-- but I believe any / multiple prefixes can be defined. Uppercase prefix is convention, but I'm not sure it's required. The key name case doesn't matter.
Some of the use cases translate easily, but others are more complicated:
PREFIX::KEY { ... }
could map to Haxe's conditional compilation #if PREFIX_KEY ... #end
, with perhaps a special case prefix/key mapping to #if debug
(programmable? default?)-D
definitions to static inline constants (string or boolean).Internal access specifier on root package gets translated to @:allow(), which in current version of Haxe does nothing. There is unfortunately no fix available to make this possible in the current version of Haxe. Discussions with Simn led to possibilities of using @:allow("") to mean the root namespace, but it is unclear if this is the direction that will be taken and when.
Tends to be that a > b ? c : d becomes a > (b != null) ? c : d
Problem that haxe variables are block-level scoped, but as3 ones are not.
From ActionScript3 documetation:
ActionScript variables, unlike variables in C++ and Java, do not have block-level scope. A block of code is any group of statements between an opening curly brace ( { ) and a closing curly brace ( } ). In some programming languages, such as C++ and Java, variables declared inside a block of code are not available outside that block of code. This restriction of scope is called block-level scope, and does not exist in ActionScript. If you declare a variable inside a block of code, that variable will be available not only in that block of code, but also in any other parts of the function to which the code block belongs. For example, the following function contains variables that are defined in various block scopes. All the variables are available throughout the function.
function blockTest (testArray:Array)
{
var numElements:int = testArray.length;
if (numElements > 0)
{
var elemStr:String = "Element #";
for (var i:int = 0; i < numElements; i++)
{
var valueStr:String = i + ": " + testArray[i];
trace(elemStr + valueStr);
}
trace(elemStr, valueStr, i); // all still defined
}
trace(elemStr, valueStr, i); // all defined if numElements > 0
}
blockTest(["Earth", "Moon", "Sun"]);
array.concat() with no parameters should be array.copy
While including function definitions is supported, as3hx does not seem to support including expressions (which mxmlc does support):
Test.as:
package {
public class Test {
public function Test():void {
include "some_expressions.as";
}
}
}
some_expressions.as:
trace("I am an included expression");
trace("Goodbye.");
Expected output .hx:
...
public function new():Void {
trace("I am an included expression");
trace("Goodbye.");
}
Actual output .hx:
...
public function new():Void {
include;"some_expressions.as";
}
We're having quite a few printer problems with this tool at the moment, which makes me wonder if it made sense to convert the parsed As3 AST to haxe.macro.Expr and then use (and improve) haxe.macro.Printer. I've taken this approach int ts2hx with some success.
A problem is that haxe.macro.Printer has no configuration for things like bracesOnNewline
, but that's not hard to add.
compound loop conditions (i<10 && stuff[i] != null) create bad code, where the anded condition is often missing entirely
I ran as3hx over an old as3 project of mine and 3 files cause uncaught exceptions.
Two from Phillipe Elsass' EazeTween library (http://code.google.com/p/eaze-tween/) and one from my project.
EazeTween.as
https://dl.dropboxusercontent.com/u/21016934/EazeTween.as
Called from ? line 1
Called from Run.hx line 80
Called from Run.hx line 68
Called from Run.hx line 68
Called from Run.hx line 46
Called from Run.hx line 46
Called from as3hx/Parser.hx line 123
Called from as3hx/Parser.hx line 138
Called from as3hx/Parser.hx line 644
Called from as3hx/Parser.hx line 506
Uncaught exception - Invalid field access : index
PropertyColorMatrix.as
https://dl.dropboxusercontent.com/u/21016934/PropertyColorMatrix.as
Called from ? line 1
Called from Run.hx line 80
Called from Run.hx line 68
Called from Run.hx line 68
Called from Run.hx line 68
Called from Run.hx line 46
Called from Run.hx line 46
Called from as3hx/Parser.hx line 123
Called from as3hx/Parser.hx line 138
Called from as3hx/Parser.hx line 644
Called from as3hx/Parser.hx line 506
Uncaught exception - Invalid field access : index
UserDataTemplate.as
https://dl.dropboxusercontent.com/u/21016934/UserDataTemplate.as
Called from ? line 1
Called from Run.hx line 80
Called from Run.hx line 68
Called from Run.hx line 68
Called from Run.hx line 68
Called from Run.hx line 62
Called from as3hx/Writer.hx line 3148
Called from as3hx/Writer.hx line 247
Called from as3hx/Writer.hx line 255
Called from as3hx/Writer.hx line 326
Called from as3hx/Writer.hx line 460
Called from as3hx/Writer.hx line 590
Called from as3hx/Writer.hx line 575
Uncaught exception - Invalid field access : index
'as' is translated to try { cast(a, B) } catch (e:Dynamic) null instead of Std.instance, which is a better choice in terms of runtime performance.
if i convert {name: "hello"}
exception at this 1058 line.
Uncaught exception - In /Users/user/Downloads/as3-XFL-compiler-master/src/nid/utils/zip/ZIPArchive.as(32) : Unexpected :
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.