Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Tyson Andre
    @TysonAndre
    phan ±0198a2479⚡ » php internal/dump_fallback_ast.php --php-ast-native '$x = ($a & $b === $a);'
    AST_STMT_LIST [] #1
            0 => AST_ASSIGN [] #1
                    var => AST_VAR [] #1
                            name => x
                    expr => AST_BINARY_OP [BINARY_BITWISE_AND] #1
                            left => AST_VAR [] #1
                                    name => a
                            right => AST_BINARY_OP [BINARY_IS_IDENTICAL] #1
                                    left => AST_VAR [] #1
                                            name => b
                                    right => AST_VAR [] #1
                                            name => a
    So your code is buggy and should be $x = ($a & $b) === $a;
    PHP bases the precedence on C, which is the same for those operators
    Adrian
    @adrian-enspired
    oh holy cow : [ i even had the parenthesis on a similar statement in another function.
    thanks. sorry to bother.
    Tyson Andre
    @TysonAndre
    exclude_file_regex should be @(^(\./)?src/)@ since it's probably checking against ./src/
    Vladimir Belozyorov
    @VBelozyorov
    Thank you! phan -D output has confused me a little bit
    Adrian
    @adrian-enspired

    phan 2.7.3 is emittingPhanEmptyFQSENInClasslike with code like

    class C {
      /** @var string Fully Qualified Classname. */
      const FQCN = '';
    
      public function f() {
        if (! empty(static::FQCN)) {
          $fqcn = static::FQCN;
          new $fqcn();
        }
      }
    }

    shouldn't it be obvious to phan that $fqcn is a non-empty string?

    Tyson Andre
    @TysonAndre
    phan/phan#2495 is similar but not the cause - Phan currently doesn't infer anything about constants, class constants, function_exists(), etc in the local scope. Just variables, $this->prop, SomeClass::$static_prop, but not $other->prop
    The 2.x release line isn't supported, but 3.2.6 would have the same false positive
    Filed phan/phan#4286 to track the suggestion
    Adrian
    @adrian-enspired
    trait T { 
      /**
       * @phan-suppress PhanUndeclaredConstantOfClass
       */
      public function f() { echo static::X; }
    }
    
    class C { use T; }
    is there a way I can suppress the warning when analyzing the trait, but still see it when analyzing the class that uses it?
    Tyson Andre
    @TysonAndre

    Currently, no - in abstract classes declaring a class constant with /** @phan-abstract */ public const X = ''; would help detect classes that didn't override the constant, but that doesn't help in your use case because traits can't have class constants.

    • I think you might be able to do something with @mixin for a stub interface (e.g. .phan/stubs) with a abstract class constant but I don't know if that even works now and wouldn't rely on it even if it did work.
    • Phan only analyzes trait methods on the declaring trait right now, and there's no way to suppress something only on the declaring context

    There were discussions of allowing traits to have class constants or require implementing interfaces in php itself in some future php version

    Abstract methods would be how I typically would work around that, or to just keep suppressing it
    Eddie Kohler
    @kohler
    Hi all! Thanks for phan. Question: Is there a way to mark a class that inherits from, say, IteratorAggregate as being a kind of Iterator<T> for a specific T? For example, in the following code, I’d like Phan to emit a deprecation error on lines 19 and 26, but it only does so on line 26.
    <?php
    class X {
        /** @deprecated */
        public $x;
    }
    
    class Y implements IteratorAggregate {
        /** @var list<X> */
        public $xs;
        /** @return Iterator<X> */
        function getIterator() {
            return new ArrayIterator($this->xs);
        }
    }
    
    /** @param Y $y */
    function f1($y) {
        foreach ($y as $x) {
            echo $x->x;
        }
    }
    
    /** @param Y|Iterator<X> $y */
    function f2($y) {
        foreach ($y as $x) {
            echo $x->x;
        }
    }
    Tyson Andre
    @TysonAndre
    I initially thought that was a special case of phan/phan#824 or phan/phan#3238 but it wasn't - it's now fixed for that particular case in phan/phan@716c242 (see previous issues for remaining work)
    Adrian
    @adrian-enspired
    should covariant return types be expected to work with phan ^4.0 ? I found phan/phan#3795 but unclear if there was any movement on it.
    Adrian
    @adrian-enspired
    also seems there's a setting allow_method_param_type_widening but nothing like allow_method_return_type_narrowing
    Vladimir Belozyorov
    @VBelozyorov

    Hello! I have a question about

    input:22: PhanTypeNoPropertiesForeach Class \ActiveRecord was passed to foreach, but it does not extend Traversable and doesn't have any declared properties. (This check excludes dynamic properties)

    In this snippet

    If I remove ActiveRecord from union type on line 5, why Phan doesn't warn about passing null|int|string|bool to foreach? Why only non-traversable object instance bothers it?

    As you already guessed, in real code return type of that find() method depends on its arguments. Can I help Phan to define type in each case more precisely except of add exclusive @phan-var for each call of find()?

    Tyson Andre
    @TysonAndre

    PhanTypeMismatchForeach detects the case where there are no valid types, but if some of the types are valid, it doesn't warn. I don't believe that --strict-type-checking or similar options currently cover array|null - there's probably hundreds of issues for which a warning about being partially invalid could start being emitted

    https://github.com/phan/phan#readme

    Phan is a static analyzer for PHP that prefers to minimize false-positives.

    Vladimir Belozyorov
    @VBelozyorov
    But it warns about PhanTypeNoPropertiesForeachin the initial snippet while there is valid ActiveRecord[] in that union type, is it intentional?
    Vladimir Belozyorov
    @VBelozyorov
    Ahh! Seems it's just another kind of problem, I'm kind of understand now, thank you :)
    DDorrance90
    @DDorrance90
    Ok that's it I'm gonna do it. Gonna analyze a few small(ish) php 5.3/5.5 codebases and see if we can upgrade to 7.x
    Vladimir Belozyorov
    @VBelozyorov
    Hi! Is Phan intended to detect PHP Parse errors corresponding its target_php_version? Faced with overlooked one like this for PHP 5.6. It worth to mention that PHPStorm also doesn't show it while Netbeans IDE does. And this code become valid in PHP 7+
    Tyson Andre
    @TysonAndre

    https://github.com/phan/phan/wiki/Incrementally-Strengthening-Analysis#just-backward-compatibility

    If you are still using versions of php older than 5.6, PHP53CompatibilityPlugin may be worth looking into if you are not running syntax checks for php 5.3 through another method such as InvokePHPNativeSyntaxCheckPlugin or phan --native-syntax-check php53 (see .phan/plugins/README.md).

    For issues that php5.6 --syntax-check would check, I'd recommend using php5.6 --syntax-check in addition to Phan,, whether internally or externally - it's redundant to detect the hundreds of issue types that the syntax checks would already check for

    That would be phan --native-syntax-check /path/to/php53 assuming php5.6 is a binary in your PATH

    Is Phan intended to detect PHP Parse errors corresponding its target_php_version?
    It doesn't - it catches some of the parse/compile errors, in addition to incompatibilities (e.g. using string would mean a class named string in php 5.6 and not be detected by php56 --syntax-check)

    Also,

    If you are migrating from PHP 5 to PHP 7, you should also look into using php7cc (no longer maintained) and php7mar, which have different backwards compatibility checks.

    Vladimir Belozyorov
    @VBelozyorov
    Thank you for so detailed answer, @TysonAndre!