#
# Jasy - Web Tooling Framework
# Copyright 2010-2012 Zynga Inc.
# Copyright 2013-2014 Sebastian Werner
#
import jasy.script.parse.Parser as Parser
import jasy.core.Console as Console
from jasy.script.util import *
def __translateToJS(code):
"""Returns the code equivalent of the stored value for the given key."""
if code is None:
pass
elif code is True:
code = "true"
elif code is False:
code = "false"
elif isinstance(code, str) and code.startswith("{") and code.endswith("}"):
pass
elif isinstance(code, str) and code.startswith("[") and code.endswith("]"):
pass
else:
code = "\"%s\"" % code
return code
[docs]def patch(node, permutation):
"""Replaces all occourences with incoming values."""
modified = False
if node.type == "dot" and node.parent.type == "call":
assembled = assembleDot(node)
# jasy.Env.getValue(key)
if assembled == "jasy.Env.getValue" and node.parent.type == "call":
callNode = node.parent
params = callNode[1]
name = params[0].value
Console.debug("Found jasy.Env.getValue(%s) in line %s", name, node.line)
replacement = __translateToJS(permutation.get(name))
if replacement:
replacementNode = Parser.parseExpression(replacement)
callNode.parent.replace(callNode, replacementNode)
modified = True
Console.debug("Replaced with %s", replacement)
# jasy.Env.isSet(key, expected)
# also supports boolean like: jasy.Env.isSet(key)
elif assembled == "jasy.Env.isSet" and node.parent.type == "call":
callNode = node.parent
params = callNode[1]
name = params[0].value
Console.debug("Found jasy.Env.isSet(%s) in line %s", name, node.line)
replacement = __translateToJS(permutation.get(name))
if replacement is not None:
# Auto-fill second parameter with boolean "true"
expected = params[1] if len(params) > 1 else Parser.parseExpression("true")
if expected.type in ("string", "number", "true", "false"):
parsedReplacement = Parser.parseExpression(replacement)
expectedValue = getattr(expected, "value", None)
if expectedValue is not None:
if getattr(parsedReplacement, "value", None) is not None:
replacementResult = parsedReplacement.value in str(expected.value).split("|")
else:
replacementResult = parsedReplacement.type in str(expected.value).split("|")
else:
replacementResult = parsedReplacement.type == expected.type
# Do actual replacement
replacementNode = Parser.parseExpression("true" if replacementResult else "false")
callNode.parent.replace(callNode, replacementNode)
modified = True
Console.debug("Replaced with %s", "true" if replacementResult else "false")
# jasy.Env.select(key, map)
elif assembled == "jasy.Env.select" and node.parent.type == "call":
Console.debug("Found jasy.Env.select() in line %s", node.line)
callNode = node.parent
params = callNode[1]
replacement = __translateToJS(permutation.get(params[0].value))
if replacement:
parsedReplacement = Parser.parseExpression(replacement)
if parsedReplacement.type != "string":
raise Exception("jasy.Env.select requires that the given replacement is of type string.")
# Directly try to find matching identifier in second param (map)
objectInit = params[1]
if objectInit.type == "object_init":
fallbackNode = None
for propertyInit in objectInit:
if propertyInit[0].value == "default":
fallbackNode = propertyInit[1]
elif parsedReplacement.value in str(propertyInit[0].value).split("|"):
callNode.parent.replace(callNode, propertyInit[1])
modified = True
break
if not modified and fallbackNode is not None:
callNode.parent.replace(callNode, fallbackNode)
modified = True
Console.debug("Updated with %s", replacement)
# Process children
for child in reversed(node):
if child is not None:
if patch(child, permutation):
modified = True
return modified