Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preg_replace with anchor will always only have 1 replacement #8469

Merged
merged 1 commit into from Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Psalm/Codebase.php
Expand Up @@ -1669,7 +1669,7 @@ public function getCompletionItemsForPartialSymbol(
) {
$file_contents = $this->getFileContents($file_path);

$class_name = preg_replace('/^.*\\\/', '', $fq_class_name);
$class_name = preg_replace('/^.*\\\/', '', $fq_class_name, 1);

if ($aliases->uses_end) {
$position = self::getPositionFromOffset($aliases->uses_end, $file_contents);
Expand Down
8 changes: 4 additions & 4 deletions src/Psalm/Config.php
Expand Up @@ -1313,7 +1313,7 @@ public function setCustomErrorLevel(string $issue_key, string $error_level): voi
private function loadFileExtensions(SimpleXMLElement $extensions): void
{
foreach ($extensions as $extension) {
$extension_name = preg_replace('/^\.?/', '', (string)$extension['name']);
$extension_name = preg_replace('/^\.?/', '', (string)$extension['name'], 1);
$this->file_extensions[] = $extension_name;

if (isset($extension['scanner'])) {
Expand Down Expand Up @@ -1507,7 +1507,7 @@ private function getPluginClassForPath(Codebase $codebase, string $path, string
public function shortenFileName(string $to): string
{
if (!is_file($to)) {
return preg_replace('/^' . preg_quote($this->base_dir, '/') . '/', '', $to);
return preg_replace('/^' . preg_quote($this->base_dir, '/') . '/', '', $to, 1);
}

$from = $this->base_dir;
Expand Down Expand Up @@ -1679,7 +1679,7 @@ public static function getParentIssueType(string $issue_type): ?string
}

if (strpos($issue_type, 'Possibly') === 0) {
$stripped_issue_type = preg_replace('/^Possibly(False|Null)?/', '', $issue_type);
$stripped_issue_type = preg_replace('/^Possibly(False|Null)?/', '', $issue_type, 1);

if (strpos($stripped_issue_type, 'Invalid') === false && strpos($stripped_issue_type, 'Un') !== 0) {
$stripped_issue_type = 'Invalid' . $stripped_issue_type;
Expand All @@ -1693,7 +1693,7 @@ public static function getParentIssueType(string $issue_type): ?string
}

if (preg_match('/^(False|Null)[A-Z]/', $issue_type) && !strpos($issue_type, 'Reference')) {
return preg_replace('/^(False|Null)/', 'Invalid', $issue_type);
return preg_replace('/^(False|Null)/', 'Invalid', $issue_type, 1);
}

if ($issue_type === 'UndefinedInterfaceMethod') {
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Config/Creator.php
Expand Up @@ -242,7 +242,7 @@ private static function getPsr4Or0Paths(string $current_dir, array $composer_jso
continue;
}

$path = preg_replace('@[\\\\/]$@', '', $path);
$path = preg_replace('@[/\\\]$@', '', $path, 1);

if ($path !== 'tests') {
$nodes[] = '<directory name="' . $path . '" />';
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Config/FileFilter.php
Expand Up @@ -421,7 +421,7 @@ function (): bool {
*/
protected static function slashify(string $str): string
{
return preg_replace('/\/?$/', DIRECTORY_SEPARATOR, $str);
return rtrim( $str, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
}

public function allows(string $file_name, bool $case_sensitive = false): bool
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Context.php
Expand Up @@ -752,7 +752,7 @@ public function hasVariable(string $var_name): bool
return false;
}

$stripped_var = preg_replace('/(->|\[).*$/', '', $var_name);
$stripped_var = preg_replace('/(->|\[).*$/', '', $var_name, 1);

if ($stripped_var !== '$this' || $var_name !== $stripped_var) {
$this->referenced_var_ids[$var_name] = true;
Expand Down
8 changes: 4 additions & 4 deletions src/Psalm/DocComment.php
Expand Up @@ -64,9 +64,9 @@ public static function parse(string $docblock, ?int $line_number = null, bool $p
{
// Strip off comments.
$docblock = trim($docblock);
$docblock = preg_replace('@^/\*\*@', '', $docblock);
$docblock = preg_replace('@\*/$@', '', $docblock);
$docblock = preg_replace('@^[ \t]*\*@m', '', $docblock);
$docblock = preg_replace('@^/\*\*@', '', $docblock, 1);
$docblock = preg_replace('@\*/$@', '', $docblock, 1);
$docblock = preg_replace('@^[ \t]*\*@m', '', $docblock, 1);

// Normalize multi-line @specials.
$lines = explode("\n", $docblock);
Expand Down Expand Up @@ -157,7 +157,7 @@ public static function parse(string $docblock, ?int $line_number = null, bool $p

// Trim any empty lines off the front, but leave the indent level if there
// is one.
$docblock = preg_replace('/^\s*\n/', '', $docblock);
$docblock = preg_replace('/^\s*\n/', '', $docblock, 1);

foreach ($special as $special_key => $_) {
if (strpos($special_key, 'psalm-') === 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php
Expand Up @@ -231,7 +231,7 @@ public static function checkFullyQualifiedClassLikeName(
return null;
}

$fq_class_name = preg_replace('/^\\\/', '', $fq_class_name);
$fq_class_name = preg_replace('/^\\\/', '', $fq_class_name, 1);

if (in_array($fq_class_name, ['callable', 'iterable', 'self', 'static', 'parent'], true)) {
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Analyzer/NamespaceAnalyzer.php
Expand Up @@ -221,7 +221,7 @@ public static function isWithinAny(string $calling_identifier, array $identifier
*/
public static function getNameSpaceRoot(string $fullyQualifiedClassName): string
{
$root_namespace = preg_replace('/^([^\\\]+).*/', '$1', $fullyQualifiedClassName);
$root_namespace = preg_replace('/^([^\\\]+).*/', '$1', $fullyQualifiedClassName, 1);
if ($root_namespace === "") {
throw new InvalidArgumentException("Invalid classname \"$fullyQualifiedClassName\"");
}
Expand Down
Expand Up @@ -735,7 +735,7 @@ private static function getAnalyzeNamedExpression(
if (strpos($var_type_part->value, '::')) {
$parts = explode('::', strtolower($var_type_part->value));
$fq_class_name = $parts[0];
$fq_class_name = preg_replace('/^\\\\/', '', $fq_class_name);
$fq_class_name = preg_replace('/^\\\/', '', $fq_class_name, 1);
$potential_method_id = new MethodIdentifier($fq_class_name, $parts[1]);
} else {
$function_call_info->new_function_name = new VirtualFullyQualified(
Expand Down
Expand Up @@ -522,7 +522,7 @@ public static function getFunctionIdsFromCallableArg(
}

if ($callable_arg instanceof PhpParser\Node\Scalar\String_) {
$potential_id = preg_replace('/^\\\/', '', $callable_arg->value);
$potential_id = preg_replace('/^\\\/', '', $callable_arg->value, 1);

if (preg_match('/^[A-Za-z0-9_]+(\\\[A-Za-z0-9_]+)*(::[A-Za-z0-9_]+)?$/', $potential_id)) {
return [$potential_id];
Expand Down Expand Up @@ -552,7 +552,7 @@ public static function getFunctionIdsFromCallableArg(
}

if ($class_arg instanceof PhpParser\Node\Scalar\String_) {
return [preg_replace('/^\\\/', '', $class_arg->value) . '::' . $method_name_arg->value];
return [preg_replace('/^\\\/', '', $class_arg->value, 1) . '::' . $method_name_arg->value];
}

if ($class_arg instanceof PhpParser\Node\Expr\ClassConstFetch
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Cli/LanguageServer.php
Expand Up @@ -93,7 +93,7 @@ public static function run(array $argv): void
array_map(
function (string $arg) use ($valid_long_options): void {
if (strpos($arg, '--') === 0 && $arg !== '--') {
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2));
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2), 1);

if (!in_array($arg_name, $valid_long_options, true)
&& !in_array($arg_name . ':', $valid_long_options, true)
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Cli/Psalm.php
Expand Up @@ -431,7 +431,7 @@ private static function validateCliArguments(array $args): void
array_map(
function (string $arg): void {
if (strpos($arg, '--') === 0 && $arg !== '--') {
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2));
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2), 1);

if (!in_array($arg_name, self::LONG_OPTIONS)
&& !in_array($arg_name . ':', self::LONG_OPTIONS)
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Cli/Psalter.php
Expand Up @@ -432,7 +432,7 @@ private static function validateCliArguments(array $args): void
array_map(
function (string $arg): void {
if (strpos($arg, '--') === 0 && $arg !== '--') {
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2));
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2), 1);

if ($arg_name === 'alter') {
// valid option for psalm, ignored by psalter
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Cli/Refactor.php
Expand Up @@ -82,7 +82,7 @@ public static function run(array $argv): void
array_map(
function (string $arg) use ($valid_long_options): void {
if (strpos($arg, '--') === 0 && $arg !== '--') {
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2));
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2), 1);

if ($arg_name === 'refactor') {
// valid option for psalm, ignored by psalter
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Codebase/Analyzer.php
Expand Up @@ -773,7 +773,7 @@ public function loadCachedResults(ProjectAnalyzer $project_analyzer): void
$method_param_uses[$member_id]
);

$member_stub = preg_replace('/::.*$/', '::*', $member_id);
$member_stub = preg_replace('/::.*$/', '::*', $member_id, 1);

if (isset($all_referencing_methods[$member_stub])) {
$newly_invalidated_methods = array_merge(
Expand Down
4 changes: 2 additions & 2 deletions src/Psalm/Internal/Codebase/ClassLikes.php
Expand Up @@ -185,7 +185,7 @@ private function collectPredefinedClassLikes(): void
$predefined_classes = get_declared_classes();

foreach ($predefined_classes as $predefined_class) {
$predefined_class = preg_replace('/^\\\/', '', $predefined_class);
$predefined_class = preg_replace('/^\\\/', '', $predefined_class, 1);
/** @psalm-suppress ArgumentTypeCoercion */
$reflection_class = new ReflectionClass($predefined_class);

Expand All @@ -201,7 +201,7 @@ private function collectPredefinedClassLikes(): void
$predefined_interfaces = get_declared_interfaces();

foreach ($predefined_interfaces as $predefined_interface) {
$predefined_interface = preg_replace('/^\\\/', '', $predefined_interface);
$predefined_interface = preg_replace('/^\\\/', '', $predefined_interface, 1);
/** @psalm-suppress ArgumentTypeCoercion */
$reflection_class = new ReflectionClass($predefined_interface);

Expand Down
16 changes: 8 additions & 8 deletions src/Psalm/Internal/Codebase/Properties.php
Expand Up @@ -83,8 +83,8 @@ public function propertyExists(
?Context $context = null,
?CodeLocation $code_location = null
): bool {
// remove trailing backslash if it exists
$property_id = preg_replace('/^\\\\/', '', $property_id);
// remove leading backslash if it exists
$property_id = ltrim( $property_id, '\\' );

[$fq_class_name, $property_name] = explode('::$', $property_id);
$fq_class_name_lc = strtolower($fq_class_name);
Expand Down Expand Up @@ -248,8 +248,8 @@ public function getAppearingClassForProperty(

public function getStorage(string $property_id): PropertyStorage
{
// remove trailing backslash if it exists
$property_id = preg_replace('/^\\\\/', '', $property_id);
// remove leading backslash if it exists
$property_id = ltrim( $property_id, '\\' );

[$fq_class_name, $property_name] = explode('::$', $property_id);

Expand All @@ -269,8 +269,8 @@ public function getStorage(string $property_id): PropertyStorage

public function hasStorage(string $property_id): bool
{
// remove trailing backslash if it exists
$property_id = preg_replace('/^\\\\/', '', $property_id);
// remove leading backslash if it exists
$property_id = ltrim( $property_id, '\\' );

[$fq_class_name, $property_name] = explode('::$', $property_id);

Expand All @@ -291,8 +291,8 @@ public function getPropertyType(
?StatementsSource $source = null,
?Context $context = null
): ?Union {
// remove trailing backslash if it exists
$property_id = preg_replace('/^\\\\/', '', $property_id);
// remove leading backslash if it exists
$property_id = ltrim( $property_id, '\\' );

[$fq_class_name, $property_name] = explode('::$', $property_id);

Expand Down
4 changes: 2 additions & 2 deletions src/Psalm/Internal/MethodIdentifier.php
Expand Up @@ -56,8 +56,8 @@ public static function fromMethodIdReference(string $method_id): self
if (!static::isValidMethodIdReference($method_id)) {
throw new InvalidArgumentException('Invalid method id reference provided: ' . $method_id);
}
// remove trailing backslash if it exists
$method_id = preg_replace('/^\\\\/', '', $method_id);
// remove leading backslash if it exists
$method_id = ltrim($method_id, '\\');
$method_id_parts = explode('::', $method_id);
return new self($method_id_parts[0], strtolower($method_id_parts[1]));
}
Expand Down
Expand Up @@ -506,7 +506,7 @@ protected static function addMagicPropertyToInfo(
) {
$line_parts[1] = str_replace('&', '', $line_parts[1]);

$line_parts[1] = preg_replace('/,$/', '', $line_parts[1]);
$line_parts[1] = preg_replace('/,$/', '', $line_parts[1], 1);

$end = $offset + strlen($line_parts[0]);

Expand Down
Expand Up @@ -1838,8 +1838,8 @@ private static function getTypeAliasesFromCommentLines(

$type_string = str_replace("\n", '', implode('', $var_line_parts));

$type_string = preg_replace('/>[^>^\}]*$/', '>', $type_string);
$type_string = preg_replace('/\}[^>^\}]*$/', '}', $type_string);
$type_string = preg_replace('/>[^>^\}]*$/', '>', $type_string, 1);
$type_string = preg_replace('/\}[^>^\}]*$/', '}', $type_string, 1);

try {
$type_tokens = TypeTokenizer::getFullyQualifiedTokens(
Expand Down
Expand Up @@ -76,7 +76,7 @@ public static function parse(
) {
$line_parts[1] = str_replace('&', '', $line_parts[1]);

$line_parts[1] = preg_replace('/,$/', '', $line_parts[1]);
$line_parts[1] = preg_replace('/,$/', '', $line_parts[1], 1);

$end = $offset + strlen($line_parts[0]);

Expand Down Expand Up @@ -152,7 +152,7 @@ public static function parse(
throw new IncorrectDocblockException('Misplaced variable');
}

$line_parts[1] = preg_replace('/,$/', '', $line_parts[1]);
$line_parts[1] = preg_replace('/,$/', '', $line_parts[1], 1);

$info->params_out[] = [
'name' => trim($line_parts[1]),
Expand Down Expand Up @@ -340,7 +340,7 @@ public static function parse(
throw new IncorrectDocblockException('Misplaced variable');
}

$line_parts[1] = preg_replace('/,$/', '', $line_parts[1]);
$line_parts[1] = preg_replace('/,$/', '', $line_parts[1], 1);

$info->globals[] = [
'name' => $line_parts[1],
Expand Down
4 changes: 2 additions & 2 deletions src/Psalm/Internal/Scanner/DocblockParser.php
Expand Up @@ -111,7 +111,7 @@ public static function parse(string $docblock, int $offsetStart): ParsedDocblock
// Strip the leading *, if present.
$text = $lines[$k];
$text = str_replace("\t", ' ', $text);
$text = preg_replace('/^ *\*/', '', $text);
$text = preg_replace('/^ *\*/', '', $text, 1);
$lines[$k] = $text;
}

Expand Down Expand Up @@ -142,7 +142,7 @@ public static function parse(string $docblock, int $offsetStart): ParsedDocblock

// Trim any empty lines off the front, but leave the indent level if there
// is one.
$docblock = preg_replace('/^\s*\n/', '', $docblock);
$docblock = preg_replace('/^\s*\n/', '', $docblock, 1);

$parsed = new ParsedDocblock($docblock, $special, $first_line_padding ?: '');

Expand Down