예제 #1
0
파일: sample.py 프로젝트: plum-umd/pasket
 def sources(self):
   # assume runtime instances are of the form: @Object(typ=..., idx=...)
   def obj_finder(val):
     m = re.match(r"@Object\(typ=(.+), idx=\d+\)", val)
     if m: return m.group(1)
     else: return None
   return util.rm_dup(util.rm_none(map(obj_finder, self._vals)))
예제 #2
0
    def sources(self):
        # assume runtime instances are of the form: @Object(typ=..., idx=...)
        def obj_finder(val):
            m = re.match(r"@Object\(typ=(.+), idx=\d+\)", val)
            if m: return m.group(1)
            else: return None

        return util.rm_dup(util.rm_none(map(obj_finder, self._vals)))
예제 #3
0
    def trans_call(callee, rcv_ty, rcv):
      if callee.is_static: rcv = None
      logging = None
      if not util.is_collection(callee.clazz.name):
        logging = str(check_logging(mtd, callee)).lower()

      args = util.rm_none([rcv] + map(curried, e.a) + [logging])
      mid = trans_mname(rcv_ty, callee.name, arg_typs)
      return u"{}({})".format(mid, ", ".join(args))
예제 #4
0
 def trans_call(callee, rcv_ty, rcv):
   if callee.is_static: rcv = None
   args = util.rm_none([rcv] + map(curried, e.a))
   mid = trans_mname(rcv_ty, callee.name, arg_typs)
   return u"{}({})".format(mid, ", ".join(args))
예제 #5
0
def trans_e(mtd, e):
  curried = partial(trans_e, mtd)
  buf = cStringIO.StringIO()

  if e.kind == C.E.GEN:
    if e.es:
      buf.write("{| ")
      buf.write(" | ".join(map(curried, e.es)))
      buf.write(" |}")
    else:
      buf.write(C.T.HOLE)

  elif e.kind == C.E.ID:
    if hasattr(e, "ty"): buf.write(trans_ty(e.ty) + ' ')
    fld = None
    if mtd and e.id not in mtd.param_vars:
      fld = find_fld(mtd.clazz.name, e.id)
    if fld: # fname -> self.new_fname (unless the field is static)
      new_fname = trans_fname(fld.clazz.name, e.id, fld.is_static)
      if fld.is_static:
        # access to the static field inside the same class
        if fld.clazz.name == mtd.clazz.name: buf.write(e.id)
        # o.w., e.g., static constant in an interface, call the accessor
        else: buf.write(new_fname + "()")
      else: buf.write('.'.join([C.SK.self, new_fname]))
    elif e.id in [C.J.THIS, C.J.SUP]: buf.write(C.SK.self)
    elif util.is_str(e.id): # constant string, such as "Hello, World"
      str_init = trans_mname(C.J.STR, C.J.STR, [u"char[]", C.J.i, C.J.i])
      s_hash = hash(e.id) % 256 # hash string value itself
      buf.write("{}(new Object(hash={}), {}, 0, {})".format(str_init, s_hash, e.id, len(e.id)))
    else: buf.write(e.id)

  elif e.kind == C.E.UOP:
    buf.write(' '.join([e.op, curried(e.e)]))

  elif e.kind == C.E.BOP:
    buf.write(' '.join([curried(e.le), e.op, curried(e.re)]))

  elif e.kind == C.E.DOT:
    # with package names, e.g., javax.swing.SwingUtilities
    if util.is_class_name(e.re.id) and class_lookup(e.re.id):
      buf.write(curried(e.re))
    elif e.re.id == C.J.THIS: # ClassName.this
      buf.write(C.SK.self)
    else:
      rcv_ty = typ_of_e(mtd, e.le)
      fld = find_fld(rcv_ty, e.re.id)
      new_fname = trans_fname(rcv_ty, e.re.id, fld.is_static)
      if fld.is_static:
        # access to the static field inside the same class
        if mtd and rcv_ty == mtd.clazz.name: buf.write(e.re.id)
        # o.w., e.g., static constant in an interface, call the accessor
        else: buf.write(new_fname + "()")
      else: buf.write('.'.join([curried(e.le), new_fname]))

  elif e.kind == C.E.IDX:
    buf.write(curried(e.e) + '[' + curried(e.idx) + ']')

  elif e.kind == C.E.NEW:
    if e.e.kind == C.E.CALL:
      ty = typ_of_e(mtd, e.e.f)
      cls = class_lookup(ty)
      if cls and cls.has_init:
        arg_typs = map(partial(typ_of_e, mtd), e.e.a)
        mname = trans_mname(cls.name, cls.name, arg_typs)
        obj = "alloc@log({})".format(cls.id)
        args = [obj] + map(unicode, map(curried, e.e.a))
        buf.write("{}({})".format(mname, ", ".join(args)))
      else: # collection or Object
        buf.write(C.J.NEW + ' ' + trans_ty(ty) + "()")
    else: # o.w., array initialization, e.g., new int[] { ... }
      buf.write(str(e.init))

  elif e.kind == C.E.CALL:
    arg_typs = map(partial(typ_of_e, mtd), e.a)

    def trans_call(callee, rcv_ty, rcv):
      if callee.is_static: rcv = None
      args = util.rm_none([rcv] + map(curried, e.a))
      mid = trans_mname(rcv_ty, callee.name, arg_typs)
      return u"{}({})".format(mid, ", ".join(args))

    def dynamic_dispatch(rcv_ty, rcv, acc, callee):
      _dispatched = trans_call(callee, callee.clazz.name, rcv)
      _guarded = "{}.__cid == {} ? {}".format(rcv, callee.clazz.id, _dispatched)
      return "({} : {})".format(_guarded, acc)

    if e.f.kind == C.E.DOT: # rcv.mid
      rcv_ty = typ_of_e(mtd, e.f.le)
      rcv = curried(e.f.le)
      mname = e.f.re.id
      mtd_callees = find_mtds_by_sig(rcv_ty, mname, arg_typs)
      if mtd_callees and 1 < len(mtd_callees): # needs dynamic dispatch
        curried_dispatch = partial(dynamic_dispatch, rcv_ty, rcv)
        # TODO: use least upper bound?
        default_v = util.default_value(mtd_callees[0].typ)
        buf.write(reduce(curried_dispatch, mtd_callees, default_v))
      elif mtd_callees and 1 == len(mtd_callees):
        mtd_callee = mtd_callees[0]
        buf.write(trans_call(mtd_callee, rcv_ty, rcv))
      else: # unresolved, maybe library method
        mid = trans_mname(rcv_ty, mname, arg_typs)
        args = util.rm_none([rcv] + map(curried, e.a))
        buf.write("{}({})".format(mid, ", ".join(args)))

    else: # mid
      mname = e.f.id
      # pre-defined meta information or Sketch primitive functions
      if mname in C.typ_arrays + [u"minimize"]:
        mid = mname
        rcv = None
        args = util.rm_none([rcv] + map(curried, e.a))
        buf.write("{}({})".format(mid, ", ".join(args)))
      elif mname == C.J.SUP and mtd.is_init: # super(...) inside <init>
        sup = class_lookup(mtd.clazz.sup)
        mid = trans_mname(sup.name, sup.name, arg_typs)
        rcv = C.SK.self
        args = util.rm_none([rcv] + map(curried, e.a))
        buf.write("{}({})".format(mid, ", ".join(args)))
      else: # member methods
        mtd_callees = find_mtds_by_sig(mtd.clazz.name, mname, arg_typs)
        if mtd_callees and 1 < len(mtd_callees): # needs dynamic dispatch
          curried_dispatch = partial(dynamic_dispatch, mtd.clazz.name, C.SK.self)
          # TODO: use least upper bound?
          default_v = util.default_value(mtd_callees[0].typ)
          buf.write(reduce(curried_dispatch, mtd_callees, default_v))
        elif mtd_callees and 1 == len(mtd_callees):
          mtd_callee = mtd_callees[0]
          buf.write(trans_call(mtd_callee, mtd.clazz.name, C.SK.self))
        else: # unresolved, maybe library method
          mid = trans_mname(mtd.clazz.name, mname, arg_typs)
          args = util.rm_none([rcv] + map(curried, e.a))
          buf.write("{}({})".format(mid, ", ".join(args)))

  elif e.kind == C.E.CAST:
    # since a family of classes is merged, simply ignore the casting
    buf.write(curried(e.e))

  elif e.kind == C.E.INS_OF:
    ty = typ_of_e(mtd, e.ty)
    cls = class_lookup(ty)
    if cls:
      buf.write(curried(e.e) + ".__cid == " + str(cls.id))
    else:
      logging.debug("unknown type: {}".format(ty))
      buf.write("0")

  else: buf.write(str(e))
  return buf.getvalue()
예제 #6
0
def trans_e(mtd, e):
  curried = partial(trans_e, mtd)
  buf = cStringIO.StringIO()
  if e.kind == C.E.ANNO:
    anno = e.anno
    if anno.name == C.A.NEW: pass # TODO

    elif anno.name == C.A.OBJ:
      buf.write("retrieve_{}@log({})".format(util.sanitize_ty(anno.typ), anno.idx))

    # @Compare(exps) => {| exps[0] (< | <= | == | != | >= | >) exps[1] |}
    # @CompareString(exps) => exps[0].eqauls(exps[1])
    elif anno.name in [C.A.CMP, C.A.CMP_STR]:
      le = curried(anno.exps[0])
      re = curried(anno.exps[1])
      if anno.name == C.A.CMP:
        buf.write("{| " + le + " (< | <= | == | != | >= | >) " + re + " |}")
      else:
        buf.write("{}({},{})".format(trans_mname(C.J.STR, u"equals"), le, re))

  elif e.kind == C.E.GEN:
    if e.es:
      buf.write("{| ")
      buf.write(" | ".join(map(curried, e.es)))
      buf.write(" |}")
    else:
      buf.write(C.T.HOLE)

  elif e.kind == C.E.ID:
    if hasattr(e, "ty"): buf.write(trans_ty(e.ty) + ' ')
    fld = None
    if mtd and e.id not in mtd.param_vars:
      fld = find_fld(mtd.clazz.name, e.id)
    if fld: # fname -> self.new_fname (unless the field is static)
      new_fname = trans_fname(fld.clazz.name, e.id, fld.is_static)
      if fld.is_static:
        # access to the static field inside the same class
        if fld.clazz.name == mtd.clazz.name: buf.write(e.id)
        # o.w., e.g., static constant in an interface, call the accessor
        else: buf.write(new_fname + "()")
      else: buf.write('.'.join([C.SK.self, new_fname]))
    elif e.id in [C.J.THIS, C.J.SUP]: buf.write(C.SK.self)
    elif util.is_str(e.id): # constant string, such as "Hello, World"
      str_init = trans_mname(C.J.STR, C.J.STR, [u"char[]", C.J.i, C.J.i])
      s_hash = hash(e.id) % 256 # hash string value itself
      buf.write("{}(new Object(hash={}), {}, 0, {})".format(str_init, s_hash, e.id, len(e.id)))
    else: buf.write(e.id)

  elif e.kind == C.E.UOP:
    buf.write(' '.join([e.op, curried(e.e)]))

  elif e.kind == C.E.BOP:
    buf.write(' '.join([curried(e.le), e.op, curried(e.re)]))

  elif e.kind == C.E.DOT:
    # with package names, e.g., javax.swing.SwingUtilities
    if util.is_class_name(e.re.id) and class_lookup(e.re.id):
      buf.write(curried(e.re))
    elif e.re.id == C.J.THIS: # ClassName.this
      buf.write(C.SK.self)
    else:
      rcv_ty = typ_of_e(mtd, e.le)
      fld = find_fld(rcv_ty, e.re.id)
      new_fname = trans_fname(rcv_ty, e.re.id, fld.is_static)
      if fld.is_static:
        # access to the static field inside the same class
        if mtd and rcv_ty == mtd.clazz.name: buf.write(e.re.id)
        # o.w., e.g., static constant in an interface, call the accessor
        else: buf.write(new_fname + "()")
      else: buf.write('.'.join([curried(e.le), new_fname]))

  elif e.kind == C.E.IDX:
    buf.write(curried(e.e) + '[' + curried(e.idx) + ']')

  elif e.kind == C.E.NEW:
    if e.e.kind == C.E.CALL:
      ty = typ_of_e(mtd, e.e.f)
      cls = class_lookup(ty)
      if cls and cls.has_init:
        arg_typs = map(partial(typ_of_e, mtd), e.e.a)
        mname = trans_mname(cls.name, cls.name, arg_typs)
        obj = "alloc@log({})".format(cls.id)
        args = [obj] + map(unicode, map(curried, e.e.a))
        buf.write("{}({})".format(mname, ", ".join(args)))
      else: # collection or Object
        buf.write(C.J.NEW + ' ' + trans_ty(ty) + "()")
    else: # o.w., array initialization, e.g., new int[] { ... }
      buf.write(str(e.init))

  elif e.kind == C.E.CALL:
    arg_typs = map(partial(typ_of_e, mtd), e.a)

    def trans_call(callee, rcv_ty, rcv):
      if callee.is_static: rcv = None
      logging = None
      if not util.is_collection(callee.clazz.name):
        logging = str(check_logging(mtd, callee)).lower()

      args = util.rm_none([rcv] + map(curried, e.a) + [logging])
      mid = trans_mname(rcv_ty, callee.name, arg_typs)
      return u"{}({})".format(mid, ", ".join(args))

    def dynamic_dispatch(rcv_ty, rcv, acc, callee):
      _dispatched = trans_call(callee, callee.clazz.name, rcv)
      _guarded = "{}.__cid == {} ? {}".format(rcv, callee.clazz.id, _dispatched)
      return "({} : {})".format(_guarded, acc)

    if e.f.kind == C.E.DOT: # rcv.mid
      rcv_ty = typ_of_e(mtd, e.f.le)
      rcv = curried(e.f.le)
      mname = e.f.re.id
      mtd_callees = find_mtds_by_sig(rcv_ty, mname, arg_typs)
      if mtd_callees and 1 < len(mtd_callees): # needs dynamic dispatch
        curried_dispatch = partial(dynamic_dispatch, rcv_ty, rcv)
        # TODO: use least upper bound?
        default_v = util.default_value(mtd_callees[0].typ)
        buf.write(reduce(curried_dispatch, mtd_callees, default_v))
      elif mtd_callees and 1 == len(mtd_callees):
        mtd_callee = mtd_callees[0]
        buf.write(trans_call(mtd_callee, rcv_ty, rcv))
      else: # unresolved, maybe library method
        mid = trans_mname(rcv_ty, mname, arg_typs)
        args = util.rm_none([rcv] + map(curried, e.a))
        buf.write("{}({})".format(mid, ", ".join(args)))

    else: # mid
      mname = e.f.id
      # pre-defined meta information or Sketch primitive functions
      if mname in C.typ_arrays + [u"minimize"]:
        mid = mname
        rcv = None
        args = util.rm_none([rcv] + map(curried, e.a))
        buf.write("{}({})".format(mid, ", ".join(args)))
      elif mname == C.J.SUP and mtd.is_init: # super(...) inside <init>
        sup = class_lookup(mtd.clazz.sup)
        mid = trans_mname(sup.name, sup.name, arg_typs)
        rcv = C.SK.self
        args = util.rm_none([rcv] + map(curried, e.a))
        buf.write("{}({})".format(mid, ", ".join(args)))
      else: # member methods
        mtd_callees = find_mtds_by_sig(mtd.clazz.name, mname, arg_typs)
        if mtd_callees and 1 < len(mtd_callees): # needs dynamic dispatch
          curried_dispatch = partial(dynamic_dispatch, mtd.clazz.name, C.SK.self)
          # TODO: use least upper bound?
          default_v = util.default_value(mtd_callees[0].typ)
          buf.write(reduce(curried_dispatch, mtd_callees, default_v))
        elif mtd_callees and 1 == len(mtd_callees):
          mtd_callee = mtd_callees[0]
          buf.write(trans_call(mtd_callee, mtd.clazz.name, C.SK.self))
        else: # unresolved, maybe library method
          mid = trans_mname(mtd.clazz.name, mname, arg_typs)
          args = util.rm_none([rcv] + map(curried, e.a))
          buf.write("{}({})".format(mid, ", ".join(args)))

  elif e.kind == C.E.CAST:
    # since a family of classes is merged, simply ignore the casting
    buf.write(curried(e.e))

  elif e.kind == C.E.INS_OF:
    ty = typ_of_e(mtd, e.ty)
    cls = class_lookup(ty)
    if cls:
      buf.write(curried(e.e) + ".__cid == " + str(cls.id))
    else:
      logging.debug("unknown type: {}".format(ty))
      buf.write("0")

  else: buf.write(str(e))
  return buf.getvalue()