def parse_decl(cls, node): annos = [] def anno_filter(node): return node.getText() == C.T.ANNO for _node in ifilter(anno_filter, node.getChildren()): _anno = parse_anno(_node) annos.append(_anno) tags = map(op.methodcaller("getText"), node.getChildren()) def mod_filter(tag): return tag not in [C.T.ANNO, C.T.CLS, C.T.ITF, C.T.ENUM, C.T.FLD, C.T.MTD] mods = filter(mod_filter, tags) _node = node.getChildren()[-1] f_or_m = _node.getText() # (FIELD (TYPE Id) (NAME Id (= (E... ))?)) if f_or_m == C.T.FLD: field.parse(cls, node, annos, mods) # (METHOD (TYPE Id) (NAME Id) (PARAMS (Id Id)+)? (THROWS Id+)? Body) elif f_or_m == C.T.MTD: method.parse(cls, node, annos, mods) # inner class or interface else: inner = parse_class(_node) inner.annos = annos inner.mods = mods inner.outer = cls cls.inners.append(inner)
def __init__(self, ast): # reset ids and lists of meta-classes: Field, Method, and Clazz fields_reset() methods_reset() classes_reset() self._frozen = False # class declarations in this template self._classes = [] # [ Clazz... ] # primitive classes cls_obj = Clazz(pkg=u"java.lang", name=C.J.OBJ) cls_obj.sup = None # Object is the root self._classes.append(cls_obj) annos = [] pkg = None mods = [] for _ast in ast.getChildren(): tag = _ast.getText() if tag in [C.T.CLS, C.T.ITF, C.T.ENUM]: clazz = parse_class(_ast) clazz.annos = annos if pkg: for cls in util.flatten_classes([clazz], "inners"): cls.pkg = pkg clazz.mods = mods self._classes.append(clazz) annos = [] pkg = None mods = [] elif tag == C.T.ANNO: annos.append(parse_anno(_ast)) elif tag == C.T.PKG: p_node = util.mk_v_node_w_children(_ast.getChildren()) pkg = util.implode_id(p_node) else: # modifiers mods.append(tag) ## parsing done ## post manipulations go below logging.debug("# class(es): {}".format(len(classes()))) logging.debug("# method(s): {}".format(len(methods()))) logging.debug("# field(s): {}".format(len(fields()))) self.consist()
def parse_e(node, cls=None): curried_e = lambda n: parse_e(n, cls) kind = node.getText() _nodes = node.getChildren() # (E... STH) or (None STH) (i.e., synthetic node) if len(_nodes) == 1 and (not kind or kind == C.T.EXP): # unwrap return curried_e(node.getChild(0)) else: # already in a recursive expression _node = node # (A... ) if kind == C.T.ANNO: a = parse_anno(_node) e = Expression(C.E.ANNO, anno=a) # ?? elif kind == C.T.HOLE: e = gen_E_hole() # {| e* |} elif kind == C.T.REGEN: es = map(curried_e, _nodes) e = gen_E_gen(es) # (CAST (TYPE (E... ty)) e) elif kind == C.T.CAST: t_node = _node.getChild(0).getChild(0) e_node = util.mk_v_node_w_children(_node.getChildren()[1:]) ty = curried_e(t_node) re = curried_e(e_node) e = gen_E_cast(ty, re) # (INS_OF e (TYPE (E... ty))) elif kind == C.T.INS_OF: e_node = util.mk_v_node_w_children(_node.getChildren()[:-1]) t_node = _node.getChildren()[-1].getChild(0) le = curried_e(e_node) ty = curried_e(t_node) e = gen_E_ins_of(le, ty) # (bop le re) elif kind in C.bop + C.rop and _node.getChildCount() == 2: le = curried_e(_node.getChild(0)) re = curried_e(_node.getChild(1)) e = gen_E_bop(kind, le, re) # (uop e) elif kind in C.uop: e_node = util.mk_v_node_w_children(_node.getChildren()) re = curried_e(e_node) e = gen_E_uop(kind, re) # const or id elif len(_nodes) <= 1: if kind: try: if kind in [C.J.TRUE, C.J.FALSE, C.J.N]: e = gen_E_c(unicode(kind)) else: e = gen_E_c(ast.literal_eval(kind)) except Exception: e = gen_E_id(unicode(kind)) else: e = gen_E_id(_nodes[0].getText()) # (E... new Clazz (ARGUMENT ...) ('{' (DECL ...)* '}')?) # (E... new typ([])* '{' ... '}') # (E... new typ '[' sz ']') elif _nodes[0].getText() == C.J.NEW: is_init = util.exists(lambda n: n.getText() == C.T.ARG, _nodes) if is_init: # class <init> if _nodes[-1].getText() == '}': # anonymous inner class for i, n in enumerate(_nodes): if n.getText() == '{': c_node = util.mk_v_node_w_children(_nodes[1:i]) decl_nodes = _nodes[i+1:-1] break c = curried_e(c_node) name = clazz.anony_name(cls) anony = clazz.Clazz(name=name, itfs=[unicode(c.f)], outer=cls) map(partial(clazz.parse_decl, anony), decl_nodes) cls.inners.append(anony) c.f.id = name e = gen_E_new(c) else: c_node = util.mk_v_node_w_children(_nodes[1:]) c = curried_e(c_node) e = gen_E_new(c) else: # array (w/ initial values) w_init_vals = util.exists(lambda n: n.getText() in ['{', '}'], _nodes) if w_init_vals: what_to_find = '{' # starting point of initial values else: what_to_find = '[' # starting point of array size for i, n in enumerate(_nodes): if n.getText() == what_to_find: t_node = util.mk_v_node_w_children(_nodes[1:i]) init_node = util.mk_v_node_w_children(_nodes[i:]) break t = gen_E_id(util.implode_id(t_node)) init = util.implode_id(init_node) e = gen_E_new(t, init) # (E... ... (ARGV ...)) elif _nodes[-1].getText() == C.T.ARG: f_node = util.mk_v_node_w_children(_nodes[:-1]) f = curried_e(f_node) a = map(curried_e, _nodes[-1].getChildren()) e = gen_E_call(f, a) # (E... ... '[' (E... ) ']') elif _nodes[-1].getText() == ']' and _nodes[-3].getText() == '[': idx = curried_e(_nodes[-2]) le_node = util.mk_v_node_w_children(_nodes[:-3]) le = curried_e(le_node) e = gen_E_idx(le, idx) # (... '.' ...) elif any(filter(lambda n: n.getText() == '.', _nodes)): i = [i for i, n in enumerate(_nodes) if n.getText() == '.'][-1] l_node = util.mk_v_node_w_children(_nodes[:i]) le = curried_e(l_node) r_node = util.mk_v_node_w_children(_nodes[i+1:]) re = curried_e(r_node) e = gen_E_dot(le, re) # (... '<' ... '>') # e.g., Collection<T> elif _nodes[-1].getText() == '>': e = gen_E_id(util.implode_id(_node)) else: raise Exception("unhandled expression", node.toStringTree()) return e