编译变量访问和变量替换的代码
用于普通文本或if、var、filter等命令生成编译代码

@inner
@param {string} source 源代码
@param {Engine} engine 引擎实例
@param {boolean} forText 是否为输出文本的变量替换
@return {string} 编译代码
359775
function compileVariable(source, engine, forText) {
        var code = [];
        var options = engine.options;

        var toStringHead = '';
        var toStringFoot = '';
        var wrapHead = '';
        var wrapFoot = '';

        // 默认的filter，当forText模式时有效
        var defaultFilter;

        if (forText) {
            toStringHead = 'ts(';
            toStringFoot = ')';
            wrapHead = RENDER_STRING_ADD_START;
            wrapFoot = RENDER_STRING_ADD_END;
            defaultFilter = options.defaultFilter;
        }

        parseTextBlock(
            source, options.variableOpen, options.variableClose, 1,

            function (text) {
                // 加入默认filter
                // 只有当处理forText时，需要加入默认filter
                // 处理if/var/use等command时，不需要加入默认filter
                if (forText && text.indexOf('|') < 0 && defaultFilter) {
                    text += '|' + defaultFilter;
                }

                // variableCode是一个gv调用，然后通过循环，在外面包filter的调用
                // 形成filter["b"](filter["a"](gv(...)))
                //
                // 当forText模式，处理的是文本中的变量替换时
                // 传递给filter的需要是字符串形式，所以gv外需要包一层ts调用
                // 形成filter["b"](filter["a"](ts(gv(...))))
                //
                // 当variableName以*起始时，忽略ts调用，直接传递原值给filter
                var filterCharIndex = text.indexOf('|');
                var variableName = (
                        filterCharIndex > 0
                        ? text.slice(0, filterCharIndex)
                        : text
                    ).replace(/^\s+/, '').replace(/\s+$/, '');
                var filterSource = filterCharIndex > 0
                    ? text.slice(filterCharIndex + 1)
                    : '';

                var variableRawValue = variableName.indexOf('*') === 0;
                var variableCode = [
                    variableRawValue ? '' : toStringHead,
                    toGetVariableLiteral(variableName),
                    variableRawValue ? '' : toStringFoot
                ];

                if (filterSource) {
                    filterSource = compileVariable(filterSource, engine);
                    var filterSegs = filterSource.split('|');
                    for (var i = 0, len = filterSegs.length; i < len; i++) {
                        var seg = filterSegs[i];
                        var segMatch = seg.match(/^\s*([a-z0-9_-]+)(\((.*)\))?\s*$/i);
                        if (segMatch) {
                            variableCode.unshift('fs["' + segMatch[1] + '"](');

                            if (segMatch[3]) {
                                variableCode.push(',', segMatch[3]);
                            }

                            variableCode.push(')');
                        }
                    }
                }

                code.push(
                    wrapHead,
                    variableCode.join(''),
                    wrapFoot
                );
            },

            function (text) {
                code.push(
                    wrapHead,
                    forText ? stringLiteralize(text) : text,
                    wrapFoot
                );
            }
        );

        return code.join('');
    }
543991
public String exportRule(Rule rule, Engine engine) {
        List<Proposition> propositions = new ArrayList<Proposition>();
        List<Operator> operators = new ArrayList<Operator>();
        Deque<Expression> queue = new ArrayDeque<Expression>();

        queue.offer(rule.getAntecedent().getExpression());
        while (!queue.isEmpty()) {
            Expression front = queue.poll();
            if (front instanceof Operator) {
                Operator op = (Operator) front;
                queue.offer(op.getLeft());
                queue.offer(op.getRight());
                operators.add(op);
            } else if (front instanceof Proposition) {
                propositions.add((Proposition) front);
            } else {
                throw new RuntimeException(String.format(
                        "[export error] unexpected class <%s>", front.getClass().getName()));
            }
        }
        boolean equalOperators = true;
        for (int i = 0; i < operators.size() - 1; ++i) {
            if (!operators.get(i).getName().equals(operators.get(i + 1).getName())) {
                equalOperators = false;
                break;
            }
        }
        if (!equalOperators) {
            throw new RuntimeException("[export error] "
                    + "fis files do not support rules with different connectors "
                    + "(i.e. ['and', 'or']). All connectors within a rule must be the same");
        }
        List<Variable> inputVariables = new ArrayList<Variable>();
        List<Variable> outputVariables = new ArrayList<Variable>();
        for (InputVariable inputVariable : engine.getInputVariables()) {
            inputVariables.add(inputVariable);
        }
        for (OutputVariable outputVariable : engine.getOutputVariables()) {
            outputVariables.add(outputVariable);
        }

        StringBuilder result = new StringBuilder();
        result.append(translate(propositions, inputVariables)).append(", ");
        result.append(translate(rule.getConsequent().getConclusions(), outputVariables));
        result.append(String.format("(%s)", Op.str(rule.getWeight())));
        String connector;
        if (operators.isEmpty()) {
            connector = "1";
        } else if (Rule.FL_AND.equals(operators.get(0).getName())) {
            connector = "1";
        } else if (Rule.FL_OR.equals(operators.get(0).getName())) {
            connector = "2";
        } else {
            connector = operators.get(0).getName();
        }
        result.append(" : ").append(connector);
        return result.toString();
    }
1231804
function getSource(fn) {
      var result = '';
      if (isStringable(fn)) {
        result = String(fn);
      } else if (support.decompilation) {
        // Escape the `{` for Firefox 1.
        result = _.result(/^[^{]+\{([\s\S]*)\}\s*$/.exec(fn), 1);
      }
      // Trim string.
      result = (result || '').replace(/^\s+|\s+$/g, '');

      // Detect strings containing only the "use strict" directive.
      return /^(?:\/\*+[\w\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result)
        ? ''
        : result;
    }
686596
function () {
            var value = this.value;
            var options = this.engine.options;

            if (!value
                || (options.strip && /^\s*$/.test(value))
            ) {
                return '';
            }

            return compileVariable(value, this.engine, 1);
        }
505350
def render_source(self, source, variables=None):
        
        if variables is None:
            variables = {}
        template = self._engine.from_string(source)
        return template.render(**variables)
1072610
def bootstrap_c_source(scheduler_bindings_path, output_dir, module_name=NATIVE_ENGINE_MODULE):
  """"""

  safe_mkdir(output_dir)

  with temporary_dir() as tempdir:
    temp_output_prefix = os.path.join(tempdir, module_name)
    real_output_prefix = os.path.join(output_dir, module_name)
    temp_c_file = '{}.c'.format(temp_output_prefix)
    if PY2:
      temp_c_file = temp_c_file.encode('utf-8')
    c_file = '{}.c'.format(real_output_prefix)
    env_script = '{}.cflags'.format(real_output_prefix)

    # Preprocessor directives won't parse in the .cdef calls, so we have to hide them for now.
    scheduler_bindings_content = read_file(scheduler_bindings_path)
    scheduler_bindings = _hackily_rewrite_scheduler_bindings(scheduler_bindings_content)

    ffibuilder = cffi.FFI()
    ffibuilder.cdef(scheduler_bindings)
    ffibuilder.cdef(_FFISpecification.format_cffi_externs())
    ffibuilder.set_source(module_name, scheduler_bindings)
    ffibuilder.emit_c_code(temp_c_file)

    # Work around https://github.com/rust-lang/rust/issues/36342 by renaming initnative_engine to
    # wrapped_initnative_engine so that the rust code can define the symbol initnative_engine.
    #
    # If we dont do this, we end up at the mercy of the implementation details of rust's stripping
    # and LTO. In the past we have found ways to trick it into not stripping symbols which was handy
    # (it kept the binary working) but inconvenient (it was relying on unspecified behavior, it meant
    # our binaries couldn't be stripped which inflated them by 2~3x, and it reduced the amount of LTO
    # we could use, which led to unmeasured performance hits).
    #
    # We additionally remove the ifdefs that apply conditional `init` logic for Py2 vs Py3, in order
    # to define a module that is loadable by either 2 or 3.
    # TODO: Because PyPy uses the same `init` function name regardless of the python version, this
    # trick does not work there: we leave its conditional in place.
    file_content = read_file(temp_c_file)
    if CFFI_C_PATCH_BEFORE not in file_content:
      raise Exception('The patch for the CFFI generated code will not apply cleanly.')
    file_content = file_content.replace(CFFI_C_PATCH_BEFORE, CFFI_C_PATCH_AFTER)

    # Extract the preprocessor directives we had to hide to get the .cdef call to parse.
    file_content = _hackily_recreate_includes_for_bindings(file_content)

  _replace_file(c_file, file_content)

  # Write a shell script to be sourced at build time that contains inherited CFLAGS.
  _replace_file(env_script, get_build_cflags())
1207287
function(source) {
    var proto = Lexer.prototype;
    var tokens = source.match(proto.regs.token);
    for (var i = 0, l = tokens.length; i < l; i ++) {
        if (proto.regs.strip.test(tokens[i])) {
            tokens.splice(i, 1);
        }
    }
    for (var n in proto) tokens[n] = proto[n];
    tokens.index = 0;
    return tokens;
}
165461
private ScriptEngine getScriptEngine(String value) {
        String engineName = value.substring(0, value.indexOf(":"));
        if (engines.containsKey(engineName)) {
            return engines.get(engineName);
        } else {
            ScriptEngine engine = manager.getEngineByName(engineName);
            if (engine != null) {
                engines.put(engineName, engine);
            } else {
                log.warning(String.format("Could not find script engine by name '%s'", engineName));
            }
            return engine;
        }
    }
116189
@Override
    public SqlInfo buildSqlInfo(BuildSource source) {
        // 判断是否生成，如果不匹配则不生成SQL片段.
        String matchText = XmlNodeHelper.getNodeAttrText(source.getNode(), ZealotConst.ATTR_MATCH);
        if (ParseHelper.isNotMatch(matchText, source.getParamObj())) {
            return source.getSqlInfo();
        }

        // 获取命名空间的文本值.
        String nameSpaceText = XmlNodeHelper.getNodeAttrText(source.getNode(), ZealotConst.ATTR_NAME_SPACE);
        String nameSpace = StringHelper.isNotBlank(nameSpaceText) ? nameSpaceText : source.getNameSpace();

        // 获取ZealotId的文本值.
        String zealotIdText = XmlNodeHelper.getNodeAttrText(source.getNode(), ZealotConst.ATTR_ZEALOT_ID);
        Node node = XmlNodeHelper.getNodeBySpaceAndId(nameSpace, zealotIdText);

        // 获取valueText值，如果valueText不为空，则视为将此valueText的解析值再次传入到引入的模板中作为新的上下文参数.
        String valueText = XmlNodeHelper.getNodeAttrText(source.getNode(), ZealotConst.ATTR_VALUE);
        if (StringHelper.isNotBlank(valueText)) {
            Object paramObj = ParseHelper.parseExpressWithException(valueText, source.getParamObj());
            return Zealot.buildSqlInfo(nameSpace, source.getSqlInfo(), node, paramObj);
        }

        // 使用默认参数对象传入到待解析的引入模板中.
        return Zealot.buildSqlInfo(nameSpace, source.getSqlInfo(), node, source.getParamObj());
    }
1198613
function getSource(fn, altSource) {
    var result = altSource;
    if (isStringable(fn)) {
      result = String(fn);
    } else if (support.decompilation) {
      // escape the `{` for Firefox 1
      result = (/^[^{]+\{([\s\S]*)}\s*$/.exec(fn) || 0)[1];
    }
    return (result || '').replace(/^\s+|\s+$/g, '');
  }
184719
function getNodeFromScriptFile(scriptfile) {
    if (fs.existsSync(scriptfile)) {
        try {
            return SourceNode.fromStringWithSourceMap(
                getScriptFromFile(scriptfile),
                new SourceMapConsumer(getMapFromScriptFile(scriptfile))
            );
        } catch (error) {
            console.error('getNodeFromScriptFile() error: ' + error);
            return new SourceNode();
        }
    } else {
        return new SourceNode();
    }
}
1142047
function render(engine, str, locals, engineOptions) {
  try {
    var output = engine.render(engine.engine, str, locals, engineOptions)
  } catch(e) {
    throw new Error(
      NAME + ': there was a problem rendering the template:\n' + e)
  }
  return output
}
429021
function generateJsx(node) {
    if (isReactElement(node)) {
        var type = node.type;

        var name = type.name ? type.name : type;
        var props = node.props ? node.props : {};

        var children = props.children;

        var jsxStr = '<' + name + propsToString(props, type.defaultProps);

        if (children) {
            return jsxStr + '>' + generateJsx(children) + '</' + name + '>';
        }

        return jsxStr + '/>';
    } else if (isReactFragment(node)) {
        var _jsxStr = '';

        node.map(function (child) {
            _jsxStr += generateJsx(child);
        });

        return _jsxStr;
    } else if (isReactText(node)) {
        return String(node);
    } else if (isReactEmpty(node)) {
        return '';
    }

    try {
        return JSON.stringify(node);
    } catch (err) {
        console.error('stringify error:', err.message);
        return node;
    }
}
1015777
function compileExpression(expr, filter, dependencies) {
	// console.log('xpr parse : ', expr);
	var total = expr + filter;
	if (cacheXpr[total]) {
		dependencies.push.apply(dependencies, cacheXpr[total].dependencies);
		return cacheXpr[total].func;
	}
	var dep = [],
		exprReplaced = expr.replace(replacementRegExp, function(whole) {
			if (whole == 'true' || whole == 'false' ||  whole == 'null')
				return whole;
			switch (whole[0]) {
				case '"':
				case "'":
					return whole;
				case '$':
					if (whole[1] === '.')
						return '__global' + whole.substring(1);
				default:
					if (whole[whole.length - 1] === '(') { // function call
						dep.push(whole.substring(0, whole.length - 1));
						return '__context.data.' + whole;
					} else { // simple path to var
						dep.push(whole);
						// we use indirect value retrieval to avoid throw if path provides null or undefined somewhere
						return '__context.get(["' + whole.split('.').join('","') + '"])';
					}
			}
		});
	// console.log('xpr parsing res : ', expr);
	dependencies.push.apply(dependencies, dep);

	var func = new Function("__context", "__global", "return " + exprReplaced + ";");
	if (!filter) {
		cacheXpr[total] = {
			func: func,
			dependencies: dep
		};
		if (Interpolable.debug)
			func.expression = expr;
		return func;
	}
	// produce filter 
	var fltr = new Function('Filter', 'return new Filter().' + filter)(Filter);
	// wrap expr func with filter
	var f = function(context, global) {
		return fltr.call(context, func.call(this, context, global));
	};
	if (Interpolable.debug)
		f.expression = expr;
	cacheXpr[total] = {
		func: f,
		dependencies: dep
	};
	return f;
}
127345
function getEngineFor(inDocument) {
        if (allowNativeXPath &&
            nativeEngine.setDocument(inDocument).isAvailable()) {
            return nativeEngine;
        }

        var currentEngine = engines[currentEngineName];

        if (currentEngine &&
            currentEngine.setDocument(inDocument).isAvailable()) {
            return currentEngine;
        }

        return engines[defaultEngineName].setDocument(inDocument);
    }
906173
function interpret(source) {
  var tree = parser.parse(source);
  var js = [
    'module.exports = function (out, globals) {',
    '  var end = false;',
    '  if (Object.getPrototypeOf(out) !== module.xjs.XjsStream.prototype) {',
    '    out = new module.xjs.XjsStream(out);',
    '    end = true;',
    '  }',
    '  if (globals && typeof globals.length === "number" && typeof globals !== "string") {',
    '    var callee = arguments.callee;',
    '    for (var i in globals) {',
    '      callee.call(this, out, globals[i]);',
    '    }',
    '    return;',
    '  }',
    '  globals = globals || {};',
    '  with (globals) {'
  ];
  interpretChildren(js, tree, '    ');
  js.push(
    '  }',
    '  if (end) {',
    '    out.end();',
    '  }',
    '}'
  );
  js = js.join('\n');
  return js;
}
103668
private static SqlInfo doBuildSqlInfo(BuildSource source, TagHandler th) {
        try {
            // 使用反射获取该Handler对应的实例，并执行方法
            IConditHandler handler = th.getHandlerCls().newInstance();
            return handler.buildSqlInfo(source);
        } catch (InstantiationException e) {
            log.error("实例化IConditHandler的实现类出错!", e);
        } catch (IllegalAccessException e) {
            log.error("访问Handler的实现类出错!", e);
        }
        return source.getSqlInfo();
    }