Permalink
Browse files

Do not emit self in default parameter values for static property acce…

…sses

Summary:
as in title
- use existing logic to resolve class from `ast_class_expr`
- share code for printing class constants and static property accesses

Reviewed By: oulgen

Differential Revision: D6830266

fbshipit-source-id: 1d3aa68e102d8626f8ac434910988e3ee0d87319
  • Loading branch information...
vladima authored and hhvm-bot committed Jan 28, 2018
1 parent 975060a commit 8b2df328015a05101869adbc6e5b4f9879b0dfbd
Showing with 41 additions and 41 deletions.
  1. +7 −7 hphp/hack/src/hhbc/ast_class_expr.ml
  2. +34 −34 hphp/hack/src/hhbc/hhbc_hhas.ml
@@ -21,11 +21,11 @@ type class_expr =
| Class_expr of Ast.expr
| Class_unnamed_local of Local.t
let get_original_class_name ~resolve_self scope =
let get_original_class_name ~resolve_self ~check_traits scope =
match Ast_scope.Scope.get_class scope with
| None -> None
| Some cd ->
if cd.Ast.c_kind = Ast.Ctrait || not resolve_self
if (cd.Ast.c_kind = Ast.Ctrait && not check_traits) || not resolve_self
then None
else
let class_name = snd cd.Ast.c_name in
@@ -44,11 +44,11 @@ let get_parent_class_name cd =
| [(_, A.Happly((_, parent_cid), _))] -> Some parent_cid
| _ -> None
let get_original_parent_class_name ~resolve_self scope =
let get_original_parent_class_name ~check_traits ~resolve_self scope =
match Ast_scope.Scope.get_class scope with
| None -> None
| Some cd ->
if cd.Ast.c_kind = Ast.Ctrait || not resolve_self
if (cd.Ast.c_kind = Ast.Ctrait && not check_traits) || not resolve_self
then None
else
let class_name = snd cd.Ast.c_name in
@@ -59,16 +59,16 @@ let get_original_parent_class_name ~resolve_self scope =
| None -> get_parent_class_name cd
(* Return true in second component if this is a forwarding reference *)
let expr_to_class_expr ~resolve_self scope (_, expr_ as expr) =
let expr_to_class_expr ?(check_traits=false) ~resolve_self scope (_, expr_ as expr) =
match expr_ with
| A.Id (_, id) when SU.is_static id -> Class_static
| A.Id (pos, id) when SU.is_parent id ->
begin match get_original_parent_class_name ~resolve_self scope with
begin match get_original_parent_class_name ~resolve_self ~check_traits scope with
| Some name -> Class_id (pos, name)
| None -> Class_parent
end
| A.Id (pos, id) when SU.is_self id ->
begin match get_original_class_name ~resolve_self scope with
begin match get_original_class_name ~resolve_self ~check_traits scope with
| Some name -> Class_id (pos, name)
| None -> Class_self
end
@@ -1027,8 +1027,35 @@ and string_of_param_default_value ?(use_single_quote=false) ~env expr =
let e2 = string_of_param_default_value ~env e2 in
e1 ^ s ^ e2
in
let fmt_class_name cn =
"\\\\" ^ (Php_escaping.escape (SU.strip_global_ns cn)) in
let fmt_class_name ~is_class_constant cn =
let cn = (Php_escaping.escape (SU.strip_global_ns cn)) in
if is_class_constant then "\\\\" ^ cn else cn in
let get_special_class_name ~is_class_constant ~env id =
let scope = match env with
| None -> Ast_scope.Scope.toplevel
| Some env -> Emit_env.get_scope env in
let module ACE = Ast_class_expr in
let e =
let p0 = Pos.none in
(p0, (A.Id (p0, id))) in
match ACE.expr_to_class_expr ~check_traits:true ~resolve_self:true scope e with
| ACE.Class_id (_, name) -> fmt_class_name ~is_class_constant name
| _ -> id
in
let get_class_name_from_id ~is_class_constant ~env id =
if id = SN.Classes.cSelf || id = SN.Classes.cParent || id = SN.Classes.cStatic
then get_special_class_name ~env ~is_class_constant id
else
let id =
match env with
| Some env ->
Hhbc_id.Class.to_raw_string @@ fst @@
Hhbc_id.Class.elaborate_id
(Emit_env.get_namespace env) (p, SU.strip_global_ns id)
| _ -> id
in
fmt_class_name ~is_class_constant id
in
let escape_char_for_printing = function
| '\\' | '$' | '"' -> "\\\\"
| '\n' | '\r' | '\t' -> "\\"
@@ -1105,44 +1132,17 @@ and string_of_param_default_value ?(use_single_quote=false) ~env expr =
^ "("
^ String.concat ", " es
^ ")"
| A.Class_get ((_, A.Id (_, s1)), e2)
when s1 = SN.Classes.cSelf ||
s1 = SN.Classes.cParent ||
s1 = SN.Classes.cStatic ->
let s2 = string_of_param_default_value ~env e2 in
s1 ^ "::" ^ s2
| A.Class_get ((_, A.Id (_, s1)), e2) ->
let s1 = get_class_name_from_id ~env ~is_class_constant:false s1 in
let s2 = string_of_param_default_value ~env e2 in
fmt_class_name s1 ^ "::" ^ s2
s1 ^ "::" ^ s2
| A.Class_get (e1, e2) ->
let s1 = string_of_param_default_value ~env e1 in
let s2 = string_of_param_default_value ~env e2 in
s1 ^ "::" ^ s2
| A.Class_const ((_, A.Id (_, s1)), (_, s2))
when s1 = SN.Classes.cSelf ||
s1 = SN.Classes.cParent ||
s1 = SN.Classes.cStatic ->
let scope = match env with
| None -> Ast_scope.Scope.toplevel
| Some env -> Emit_env.get_scope env in
let s1 = match Ast_scope.Scope.get_class scope with
| Some cd when s1 = SN.Classes.cSelf -> snd cd.A.c_name
| Some cd when s1 = SN.Classes.cParent ->
begin match cd.A.c_extends with
| [(_, A.Happly((_, parent_cid), _))] -> parent_cid
| _ -> s1
end
| _ -> s1 in
fmt_class_name s1 ^ "::" ^ s2
| A.Class_const ((_, A.Id (p, s1)), (_, s2)) ->
let s1 = match env with
| Some env ->
Hhbc_id.Class.to_raw_string @@ fst @@
Hhbc_id.Class.elaborate_id
(Emit_env.get_namespace env) (p, SU.strip_global_ns s1)
| _ -> s1
in
fmt_class_name s1 ^ "::" ^ s2
| A.Class_const ((_, A.Id (_, s1)), (_, s2)) ->
let s1 = get_class_name_from_id ~env ~is_class_constant:true s1 in
s1 ^ "::" ^ s2
| A.Class_const (e1, (_, s2)) ->
let s1 = string_of_param_default_value ~env e1 in
s1 ^ "::" ^ s2

0 comments on commit 8b2df32

Please sign in to comment.