Permalink
Browse files

Fix case insensitivity of PHP keywords

Summary:
This changes all PHP keywords + a few Hack ones to be case insensitive.

Words like "dynamic" and "mixed" which are only valid keywords in PHP will mostly stay case sensitive(I changed a few of them anyway before I decided it was too annoying), but PHP builtins will be case insensitive after this diff.

Fixes #8194

Reviewed By: oulgen

Differential Revision: D7958203
  • Loading branch information...
jamesjwu authored and fredemmott committed May 11, 2018
1 parent 6272f66 commit 27854f21176054bf83b437c5f295b804326d2b82
Showing with 31 additions and 170 deletions.
  1. +13 −9 hphp/hack/src/hhbc/emit_expression.ml
  2. +2 −1 hphp/hack/src/hhbc/emit_statement.ml
  3. +1 −1 hphp/hack/src/hhbc/emit_type_hint.ml
  4. +1 −1 hphp/hack/src/hhbc/hhbc_id.ml
  5. +11 −6 hphp/hack/src/parser/full_fidelity_lexer.ml
  6. +0 −16 hphp/test/hhcodegen_failing_tests_slow
  7. +0 −2 hphp/test/slow/parser/keyword_case/basic.php.skipif
  8. +0 −2 hphp/test/slow/parser/keyword_case/class.php.skipif
  9. +0 −2 hphp/test/slow/parser/keyword_case/control_flow.php.skipif
  10. +0 −2 hphp/test/slow/parser/keyword_case/eval.php.skipif
  11. +0 −2 hphp/test/slow/parser/keyword_case/exception.php.skipif
  12. +0 −12 hphp/test/slow/parser/keyword_case/hack_async_await.php
  13. +0 −2 hphp/test/slow/parser/keyword_case/hack_async_await.php.skipif
  14. +0 −18 hphp/test/slow/parser/keyword_case/hack_containers.php
  15. +0 −30 hphp/test/slow/parser/keyword_case/hack_containers.php.expect
  16. +0 −2 hphp/test/slow/parser/keyword_case/hack_containers.php.skipif
  17. +3 −3 hphp/test/slow/parser/keyword_case/hack_generics.php
  18. +0 −2 hphp/test/slow/parser/keyword_case/hack_generics.php.skipif
  19. +0 −2 hphp/test/slow/parser/keyword_case/hack_inout.php.skipif
  20. +0 −2 hphp/test/slow/parser/keyword_case/hack_type_newtype.php.skipif
  21. +0 −2 hphp/test/slow/parser/keyword_case/hack_using.php.skipif
  22. +0 −13 hphp/test/slow/parser/keyword_case/hack_xhp.php
  23. +0 −1 hphp/test/slow/parser/keyword_case/hack_xhp.php.expect
  24. +0 −2 hphp/test/slow/parser/keyword_case/hack_xhp.php.skipif
  25. +0 −2 hphp/test/slow/parser/keyword_case/include.php.skipif
  26. +0 −2 hphp/test/slow/parser/keyword_case/misc.php.skipif
  27. +0 −2 hphp/test/slow/parser/keyword_case/namespace.php.skipif
  28. +0 −2 hphp/test/slow/parser/keyword_case/old_ends.php.skipif
  29. +0 −27 hphp/test/zend/good/Zend/tests/is_a.php
@@ -266,7 +266,7 @@ let is_special_function env e args =
| A.Id (_, s) ->
begin
let n = List.length args in
match s with
match String.lowercase_ascii s with
| "isset" -> n > 0
| "empty" -> n = 1
| "define" when is_global_namespace env ->
@@ -1657,25 +1657,29 @@ and emit_expr env ?last_pos ?(need_ref=false) (pos, expr_ as expr) =
| A.Obj_get (expr, prop, nullflavor) ->
let query_op = if need_ref then QueryOp.Empty else QueryOp.CGet in
emit_obj_get ~need_ref env pos None query_op expr prop nullflavor
| A.Call ((_, A.Id (_, "isset")), _, exprs, []) ->
| A.Call ((_, A.Id (_, id)), _, exprs, [])
when String.lowercase_ascii id = "isset" ->
emit_box_if_necessary pos need_ref @@ emit_call_isset_exprs env pos exprs
| A.Call ((_, A.Id (_, "empty")), _, [expr], []) ->
| A.Call ((_, A.Id (_, id)), _, [expr], [])
when String.lowercase_ascii id = "empty" ->
emit_box_if_necessary pos need_ref @@ emit_call_empty_expr env pos expr
| A.Call ((_, A.Id (_, "idx")), _, ([_; _] | [_; _; _] as es), _)
when not (jit_enable_rename_function ()) ->
| A.Call ((_, A.Id (_, id)), _, ([_; _] | [_; _; _] as es), _)
when String.lowercase_ascii id = "idx" && not (jit_enable_rename_function ()) ->
emit_box_if_necessary pos need_ref @@ emit_idx env pos es
| A.Call ((_, A.Id (_, "define")), _, [(_, A.String (_, s)); e], _)
when is_global_namespace env ->
| A.Call ((_, A.Id (_, id)), _, [(_, A.String (_, s)); e], _)
when String.lowercase_ascii id = "define" && is_global_namespace env ->
emit_box_if_necessary pos need_ref @@ emit_define env pos s e
| A.Call ((_, A.Id (_, "eval")), _, [expr], _) ->
| A.Call ((_, A.Id (_, id)), _, [expr], _) when String.lowercase_ascii id = "eval" ->
emit_box_if_necessary pos need_ref @@ emit_eval env pos expr
| A.Call ((_, A.Id (_, "class_alias")), _, es, _)
when is_global_namespace env ->
emit_pos_then pos @@
emit_box_if_necessary pos need_ref @@ emit_class_alias es
| A.Call ((_, A.Id (_, "get_class")), _, [], _) ->
emit_box_if_necessary pos need_ref @@ emit_get_class_no_args ()
| A.Call ((_, A.Id (_, ("exit" | "die"))), _, es, _) ->
| A.Call ((_, A.Id (_, s)), _, es, _)
when (String.lowercase_ascii s = "exit" || String.lowercase_ascii s = "die") ->
emit_pos_then pos @@
emit_exit env (List.hd es)
| A.Call _
@@ -131,7 +131,8 @@ let rec emit_stmt env (pos, st_) =
instr_null;
emit_return ~need_ref:false env;
]
| A.Expr (_, A.Call ((_, A.Id (_, "unset")), _, exprl, [])) ->
| A.Expr (_, A.Call ((_, A.Id (_, s)), _, exprl, []))
when String.lowercase_ascii s = "unset" ->
gather (List.map exprl (emit_unset_expr env))
| A.Return (Some (inner_pos, A.Await e)) ->
gather [
@@ -109,7 +109,7 @@ let rec hint_to_type_constraint
then TC.make None []
else TC.make (Some "mixed") []
| A.Happly ((_, "void"), []) when kind <> TypeDef ->
| A.Happly ((_, s), []) when String.lowercase_ascii s = "void" && kind <> TypeDef ->
if Emit_env.is_hh_syntax_enabled ()
|| Hhbc_options.php7_scalar_types !Hhbc_options.compiler_options
then TC.make None []
@@ -207,7 +207,7 @@ module Function = struct
| Some id ->
if List.mem builtins_in_hh id && (Emit_env.is_hh_syntax_enabled ())
then SU.prefix_namespace "HH" id, Some id
else if List.mem builtins_at_top id
else if List.mem builtins_at_top (String.lowercase_ascii id)
then id, None
else fq_id, backoff_id
(* Likewise for top-level, with no namespace *)
@@ -1390,12 +1390,17 @@ let as_case_insensitive_keyword text =
non-lower versions in our codebase. *)
let lower = String.lowercase_ascii text in
match lower with
| "eval" | "isset" | "unset" | "empty" | "const" | "new"
| "and" | "or" | "xor" | "as" | "print" | "throw"
| "true" | "false" | "null" | "array" | "instanceof"
| "trait" | "class" | "interface" | "using" | "static" | "inout"
| "self" | "parent" | "__halt_compiler" | "foreach" | "echo"
| "abstract" | "final" -> lower
| "__halt_compiler" | "abstract" | "and" | "array" | "as" | "bool" | "break" | "callable"
| "case" | "catch" | "class" | "clone" | "const" | "continue" | "declare" | "default"
| "die" | "do" | "echo" | "else" | "elseif" | "empty" | "enddeclare" | "endfor"
| "endforeach" | "endif" | "endswitch" | "endwhile" | "eval" | "exit" | "extends" | "false"
| "final" | "finally" | "for" | "foreach" | "function" | "global" | "goto" | "if"
| "implements" | "include" | "include_once" | "inout" | "instanceof"
| "insteadof" | "int" | "interface" | "isset" | "list" | "namespace" | "new" | "newtype"
| "null" | "or" | "parent" | "print" | "private" | "protected" | "public" | "require"
| "require_once" | "return" | "self" | "static" | "switch" | "throw" | "trait"
| "try" | "true" | "type" | "unset" | "use" | "using" | "var" | "void" | "while"
| "xor" | "yield" -> lower
| _ -> text
let as_keyword kind lexer =
@@ -1,18 +1,2 @@
slow/parser/keyword_case/basic.php
slow/parser/keyword_case/class.php
slow/parser/keyword_case/control_flow.php
slow/parser/keyword_case/eval.php
slow/parser/keyword_case/exception.php
slow/parser/keyword_case/hack_async_await.php
slow/parser/keyword_case/hack_containers.php
slow/parser/keyword_case/hack_generics.php
slow/parser/keyword_case/hack_inout.php
slow/parser/keyword_case/hack_type_newtype.php
slow/parser/keyword_case/hack_using.php
slow/parser/keyword_case/hack_xhp.php
slow/parser/keyword_case/include.php
slow/parser/keyword_case/misc.php
slow/parser/keyword_case/namespace.php
slow/parser/keyword_case/old_ends.php
slow/php7_backported/array_destructuring.php
slow/php7_backported/array_destructuring_byref.php

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.
@@ -1,10 +1,10 @@
<?hh
FUNCTION FOO<T1 AS INT, T2 SUPER T1, PROHIBITED>(
// where, super are hack specific and case sensitive
FUNCTION FOO<T1 AS INT, T2 super T1, PROHIBITED>(
T1 $_a,
T2 $_b,
PROHIBITED $_c
): VOID WHERE PROHIBITED = T1 {
): VOID where PROHIBITED = T1 {
ECHO "NO CASH VALUE\n";
}

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

0 comments on commit 27854f2

Please sign in to comment.