builtins_generator.py [plain text]
import logging
import os.path
import re
from string import Template
import json
from builtins_model import BuiltinFunction, BuiltinObject
from builtins_templates import BuiltinsGeneratorTemplates as Templates
log = logging.getLogger('global')
def WK_lcfirst(str):
str = str[:1].lower() + str[1:]
str = str.replace('hTML', 'html')
str = str.replace('uRL', 'url')
str = str.replace('jS', 'js')
str = str.replace('xML', 'xml')
str = str.replace('xSLT', 'xslt')
str = str.replace('cSS', 'css')
str = str.replace('rTC', 'rtc')
return str
def WK_ucfirst(str):
str = str[:1].upper() + str[1:]
str = str.replace('Xml', 'XML')
str = str.replace('Svg', 'SVG')
return str
class BuiltinsGenerator:
def __init__(self, model):
self._model = model
def model(self):
return self._model
def generate_output(self):
pass
def output_filename(self):
pass
def generate_license(self):
raw_license = Template(Templates.LicenseText).substitute(None)
copyrights = self._model.copyrights()
copyrights.sort()
license_block = []
license_block.append("/*")
for copyright in copyrights:
license_block.append(" * Copyright (c) %s" % copyright)
if len(copyrights) > 0:
license_block.append(" * ")
for line in raw_license.split('\n'):
license_block.append(" * " + line)
license_block.append(" */")
return '\n'.join(license_block)
def generate_includes_from_entries(self, entries):
includes = set()
for entry in entries:
(allowed_framework_names, data) = entry
(framework_name, header_path) = data
if self.model().framework.name not in allowed_framework_names:
continue
if self.model().framework.name != framework_name:
includes.add("#include <%s>" % header_path)
else:
includes.add("#include \"%s\"" % os.path.basename(header_path))
return sorted(list(includes))
def generate_primary_header_includes(self):
name, _ = os.path.splitext(self.output_filename())
return '\n'.join([
"#include \"config.h\"",
"#include \"%s.h\"" % name,
])
def generate_embedded_code_string_section_for_function(self, function):
text = function.function_source
text = "(function " + text[text.index("("):] + ")"
embeddedSourceLength = len(text) + 1 textLines = json.dumps(text)[1:-1].split("\\n")
embeddedSource = '\n'.join([' "%s\\n" \\' % line for line in textLines])
constructAbility = "CannotConstruct"
if function.is_constructor:
constructAbility = "CanConstruct"
args = {
'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code',
'embeddedSource': embeddedSource,
'embeddedSourceLength': embeddedSourceLength,
'canConstruct': constructAbility,
'intrinsic': function.intrinsic
}
lines = []
lines.append("const JSC::ConstructAbility s_%(codeName)sConstructAbility = JSC::ConstructAbility::%(canConstruct)s;" % args);
lines.append("const int s_%(codeName)sLength = %(embeddedSourceLength)d;" % args);
lines.append("static const JSC::Intrinsic s_%(codeName)sIntrinsic = JSC::%(intrinsic)s;" % args);
lines.append("const char* s_%(codeName)s =\n%(embeddedSource)s\n;" % args);
return '\n'.join(lines)
@staticmethod
def wrap_with_guard(guard, text):
if not guard:
return text
return '\n'.join([
'#if %s' % guard,
text,
'#endif // %s' % guard,
])
@staticmethod
def mangledNameForObject(object):
if not isinstance(object, BuiltinObject):
raise Exception("Invalid argument passed to mangledNameForObject()")
def toCamel(match):
str = match.group(0)
return str[1].upper()
return re.sub(r'\.[a-z]', toCamel, object.object_name, flags=re.IGNORECASE)
@staticmethod
def mangledNameForFunction(function):
if not isinstance(function, BuiltinFunction):
raise Exception("Invalid argument passed to mangledNameForFunction()")
function_name = WK_ucfirst(function.function_name)
def toCamel(match):
str = match.group(0)
return str[1].upper()
function_name = re.sub(r'\.[a-z]', toCamel, function_name, flags=re.IGNORECASE)
if function.is_constructor:
function_name = function_name + "Constructor"
object_name = BuiltinsGenerator.mangledNameForObject(function.object)
return WK_lcfirst(object_name + function_name)