Skip to content

Commit 43d5cef

Browse files
committed
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.
1 parent 37aaf2f commit 43d5cef

File tree

1 file changed

+109
-106
lines changed

1 file changed

+109
-106
lines changed

build/gen_stub.php

Lines changed: 109 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,129 +1081,132 @@ function parseFunctionLike(
10811081
Node\FunctionLike $func,
10821082
?string $cond
10831083
): FuncInfo {
1084-
$comment = $func->getDocComment();
1085-
$paramMeta = [];
1086-
$aliasType = null;
1087-
$alias = null;
1088-
$isDeprecated = false;
1089-
$verify = true;
1090-
$docReturnType = null;
1091-
$docParamTypes = [];
1092-
1093-
if ($comment) {
1094-
$tags = parseDocComment($comment);
1095-
foreach ($tags as $tag) {
1096-
if ($tag->name === 'prefer-ref') {
1097-
$varName = $tag->getVariableName();
1098-
if (!isset($paramMeta[$varName])) {
1099-
$paramMeta[$varName] = [];
1100-
}
1101-
$paramMeta[$varName]['preferRef'] = true;
1102-
} else if ($tag->name === 'alias' || $tag->name === 'implementation-alias') {
1103-
$aliasType = $tag->name;
1104-
$aliasParts = explode("::", $tag->getValue());
1105-
if (count($aliasParts) === 1) {
1106-
$alias = new FunctionName(new Name($aliasParts[0]));
1107-
} else {
1108-
$alias = new MethodName(new Name($aliasParts[0]), $aliasParts[1]);
1084+
try {
1085+
$comment = $func->getDocComment();
1086+
$paramMeta = [];
1087+
$aliasType = null;
1088+
$alias = null;
1089+
$isDeprecated = false;
1090+
$verify = true;
1091+
$docReturnType = null;
1092+
$docParamTypes = [];
1093+
1094+
if ($comment) {
1095+
$tags = parseDocComment($comment);
1096+
foreach ($tags as $tag) {
1097+
if ($tag->name === 'prefer-ref') {
1098+
$varName = $tag->getVariableName();
1099+
if (!isset($paramMeta[$varName])) {
1100+
$paramMeta[$varName] = [];
1101+
}
1102+
$paramMeta[$varName]['preferRef'] = true;
1103+
} else if ($tag->name === 'alias' || $tag->name === 'implementation-alias') {
1104+
$aliasType = $tag->name;
1105+
$aliasParts = explode("::", $tag->getValue());
1106+
if (count($aliasParts) === 1) {
1107+
$alias = new FunctionName(new Name($aliasParts[0]));
1108+
} else {
1109+
$alias = new MethodName(new Name($aliasParts[0]), $aliasParts[1]);
1110+
}
1111+
} else if ($tag->name === 'deprecated') {
1112+
$isDeprecated = true;
1113+
} else if ($tag->name === 'no-verify') {
1114+
$verify = false;
1115+
} else if ($tag->name === 'return') {
1116+
$docReturnType = $tag->getType();
1117+
} else if ($tag->name === 'param') {
1118+
$docParamTypes[$tag->getVariableName()] = $tag->getType();
11091119
}
1110-
} else if ($tag->name === 'deprecated') {
1111-
$isDeprecated = true;
1112-
} else if ($tag->name === 'no-verify') {
1113-
$verify = false;
1114-
} else if ($tag->name === 'return') {
1115-
$docReturnType = $tag->getType();
1116-
} else if ($tag->name === 'param') {
1117-
$docParamTypes[$tag->getVariableName()] = $tag->getType();
11181120
}
11191121
}
1120-
}
11211122

1122-
$varNameSet = [];
1123-
$args = [];
1124-
$numRequiredArgs = 0;
1125-
$foundVariadic = false;
1126-
foreach ($func->getParams() as $i => $param) {
1127-
$varName = $param->var->name;
1128-
$preferRef = !empty($paramMeta[$varName]['preferRef']);
1129-
unset($paramMeta[$varName]);
1123+
$varNameSet = [];
1124+
$args = [];
1125+
$numRequiredArgs = 0;
1126+
$foundVariadic = false;
1127+
foreach ($func->getParams() as $i => $param) {
1128+
$varName = $param->var->name;
1129+
$preferRef = !empty($paramMeta[$varName]['preferRef']);
1130+
unset($paramMeta[$varName]);
11301131

1131-
if (isset($varNameSet[$varName])) {
1132-
throw new Exception("Duplicate parameter name $varName for function $name");
1133-
}
1134-
$varNameSet[$varName] = true;
1132+
if (isset($varNameSet[$varName])) {
1133+
throw new Exception("Duplicate parameter name $varName");
1134+
}
1135+
$varNameSet[$varName] = true;
11351136

1136-
if ($preferRef) {
1137-
$sendBy = ArgInfo::SEND_PREFER_REF;
1138-
} else if ($param->byRef) {
1139-
$sendBy = ArgInfo::SEND_BY_REF;
1140-
} else {
1141-
$sendBy = ArgInfo::SEND_BY_VAL;
1142-
}
1137+
if ($preferRef) {
1138+
$sendBy = ArgInfo::SEND_PREFER_REF;
1139+
} else if ($param->byRef) {
1140+
$sendBy = ArgInfo::SEND_BY_REF;
1141+
} else {
1142+
$sendBy = ArgInfo::SEND_BY_VAL;
1143+
}
11431144

1144-
if ($foundVariadic) {
1145-
throw new Exception("Error in function $name: only the last parameter can be variadic");
1146-
}
1145+
if ($foundVariadic) {
1146+
throw new Exception("Only the last parameter can be variadic");
1147+
}
11471148

1148-
$type = $param->type ? Type::fromNode($param->type) : null;
1149-
if ($type === null && !isset($docParamTypes[$varName])) {
1150-
throw new Exception("Missing parameter type for function $name()");
1151-
}
1149+
$type = $param->type ? Type::fromNode($param->type) : null;
1150+
if ($type === null && !isset($docParamTypes[$varName])) {
1151+
throw new Exception("Missing parameter type");
1152+
}
11521153

1153-
if ($param->default instanceof Expr\ConstFetch &&
1154-
$param->default->name->toLowerString() === "null" &&
1155-
$type && !$type->isNullable()
1156-
) {
1157-
$simpleType = $type->tryToSimpleType();
1158-
if ($simpleType === null) {
1159-
throw new Exception(
1160-
"Parameter $varName of function $name has null default, but is not nullable");
1154+
if ($param->default instanceof Expr\ConstFetch &&
1155+
$param->default->name->toLowerString() === "null" &&
1156+
$type && !$type->isNullable()
1157+
) {
1158+
$simpleType = $type->tryToSimpleType();
1159+
if ($simpleType === null) {
1160+
throw new Exception("Parameter $varName has null default, but is not nullable");
1161+
}
11611162
}
1162-
}
11631163

1164-
$foundVariadic = $param->variadic;
1164+
$foundVariadic = $param->variadic;
11651165

1166-
$args[] = new ArgInfo(
1167-
$varName,
1168-
$sendBy,
1169-
$param->variadic,
1170-
$type,
1171-
isset($docParamTypes[$varName]) ? Type::fromPhpDoc($docParamTypes[$varName]) : null,
1172-
$param->default ? $prettyPrinter->prettyPrintExpr($param->default) : null
1173-
);
1174-
if (!$param->default && !$param->variadic) {
1175-
$numRequiredArgs = $i + 1;
1166+
$args[] = new ArgInfo(
1167+
$varName,
1168+
$sendBy,
1169+
$param->variadic,
1170+
$type,
1171+
isset($docParamTypes[$varName]) ? Type::fromPhpDoc($docParamTypes[$varName]) : null,
1172+
$param->default ? $prettyPrinter->prettyPrintExpr($param->default) : null
1173+
);
1174+
if (!$param->default && !$param->variadic) {
1175+
$numRequiredArgs = $i + 1;
1176+
}
11761177
}
1177-
}
11781178

1179-
foreach (array_keys($paramMeta) as $var) {
1180-
throw new Exception("Found metadata for invalid param $var of function $name");
1181-
}
1179+
foreach (array_keys($paramMeta) as $var) {
1180+
throw new Exception("Found metadata for invalid param $var");
1181+
}
11821182

1183-
$returnType = $func->getReturnType();
1184-
if ($returnType === null && $docReturnType === null && !$name->isConstructor() && !$name->isDestructor()) {
1185-
throw new Exception("Missing return type for function $name()");
1186-
}
1183+
$returnType = $func->getReturnType();
1184+
if ($returnType === null && $docReturnType === null && !$name->isConstructor() && !$name->isDestructor()) {
1185+
throw new Exception("Missing return type");
1186+
}
11871187

1188-
$return = new ReturnInfo(
1189-
$func->returnsByRef(),
1190-
$returnType ? Type::fromNode($returnType) : null,
1191-
$docReturnType ? Type::fromPhpDoc($docReturnType) : null
1192-
);
1188+
$return = new ReturnInfo(
1189+
$func->returnsByRef(),
1190+
$returnType ? Type::fromNode($returnType) : null,
1191+
$docReturnType ? Type::fromPhpDoc($docReturnType) : null
1192+
);
11931193

1194-
return new FuncInfo(
1195-
$name,
1196-
$classFlags,
1197-
$flags,
1198-
$aliasType,
1199-
$alias,
1200-
$isDeprecated,
1201-
$verify,
1202-
$args,
1203-
$return,
1204-
$numRequiredArgs,
1205-
$cond
1206-
);
1194+
return new FuncInfo(
1195+
$name,
1196+
$classFlags,
1197+
$flags,
1198+
$aliasType,
1199+
$alias,
1200+
$isDeprecated,
1201+
$verify,
1202+
$args,
1203+
$return,
1204+
$numRequiredArgs,
1205+
$cond
1206+
);
1207+
} catch (Exception $e) {
1208+
throw new Exception($name . "(): " .$e->getMessage());
1209+
}
12071210
}
12081211

12091212
function handlePreprocessorConditions(array &$conds, Stmt $stmt): ?string {

0 commit comments

Comments
 (0)