Skip to content

Instantly share code, notes, and snippets.

@neuronix
Last active November 30, 2015 21:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neuronix/8693c7d7ed6ec49caf6b to your computer and use it in GitHub Desktop.
Save neuronix/8693c7d7ed6ec49caf6b to your computer and use it in GitHub Desktop.
AS3 pre-build script for debugging anonymous functions in release builds
# Author: @cameron_vdb
#
# Renames anonymous functions in AS3 files with following pattern: _anonymous_myPackage_MyClass_l<line number> (...)
# Allows easy debugging of anonymous functions in release builds at runtime.
# You should run the script in name mode before the build and run it in unname mode after the build to remove function names from your code.
# The script currently only runs on your current project files and does not process referenced projects.
#
# Usage: python names.py <name|unname> <ProjectRootFolder> [<buildType>]
# name to add function names, unname to remove them.
# buildType is optional, if defined, script will only run if buildType == "release"
#
# Setting up script for building projects in FlashDevelop:
# 1. Place names.py at the root of your Project
# 2. Project settings > Build
# 3. Pre-build line: cmd.exe /c "python $(ProjectDir)\names.py name $(ProjectDir) $(BuildConfig)"
# 4. Post-build line: cmd.exe /c "python $(ProjectDir)\names.py unname $(ProjectDir) $(BuildConfig)"
import re
import sys
import os
regPackage = re.compile("package\s+([\w\.]*)[\s\{]")
regClass = re.compile("\s+class\s+(\w+)[\s\{]")
regFunction = re.compile("function\s*(\_anonymous\_.*\_l\d+)?\s*\(")
regCamel = re.compile("\.\w+")
def camelCase(str):
def camel(m):
s = m.group(0)[1:]
return s[0].upper() + s[1:]
return regCamel.sub(camel, str)
def filesRecursive(folder, filter=None):
files = []
for (dirPath, dirNames, fileNames) in os.walk(folder):
relPath = (dirPath + os.path.sep).replace(folder + os.path.sep, "")
if filter:
for f in fileNames:
if re.match(filter, f):
files.append(relPath + f)
else:
files.extend(map(lambda x:relPath + x, fileNames))
return files
def nameAnonymous(filename):
f = open(filename, "r+")
file = f.read()
match = regPackage.search(file)
if not match:
print("No package")
exit(1)
package = match.group(1)
match = regClass.search(file)
if not match:
print("No class name")
exit(1)
classname = match.group(1)
location = classname if not len(package) else package + "_" + classname
location = camelCase(location)
out = ""
index = 1
f.seek(0)
for line in f.readlines():
out += regFunction.sub("function _anonymous_%s_l%s(" % (location, index), line)
index += 1
f.seek(0)
f.truncate()
f.write(out)
f.close()
def unnameAnonymous(filename):
f = open(filename, "r+")
out = ""
for line in f.readlines():
out += regFunction.sub("function (", line)
f.seek(0)
f.truncate()
f.write(out)
f.close()
# MAIN
override = False
isRelease = len(sys.argv) == 4 and sys.argv[3] == "release"
isComplete = len(sys.argv) == 3 or isRelease
projectDir = ""
if isComplete:
method = sys.argv[1]
projectDir = sys.argv[2]
# debug
# method = "unname"
# override = True
# projectDir = 'D:\FDWorkspace\Quizz'
if override or (isComplete and (method == "name" or method == "unname")):
print("Begin", method, projectDir)
projectDir += '\src'
files = filesRecursive(projectDir, "(.*)\.as$")
processing = nameAnonymous if method == "name" else unnameAnonymous
for f in files:
processing(projectDir + "\\" + f)
print("Complete (%d files)" % len(files))
exit(0)
else:
if isRelease:
print("Bad arguments", sys.argv)
exit(1)
else:
print("Ignoring debug build")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment