in src/markdown-extensions/extracted-code-blocks/FilterBase.php [293:398]
private static function addBoilerplate(
string $path,
string $extracted_code,
): string {
// Strip #! and <?hh lines so that we don't insert any code before them
// below. The stripped lines are added back at the end.
$m = Regex\first_match($extracted_code, re"/^(#!.*\n|)(<\\?hh.*\n|)\\s*/");
$headers = $m is nonnull ? $m[0] : '';
$code = Str\strip_prefix($extracted_code, $headers);
// If we can't find any top-level declarations, assume the code block
// contains top-level code that needs to be wrapped in an <<__EntryPoint>>
// function. This would ideally be done using HHAST, but that would be too
// expensive.
if (!Regex\matches(
$code,
re"/^(namespace|use|const|(async |)function|[a-z ]*class|interface|trait|enum) /m",
)) {
$code = Str\trim_right($code)
|> Str\split($$, "\n")
|> Vec\map($$, $line ==> Str\trim_right(' '.$line))
|> Str\join($$, "\n");
$code = "<<__EntryPoint>>\n".
"async function _main(): Awaitable<void> {\n$code\n}\n";
}
// Insert \init_docs_autoloader() call at the beginning of the
// <<__EntryPoint>> function (if there is one).
if (
!Str\ends_with($path, '.'.self::TYPE_ERRORS) &&
Str\contains($code, '<<__EntryPoint>>') &&
!Str\contains($code, 'init_docs_autoloader()')
) {
$entrypoint_opening_brace = Str\search(
$code,
'{',
Str\search($code, '<<__EntryPoint>>') as nonnull
);
invariant(
$entrypoint_opening_brace is nonnull,
'Failed to locate <<__EntryPoint>> opening brace.',
);
$code = Str\slice($code, 0, $entrypoint_opening_brace + 1).
"\n \\init_docs_autoloader();\n".
Str\slice($code, $entrypoint_opening_brace + 1);
}
// Insert `use` clauses for common HSL namespaces. There might be some false
// positives here, but that's fine.
$uses = vec[];
foreach (self::COMMON_HSL_NAMESPACES as $ns) {
if (
Str\contains($code, $ns.'\\') &&
!\preg_match('/^use namespace HH\\\\Lib\\\\.*'.$ns.'/m', $code)
) {
$uses[] = $ns;
}
}
if (!C\is_empty($uses)) {
$uses_str = Str\join($uses, ', ');
if (C\count($uses) > 1) {
$uses_str = '{'.$uses_str.'}';
}
$code = 'use namespace HH\\Lib\\'.$uses_str.";\n\n$code";
}
// Generate a unique namespace name (unless one is already specified),
// e.g. HHVM\UserDocumentation\Guides\Hack\GettingStarted\MyFirstProgram.
if (
!Str\starts_with($code, 'namespace ') &&
!Str\contains($code, "\nnamespace ")
) {
// Cut off anything after the first period. This makes it possible to
// force multiple examples to use the same namespace, e.g. example.hack
// and example.inc.hack.
$suffix = Str\split(\basename($path), '.', 2)[1];
$ns = Str\strip_suffix($path, '.'.$suffix)
|> Str\strip_prefix($$, BuildPaths::EXAMPLES_EXTRACT_DIR.'/')
|> Str\split($$, '/')
|> Vec\map(
$$,
$part ==> Str\trim_left($part, '0123456789-_')
|> Str\capitalize($$)
|> Regex\replace_with( // convert to CamelCase
$$,
re"/[^a-zA-Z0-9]+([a-zA-Z0-9])/",
$match ==> Str\uppercase($match[1]),
),
)
|> Str\join($$, '\\');
$code = 'namespace HHVM\\UserDocumentation\\'.$ns.";\n\n$code";
}
if ($code !== $extracted_code) {
$code =
"// WARNING: Contains some auto-generated boilerplate code, see:\n".
'// '.__METHOD__."\n\n".
$code;
}
if (Str\contains($path, '.php') && !Str\contains($headers, '<?hh')) {
$code = "<?hh\n\n".$code;
}
return $headers.$code;
}