/lang_php/analyze/foundation/builtins_typed_php.ml

https://github.com/facebook/pfff · OCaml · 392 lines · 267 code · 69 blank · 56 comment · 0 complexity · 2412b774b26bcd0e4993bea1ebe46334 MD5 · raw file

  1. (* Julien Verlaguet
  2. *
  3. * Copyright (C) 2011 Facebook
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public License
  7. * version 2.1 as published by the Free Software Foundation, with the
  8. * special exception on linking described in file license.txt.
  9. *
  10. * This library is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
  13. * license.txt for more details.
  14. *)
  15. open Env_typing_php
  16. module Env = Env_typing_php
  17. module GEnv = Typing_helpers_php.GEnv
  18. (*****************************************************************************)
  19. (* Prelude *)
  20. (*****************************************************************************)
  21. (*****************************************************************************)
  22. (* Helpers *)
  23. (*****************************************************************************)
  24. let or_ l =
  25. let l = List.sort (fun x y -> Env.proj x - Env.proj y) l in
  26. Tsum l
  27. (*****************************************************************************)
  28. (* Types *)
  29. (*****************************************************************************)
  30. (*-------------------------------------------------------------------*)
  31. (* Core *)
  32. (*-------------------------------------------------------------------*)
  33. let id =
  34. let v = Tvar (fresh()) in
  35. fun_ [v] v
  36. (*-------------------------------------------------------------------*)
  37. (* Arrays *)
  38. (*-------------------------------------------------------------------*)
  39. let array_fill =
  40. let v = Tvar (fresh()) in
  41. fun_ [int; int; v] (array (int, v))
  42. let array_merge =
  43. let v = array (Tvar (fresh()), Tvar (fresh())) in
  44. fun_ [v;v;v;v;v;v;v;v;v;v;v;v;v] v
  45. (*-------------------------------------------------------------------*)
  46. (* String, regexps *)
  47. (*-------------------------------------------------------------------*)
  48. let preg_match =
  49. fun_ [string; string; array (int, string); int; int] int
  50. let strpos =
  51. fun_ [string; string; int] (or_ [pint; pstring])
  52. (*-------------------------------------------------------------------*)
  53. (* Misc *)
  54. (*-------------------------------------------------------------------*)
  55. let implode =
  56. fun_ [string; array (any, string)] string
  57. let preg_replace =
  58. fun_ [string; string; string; int; int] string
  59. let array_change_key_case =
  60. let v = Tvar (fresh()) in
  61. let ien = SSet.add "CASE_UPPER" (SSet.add "CASE_LOWER" SSet.empty) in
  62. let ien = Tsum [Tienum ien] in
  63. fun_ [array (string, v); ien] (array (string, v))
  64. let array_chunk =
  65. let v = Tvar (fresh()) in
  66. fun_ [array (int, v); int; bool] (array (int, array(int, v)))
  67. let array_combine =
  68. let k = Tvar (fresh()) in
  69. let v = Tvar (fresh()) in
  70. fun_ [k; v] (array (k, v))
  71. let array_count_values =
  72. let v = Tvar (fresh()) in
  73. fun_ [array (int, v)] (array (v, int))
  74. let array_fill_keys =
  75. let v = Tvar (fresh()) in
  76. let x = Tvar (fresh()) in
  77. fun_ [array (int, v); x] (array (v, x))
  78. let array_filter =
  79. let k = Tvar (fresh()) in
  80. let v = Tvar (fresh()) in
  81. fun_ [array (k, v); any] (array (k, v))
  82. let array_flip =
  83. let k = Tvar (fresh()) in
  84. let v = Tvar (fresh()) in
  85. fun_ [array (k, v)] (array (v, k))
  86. let array_key_exists =
  87. let k = Tvar (fresh()) in
  88. let v = Tvar (fresh()) in
  89. fun_ [k; array (k, v)] bool
  90. let array_keys =
  91. let k = Tvar (fresh()) in
  92. let v = Tvar (fresh()) in
  93. fun_ [array (k, v); v; bool] (array (int, k))
  94. let array_map =
  95. let k = Tvar (fresh()) in
  96. fun_ [any; array (k, any)] (array (k, any))
  97. let array_merge_recursive =
  98. let k = Tvar (fresh()) in
  99. let v = Tvar (fresh()) in
  100. let x = array (k, v) in
  101. fun_ [x;x;x;x;x;x;x;x;x;x;x;x] x
  102. let array_multisort = id
  103. let array_pad =
  104. let k = Tvar (fresh()) in
  105. let v = Tvar (fresh()) in
  106. fun_ [array(k, v); int; v] (array(k, v))
  107. let array_pop =
  108. let v = Tvar (fresh()) in
  109. fun_ [array (int, v)] v
  110. let array_product =
  111. fun_ [array (int, int)] int
  112. let array_push =
  113. let v = Tvar (fresh()) in
  114. fun_ [array (int, v)] (array (int, v))
  115. let array_rand =
  116. let v = Tvar (fresh()) in
  117. fun_ [array (int, v); int] v
  118. let array_reduce =
  119. let v = Tvar (fresh()) in
  120. fun_ [array (int, v); any; v] v
  121. let array_reverse =
  122. let v = Tvar (fresh()) in
  123. fun_ [array (int, v)] (array (int, v))
  124. let array_search =
  125. let k = Tvar (fresh()) in
  126. let v = Tvar (fresh()) in
  127. fun_ [array (k, v); v; bool] k
  128. let array_shift =
  129. let v = Tvar (fresh()) in
  130. fun_ [array (int, v)] (array (int, v))
  131. let array_slice =
  132. let v = Tvar (fresh()) in
  133. fun_ [array (int, v); int; int] (array (int, v))
  134. let array_splice =
  135. let v = Tvar (fresh()) in
  136. fun_ [array (int, v); int; int; v] (array (int, v))
  137. let array_sum =
  138. let v = Tvar (fresh()) in
  139. fun_ [array (int, v)] v
  140. let array_unique =
  141. let k = Tvar (fresh()) in
  142. let v = Tvar (fresh()) in
  143. let x = array (k, v) in
  144. fun_ [x] x
  145. let array_unshift =
  146. let v = Tvar (fresh()) in
  147. fun_ [array (int, v);v;v;v;v;v;v;v;v;v;v;v] v
  148. let array_values =
  149. let v = Tvar (fresh()) in
  150. fun_ [array (any, v)] (array (int, v))
  151. let array_walk_recursive =
  152. let k = Tvar (fresh()) in
  153. fun_ [array (k, any); any; any] (array (k, any))
  154. let array_walk = array_walk_recursive
  155. let array_shuffle =
  156. let v = Tvar (fresh()) in
  157. let x = (array (int, v)) in
  158. fun_ [x] x
  159. let current =
  160. let v = Tvar (fresh()) in
  161. fun_ [array (any, v)] v
  162. let next =
  163. fun_ [array (any, any)] null
  164. let pos = current
  165. let prev = next
  166. let reset = next
  167. let end_ = next
  168. let in_array =
  169. let v = Tvar (fresh()) in
  170. fun_ [array (any, v)] bool
  171. let key =
  172. let k = Tvar (fresh()) in
  173. fun_ [array (k, any)] k
  174. let range =
  175. let v = Tvar (fresh()) in
  176. fun_ [v; v; v] (array (int, v))
  177. let array_diff =
  178. let k = Tvar (fresh()) in
  179. let v = Tvar (fresh()) in
  180. let x = array (k, v) in
  181. fun_ [x;x] x
  182. let sort =
  183. let v = Tvar (fresh()) in
  184. fun_ [array (int, v); int; bool] (array (int, v))
  185. let list =
  186. let v = Tvar (fresh()) in
  187. let a = array (int, v) in
  188. fun_ [a;a;a;a;a;a;a;a;a] any
  189. (*****************************************************************************)
  190. (* Misc *)
  191. (*****************************************************************************)
  192. let super_globals =
  193. let h = Hashtbl.create 23 in
  194. let add x = Hashtbl.add h x true in
  195. add "$GLOBALS";
  196. add "$_SERVER";
  197. add "$_GET";
  198. add "$_POST";
  199. add "$_FILES";
  200. add "$_COOKIE";
  201. add "$_SESSION";
  202. add "$_REQUEST";
  203. add "$_ENV";
  204. h
  205. (*****************************************************************************)
  206. (* Main entry point *)
  207. (*****************************************************************************)
  208. let make env =
  209. let add x y =
  210. env.builtins := SSet.add ("^Fun:"^x) !(env.builtins);
  211. GEnv.set_fun env x y
  212. in
  213. (*-------------------------------------------------------------------*)
  214. (* Types *)
  215. (*-------------------------------------------------------------------*)
  216. add "int" int;
  217. add "bool" bool;
  218. add "float" float;
  219. add "string" string;
  220. add "u" (fun_ [string] string);
  221. add "null" null;
  222. (*-------------------------------------------------------------------*)
  223. (* Core *)
  224. (*-------------------------------------------------------------------*)
  225. add "isset" (fun_ [any] bool);
  226. add "count" (fun_ [any] int);
  227. add "sizeof" (fun_ [any] int);
  228. add "id" id;
  229. (*-------------------------------------------------------------------*)
  230. (* Arrays *)
  231. (*-------------------------------------------------------------------*)
  232. add "array_fill" array_fill;
  233. (*-------------------------------------------------------------------*)
  234. (* Strings *)
  235. (*-------------------------------------------------------------------*)
  236. add "sprintf" (fun_ [string] string);
  237. add "substr" (fun_ [string; int; int] string);
  238. add "intval" (fun_ [any] int);
  239. add "starts_with" (fun_ [string;string] bool);
  240. add "ends_with" (fun_ [string;string] bool);
  241. (*-------------------------------------------------------------------*)
  242. (* Misc *)
  243. (*-------------------------------------------------------------------*)
  244. add "array_merge" array_merge;
  245. add "preg_match" preg_match;
  246. add "preg_replace" preg_replace;
  247. add "strpos" strpos;
  248. add "time" (fun_ [] int);
  249. add "array_keys" array_keys;
  250. add "implode" implode;
  251. add "empty" (fun_ [any] bool);
  252. add "unset" (fun_ [any] null);
  253. add "trim" (fun_ [string; string] string);
  254. add "get_class" (fun_ [any] string);
  255. add "str_replace" (fun_ [string; string; string] string);
  256. add "strlen" (fun_ [string] int);
  257. add "is_array" (fun_ [array (any, any)] bool);
  258. add "is_string" (fun_ [string] bool);
  259. add "is_bool" (fun_ [bool] bool);
  260. add "is_int" (fun_ [int] int);
  261. add "is_float" (fun_ [float] bool);
  262. add "is_scalar" (fun_ [or_ [pint;pfloat;pbool]] bool);
  263. add "is_object" (fun_ [Tsum [Tobject (SMap.empty)]] bool);
  264. add "is_numeric" (fun_ [or_ [pint;pfloat]] bool);
  265. add "array_change_key_case" array_change_key_case;
  266. add "array_chunk" array_chunk;
  267. add "array_combine" array_combine;
  268. add "array_count_values" array_count_values;
  269. add "array_fill_keys" array_fill_keys;
  270. add "array_filter" array_filter;
  271. add "array_flip" array_flip;
  272. add "array_key_exists" array_key_exists;
  273. add "array_keys" array_keys;
  274. add "array_map" array_map;
  275. add "array_merge_recursive" array_merge_recursive;
  276. add "array_multisort" array_multisort;
  277. add "array_pad" array_pad;
  278. add "array_pop" array_pop;
  279. add "array_product" array_product;
  280. add "array_push" array_push;
  281. add "array_rand" array_rand;
  282. add "array_reduce" array_reduce;
  283. add "array_reverse" array_reverse;
  284. add "array_search" array_search;
  285. add "array_shift" array_shift;
  286. add "array_slice" array_slice;
  287. add "array_splice" array_splice;
  288. add "array_sum" array_sum;
  289. add "array_unique" array_unique;
  290. add "array_unshift" array_unshift;
  291. add "array_values" array_values;
  292. add "array_walk_recursive" array_walk_recursive;
  293. add "array_walk" array_walk;
  294. add "array_shuffle" array_shuffle;
  295. add "current" current;
  296. add "next" next;
  297. add "pos" pos;
  298. add "prev" prev;
  299. add "reset" reset;
  300. add "end" end_;
  301. add "in_array" in_array;
  302. add "key" key;
  303. add "range" range;
  304. add "array_diff" array_diff;
  305. add "explode" (fun_ [string; string; int] (array (int, string)));
  306. add "max" (fun_ [] any);
  307. add "chr" (fun_ [int] string);
  308. add "strtoupper" (fun_ [string] string);
  309. add "floor" (fun_ [float] int);
  310. add "strtotime" (fun_ [string; int] int);
  311. add "microtime" (fun_ [bool] (or_ [pint; pfloat]));
  312. add "echo" (fun_ [string] null);
  313. add "exit" (fun_ [int] null);
  314. add "print" (fun_ [string] null);
  315. add "json_encode" (fun_ [string] string);
  316. add "date" (fun_ [string; int] string);
  317. add "strftime" (fun_ [string; int] string);
  318. add "sort" sort;
  319. add "round" (fun_ [float] int);
  320. add "join" implode;
  321. add "htmlize" (fun_ [thtml] string);
  322. add "txt2html" (fun_ [thtml; bool] string);
  323. add "list" list;