Latest Changes
Differences between version EMPTY and #14358
0a1,445
> <code haxe>
> /*
> * Copyright (c) 2011, TouchMyPixel & contributors
> * Original author : Tarwin Stroh-Spijer <tarwin@touchmypixel.com>
> * Contributers: Tony Polinelli <tonyp@touchmypixel.com>
> * 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.
> *
> * THIS SOFTWARE IS PROVIDED BY THE TOUCH MY PIXEL & CONTRIBUTERS "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 TOUCH MY PIXEL & 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;
>
> import neko.FileSystem;
> import neko.Lib;
> import neko.Sys;
>
> using StringTools;
> using As3ToHaxe;
>
> /**
> * Simple Program which iterates -from folder, finds .mtt templates and compiles them to the -to folder
> */
> class As3ToHaxe
> {
> public static inline var keys = ["-from", "-to", "-remove"];
>
> var to:String;
> var from:String;
> var remove:String;
> var sysargs:Array<String>;
>
> var items:Array<String>;
>
> public static var basePackage:String = "away3d";
>
> private var nameSpaces:Hash<Ns>;
> private var maxLoop:Int;
>
> static function main()
> {
> new As3ToHaxe();
> }
>
> public function new()
> {
> maxLoop = 1000;
>
> if (parseArgs())
> {
>
> // make sure that the to directory exists
> if (!FileSystem.exists(to)) FileSystem.createDirectory(to);
>
> // delete old files
> if (remove == "true")
> removeDirectory(to);
>
> items = [];
> // fill items
> recurse(from);
>
> // to remember namespaces
> nameSpaces = new Hash();
>
> for (item in items)
> {
> // make sure we only work wtih AS fiels
> var ext = getExt(item);
> switch(ext)
> {
> case "as":
> doConversion(item);
> }
> }
>
> // build namespace files
> buildNameSpaces();
> }
> }
>
> private function doConversion(file:String):Void
> {
> var fromFile = file;
> var toFile = to + "/" + file.substr(from.length + 1, file.lastIndexOf(".") - (from.length)) + "hx";
>
> var rF = "";
> var rC = "";
>
> var b = 0;
>
> // create the folder if it doesn''t exist
> var dir = toFile.substr(0, toFile.lastIndexOf("/"));
> createFolder(dir);
>
> var s = neko.io.File.getContent(fromFile);
>
> // spacse to tabs
> s = quickRegR(s, " ", "\t");
> // undent
> s = quickRegR(s, "\t\t", "\t");
>
> // some quick setup, finding what we''ve got
> var className = quickRegM(s, "public class([ ]*)([A-Z][a-zA-Z0-9_]*)", 2)[1];
> var hasVectors = (quickRegM(s, "Vector([ ]*)\\.([ ]*)<([ ]*)([^>]*)([ ]*)>").length != 0);
>
> // package
> s = quickRegR(s, "package ([a-zA-Z\\.0-9-_]*)([ \n\r]*){", "package $1;\n", "gs");
> // remove last
> s = quickRegR(s, "\\}([\n\r\t ]*)\\}([\n\r\t ]*)$", "}", "gs");
>
> // extra indentation
> s = quickRegR(s, "\n\t", "\n");
>
> // class
> s = quickRegR(s, "public class", "class");
>
> // constructor
> s = quickRegR(s, "function " + className, "function new");
>
> // simple typing
> s = quickRegR(s, ":([ ]*)void", ":$1Void");
> s = quickRegR(s, ":([ ]*)Boolean", ":$1Bool");
> s = quickRegR(s, ":([ ]*)int", ":$1Int");
> s = quickRegR(s, ":([ ]*)uint", ":$1UInt");
> s = quickRegR(s, ":([ ]*)Number", ":$1Float");
> s = quickRegR(s, ":([ ]*)\\*", ":$1Dynamic");
>
> s = quickRegR(s, "<Number>", "<Float>");
> s = quickRegR(s, "<int>", "<Int>");
> s = quickRegR(s, "<uint>", "<UInt>");
> s = quickRegR(s, "<Boolean>", "<Bool>");
>
> // vector
> // definition
> s = quickRegR(s, "Vector([ ]*)\\.([ ]*)<([ ]*)([^>]*)([ ]*)>", "Vector<$3$4$5>");
> // new (including removing stupid spaces)
> s = quickRegR(s, "new Vector([ ]*)([ ]*)<([ ]*)([^>]*)([ ]*)>([ ]*)\\(([ ]*)\\)([ ]*)", "new Vector()");
> // and import if we have to
> if (hasVectors) {
> s = quickRegR(s, "class([ ]*)(" + className + ")", "import flash.Vector;\n\nclass$1$2");
> }
>
> // array
> s = quickRegR(s, " Array([ ]*);", " Array<Dynamic>;");
>
> // remap protected -> private & internal -> private
> s = quickRegR(s, "protected var", "private var");
> s = quickRegR(s, "internal var", "private var");
> s = quickRegR(s, "protected function", "private function");
> s = quickRegR(s, "internal function", "private function");
>
> /* -----------------------------------------------------------*/
> // namespaces
> // find which namespaces are used in this class
> var r = new EReg("([^#])use([ ]+)namespace([ ]+)([a-zA-Z-]+)([ ]*);", "g");
> b = 0;
> while (true) {
> b++; if (b > maxLoop) { logLoopError("namespaces find", file); break; }
> if (r.match(s)) {
> var ns:Ns = {
> name : r.matched(4),
> classDefs : new Hash()
> };
> nameSpaces.set(ns.name, ns);
> s = r.replace(s, "//" + r.matched(0).replace("use", "#use") + "\nusing " + basePackage + ".namespace." + ns.name.fUpper() + ";");
> }else {
> break;
> }
> }
>
> // collect all namespace definitions
> // replace them with private
> for (k in nameSpaces.keys()) {
> var n = nameSpaces.get(k);
> b = 0;
> while (true) {
> b++; if (b > maxLoop) { logLoopError("namespaces collect/replace var", file); break; }
> // vars
> var r = new EReg(n.name + "([ ]+)var([ ]+)", "g");
> s = r.replace(s, "private$1var$2");
> if (!r.match(s)) break;
> }
> b = 0;
> while (true) {
> b++; if (b > maxLoop) { logLoopError("namespaces collect/replace func", file); break; }
> // funcs
> var matched:Bool = false;
> var r = new EReg(n.name + "([ ]+)function([ ]+)", "g");
> if (r.match(s)) matched = true;
> s = r.replace(s, "private$1function$2");
> r = new EReg(n.name + "([ ]+)function([ ]+)get([ ]+)", "g");
> if (r.match(s)) matched = true;
> s = r.replace(s, "private$1function$2get$3");
> r = new EReg(n.name + "([ ]+)function([ ]+)set([ ]+)", "g");
> if (r.match(s)) matched = true;
> s = r.replace(s, "private$1function$2$3set");
> if (!matched) break;
> }
> }
>
> /* -----------------------------------------------------------*/
> // change const to inline statics
> s = quickRegR(s, "([\n\t ]+)(public|private)([ ]*)const([ ]+)([a-zA-Z0-9_]+)([ ]*):", "$1$2$3static inline var$4$5$6:");
> s = quickRegR(s, "([\n\t ]+)(public|private)([ ]*)(static)*([ ]+)const([ ]+)([a-zA-Z0-9_]+)([ ]*):", "$1$2$3$4$5inline var$6$7$8:");
>
> /* -----------------------------------------------------------*/
> // move variables being set from var def to top of constructor
> // do NOT do this for const
> // if they're static, leave them there
> // TODO!
>
> /* -----------------------------------------------------------*/
> // Error > flash.Error
> // if " Error (" then add "import flash.Error" to head
> var r = new EReg("([ ]+)new([ ]+)Error([ ]*)\\(", "");
> if (r.match(s))
> s = quickRegR(s, "class([ ]*)(" + className + ")", "import flash.Error;\n\nclass$1$2");
>
> /* -----------------------------------------------------------*/
>
> // create getters and setters
> b = 0;
> while (true) {
> b++;
> var d = { get: null, set: null, type: null, ppg: null, pps: null, name: null };
>
> // get
> var r = new EReg("([\n\t ]+)([a-z]+)([ ]*)function([ ]*)get([ ]+)([a-zA-Z_][a-zA-Z0-9_]+)([ ]*)\\(([ ]*)\\)([ ]*):([ ]*)([A-Z][a-zA-Z0-9_]*)", "");
> var m = r.match(s);
> if (m) {
> d.ppg = r.matched(2);
> if (d.ppg == "") d.ppg = "public";
> d.name = r.matched(6);
> d.get = "get" + d.name.substr(0, 1).toUpperCase() + d.name.substr(1);
> d.type = r.matched(11);
> }
>
> // set
> var r = new EReg("([\n\t ]+)([a-z]+)([ ]*)function([ ]*)set([ ]+)([a-zA-Z_][a-zA-Z0-9_]*)([ ]*)\\(([ ]*)([a-zA-Z][a-zA-Z0-9_]*)([ ]*):([ ]*)([a-zA-Z][a-zA-Z0-9_]*)", "");
> var m = r.match(s);
> if (m) {
> if (r.matched(6) == d.get || d.get == null)
> if (d.name == null) d.name = r.matched(6);
> d.pps = r.matched(2);
> if (d.pps == "") d.pps = "public";
> d.set = "set" + d.name.substr(0, 1).toUpperCase() + d.name.substr(1);
> if (d.type == null) d.type = r.matched(12);
> }
>
> // ERROR
> if (b > maxLoop) { logLoopError("getter/setter: " + d, file); break; }
>
> // replace get
> if (d.get != null)
> s = quickRegR(s, d.ppg + "([ ]+)function([ ]+)get([ ]+)" + d.name, "private function " + d.get);
>
> // replace set
> if (d.set != null)
> s = quickRegR(s, d.pps + "([ ]+)function([ ]+)set([ ]+)" + d.name, "private function " + d.set);
>
> // make haxe getter/setter OR finish
> if (d.get != null || d.set != null) {
> var gs = (d.ppg != null ? d.ppg : d.pps) + " var " + d.name + "(" + d.get + ", " + d.set + "):" + d.type + ";";
> s = quickRegR(s, "private function " + (d.get != null ? d.get : d.set), gs + "\n \tprivate function " + (d.get != null ? d.get : d.set));
> }else {
> break;
> }
> }
>
> /* -----------------------------------------------------------*/
>
> // for loops (?)
> // TODO!
> //s = quickRegR(s, "for([ ]*)\\(([ ]*)var([ ]*)([A-Z][a-zA-Z0-9_]*)([.^;]*);([.^;]*);([.^\\)]*)\\)", "");
> //var t = quickRegM(s, "for([ ]*)\\(([ ]*)var([ ]*)([a-zA-Z][a-zA-Z0-9_]*)([.^;]*)", 5);
> //trace(t);
> //for (var i : Int = 0; i < len; ++i)
>
> /* -----------------------------------------------------------*/
>
> var o = neko.io.File.write(toFile, true);
> o.writeString(s);
> o.close();
>
> // use for testing on a single file
> //Sys.exit(1);
> }
>
> private function logLoopError(type:String, file:String)
> {
> trace("ERROR: " + type + " - " + file);
> }
>
> private function buildNameSpaces()
> {
> // build friend namespaces!
> trace(nameSpaces);
> }
>
> public static function quickRegR(str:String, reg:String, rep:String, ?regOpt:String = "g"):String
> {
> return new EReg(reg, regOpt).replace(str, rep);
> }
>
> public static function quickRegM(str:String, reg:String, ?numMatches:Int = 1, ?regOpt:String = "g"):Array<String>
> {
> var r = new EReg(reg, regOpt);
> var m = r.match(str);
> if (m) {
> var a = [];
> var i = 1;
> while (i <= numMatches) {
> a.push(r.matched(i));
> i++;
> }
> return a;
> }
> return [];
> }
>
> private function createFolder(path:String):Void
> {
> var parts = path.split("/");
> var folder = "";
> for (part in parts)
> {
> if (folder == "") folder += part;
> else folder += "/" + part;
> if (!FileSystem.exists(folder)) FileSystem.createDirectory(folder);
> }
> }
>
> private function parseArgs():Bool
> {
> // Parse args
> var args = Sys.args();
> for (i in 0...args.length)
> if (Lambda.has(keys, args[i]))
> Reflect.setField(this, args[i].substr(1), args[i + 1]);
>
> // Check to see if argument is missing
> if (to == null) { Lib.println("Missing argument '-to'"); return false; }
> if (from == null) { Lib.println("Missing argument '-from'"); return false; }
>
> return true;
> }
>
> public function recurse(path:String)
> {
> var dir = FileSystem.readDirectory(path);
>
> for (item in dir)
> {
> var s = path + "/" + item;
> if (FileSystem.isDirectory(s))
> {
> recurse(s);
> }
> else
> {
> var exts = ["as"];
> if(Lambda.has(exts, getExt(item)))
> items.push(s);
> }
> }
> }
>
> public function getExt(s:String)
> {
> return s.substr(s.lastIndexOf(".") + 1).toLowerCase();
> }
>
> public function removeDirectory(d, p = null)
> {
> if (p == null) p = d;
> var dir = FileSystem.readDirectory(d);
>
> for (item in dir)
> {
> item = p + "/" + item;
> if (FileSystem.isDirectory(item)) {
> removeDirectory(item);
> }else{
> FileSystem.deleteFile(item);
> }
> }
>
> FileSystem.deleteDirectory(d);
> }
>
> public static function fUpper(s:String)
> {
> return s.charAt(0).toUpperCase() + s.substr(1);
> }
> }
>
> typedef Ns = {
> var name:String;
> var classDefs:Hash<String>;
> }
> </code>
>
> ==== It can be compiled with the following compile.hxml ====
>
> <code>
> -main As3ToHaxe
> -neko bin\As3ToHaxe.n
> </code>
>
> It's still work in progress so developer notes:
> * changes any 4x spaces to tabs (needed for later cleanup)
> * fixes package, opening and closing braces as well
> * fixes classes to be haxe-like
> * replaces all the void, Boolean, Number, including
> * fixes Vectors and adds imports
> * fixes arrays, adding <Dynamic> (don't think there's an easy way to actually define these properly
> * fixes protected and internet defs
> * makes all namespaces private and adds a "using" for a friend class
> * fixes "const" and creates static inline vars
> * fixes Error class (simply imports flash.Error if it's used)
> * creates proper haxe getter/setters
>
> * TODO: create "friend" class from namespaces info collected information
> * TODO: move initial var setting from var definition to constructor (not for static inline of course)
> * TODO: loops.
>
> //If you have improvements please send them to the Haxe list for verification or post them on the Haxe forum.//
\ No newline at end of file
| Ver | Date | Entry | Lg | User | Action |
|---|---|---|---|---|---|
| #19364 | 2013-05-19 18:01:37 | manual/haxe3 | en | orwellophile | View | Diff |
| #19363 | 2013-05-19 17:58:20 | manual/haxe3 | en | orwellophile | View | Diff |
| #19362 | 2013-05-19 16:16:17 | api/haxe/timer | en | vegetablesalad | View | Diff |
| #19361 | 2013-05-19 16:14:40 | api/haxe/timer | en | vegetablesalad | View | Diff |
| #19360 | 2013-05-13 17:42:34 | doc/libraries | en | Confidant | View | Diff |
| #19359 | 2013-05-13 05:01:15 | manual/macros/advanced | en | jason | View | Diff |
| #19358 | 2013-05-12 02:55:03 | com/ide | en | MarcWeber | View | Diff |
| #19357 | 2013-05-11 05:26:13 | ref/conditionals | jp | shohei909 | View | Diff |
| #19356 | 2013-05-10 09:29:15 | manual/completion | en | jason | View | Diff |
| #19355 | 2013-05-09 00:24:39 | download/manual_install/leopard | en | JLM | View | Diff |
| #19354 | 2013-05-09 00:10:46 | download/manual_install/leopard/justinsbuildnotes | en | JLM | View | Diff |
| #19353 | 2013-05-08 18:42:04 | com/news | en | ncannasse | View | Diff |
| #19352 | 2013-05-08 18:12:08 | manual/haxe3 | en | ncannasse | View | Diff |
| #19351 | 2013-05-08 18:09:11 | manual/haxe3 | en | Simn | View | Diff |
| #19350 | 2013-05-08 18:04:19 | manual/haxe3 | en | ncannasse | View | Diff |
| #19349 | 2013-05-08 15:57:29 | doc/haxelib/haxelib2 | en | jason | View | Diff |
| #19348 | 2013-05-08 15:57:29 | doc/haxelib/haxelib2 | en | jason | Changed title from Haxelib 2 to Haxelib 3 |
| #19347 | 2013-05-08 15:21:08 | manual/haxe3/features | jp | shohei909 | View | Diff |
| #19346 | 2013-05-08 15:15:14 | manual/haxe3/features | en | shohei909 | View | Diff |
| #19345 | 2013-05-08 11:51:53 | doc/haxelib/haxelib2 | en | back2dos | View | Diff |
Previous | Next