Changelog History
Page 2
-
v3.2.1 Changes
September 13, 2020🆕 New features (Analysis):
- Don't compare parameter types against alternate method signatures which have too many required parameters.
(e.g. warn aboutmax([])
but notmax([], [1])
) - Support
/** @unused-param $param_name */
in doc comments as an additional way to support suppressing warnings about individual parameters being unused. - Warn about loop conditions that potentially don't change due to the body of the loop.
This check uses heuristics and is prone to false positives.
🆕 New issue types:PhanPossiblyInfiniteLoop
- Treat
unset($x);
as shadowing variable definitions during dead code detection. - 🔄 Change the way
$i++
,--$i
, etc. are analyzed during dead code detection - Properly enable
allow_method_param_type_widening
by default when the inferredminimum_target_php_version
is'7.2'
or newer. (#4168) - 🚀 Start preparing for switching to AST version 80 in an upcoming Phan 4 release. (#4167)`
🐛 Bug fixes:
- 🛠 Fix various crashes in edge cases.
- 🛠 Fix crash with adjacent named labels for gotos in the polyfill/fallback parser.
- 🛠 Fix false positive unused parameter warning with php 8.0 constructor property promotion.
🔌 Plugins:
- 🔌 Warn about
#
comments inPHPDocInWrongCommentPlugin
if they're not used for the expected#[
syntax of php 8.0 attributes.
🚧 Maintenance:
- ⚡️ Update polyfill/fallback parser to properly skip attributes in php 8.0.
🚀 The upcoming Phan 4 release will support analyzing attributes, which requires AST version 80.
- Don't compare parameter types against alternate method signatures which have too many required parameters.
-
v3.2.0 Changes
August 25, 2020🆕 New features (CLI, Config):
➕ Add the
minimum_target_php_version
config setting and--minimum-target-php-version
CLI flag. (#3939)
Phan will use this instead oftarget_php_version
for some backwards compatibility checks
👍 (i.e. to check that the feature in question is supported by the oldest php version the project supports).🔧 If this is not configured, Phan will attempt to use the composer.json version ranges if they are available.
Otherwise,target_php_version
will be used.Phan will use
target_php_version
instead ifminimum_target_php_version
is greater thantarget_php_version
.Update various checks to use
minimum_target_php_version
instead oftarget_php_version
.➕ Add
--always-exit-successfully-after-analysis
flag.
0️⃣ By default, phan exits with a non-zero exit code if 1 or more unsuppressed issues were reported.
When this CLI flag is set, phan will instead exit with exit code 0 as long as the analysis completed.Include the installed php-ast version and the php version used to run Phan in the output of
phan --version
. (#4147)🆕 New features (Analysis):
Emit
PhanCompatibleArrowFunction
if using arrow functions with a minimum target php version older than php 7.4.Emit
PhanCompatibleMatchExpression
if using match expressions with a minimum target php version older than php 8.0.Emit
PhanNoopRepeatedSilenceOperator
for@@expr
or@(@expr)
.
This is less efficient and only makes a difference in extremely rare edge cases.Avoid false positives for bitwise operations on floats such as unsigned 64-bit numbers (#4106)
👍 Incomplete support for analyzing calls with php 8.0's named arguments. (#4037)
New issue types:PhanUndeclaredNamedArgument*
,PhanDuplicateNamedArgument*
,
PhanMissingNamedArgument*
,
PhanDefinitelyDuplicateNamedArgument
,PhanPositionalArgumentAfterNamedArgument
, and
PhanArgumentUnpackingUsedWithNamedArgument
,PhanSuspiciousNamedArgumentForVariadic
👍 Incomplete support for analyzing uses of PHP 8.0's nullsafe operator(
?->
) for property reads and method calls. (#4067)Warn about using
@var
where@param
should be used (#1366)Treat undefined variables as definitely null/undefined in various places
when they are used outside of loops and the global scope. (#4148)Don't warn about undeclared global constants after
defined()
conditions. (#3337)
Phan will infer a broad range of types for these constants that can't be narrowed.📜 Parse
lowercase-string
andnon-empty-lowercase-string
in phpdoc for compatibility, but treat them like ordinary strings.Emit
PhanCompatibleTrailingCommaParameterList
andPhanCompatibleTrailingCommaArgumentList
when the polyfill is used. (#2269)
Trailing commas in argument lists require a minimum target version of php 7.3+,
and trailing commas in parameters or closure use lists require php 8.0+.📜 This is only available in the polyfill because the native
php-ast
parser
🔦 exposes the information that php itself tracks internally,
and php deliberately does not track whether any of these node types have trailing commas.There are already other ways to detect these backwards compatibility issues,
such as--native-syntax-check path/to/php7.x
.Warn about variable definitions that are unused due to fallthroughs in switch statements. (#4162)
🔌 Plugins:
- ➕ Add more aliases to
DeprecateAliasPlugin
Miscellaneous:
- 🚑 Raise the severity of
PhanUndeclaredConstant
andPhanStaticCallToNonStatic
from normal to critical.
Undeclared constants will become a thrownError
at runtime in PHP 8.0+.
🐛 Bug fixes:
- Suppress
PhanParamNameIndicatingUnused
in files loaded fromautoload_internal_extension_signatures
- 👌 Improve compatibility of polyfill/fallback parser with php 8.0
- Also try to check against the realpath() of the current working directory when converting absolute paths
to relative paths. - 🏁 Generate baseline files with
/
instead of\
on Windows in--save-baseline
(#4149)
- ➕ Add more aliases to
-
v3.1.1 Changes
July 31, 2020🆕 New features (CLI, Config):
Add
--baseline-summary-type={ordered_by_count,ordered_by_type,none}
to control the generation
of the summary comment generated by--save-baseline=path/to/baseline.php
(#4044)
(overrides the newbaseline_summary_type
config).
The default comment summary (ordered_by_count
) is prone to merge conflicts in large projects.
This does not affect analysis.Add
tool/phan_repl_helpers.php
, a prototype tool that adds some functionality tophp -a
.
It can be required by runningrequire_once 'path/to/phan/tool/phan_repl_helpers.php'
during an interactive session.- This replaces the readline code completion and adds autocomplete for
->
on global variables.
This is currently buggy and very limited, and is missing some of the code completion functionality that is available inphp -a
.
(And it's missing a lot of the code completion functionality from the language server) - This adds a global function
help($element_name_or_object)
. Runhelp('help')
for usage and examples. - Future releases may advantage of Phan's parsing/analysis capabilities in more ways.
- Several alternatives to the php shell already exist, such as psysh.
tool/phan_repl_helpers.php
is an experiment in augmenting the interactive php shell, not an alternative shell.
⚡️ Update progress bar during class analysis phase. (#4099)
🆕 New features (Analysis):
- 👌 Support casting
iterable<SubClass>
toiterable<BaseClass>
(#4089) - 🔄 Change phrasing for
analyze
phase in--long-progress-bar
with--analyze-twice
- ➕ Add
PhanParamNameIndicatingUnused
andPhanParamNameIndicatingUnusedInClosure
to indicate that using parameter names($unused*
,$_
) to indicate to Phan that a parameter is unused is no longer recommended.
Suppressions or the@param [Type] $param_name @unused-param
syntax can be used instead.
👍 PHP 8.0 will introduce named argument support. - ➕ Add a message to
PhanParamSignatureMismatch
indicating the cause of the issue being emitted. (#4103)
Note thatPhanParamSignaturePHPDocMismatch*
andPhanParamSignatureReal*
have fewer false positives. - Warn about invalid types in class constants. (#4104)
👀 EmitPhanUndeclaredTypeClassConstant
if undeclared types are seen in phpdoc for class constants.
👀 EmitPhanCommentObjectInClassConstantType
if object types are seen in phpdoc for class constants. - Warn about
iterable<UndeclaredClass>
containing undeclared classes. (#4104)
Language Server/Daemon mode:
- Include PHP keywords such as
__FILE__
,switch
,function
, etc. in suggestions for code completions.
🔌 Plugins:
- 🔌 Make
DuplicateExpressionPlugin
warn if adjacent statements are identical. (#4074)
🆕 New issue types:PhanPluginDuplicateAdjacentStatement
. - 🚑 Consistently make
PhanPluginPrintfNonexistentArgument
have critical severity. (#4080)
🖨 Passing too few format string arguments (e.g.printf("%s %s", "Hello,")
) will be anArgumentCountError
in PHP 8.
🐛 Bug fixes:
- This replaces the readline code completion and adds autocomplete for
-
v3.1.0 Changes
July 16, 2020🆕 New features (CLI, Config):
- ➕ Add
--output-mode=verbose
to print the line of code which caused the issue to be emitted after the textual issue output.
This is only emitted if the line is not whitespace, could be read, and does not exceed the config settingmax_verbose_snippet_length
. - Add
included_extension_subset
to limit Phan to using the reflection information to a subset of available extensions. (#4015)
This can be used to make Phan warn about using constants/functions/classes that are not in the target environment or dependency list
of a given PHP project/library.
Note that this may cause issues if a class from an extension in this list depends on classes from another extension that is outside of this list.
🆕 New features (Analysis):
⚠ Don't emit
PhanTypeInvalidLeftOperandOfBitwiseOp
and other binary operation warnings formixed
Emit
PhanIncompatibleRealPropertyType
when real property types are incompatible (#4016)🔄 Change the way
PhanIncompatibleCompositionProp
is checked for. (#4024)
Only emit it when the property was redeclared in an inherited trait.Emit
PhanProvidingUnusedParameter
when passing an argument to a function with an optional parameter named$unused*
or$_
. (#4026)
This can also be suppressed on the functionlike's declaration, and should be suppressed if this does not match the project's parameter naming.
This is limited to functions with no overrides.Emit
PhanParamTooFewInPHPDoc
when a parameter that is marked with@phan-mandatory-param
is not passed in. (#4026)
🚀 This is useful when needing to preserve method signature compatibility in a method override, or when a parameter will become mandatory in a future backwards incompatible release of a project.Emit
PhanTypeMismatchArgumentProbablyReal
instead ofPhanTypeMismatchArgument
when the inferred real type of an argument has nothing in common with the phpdoc type of a user-defined function/method.
This is usually a stronger indicator that the phpdoc parameter type is inaccurate/incomplete or the argument is incorrect.
🚚 (Overall, fixing phpdoc errors may help ensure compatibility long-term if the library/framework being used moves to real types (e.g. php 8.0 union types) in the future.)Note that Phan provides many ways to suppress issues (including the
--save-baseline=.phan/baseline.php
and--load-baseline=.phan/baseline.php
functionality) in case
the switch toProbablyReal
introduces too many new issues in your codebase.
(The newProbablyReal
issues are more severe than the original issue types.
When they're suppressed, the original less severe issue types will also be suppressed)Emit
PhanTypeMismatchReturnProbablyReal
instead ofPhanTypeMismatchReturn
when the inferred real return type has nothing in common with the declared phpdoc return type of a user-defined function/method. (#4028)Emit
PhanTypeMismatchPropertyProbablyReal
instead ofPhanTypeMismatchProperty
when the inferred assigned property type has nothing in common with a property's declared phpdoc type. (#4029)Emit
PhanTypeMismatchArgumentInternalProbablyReal
instead ofPhanTypeMismatchArgumentInternal
in a few more cases.Be stricter about checking if callables/closures have anything in common with other types.
Preserve more specific phpdoc types when the php 8.0
mixed
type is part of the real type set.🔌 Also emit
PhanPluginUseReturnValueNoopVoid
when a function/method's return type is implicitly void (#4049)👌 Support
@param MyType $name one line description @unused-param
to suppress warnings about individual unused method parameters.
This is a new alias of@phan-unused-param
.Support analyzing PHP 8.0's match expression. (#3970)
🔌 Plugins:
- 🔌 Warn and skip checks instead of crashing when running
InlineHTMLPlugin
without thetokenizer
extension installed. (#3998) - 👌 Support throwing
\Phan\PluginV3\UnloadablePluginException
instead of returning a plugin object in plugin files. - 🔌 When a plugin registers for a method definition with
AnalyzeFunctionCallCapability
, automatically register the same closure for all classlikes using the same inherited definition of that method. (#4021) - ➕ Add
UnsafeCodePlugin
to warn about uses ofeval
or the backtick string shorthand forshell_exec()
. - ➕ Add
DeprecateAliasPlugin
to mark known aliases such assizeof()
orjoin()
as deprecated.
👍 Implement support for--automatic-fix
. - Add
PHPDocInWrongCommentPlugin
to warn about using/*
instead of/**
with phpdoc annotations supported by Phan.
Miscellaneous
- ⚡️ Update more unit tests for php 8.0.
- ⚠ Emit a warning and load an extremely limited polyfill for
filter_var
to parse integers/floats if thefilter
extension is not loaded.
🐛 Bug Fixes:
- 👉 Make suppressions on trait methods/properties consistently apply to the inherited definitions from classes/traits using those traits.
- 🛠 Fix false positive where Phan would think that union types with real types containing
int
and other types had an impossible condition.
🛠 Fix another false positive checking if?A|?B
can cast to another union type.
- ➕ Add
-
v3.0.5 Changes
July 03, 2020🆕 New features(CLI, Configs):
- ➕ Add
-X
as an alias of--dead-code-detection-prefer-false-positive
.
🆕 New features(Analysis):
- Emit
PhanTypeInvalidLeftOperandOfBitwiseOp
andPhanTypeInvalidRightOperandOfBitwiseOp
for argument types to bitwise operations other thanint|string
.
(affects^
,|
,&
,^=
,|=
,&=
)
🐛 Bug fixes:
- 🛠 Fix false positives in php 8.0+ type checking against the real
mixed
type. (#3994) - 🛠 Fix unintentionally enabling GC when the
pcntl
extension is not enabled. (#4000)
It should only be enabled when running in daemon mode or as a language server.
Announcements
🐧 Phan has a new minimal docker image (30MB total) based on Alpine Linux and PHP 7.4. See https://github.com/phan/docker
- ➕ Add
-
v3.0.4 Changes
July 01, 2020🆕 New features(Analysis):
- Emit
PhanTypeVoidExpression
when using an expression returningvoid
in places such as array keys/values. - More accurately infer unspecified types when closures are used with
array_map
(#3973) - Don't flatten array shapes and literal values passed to closures when analyzing closures. (Continue flattening for methods and global functions)
- 🔗 Link to documentation for internal stubs as a suggestion for undeclared class issues when Phan has type information related to the class in its signature files.
See https://github.com/phan/phan/wiki/Frequently-Asked-Questions#undeclared_element - 0️⃣ Properly render the default values if available(
ReflectionParameter->isDefaultValueAvailable()
) in php 8.0+. - Properly set the real union types based on reflection information for functions/methods in more edge cases.
- Properly infer that union types containing the empty array shape are possibly empty after sorting (#3980)
- Infer a more accurate real type set from unary ops
~
,+
, and-
(#3991) - 👌 Improve ability to infer assignments within true branch of complex expressions in conditions such as
if (A && complex_expression) { } else { }
(#3992)
🔌 Plugins:
- ➕ Add
ShortArrayPlugin
, to suggest using[]
instead ofarray()
orlist()
- 👀 In
DuplicateExpressionPlugin
, emitPhanPluginDuplicateExpressionAssignmentOperation
ifX = X op Y
is seen and it can be converted toX op= Y
(#3985)
(excluding??=
for now) - ➕ Add
SimplifyExpressionPlugin
, to suggest shortening expressions such as$realBool ? true : false
or$realBool === false
- ➕ Add
RemoveDebugStatementPlugin
, to suggest removing debugging output statements such asecho
,print
,printf
,fwrite(STDERR, ...)
,var_export(...)
, inline html, etc.
🖨 This is only useful in applications or libraries that print output in only a few places, as a sanity check that debugging statements are not accidentally left in code.
🐛 Bug fixes:
- Emit
-
v3.0.3 Changes
June 21, 2020🆕 New features(Analysis):
- Include the most generic types when conditions such as
is_string()
to union types containingmixed
(#3947) - More aggressively infer that
while
andfor
loop bodies are executed at least once in functions outside of other loops (#3948) - Infer the union type of
!$expr
from the type of$expr
(#3948) - 0️⃣ Re-enable
simplify_ast
by default in.phan/config.php
(#3944, #3945) - Avoid false positives in
--constant-variable-detection
for++
/--
- 🚚 Make
if (!$nullableValue) { }
remove truthy literal scalar values such as'value'
and1
and1.0
when they're nullable - Emit
PhanTypeVoidArgument
when passing a void return value as a function argument (#3961) - 🔀 Correctly merge the possible union types of pass-by-reference variables (#3959)
- 👌 Improve php 8.0-dev shim support. Fix checking for array references and closure use references in php 8.0+.
- More aggressively check if expression results should be used for conditionals and binary operators.
🔌 Plugins:
- ➕ Add
ConstantVariablePlugin
to point out places where variables are read when they have only one possible scalar value. (#3953)
0️⃣ This may help detect logic errors such as$x === null ? json_encode($x) : 'default'
or code that could be simplified,
but most issues it emits wouldn't be worth fixing due to hurting readability or being false positives. - ➕ Add
MergeVariableInfoCapability
for plugins to hook into ContextMergeVisitor and update data for a variable
🔀 when merging the outcome of different scopes. (#3956) - 🔌 Make
UseReturnValuePlugin
check if a method is declared as pure before using the dynamic checks based on percentage of
calls where the return value is used, if that option is enabled. - 🔌 In
DuplicateArrayKeyPlugin
, properly check for duplicate non-scalar cases.
Language Server/Daemon mode:
- 🛠 Fix bug where the Phan daemon would crash on the next request after analyzing a file outside of the project being analyzed,
when pcntl was disabled or unavailable (#3954)
🐛 Bug fixes:
- 🛠 Fix
PhanDebugAnnotation
output for variables after the first one in@phan-debug-var $a, $b
(#3943) - 👉 Use the correct constant to check if closure use variables are references in php 8.0+
Miscellaneous:
- ⚡️ Update function signature stubs for the
memcache
PECL (#3841)
🚀 The GPG key used to sign releases has changed (it expired). See #1759
- Include the most generic types when conditions such as
-
v3.0.2 Changes
June 07, 2020🆕 New features(CLI, Configs):
- ➕ Add
--dead-code-detection-prefer-false-positive
to run dead code detection,
erring on the side of reporting potentially dead code even when it is possibly not dead.
(e.g. when methods of unknown objects are invoked, don't mark all methods with the same name as potentially used)
🆕 New features(Analysis):
- 🛠 Fix false positive
PhanAbstractStaticMethodCall
(#3935)
Also, properly emitPhanAbstractStaticMethodCall
for a variable containing a string class name.
🔌 Plugins:
- 🛠 Fix incorrect check and suggestion for
PregRegexCheckerPlugin
's warning if
🔧$
allows an optional newline before the end of the string when the configuration includes
['plugin_config' => ['regex_warn_if_newline_allowed_at_end' => true]]
) (#3938) - ➕ Add
BeforeLoopBodyAnalysisCapability
for plugins to analyze loop conditions before the body (#3936) - Warn about suspicious param order for
str_contains
,str_ends_with
, andstr_starts_with
inSuspiciousParamOrderPlugin
(#3934)
🐛 Bug fixes:
- Don't report unreferenced class properties of internal stub files during dead code detection
(i.e. files inautoload_internal_extension_signatures
). - 🚚 Don't remove the leading directory separator when attempting to convert a file outside the project to a relative path.
(in cases where the directory is different but has the project's name as a prefix)
- ➕ Add
-
v3.0.1 Changes
June 05, 2020🆕 New features(Analysis):
- 👌 Support analysis of php 8.0's
mixed
type (#3899)
🆕 New issue types:PhanCompatibleMixedType
,PhanCompatibleUseMixed
. - Treat
static
andfalse
like real types and emit more severe issues in all php versions. - 👌 Improve type inferences from negated type assertions (#3923)
(analyze more expression kinds, infer real types in more places) - Warn about unnecessary use of
expr ?? null
. (#3925)
🆕 New issue types:PhanCoalescingNeverUndefined
. - 👌 Support PHP 8.0 non-capturing catches (#3907)
🆕 New issue types:PhanCompatibleNonCapturingCatch
. - Infer type of
$x->magicProp
from the signature of__get
- Treat functions/methods that are only called by themselves as unreferenced during dead code detection.
- Warn about
each()
being deprecated when thetarget_php_version
is php 7.2+. (#2746)
🗄 This is special cased because PHP does not flag the function itself as deprecated inReflectionFunction
.
🗄 (PHP only emits the deprecation notice foreach()
once at runtime)
Miscellaneous:
- Check for keys that are too long when computing levenshtein distances (when Phan suggests alternatives).
🔌 Plugins:
- ➕ Add
AnalyzeLiteralStatementCapability
for plugins to analyze no-op string literals (#3911) - 🔌 In
PregRegexCheckerPlugin
, warn if$
allows an optional newline before the end of the string
when configuration includes['plugin_config' => ['regex_warn_if_newline_allowed_at_end' => true]]
) (#3915) - 🔌 In
SuspiciousParamOrderPlugin
, warn if an argument has a near-exact name match for a parameter at a different position (#3929)
E.g. warn about callingfoo($b)
orfoo(true, $this->A)
forfunction foo($a = false, $b = false)
.
🆕 New issue types:PhanPluginSuspiciousParamPosition
,PhanPluginSuspiciousParamPositionInternal
🐛 Bug fixes:
- 🛠 Fix false positive
PhanTypeMismatchPropertyDefault
involving php 7.4 typed properties with no default
and generic comments (#3917) - 🚚 Don't remove leading directory separator when attempting to convert a file outside the project to a relative path.
- 👌 Support analysis of php 8.0's
-
v3.0.0 Changes
May 09, 2020🚀 The Phan 3.x releases support analysis of php 7.0-7.4, and can be executed with php 7.2+.
🚀 Use the older Phan 2.x releases if you need to continue to execute Phan with php 7.1.
🚀 Use the older Phan 1.x releases if you need to execute Phan with php 7.0.Backwards incompatible changes:
- 🔒 Drop PHP 7.1 support. PHP 7.1 reached its end of life for security support in December 2019.
🚀 Many of Phan's dependencies no longer publish releases supporting php 7.1,
which will likely become a problem running Phan with future 8.x versions
🚀 (e.g. in the published phar releases). - ⬇️ Drop PluginV2 support (which was deprecated in Phan 2) in favor of PluginV3.
- ✂ Remove deprecated classes and helper methods.
🆕 New features(CLI, Config):
- Support
PHAN_COLOR_PROGRESS_BAR
as an environment variable to set the color of the progress bar.
👀 Ansi color names (e.g.light_blue
) or color codes (e.g.94
) can be used. (See src/Phan/Output/Colorizing.php)
🆕 New features(Analysis):
- Infer that
foreach
keys and values of possibly empty iterables are possibly undefined after the end of a loop. (#3898) - 👍 Allow using the polyfill parser to parse internal stubs. (#3902)
👍 (To support newer syntax such as union types, trailing commas in parameter lists, etc.)
🐛 Bug fixes
- 🛠 Fix handling of windows path separators in
phan_client
(from 2.7.3-dev) - 🛠 Fix a crash when emitting
PhanCompatibleAnyReturnTypePHP56
orPhanCompatibleScalarTypePHP56
for methods with no parameters. (from 2.7.3-dev)
- 🔒 Drop PHP 7.1 support. PHP 7.1 reached its end of life for security support in December 2019.