summaryrefslogtreecommitdiff
path: root/build/gen_stub.php
diff options
context:
space:
mode:
authorMáté Kocsis <kocsismate@woohoolabs.com>2020-04-06 11:02:13 +0200
committerMáté Kocsis <kocsismate@woohoolabs.com>2020-04-08 18:37:51 +0200
commit3709e74b5e495e210ada8039ed81fafa9cbadcdb (patch)
treeb7347572b1e22a2a27a45260b4f4773bf916b158 /build/gen_stub.php
parentb0d8f012f95ba1f2d8dba238c93baf3afb73b78e (diff)
downloadphp-git-3709e74b5e495e210ada8039ed81fafa9cbadcdb.tar.gz
Store default parameter values of internal functions in arg info
Closes GH-5353. From now on, PHP will have reflection information about default values of parameters of internal functions. Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
Diffstat (limited to 'build/gen_stub.php')
-rwxr-xr-xbuild/gen_stub.php65
1 files changed, 50 insertions, 15 deletions
diff --git a/build/gen_stub.php b/build/gen_stub.php
index fd8caffaf6..cfd1d42e36 100755
--- a/build/gen_stub.php
+++ b/build/gen_stub.php
@@ -4,7 +4,10 @@
use PhpParser\Comment\Doc as DocComment;
use PhpParser\Node;
use PhpParser\Node\Expr;
+use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
+use PhpParser\PrettyPrinter\Standard;
+use PhpParser\PrettyPrinterAbstract;
error_reporting(E_ALL);
@@ -15,6 +18,13 @@ try {
exit(1);
}
+class CustomPrettyPrinter extends Standard
+{
+ protected function pName_FullyQualified(Name\FullyQualified $node) {
+ return implode('\\', $node->parts);
+ }
+}
+
if ($argc >= 2) {
if (is_file($argv[1])) {
// Generate single file.
@@ -252,19 +262,23 @@ class ArgInfo {
public $isVariadic;
/** @var Type|null */
public $type;
+ /** @var string|null */
+ public $defaultValue;
- public function __construct(string $name, int $sendBy, bool $isVariadic, ?Type $type) {
+ public function __construct(string $name, int $sendBy, bool $isVariadic, ?Type $type, ?string $defaultValue) {
$this->name = $name;
$this->sendBy = $sendBy;
$this->isVariadic = $isVariadic;
$this->type = $type;
+ $this->defaultValue = $defaultValue;
}
public function equals(ArgInfo $other): bool {
return $this->name === $other->name
&& $this->sendBy === $other->sendBy
&& $this->isVariadic === $other->isVariadic
- && Type::equals($this->type, $other->type);
+ && Type::equals($this->type, $other->type)
+ && $this->defaultValue === $other->defaultValue;
}
public function getSendByString(): string {
@@ -278,6 +292,18 @@ class ArgInfo {
}
throw new Exception("Invalid sendBy value");
}
+
+ public function hasDefaultValue(): bool {
+ return $this->defaultValue !== null && $this->defaultValue !== "UNKNOWN";
+ }
+
+ public function getDefaultValueString(): string {
+ if ($this->hasDefaultValue()) {
+ return '"' . addslashes($this->defaultValue) . '"';
+ }
+
+ return "NULL";
+ }
}
class ReturnInfo {
@@ -432,7 +458,7 @@ function parseDocComment(DocComment $comment): array {
}
function parseFunctionLike(
- string $name, ?string $className, Node\FunctionLike $func, ?string $cond
+ PrettyPrinterAbstract $prettyPrinter, string $name, ?string $className, Node\FunctionLike $func, ?string $cond
): FuncInfo {
$comment = $func->getDocComment();
$paramMeta = [];
@@ -494,7 +520,8 @@ function parseFunctionLike(
$varName,
$sendBy,
$param->variadic,
- $type
+ $type,
+ $param->default ? $prettyPrinter->prettyPrintExpr($param->default) : null
);
if (!$param->default && !$param->variadic) {
$numRequiredArgs = $i + 1;
@@ -572,6 +599,7 @@ function parseStubFile(string $fileName): FileInfo {
$parser = new PhpParser\Parser\Php7($lexer);
$nodeTraverser = new PhpParser\NodeTraverser;
$nodeTraverser->addVisitor(new PhpParser\NodeVisitor\NameResolver);
+ $prettyPrinter = new CustomPrettyPrinter();
$stmts = $parser->parse($code);
$nodeTraverser->traverse($stmts);
@@ -594,7 +622,7 @@ function parseStubFile(string $fileName): FileInfo {
}
if ($stmt instanceof Stmt\Function_) {
- $funcInfos[] = parseFunctionLike($stmt->name->toString(), null, $stmt, $cond);
+ $funcInfos[] = parseFunctionLike($prettyPrinter, $stmt->name->toString(), null, $stmt, $cond);
continue;
}
@@ -612,7 +640,7 @@ function parseStubFile(string $fileName): FileInfo {
}
$methodInfos[] = parseFunctionLike(
- $classStmt->name->toString(), $className, $classStmt, $cond);
+ $prettyPrinter, $classStmt->name->toString(), $className, $classStmt, $cond);
}
$classInfos[] = new ClassInfo($className, $methodInfos);
@@ -673,20 +701,23 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
foreach ($funcInfo->args as $argInfo) {
$argKind = $argInfo->isVariadic ? "ARG_VARIADIC" : "ARG";
+ $argDefaultKind = $argInfo->hasDefaultValue() ? "_WITH_DEFAULT_VALUE" : "";
$argType = $argInfo->type;
if ($argType !== null) {
if (null !== $simpleArgType = $argType->tryToSimpleType()) {
if ($simpleArgType->isBuiltin) {
$code .= sprintf(
- "\tZEND_%s_TYPE_INFO(%s, %s, %s, %d)\n",
- $argKind, $argInfo->getSendByString(), $argInfo->name,
- $simpleArgType->toTypeCode(), $argType->isNullable()
+ "\tZEND_%s_TYPE_INFO%s(%s, %s, %s, %d%s)\n",
+ $argKind, $argDefaultKind, $argInfo->getSendByString(), $argInfo->name,
+ $simpleArgType->toTypeCode(), $argType->isNullable(),
+ $argInfo->hasDefaultValue() ? ", " . $argInfo->getDefaultValueString() : ""
);
} else {
$code .= sprintf(
- "\tZEND_%s_OBJ_INFO(%s, %s, %s, %d)\n",
- $argKind, $argInfo->getSendByString(), $argInfo->name,
- $simpleArgType->toEscapedName(), $argType->isNullable()
+ "\tZEND_%s_OBJ_INFO%s(%s, %s, %s, %d%s)\n",
+ $argKind,$argDefaultKind, $argInfo->getSendByString(), $argInfo->name,
+ $simpleArgType->toEscapedName(), $argType->isNullable(),
+ $argInfo->hasDefaultValue() ? ", " . $argInfo->getDefaultValueString() : ""
);
}
} else if (null !== $representableType = $argType->tryToRepresentableType()) {
@@ -694,16 +725,20 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
throw new Exception('Unimplemented');
}
$code .= sprintf(
- "\tZEND_%s_TYPE_MASK(%s, %s, %s)\n",
+ "\tZEND_%s_TYPE_MASK(%s, %s, %s, %s)\n",
$argKind, $argInfo->getSendByString(), $argInfo->name,
- $representableType->toTypeMask()
+ $representableType->toTypeMask(),
+ $argInfo->getDefaultValueString()
);
} else {
throw new Exception('Unimplemented');
}
} else {
$code .= sprintf(
- "\tZEND_%s_INFO(%s, %s)\n", $argKind, $argInfo->getSendByString(), $argInfo->name);
+ "\tZEND_%s_INFO%s(%s, %s%s)\n",
+ $argKind, $argDefaultKind, $argInfo->getSendByString(), $argInfo->name,
+ $argInfo->hasDefaultValue() ? ", " . $argInfo->getDefaultValueString() : ""
+ );
}
}