'Requested to create Unix socket server in %s, but folder %s does not exist',
StringUtil::jsonEncode($value),
StringUtil::jsonEncode($socket_dirname)
);
thrownewUsageException($msg,1,null,true);
}else{
Config::setValue('daemonize_socket',$value);// Daemonize. Assumes the file list won't change. Accepts requests over a Unix socket, or some other IPC mechanism.
}
break;
// TODO(possible idea): HTTP server binding to 127.0.0.1, daemonize-http-port.
case'daemonize-tcp-host':
$this->checkCanDaemonize('tcp',$key);
Config::setValue('daemonize_tcp',true);
$host=\filter_var($value,FILTER_VALIDATE_IP);
if(\strcasecmp($value,'default')!==0&&!$host){
thrownewUsageException("--daemonize-tcp-host must be the string 'default' or a valid ip address to listen on, got '$value'",1);
thrownewUsageException("The $option_pluralized ".\implode(' and ',$bad_options)." only $make_pluralized sense when initializing a new Phan config with --init",EXIT_FAILURE,UsageException::PRINT_INIT_ONLY);
}
}
/**
* Configure settings for colorized output for help and issue messages.
// If the client has multiple files open at once (and requests analysis of multiple files),
// then there there would be multiple processes doing analysis.
//
// This would not work with Phan's current design - the socket used by the daemon can only be used by one process.
// Also, the implementation of some requests such as "Go to Definition", "Find References" (planned), etc. assume Phan runs as a single process.
$processes=Config::getValue('processes');
if($processes!==1){
\fprintf(STDERR,"Notice: Running with processes=1 instead of processes=%s - the daemon/language server assumes it will run as a single process".PHP_EOL,(string)\json_encode($processes));
Config::setValue('processes',1);
}
if(Config::getValue('__analyze_twice')){
\fwrite(STDERR,"Notice: Running analysis phase once instead of --analyze-twice - the daemon/language server assumes it will run as a single process".PHP_EOL);
thrownewUsageException("The pcntl extension is not available to fork a new process, so $opt will not be able to create workers to respond to requests.",1);
// Make sure that if two flags have the same distance, ties are sorted alphabetically
if($distance>5){
continue;
}
if($key===$flag){
if(in_array($key.':',$long_options,true)){
return" (This option is probably missing the required value. Or this option may not apply to a regular Phan analysis, and/or it may be unintentionally unhandled in \Phan\CLI::__construct())";
}else{
return" (This option may not apply to a regular Phan analysis, and/or it may be unintentionally unhandled in \Phan\CLI::__construct())";
CLI::printErrorToStderr("Unable to read file $file_path: SplFileInfo->isFile() is false for SplFileInfo->getType() == ".\var_representation(self::getSplFileInfoType($file_info))."\n");
returnfalse;
}
if(!$file_info->isReadable()){
$file_path=$file_info->getRealPath();
CLI::printErrorToStderr("Unable to read file $file_path: SplFileInfo->isReadable() is false, getPerms()=".sprintf("%o(octal)",@$file_info->getPerms())."\n");
returnfalse;
}
// Compare exclude_file_regex against the relative path within the project
CLI::printErrorToStderr(sprintf("Unexpected error checking if %s should be parsed: %s %s\n",$file_info->getPathname(),\get_class($e),$e->getMessage()));
* @suppress PhanUndeclaredFunction, UnusedSuppression the function exists only in Windows.
* @suppress PhanImpossibleTypeComparison, PhanRedundantCondition, PhanImpossibleCondition, PhanSuspiciousValueComparison the value for strtoupper is inferred as a literal.
// But if the CLI option --require-config-exists is provided, exit immediately.
// (Include extended help documenting that option)
if($config_file_name!==false){
thrownewUsageException("Could not find a config file at '$config_file_name', but --require-config-exists was set",EXIT_FAILURE,UsageException::PRINT_EXTENDED);
}else{
$msg=sprintf(
"Could not figure out the path for config file %s, but --require-config-exists was set",
"ERROR: The php-ast extension must be loaded in order for Phan to work. Either install and enable php-ast, or invoke Phan with the CLI option --allow-polyfill-parser (which is noticeably slower)\n",
false,
true
);
\phan_output_ast_installation_instructions();
exit(EXIT_FAILURE);
}
self::exitIfAstVersionIsInvalid();
try{
// Split up the opening PHP tag to fix highlighting in vim.
\ast\parse_code(
'<'.'?php 42;',
Config::AST_VERSION
);
}catch(\LogicException$_){
self::printHelpSection(
'ERROR: Unknown AST version ('
.Config::AST_VERSION
.') in configuration. '
."You may need to rebuild the latest version of the php-ast extension.\n"
."See https://github.com/phan/phan#getting-started for more details.\n"
."(You are using php-ast ".(newReflectionExtension('ast'))->getVersion().", but ".Config::MINIMUM_AST_EXTENSION_VERSION." or newer is required. Alternately, test with --allow-polyfill-parser or --force-polyfill-parser (which are noticeably slower))\n",
false,
true
);
exit(EXIT_FAILURE);
}
// Workaround for https://github.com/nikic/php-ast/issues/79
try{
\ast\parse_code(
'<'.'?php syntaxerror',
Config::AST_VERSION
);
self::printHelpSection(
'ERROR: Expected ast\\parse_code to throw ParseError on invalid inputs. Configured AST version: '
.Config::AST_VERSION
.'. '
."You may need to rebuild the latest version of the php-ast extension.\n",
false,
true
);
exit(EXIT_FAILURE);
}catch(\ParseError$_){
// error message may validate with locale and version, don't validate that.
}
}
/**
* This duplicates the check in Bootstrap.php, in case opcache.file_cache has outdated information about whether extension_loaded('ast') is true. exists.
// Seen in php 7.3 with file_cache when ast is initially enabled but later disabled, due to the result of extension_loaded being assumed to be a constant by opcache.
CLI::printErrorToStderr("ERROR: extension_loaded('ast') is true, but phpversion('ast') is the empty string. You probably need to clear opcache (opcache.file_cache='".\ini_get('opcache.file_cache')."')".PHP_EOL);
}
// NOTE: We haven't loaded the autoloader yet, so these issue messages can't be colorized.
CLI::printErrorToStderr(sprintf(
"Phan 5.x requires php-ast %s+ because it depends on AST version 85. php-ast '%s' is installed.".PHP_EOL,
Config::MINIMUM_AST_EXTENSION_VERSION,
$ast_version
));
require_once__DIR__.'/Bootstrap.php';
\phan_output_ast_installation_instructions();
\fwrite(STDERR,"Exiting without analyzing files.".PHP_EOL);
exit(1);
}
if(\version_compare($ast_version,'1.0.11')<0){
CLI::printWarningToStderr(sprintf("php-ast %s is being used with Phan 5. php-ast 1.0.11 or newer is recommended for compatibility with plugins and support for AST version 85.\n",$ast_version));
// Reuse PHAN_SUPPRESS_AST_DEPRECATION for this purpose as well.
if(!getenv('PHAN_SUPPRESS_AST_DEPRECATION')){
\phan_output_ast_installation_instructions();
fwrite(STDERR,"(Set PHAN_SUPPRESS_AST_DEPRECATION=1 to suppress this message)".PHP_EOL);
}
}
}
/**
* Returns a string that can be used to check if dev-master versions changed (approximately).
*
* This is useful for checking if caches (e.g. of ASTs) should be invalidated.
// Restart if Xdebug is loaded, unless the environment variable PHAN_ALLOW_XDEBUG is set.
if(!getenv('PHAN_DISABLE_XDEBUG_WARN')){
fwrite(STDERR,<<<EOT
[info] Disabling Xdebug: Phan is around five times as slow when Xdebug is enabled (Xdebug only makes sense when debugging Phan itself)
[info] To run Phan with Xdebug, set the environment variable PHAN_ALLOW_XDEBUG to 1.
[info] To disable this warning, set the environment variable PHAN_DISABLE_XDEBUG_WARN to 1.
[info] To include function signatures of Xdebug, see .phan/internal_stubs/xdebug.phan_php
EOT
);
}
}
if(self::shouldRestartToExclude('uopz')){
// NOTE: uopz seems to cause instability when used and switched from enabled to disabled.
//
// TODO create and link to stubs if https://github.com/krakjoe/uopz/issues/123 is completed.
$extensions_to_disable[]='uopz';
fwrite(
STDERR,
<<<EOT
[info] Restarting with uopz disabled, it can cause unpredictable behavior.
[info] Set the environment variable PHAN_ALLOW_UOPZ to 1 to disable this message and to allow uopz.
[info] If you are not using uopz to debug Phan, removing uopz from php.ini or setting the ini setting uopz.disable=1 is recommended before running Phan.