模板
利用python的动态性,动态生成脚本代码
利用python的语法,支持一定的结构:for ,if ;方法调用等
package *.*;
import *.ProguardKeep;
import *.LogType;
import *.Track;
/**
* {% for comment in idl.cls_comments: %}
* {{comment.strip()}}
* {% end %}
* schema: {{ idl.file }}
* Created by AUTO_GEN_CODE on {{ idl.date }}.
*/
@Track(isRealTime = {{ 'true' if idl.is_real_time else 'false' }}, md_etype = LogType.{{idl.etype.title()}}, md_eid = "{{idl.eid}}", isCarryPathInfo = {{ 'true' if idl.is_with_path else 'false'}})
public class {{ idl.cls_name }} implements ProguardKeep {
{% for field in idl.fields: %}
public String {{ field.name }} = ""; // {{ field.comment }}
{% end %}
}
简单的模板引擎
import re
TEMPLATE_PATTERN = re.compile("{{(?P<var>.*?)}}|{%(?P<code>.*?)%}")
def parse_template(template):
start = 0
find_pattern = TEMPLATE_PATTERN.search(template, 0)
while find_pattern:
segment = template[start: find_pattern.start()]
var = find_pattern.group('var')
_code = find_pattern.group('code')
yield segment, var, _code
start = find_pattern.end()
find_pattern = TEMPLATE_PATTERN.search(template, start)
yield template[start:], None, None
class CodeBuilder:
INDENT = ' ' * 4
def __init__(self):
self.codes = []
self.cur_intent = 0
pass
def __repr__(self):
return '\n'.join(self.codes)
def add(self, string):
self.codes.append(self.cur_intent * CodeBuilder.INDENT + string)
return self
def indent(self):
self.cur_intent += 1
return self
def dedent(self):
self.cur_intent -= 1
return self
def compile_2_code(template):
builder = CodeBuilder()
builder.add('def gen_code(idl):')
builder.indent()
builder.add('render_result = []')
builder.add('__append = render_result.append')
for segment, var, _code in parse_template(template):
builder.add(f"__append('''{segment}''')")
if var:
builder.add(f'__append({var.strip()})')
if _code:
if _code.strip() == 'end':
builder.dedent()
else:
builder.add(f'{_code.strip()}')
builder.indent()
builder.add('java_code = "".join(render_result)')
builder.add('return java_code')
builder.dedent()
return repr(builder)
if __name__ == '__main__':
with open('track_code.schema', encoding='utf-8') as f:
print(compile_2_code(f.read()), file=open('gen_code.py', 'w'))
模板引擎生成的代码
def gen_code(idl):
render_result = []
__append = render_result.append
__append('''package com.meelive.ingkee.mechanism.track.codegen;
import com.meelive.ingkee.base.utils.ProguardKeep;
import com.meelive.inke.base.track.LogType;
import com.meelive.inke.base.track.Track;
/**
* ''')
for comment in idl.cls_comments:
__append('''
* ''')
__append(comment.strip())
__append('''
* ''')
__append('''
* schema: ''')
__append(idl.file)
__append('''
* Created by AUTO_GEN_CODE on ''')
__append(idl.date)
__append('''.
*/
@Track(isRealTime = ''')
__append('true' if idl.is_real_time else 'false')
__append(''', md_etype = LogType.''')
__append(idl.etype.title())
__append(''', md_eid = "''')
__append(idl.eid)
__append('''", isCarryPathInfo = ''')
__append('true' if idl.is_with_path else 'false')
__append(''')
public class ''')
__append(idl.cls_name)
__append(''' implements ProguardKeep {
''')
for field in idl.fields:
__append('''
public String ''')
__append(field.name)
__append(''' = ""; // ''')
__append(field.comment)
__append('''
''')
__append('''
}
''')
java_code = "".join(render_result)
return java_code
网友评论