From 43d5cef448429fae2cb597f72e27d93c267bea0d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 18 Jan 2021 13:09:47 +0100 Subject: gen_stub: Automatically add function name to exceptions This makes sure that it's present even on exceptions from deeper down the stack, where we can't add it manually. --- build/gen_stub.php | 215 +++++++++++++++++++++++++++-------------------------- 1 file changed, 109 insertions(+), 106 deletions(-) (limited to 'build') diff --git a/build/gen_stub.php b/build/gen_stub.php index 6d1ae99ebc..a952f61604 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1081,129 +1081,132 @@ function parseFunctionLike( Node\FunctionLike $func, ?string $cond ): FuncInfo { - $comment = $func->getDocComment(); - $paramMeta = []; - $aliasType = null; - $alias = null; - $isDeprecated = false; - $verify = true; - $docReturnType = null; - $docParamTypes = []; - - if ($comment) { - $tags = parseDocComment($comment); - foreach ($tags as $tag) { - if ($tag->name === 'prefer-ref') { - $varName = $tag->getVariableName(); - if (!isset($paramMeta[$varName])) { - $paramMeta[$varName] = []; - } - $paramMeta[$varName]['preferRef'] = true; - } else if ($tag->name === 'alias' || $tag->name === 'implementation-alias') { - $aliasType = $tag->name; - $aliasParts = explode("::", $tag->getValue()); - if (count($aliasParts) === 1) { - $alias = new FunctionName(new Name($aliasParts[0])); - } else { - $alias = new MethodName(new Name($aliasParts[0]), $aliasParts[1]); + try { + $comment = $func->getDocComment(); + $paramMeta = []; + $aliasType = null; + $alias = null; + $isDeprecated = false; + $verify = true; + $docReturnType = null; + $docParamTypes = []; + + if ($comment) { + $tags = parseDocComment($comment); + foreach ($tags as $tag) { + if ($tag->name === 'prefer-ref') { + $varName = $tag->getVariableName(); + if (!isset($paramMeta[$varName])) { + $paramMeta[$varName] = []; + } + $paramMeta[$varName]['preferRef'] = true; + } else if ($tag->name === 'alias' || $tag->name === 'implementation-alias') { + $aliasType = $tag->name; + $aliasParts = explode("::", $tag->getValue()); + if (count($aliasParts) === 1) { + $alias = new FunctionName(new Name($aliasParts[0])); + } else { + $alias = new MethodName(new Name($aliasParts[0]), $aliasParts[1]); + } + } else if ($tag->name === 'deprecated') { + $isDeprecated = true; + } else if ($tag->name === 'no-verify') { + $verify = false; + } else if ($tag->name === 'return') { + $docReturnType = $tag->getType(); + } else if ($tag->name === 'param') { + $docParamTypes[$tag->getVariableName()] = $tag->getType(); } - } else if ($tag->name === 'deprecated') { - $isDeprecated = true; - } else if ($tag->name === 'no-verify') { - $verify = false; - } else if ($tag->name === 'return') { - $docReturnType = $tag->getType(); - } else if ($tag->name === 'param') { - $docParamTypes[$tag->getVariableName()] = $tag->getType(); } } - } - $varNameSet = []; - $args = []; - $numRequiredArgs = 0; - $foundVariadic = false; - foreach ($func->getParams() as $i => $param) { - $varName = $param->var->name; - $preferRef = !empty($paramMeta[$varName]['preferRef']); - unset($paramMeta[$varName]); + $varNameSet = []; + $args = []; + $numRequiredArgs = 0; + $foundVariadic = false; + foreach ($func->getParams() as $i => $param) { + $varName = $param->var->name; + $preferRef = !empty($paramMeta[$varName]['preferRef']); + unset($paramMeta[$varName]); - if (isset($varNameSet[$varName])) { - throw new Exception("Duplicate parameter name $varName for function $name"); - } - $varNameSet[$varName] = true; + if (isset($varNameSet[$varName])) { + throw new Exception("Duplicate parameter name $varName"); + } + $varNameSet[$varName] = true; - if ($preferRef) { - $sendBy = ArgInfo::SEND_PREFER_REF; - } else if ($param->byRef) { - $sendBy = ArgInfo::SEND_BY_REF; - } else { - $sendBy = ArgInfo::SEND_BY_VAL; - } + if ($preferRef) { + $sendBy = ArgInfo::SEND_PREFER_REF; + } else if ($param->byRef) { + $sendBy = ArgInfo::SEND_BY_REF; + } else { + $sendBy = ArgInfo::SEND_BY_VAL; + } - if ($foundVariadic) { - throw new Exception("Error in function $name: only the last parameter can be variadic"); - } + if ($foundVariadic) { + throw new Exception("Only the last parameter can be variadic"); + } - $type = $param->type ? Type::fromNode($param->type) : null; - if ($type === null && !isset($docParamTypes[$varName])) { - throw new Exception("Missing parameter type for function $name()"); - } + $type = $param->type ? Type::fromNode($param->type) : null; + if ($type === null && !isset($docParamTypes[$varName])) { + throw new Exception("Missing parameter type"); + } - if ($param->default instanceof Expr\ConstFetch && - $param->default->name->toLowerString() === "null" && - $type && !$type->isNullable() - ) { - $simpleType = $type->tryToSimpleType(); - if ($simpleType === null) { - throw new Exception( - "Parameter $varName of function $name has null default, but is not nullable"); + if ($param->default instanceof Expr\ConstFetch && + $param->default->name->toLowerString() === "null" && + $type && !$type->isNullable() + ) { + $simpleType = $type->tryToSimpleType(); + if ($simpleType === null) { + throw new Exception("Parameter $varName has null default, but is not nullable"); + } } - } - $foundVariadic = $param->variadic; + $foundVariadic = $param->variadic; - $args[] = new ArgInfo( - $varName, - $sendBy, - $param->variadic, - $type, - isset($docParamTypes[$varName]) ? Type::fromPhpDoc($docParamTypes[$varName]) : null, - $param->default ? $prettyPrinter->prettyPrintExpr($param->default) : null - ); - if (!$param->default && !$param->variadic) { - $numRequiredArgs = $i + 1; + $args[] = new ArgInfo( + $varName, + $sendBy, + $param->variadic, + $type, + isset($docParamTypes[$varName]) ? Type::fromPhpDoc($docParamTypes[$varName]) : null, + $param->default ? $prettyPrinter->prettyPrintExpr($param->default) : null + ); + if (!$param->default && !$param->variadic) { + $numRequiredArgs = $i + 1; + } } - } - foreach (array_keys($paramMeta) as $var) { - throw new Exception("Found metadata for invalid param $var of function $name"); - } + foreach (array_keys($paramMeta) as $var) { + throw new Exception("Found metadata for invalid param $var"); + } - $returnType = $func->getReturnType(); - if ($returnType === null && $docReturnType === null && !$name->isConstructor() && !$name->isDestructor()) { - throw new Exception("Missing return type for function $name()"); - } + $returnType = $func->getReturnType(); + if ($returnType === null && $docReturnType === null && !$name->isConstructor() && !$name->isDestructor()) { + throw new Exception("Missing return type"); + } - $return = new ReturnInfo( - $func->returnsByRef(), - $returnType ? Type::fromNode($returnType) : null, - $docReturnType ? Type::fromPhpDoc($docReturnType) : null - ); + $return = new ReturnInfo( + $func->returnsByRef(), + $returnType ? Type::fromNode($returnType) : null, + $docReturnType ? Type::fromPhpDoc($docReturnType) : null + ); - return new FuncInfo( - $name, - $classFlags, - $flags, - $aliasType, - $alias, - $isDeprecated, - $verify, - $args, - $return, - $numRequiredArgs, - $cond - ); + return new FuncInfo( + $name, + $classFlags, + $flags, + $aliasType, + $alias, + $isDeprecated, + $verify, + $args, + $return, + $numRequiredArgs, + $cond + ); + } catch (Exception $e) { + throw new Exception($name . "(): " .$e->getMessage()); + } } function handlePreprocessorConditions(array &$conds, Stmt $stmt): ?string { -- cgit v1.2.1