Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 8f77608a17
Fetching contributors…

Cannot retrieve contributors at this time

234 lines (209 sloc) 7.196 kb
<?php
// The goal of this script is to generate PHP files containing
// the definitions of PHP builtins functions, classes and constants.
// One can use the HipHop IDL files which contains in a nice format
// most of those builtins.
// See https://github.com/facebook/hiphop-php/tree/master/src/idl
//
// Given an HipHop idl file like:
// foo.idl.php:
// <?php
// ...
// DefineConstant(
// array(
// 'name' => "INF",
// 'type' => Double,
// ));
// ...
//
// we want to generate this php file:
// builtins_foo.php:
// <?php
// define('INF', 0);
//
// Given those builtin files it's then easier for some external static analysis
// tools like pfff to not report false positives such as
// "error, undeclared constant:INF" by knowing the set of all
// PHP builtins.
// The constants below are copy pasted from hphp/idl/base.php. This file
// defines the DefineFunction(), DefineConstants(), etc that I "override"
// below. If I include base.php I can not redefine them (I could with our
// testinfra helpers functions but then it would make this dependent on
// www, and hphp, which is not not worth the trouble.
define('Boolean', 1);
define('Int32', 4);
define('Int64', 5);
define('Double', 6);
define('String', 7);
define('Int64Vec', 8);
define('StringVec', 9);
define('VariantVec', 10);
define('Int64Map', 11);
define('StringMap', 12);
define('VariantMap', 13);
define('Object', 14);
define('Resource', 15);
define('Variant', 16);
define('Numeric', 17);
define('Primitive', 18);
define('PlusOperand', 19);
define('Sequence', 20);
define('Any', 21);
define('TypeMask', 0x00FF);
define('Reference', 0x0100);
define('IsAbstract', 1 << 4);
define('IsFinal', 1 << 5);
define('IsPublic', 1 << 6);
define('IsProtected', 1 << 7);
define('IsPrivate', 1 << 8);
define('IsStatic', 1 << 9);
define('HasDocComment', 1 << 14);
define('HipHopSpecific', 1 << 16);
define('VariableArguments', 1 << 17);
define('RefVariableArguments', 1 << 18);
define('MixedVariableArguments', 1 << 19);
define('FunctionIsFoldable', 1 << 20);
define('NoEffect', 1 << 21);
define('NoInjection', 1 << 22);
define('HasOptFunction', 1 << 23);
define('AllowIntercept', 1 << 24);
define('NoProfile', 1 << 25);
define('ContextSensitive', 1 << 26);
define('NoDefaultSweep', 1 << 27);
define('VarArgsMask', (VariableArguments | RefVariableArguments |
MixedVariableArguments));
$builtins_do_not_give_decl =
array("die","eval","exit","__halt_compiler","echo", "print");
echo "<?php\n";
echo "// THIS IS AUTOGENERATED BY builtins_php.ml\n";
$is_in_class = false;
///////////////////////////////////////////////////////////////////////////////
// Constants
//
// array (
// 'name' => name of the constant
// 'type' => type of the constant
// 'note' => additional note about this constant's schema
// )
function DefineConstant($arr) {
global $is_in_class;
// don't really care about the value for static analysis purposes,
// and certain constants have no values in the HipHop IDL files so just
// put '0' here
if ($is_in_class) {
echo "const " . $arr['name'] . " = 0;\n";
} else {
echo "define('" . $arr['name'] . "', 0);\n";
}
}
///////////////////////////////////////////////////////////////////////////////
// Functions
//
// array (
// 'name' => name of the function
// 'desc' => description of the function's purpose
// 'flags' => attributes of the function, see base.php for possible values
// 'opt' => optimization callback function's name for compiler
// 'note' => additional note about this function's schema
// 'return' =>
// array (
// 'type' => return type, use Reference for ref return
// 'desc' => description of the return value
// )
// 'args' => arguments
// array (
// 'name' => name of the argument
// 'type' => type of the argument, use Reference for output parameter
// 'value' => default value of the argument
// 'desc' => description of the argument
// )
// )
function DefineFunction($arr) {
global $is_in_class;
global $builtins_do_not_give_decl;
if (in_array($arr['name'], $builtins_do_not_give_decl)) {
} else {
// TODO the return type? does hphp allow type hint on return?
// TODO use flags?
$args = array();
$args_str = "";
if(isset($arr['args'])) {
foreach($arr['args'] as $arg) {
$ref_str =
($arg['type'] & Reference) ? "&" : "";
$val_str = "";
if (isset($arg['value'])) {
$v = $arg['value'];
// certain default values are not allowed in PHP land
if ($v === "TimeStamp::Current()" ||
preg_match('/.*\|.*/', $v) ||
false) {
$val_str = " = null /* $v */";
} else {
$val_str = " = $v";
}
}
$args[] = $ref_str . '$' . $arg['name'] . $val_str;
}
$args_str=implode(", ", $args);
}
$body_str = "";
if(isset($arr['flags']) && (
($arr['flags'] & VariableArguments) ||
($arr['flags'] & MixedVariableArguments)
)) {
$body_str = "func_get_args();";
}
echo ($is_in_class ? " " : "") .
"function " . $arr['name'] . "($args_str) { $body_str}\n";
}
}
///////////////////////////////////////////////////////////////////////////////
// Classes
//
// BeginClass
// array (
// 'name' => name of the class
// 'desc' => description of the class's purpose
// 'flags' => attributes of the class, see base.php for possible values
// 'note' => additional note about this class's schema
// 'parent' => parent class name, if any
// 'ifaces' => array of interfaces this class implements
// 'bases' => extra internal and special base classes this class requires
// 'footer' => extra C++ inserted at end of class declaration
// )
//
// DefineConstant(..)
// DefineConstant(..)
// ...
// DefineFunction(..)
// DefineFunction(..)
// ...
// DefineProperty
// DefineProperty
//
// array (
// 'name' => name of the property
// 'type' => type of the property
// 'flags' => attributes of the property
// 'desc' => description of the property
// 'note' => additional note about this property's schema
// )
//
// EndClass()
function BeginClass($arr) {
global $is_in_class;
$is_in_class = true;
// TODO get the extends/implements too
echo "class " . $arr['name'] . " {\n";
// the methods will be processed by DefineFunction() above
}
function EndClass() {
global $is_in_class;
$is_in_class = false;
echo "}\n";
}
function DefinePreamble() {
}
// use: php -f gen_builtins_php.php /path/to/foo.idl.php > builtins_foo.php
require_once($argv[1]);
Jump to Line
Something went wrong with that request. Please try again.