------------ 构建AST ------------
775639
function AstParser(tokens, doc){

	// ------------ 变量 ------------
	syntaxCheck(tokens); // 删除空白文本
	let reader = new TokenReader(tokens);
	let ast = [];
	let file = doc.file;

	// ------------ 接口方法 ------------
	// 解析
	this.parse = function() {
		let ast = parseChildren();
//console.info(MODULE, JSON.stringify(ast,null,2));
		return ast;
	}

	// ------------ 内部方法 ------------
	// HTML子节点
	function parseChildren() {

		let ary = [], node;

		// 循环直到遇见标签闭合Token
		while ( !reader.eof() && reader.getCurrentToken().type != options.TypeTagClose ) {
			node = parseTag();
			node && ary.push(node);

			node = parseComment();
			node && ary.push(node);

			node = parseCodeBlock();
			node && ary.push(node);

			node = parseText();
			node && ary.push(node);

			node = parseExpression();
			node && ary.push(node);
		}

		return ary;
	}

	// HTML节点
	function parseTag() {
		let curToken = reader.getCurrentToken();
		if ( reader.eof() || (curToken.type != options.TypeTagOpen && curToken.type != options.TypeTagSelfClose) ) {
			return null;
		}

		let attrs, children, node = {tag: curToken.text};
		let isClose = (curToken.type == options.TypeTagSelfClose);
		reader.skip(1); // 跳过标签名

		// 收集属性
		attrs = parseAttr();

		if ( !isClose ) {
			children = parseChildren();
			if ( reader.getCurrentToken().type == options.TypeTagClose ) {
				if ( reader.getCurrentToken().text == node.tag ) {
					reader.skip(1); // 跳过闭合标签
				}else{

					let token = reader.getCurrentToken();
					!token.pos && (token = reader.getPreToken());

					let text = File.read(file);
					let rs = /^\[view\][\s\S]*?\n|\n\[view\][\s\S]*?\n/i.exec(text);
					let offset = rs.index + rs[0].length;
					let start = offset + curToken.pos.start+1;
					let end = offset + token.pos.end;
					let msg = 'close tag unmatch: ' + node.tag + ' / ' + token.text;
					throw Err.cat(msg, 'file=' + file, new Err( {text, start, end} )); // 标签没有闭合
				}
			}else{
				
				let token = reader.getCurrentToken();
				!token.pos && (token = reader.getPreToken());

				let text = File.read(file);
				let rs = /^\[view\][\s\S]*?\n|\n\[view\][\s\S]*?\n/i.exec(text);
				let offset = rs.index + rs[0].length;
				let start = offset + curToken.pos.start+1;
				let end = offset + token.pos.end;
				let msg = 'tag not close: ' + node.tag;
				throw Err.cat(msg, 'file=' + file, new Err( {text, start, end} )); // 标签没有闭合
			}
		}

		attrs && (node.attrs = attrs);
		children && children.length && (node.children = children);

		return node;
	}

	// HTML节点属性
	function parseAttr() {
		if ( reader.eof() || reader.getCurrentToken().type != options.TypeAttributeName ) {
			return null;
		}

		let attr = {};
		while ( !reader.eof() && reader.getCurrentToken().type == options.TypeAttributeName ) {
			if ( reader.getNextToken().type == options.TypeEqual ) {
				let key = reader.getCurrentToken().text;
				reader.skip(2); // 跳过属性名、等号
				attr[key] = reader.readToken().text;
			}else{
				// 无值属性，默认值为true
				attr[reader.getCurrentToken().text] = true;
				reader.skip(1); // 跳过属性名
			}
		}

		return attr;
	}

	// HTML注释
	function parseComment() {
		if ( !reader.eof() && reader.getCurrentToken().type == options.TypeHtmlComment ) {
			reader.readToken(); // 跳过HTML注释
		}
		return null;
	}

	// 代码块 {% %}
	function parseCodeBlock() {
		if ( reader.eof() || reader.getCurrentToken().type != options.TypeCodeBlock ) {
			return null;
		}
		return {type: options.TypeCodeBlock, src: reader.readToken().text};
	}

	// 文本
	function parseText() {
		if ( reader.eof() || reader.getCurrentToken().type != options.TypeText ) {
			return null;
		}
		return {type: 'Text', src: reader.readToken().text};
	}

	// 表达式 { } 或 {= }
	function parseExpression() {
		if ( reader.eof() || (reader.getCurrentToken().type != options.TypeUnescapeExpression && reader.getCurrentToken().type != options.TypeEscapeExpression) ) {
			return null;
		}

		if ( reader.getCurrentToken().type == options.TypeEscapeExpression ) {
			return {type: options.TypeEscapeExpression, src: reader.readToken().text};
		}else{
			return {type: options.TypeUnescapeExpression, src: reader.readToken().text};
		}
	}

}
453952
function getExpressions(ast, start, end) {
        var expns = [],
            s     = start,
            e     = end,
            expn;

        while (true) {
            expn = RefactoringUtils.findSurroundExpression(ast, {start: s, end: e});
            if (!expn) {
                break;
            }
            expns.push(expn);
            s = expn.start - 1;
        }

        s = start;
        e = end;

        function checkExpnEquality(e) {
            return e.start === expn.start && e.end === expn.end;
        }

        while (true) {
            expn = RefactoringUtils.findSurroundExpression(ast, {start: s, end: e});
            if (!expn) {
                break;
            }
            e = expn.end + 1;

            // if expn already added, continue
            if (expns.find(checkExpnEquality)) {
                 continue;
            }

            expns.push(expn);
        }

        return expns;
    }
631515
function makeAsciiTable(spec) {
  var ret = new Uint8Array(128);
  spec.forEach(function(item){
    if (typeof item === "number") {
      ret[item] = 1;
    }
    else {
      var start = item[0];
      var end = item[1];
      for (var j = start; j <= end; ++j) {
        ret[j] = 1;
      }
    }
  });

  return ret;
}
101877
function(token, match){
		var wtree = this.wtree;
		var btree = this.btree;
		if (match.name == 12/*asi*/) {
			token.tokposw = wtree.length;
			wtree.push(token);
			token.tokposb = btree.length;
			btree.push(token);
		} else {
			token.tokposw = match.tokposw;
			wtree[token.tokposw] = token;
			match.tokposw += 1;
			wtree[match.tokposw] = match;

			if (match.tokposb) {
				token.tokposb = match.tokposb;
				btree[token.tokposb] = token;
				match.tokposb += 1;
				btree[match.tokposb] = match;
			}
		}
	}
598816
function asyncLoops_1(ast, state) {
        treeWalk(ast, function (node, descend, path) {
            function mapContinue(label) {
                return {
                    type: 'ReturnStatement',
                    argument: {
                        type: 'UnaryExpression',
                        operator: 'void',
                        prefix: true,
                        argument: thisCall(label || symContinue)
                    }
                };
            }
            
            ;
            function mapExits(n, descend) {
                if (n.type === 'BreakStatement') {
                    coerce(n, cloneNode(mapBreak(n.label && opts.generatedSymbolPrefix + "Loop_" + n.label.name + "_exit")));
                } else if (n.type === 'ContinueStatement') {
                    coerce(n, cloneNode(mapContinue(n.label && opts.generatedSymbolPrefix + "Loop_" + n.label.name + "_next")));
                } else if (examine(n).isFunction) {
                    return true;
                }
                descend();
            }
            
            if (node.type === 'ForInStatement' && containsAwait(node)) {
                transformForIn(node, path);
            } else if (node.type === 'ForOfStatement' && containsAwait(node)) {
                iterizeForOf(node, path);
            }
            descend();
            var p;
            if (examine(node).isLoop && containsAwait(node)) {
                var init = node.init;
                var condition = node.test || literal(true);
                var step = node.update;
                var body = node.body;
                var loopUsesThis = containsThis(body);
                if (init) {
                    if (!examine(init).isStatement) {
                        init = {
                            type: 'ExpressionStatement',
                            expression: init
                        };
                    }
                }
                step = step && {
                    type: 'ExpressionStatement',
                    expression: step
                };
                body = examine(body).isBlockStatement ? cloneNode(body).body : [cloneNode(body)];
                var label = node.$label && node.$label.name;
                label = "Loop_" + (label || generatedSymbol++);
                var symExit = opts.generatedSymbolPrefix + (label + "_exit");
                var symContinue = opts.generatedSymbolPrefix + (label + "_next");
                var loop = ident(opts.generatedSymbolPrefix + label);
                // How to exit the loop
                var mapBreak = function (label) {
                    return {
                        type: 'ReturnStatement',
                        argument: {
                            type: 'UnaryExpression',
                            operator: 'void',
                            prefix: true,
                            argument: {
                                type: 'CallExpression',
                                callee: ident(label || symExit),
                                arguments: []
                            }
                        }
                    };
                };
                // How to continue the loop
                var defContinue = makeContinuation(symContinue, [{
                    type: 'ReturnStatement',
                    argument: {
                        type: 'CallExpression',
                        callee: loopUsesThis ? bindAsync(loop) : loop,
                        arguments: [ident(symExit),genIdent.error]
                    }
                }]);
                if (step) 
                    defContinue.body.body.unshift(step);
                for (var i = 0;i < body.length; i++) {
                    treeWalk(body[i], mapExits);
                }
                body.push(cloneNode(mapContinue()));
                var subCall = {
                    type: 'FunctionExpression',
                    id: loop,
                    params: [ident(symExit),genIdent.error],
                    body: {
                        type: 'BlockStatement',
                        body: [defContinue]
                    }
                };
                if (node.type === 'DoWhileStatement') {
                    defContinue.body.body = [{
                        type: 'IfStatement',
                        test: cloneNode(condition),
                        consequent: {
                            type: 'BlockStatement',
                            body: cloneNode(defContinue.body.body)
                        },
                        alternate: {
                            type: 'ReturnStatement',
                            argument: {
                                type: 'CallExpression',
                                callee: ident(symExit),
                                arguments: []
                            }
                        }
                    }];
                    subCall.body.body = [defContinue].concat(body);
                } else {
                    var nextTest = {
                        type: 'IfStatement',
                        test: cloneNode(condition),
                        consequent: {
                            type: 'BlockStatement',
                            body: body
                        },
                        alternate: cloneNode(mapBreak())
                    };
                    subCall.body.body.push(nextTest);
                }
                var replace = {
                    type: 'ExpressionStatement',
                    expression: {
                        type: 'AwaitExpression',
                        argument: bindAsync(subCall, literal(0))
                    }
                };
                if (init && init.type === 'VariableDeclaration' && (init.kind === 'let' || init.kind === 'const')) {
                    if (init.kind === 'const') 
                        init.kind = 'let';
                    replace = {
                        type: 'BlockStatement',
                        body: [cloneNode(init),replace]
                    };
                    init = null;
                }
                for (p = 0; p < path.length; p++) {
                    var ref = path[p];
                    if ('index' in ref) {
                        if (init) {
                            ref.parent[ref.field].splice(ref.index, 1, cloneNode(init), replace);
                        } else {
                            ref.parent[ref.field][ref.index] = replace;
                        }
                        return true;
                    }
                }
            }
            return true;
        }, state);
        return ast;
    }
622373
function babel7toBabel6(ast) {
  const visitor = {
    ArrowFunctionExpression: node => {
      node.expression = node.body.type !== 'BlockStatement';
    },
    ExistsTypeAnnotation: node => {
      node.type = 'ExistentialTypeParam';
    },
    NumberLiteralTypeAnnotation: node => {
      node.type = 'NumericLiteralTypeAnnotation';
    },
    ObjectTypeIndexer: node => {
      node.end++;
      node.loc.end.column++;
    },
    ForOfStatement: node => {
      node.type = 'ForAwaitStatement';
      delete node.await;
    },
    SpreadElement: (node, path) => {
      if (
        path.parentPath.isObjectExpression() ||
        path.parentPath.isArrayExpression()
      ) {
        node.type = 'SpreadProperty';
      }
    },
    RestElement: (node, path) => {
      if (
        path.parentPath.isObjectPattern() ||
        path.parentPath.isArrayPattern()
      ) {
        node.type = 'RestProperty';
      }
    }
  };

  traverse(ast, {
    enter(path) {
      if (path.node.variance && path.node.variance.type === 'Variance') {
        path.node.variance = path.node.variance.kind;
      }

      let visitorFunc = visitor[path.node.type];
      if (visitorFunc) {
        visitorFunc(path.node, path);
      }
    }
  });

  return ast;
}
408301
async function scanFile (dir, ext, ret_absolute)
{
return new Promise( async function(resolve, reject){
    // console.log(dir);
    fs.readdir(dir, function(err, files){
        let file_arr = [];
        if( ! files ){
            return resolve(file_arr);
        }
        files.forEach(function(elm){
            if( elm.indexOf('.') > -1 ){
                if( !ext || '.'+ext.toUpperCase()==path.extname(elm).toUpperCase() ){
                    // 返回全路径
                    if( ret_absolute ){
                        elm = path.join(dir, elm);
                    }
                    // 检查文件后缀名
                    file_arr.push(elm);
                }
            }
        });
        resolve(file_arr);
    });
});
}
1065812
def dump_ast(ast, indent=' ', newline='\n'):
    '''
    
    
    
    '''
    
    visitor = ASTPrinter(indent=indent, level=0, newline=newline)
    visitor.visit(ast)
    return visitor.dumps()
481152
@Override
    public String as( As annotation, Method method ) {
        if( annotation != null && annotationHasExplicitValue( annotation ) ) {
            return annotation.value();
        }

        return methodNameToReadableText( method.getName() );
    }
522253
function(ast, source) {
      if(!ast) return;
      for(var i=0;i<ast.length;i++) {
        var node=ast[i];
        if(node && node.length>=3 && node[0]=='=') {
          // looking for ['=', id, val]
          runtime.ast()[node[1]] = {'ast': [node]};
          runtime.source()[node[1]] = source;
        }
      }
    }
1159601
function ast_walker() {
        function _vardefs(defs) {
                return [ this[0], MAP(defs, function(def){
                        var a = [ def[0] ];
                        if (def.length > 1)
                                a[1] = walk(def[1]);
                        return a;
                }) ];
        };
        function _block(statements) {
                var out = [ this[0] ];
                if (statements != null)
                        out.push(MAP(statements, walk));
                return out;
        };
        var walkers = {
                "string": function(str) {
                        return [ this[0], str ];
                },
                "num": function(num) {
                        return [ this[0], num ];
                },
                "name": function(name) {
                        return [ this[0], name ];
                },
                "toplevel": function(statements) {
                        return [ this[0], MAP(statements, walk) ];
                },
                "block": _block,
                "splice": _block,
                "var": _vardefs,
                "const": _vardefs,
                "try": function(t, c, f) {
                        return [
                                this[0],
                                MAP(t, walk),
                                c != null ? [ c[0], MAP(c[1], walk) ] : null,
                                f != null ? MAP(f, walk) : null
                        ];
                },
                "throw": function(expr) {
                        return [ this[0], walk(expr) ];
                },
                "new": function(ctor, args) {
                        return [ this[0], walk(ctor), MAP(args, walk) ];
                },
                "switch": function(expr, body) {
                        return [ this[0], walk(expr), MAP(body, function(branch){
                                return [ branch[0] ? walk(branch[0]) : null,
                                         MAP(branch[1], walk) ];
                        }) ];
                },
                "break": function(label) {
                        return [ this[0], label ];
                },
                "continue": function(label) {
                        return [ this[0], label ];
                },
                "conditional": function(cond, t, e) {
                        return [ this[0], walk(cond), walk(t), walk(e) ];
                },
                "assign": function(op, lvalue, rvalue) {
                        return [ this[0], op, walk(lvalue), walk(rvalue) ];
                },
                "dot": function(expr) {
                        return [ this[0], walk(expr) ].concat(slice(arguments, 1));
                },
                "call": function(expr, args) {
                        return [ this[0], walk(expr), MAP(args, walk) ];
                },
                "function": function(name, args, body) {
                        return [ this[0], name, args.slice(), MAP(body, walk) ];
                },
                "debugger": function() {
                        return [ this[0] ];
                },
                "defun": function(name, args, body) {
                        return [ this[0], name, args.slice(), MAP(body, walk) ];
                },
                "if": function(conditional, t, e) {
                        return [ this[0], walk(conditional), walk(t), walk(e) ];
                },
                "for": function(init, cond, step, block) {
                        return [ this[0], walk(init), walk(cond), walk(step), walk(block) ];
                },
                "for-in": function(vvar, key, hash, block) {
                        return [ this[0], walk(vvar), walk(key), walk(hash), walk(block) ];
                },
                "while": function(cond, block) {
                        return [ this[0], walk(cond), walk(block) ];
                },
                "do": function(cond, block) {
                        return [ this[0], walk(cond), walk(block) ];
                },
                "return": function(expr) {
                        return [ this[0], walk(expr) ];
                },
                "binary": function(op, left, right) {
                        return [ this[0], op, walk(left), walk(right) ];
                },
                "unary-prefix": function(op, expr) {
                        return [ this[0], op, walk(expr) ];
                },
                "unary-postfix": function(op, expr) {
                        return [ this[0], op, walk(expr) ];
                },
                "sub": function(expr, subscript) {
                        return [ this[0], walk(expr), walk(subscript) ];
                },
                "object": function(props) {
                        return [ this[0], MAP(props, function(p){
                                return p.length == 2
                                        ? [ p[0], walk(p[1]) ]
                                        : [ p[0], walk(p[1]), p[2] ]; // get/set-ter
                        }) ];
                },
                "regexp": function(rx, mods) {
                        return [ this[0], rx, mods ];
                },
                "array": function(elements) {
                        return [ this[0], MAP(elements, walk) ];
                },
                "stat": function(stat) {
                        return [ this[0], walk(stat) ];
                },
                "seq": function() {
                        return [ this[0] ].concat(MAP(slice(arguments), walk));
                },
                "label": function(name, block) {
                        return [ this[0], name, walk(block) ];
                },
                "with": function(expr, block) {
                        return [ this[0], walk(expr), walk(block) ];
                },
                "atom": function(name) {
                        return [ this[0], name ];
                }
        };

        var user = {};
        var stack = [];
        function walk(ast) {
                if (ast == null)
                        return null;
                try {
                        stack.push(ast);
                        var type = ast[0];
                        var gen = user[type];
                        if (gen) {
                                var ret = gen.apply(ast, ast.slice(1));
                                if (ret != null)
                                        return ret;
                        }
                        gen = walkers[type];
                        return gen.apply(ast, ast.slice(1));
                } finally {
                        stack.pop();
                }
        };

        function dive(ast) {
                if (ast == null)
                        return null;
                try {
                        stack.push(ast);
                        return walkers[ast[0]].apply(ast, ast.slice(1));
                } finally {
                        stack.pop();
                }
        };

        function with_walkers(walkers, cont){
                var save = {}, i;
                for (i in walkers) if (HOP(walkers, i)) {
                        save[i] = user[i];
                        user[i] = walkers[i];
                }
                var ret = cont();
                for (i in save) if (HOP(save, i)) {
                        if (!save[i]) delete user[i];
                        else user[i] = save[i];
                }
                return ret;
        };

        return {
                walk: walk,
                dive: dive,
                with_walkers: with_walkers,
                parent: function() {
                        return stack[stack.length - 2]; // last one is current node
                },
                stack: function() {
                        return stack;
                }
        };
}
174023
function (uri, fromUri, source) {
        if (!/^\./.test(uri) || EXTNAME_RE.test(uri)) {

            var line;

            // 如果只出现一次这个字符串，很容易确认模板错误行
            if (source.split(uri).length === 2) {
                source.split(/\n/).forEach(function (code, index) {
                    if (code.indexOf(uri) !== -1) {
                        line = index + 1;
                        source = code.trim();
                    }
                });
            }

            var error = {
                name: 'Syntax Error',
                line: line,
                source: source,
                message: 'Template must be a relative path, and can not have a suffix.'
            };

            if (fromUri) {
                error.filename = fromUri;
            }

            throw error;
        }
    }
189080
function walkNodesBreadthFirstHelper(ast, f) {
  let childAst = [];
  (ast || []).forEach(node => {
    f(node);
    childAst = childAst.concat(getChildren(node));
  });
  if (childAst.length > 0) {
    walkNodesBreadthFirstHelper(childAst, f);
  }
}
1334437
function getBlocks(ast) {
  ast = Array.isArray(ast) ? ast : [ast];

  return ast.map((node) => {
    if (t.isReturnStatement(node)) {
      return getBlocks(node.argument);
    }
    if (t.isConditionalExpression(node)) {
      return node.alternate ? [
        ...getBlocks(node.consequent),
        ...getBlocks(node.alternate),
      ] : getBlocks(node.consequent);
    }
    if (t.isBinaryExpression(node)) {
      return handleBinaryExpression(node);
    }

    return null;
  }).filter(Boolean).reduce((prev, arr) => prev.concat(arr), []);
}
566799
public static <T> List<T> asList(T[] a) {
		if (a == null) {
			return Collections.emptyList();
		}
		return Arrays.asList(a);
	}
1045548
@Override
    protected void _parseMappings(String aStr, String aSourceRoot) {
        int generatedLine = 1;
        int previousGeneratedColumn = 0;
        int previousOriginalLine = 0;
        int previousOriginalColumn = 0;
        int previousSource = 0;
        int previousName = 0;
        int length = aStr.length();
        int index = 0;
        Map<String, List<Integer>> cachedSegments = new HashMap<>();
        Base64VLQResult temp;
        List<ParsedMapping> originalMappings = new ArrayList<>();
        List<ParsedMapping> generatedMappings = new ArrayList<>();
        ParsedMapping mapping;
        String str;
        List<Integer> segment;
        int end;
        int value;

        while (index < length) {
            if (aStr.charAt(index) == ';') {
                generatedLine++;
                index++;
                previousGeneratedColumn = 0;
            } else if (aStr.charAt(index) == ',') {
                index++;
            } else {
                mapping = new ParsedMapping();
                mapping.generatedLine = generatedLine;

                // Because each offset is encoded relative to the previous one,
                // many segments often have the same encoding. We can exploit this
                // fact by caching the parsed variable length fields of each segment,
                // allowing us to avoid a second parse if we encounter the same
                // segment again.
                for (end = index; end < length; end++) {
                    if (this._charIsMappingSeparator(aStr, end)) {
                        break;
                    }
                }
                str = aStr.substring(index, end);

                segment = cachedSegments.get(str);
                if (segment != null) {
                    index += str.length();
                } else {
                    segment = new ArrayList<>();
                    while (index < end) {
                        temp = Base64VLQ.decode(aStr, index);
                        value = temp.value;
                        index = temp.rest;
                        segment.add(value);
                    }

                    if (segment.size() == 2) {
                        throw new Error("Found a source, but no line and column");
                    }

                    if (segment.size() == 3) {
                        throw new Error("Found a source and line, but no column");
                    }

                    cachedSegments.put(str, segment);
                }

                // Generated column.
                mapping.generatedColumn = previousGeneratedColumn + segment.get(0);
                previousGeneratedColumn = mapping.generatedColumn;

                if (segment.size() > 1) {
                    // Original source.
                    mapping.source = previousSource + segment.get(1);
                    previousSource += segment.get(1);

                    // Original line.
                    mapping.originalLine = previousOriginalLine + segment.get(2);
                    previousOriginalLine = mapping.originalLine;
                    // Lines are stored 0-based
                    mapping.originalLine += 1;

                    // Original column.
                    mapping.originalColumn = previousOriginalColumn + segment.get(3);
                    previousOriginalColumn = mapping.originalColumn;

                    if (segment.size() > 4) {
                        // Original name.
                        mapping.name = previousName + segment.get(4);
                        previousName += segment.get(4);
                    }
                }

                generatedMappings.add(mapping);
                if (mapping.originalLine != null) {
                    originalMappings.add(mapping);
                }
            }
        }

        Collections.sort(generatedMappings, Util::compareByGeneratedPositionsDeflated);
        this.__generatedMappings = generatedMappings;

        Collections.sort(originalMappings, Util::compareByOriginalPositions);
        this.__originalMappings = originalMappings;
    }
1230288
function parseExtend (ast) {
    for (let i = 0, max = ast.body.length; i < max; i++) {
        let node = ast.body[i];

        // Search for extend('Parent', 'Child');
        if (isExpressionStatement(node) && isCallExpression(node.expression) && node.expression.callee.name === 'extend') {
            node = node.expression;

            let parent = node.arguments[0].value;
            let child = node.arguments[1].value;

            createHierarchyNode(parent);
            createHierarchyNode(child);

            // Link child to parent.
            hierarchy[parent].children.push(child);

            // Link parent to child.
            hierarchy[child].parent = parent;

            return true;
        }
    }

    return false;
}