eclipse-pdt / pdt

PHP Development Tools project (PDT)
https://eclipse.org/pdt
Eclipse Public License 2.0
189 stars 46 forks source link

Missing error on accessing undeclared/inaccessible instance property #225

Open the-liquid-metal opened 1 year ago

the-liquid-metal commented 1 year ago

Bug Description Missing error on accessing undeclared/inaccessible instance property.

Eclipse environment Version: 2023-06 (4.28.0) Build id: 20230608-1333 PDT: 8.0.0.202306050832

System

To Reproduce Steps to reproduce the behavior: copy-paste this script to the IDE

<?php
declare(strict_types=1);

namespace ns1\ns2;

class Test51 {
    public string $publicProp;
    protected string $protectedProp;
    private string $privateProp;

    public function fnInstance() {
        $this->publicProp = "foo";     // OK
        $this->protectedProp = "foo";  // OK
        $this->privateProp = "foo";    // OK
        $this->undefinedProp = "foo";  // this statement must display error

        echo $this->publicProp;     // OK
        echo $this->protectedProp;  // OK
        echo $this->privateProp;    // OK
        echo $this->undefinedProp;  // this statement must display error
    }
}

class MyStrictClass2 extends Test51 {
    public function fnInstance() {
        $this->publicProp = "foo";     // OK
        $this->protectedProp = "foo";  // OK
        $this->privateProp = "foo";    // this statement must display error
        $this->undefinedProp = "foo";  // this statement must display error

        echo $this->publicProp;     // OK
        echo $this->protectedProp;  // OK
        echo $this->privateProp;    // this statement must display error
        echo $this->undefinedProp;  // this statement must display error
    }
}

#[\AllowDynamicProperties]
class MyClassWithAnnotation1 {
    public string $publicProp;
    protected string $protectedProp;
    private string $privateProp;

    public function fnInstance() {
        $this->publicProp = "foo";     // OK
        $this->protectedProp = "foo";  // OK
        $this->privateProp = "foo";    // OK
        $this->undefinedProp = "foo";  // OK

        echo $this->publicProp;     // OK
        echo $this->protectedProp;  // OK
        echo $this->privateProp;    // OK
        echo $this->undefinedProp;  // OK
    }
}

class MyClassWithAnnotation2 extends MyClassWithAnnotation1 {
    public function fnInstance() {
        $this->publicProp = "foo";     // OK
        $this->protectedProp = "foo";  // OK
        $this->privateProp = "foo";    // OK
        $this->undefinedProp = "foo";  // OK

        echo $this->publicProp;     // OK
        echo $this->protectedProp;  // OK
        echo $this->privateProp;    // OK
        echo $this->undefinedProp;  // OK
    }
}

class MyClassWithMagicMethods1 {
    public string $publicProp;
    protected string $protectedProp;
    private string $privateProp;

    public function __set($name, $value) {
        $this->$name = $value;
    }

    public function __get($name) {
        return $this->$name;
    }

    public function fnInstance() {
        $this->publicProp = "foo";     // OK
        $this->protectedProp = "foo";  // OK
        $this->privateProp = "foo";    // OK
        $this->undefinedProp = "foo";  // OK

        echo $this->publicProp;     // OK
        echo $this->protectedProp;  // OK
        echo $this->privateProp;    // OK
        echo $this->undefinedProp;  // OK
    }
}

class MyClassWithMagicMethods2 extends MyClassWithMagicMethods1 {
    public function fnInstance() {
        $this->publicProp = "foo";     // OK
        $this->protectedProp = "foo";  // OK
        $this->privateProp = "foo";    // OK
        $this->undefinedProp = "foo";  // OK

        echo $this->publicProp;     // OK
        echo $this->protectedProp;  // OK
        echo $this->privateProp;    // OK
        echo $this->undefinedProp;  // OK
    }
}

$strict = new Test51;
$strict->publicProp = "foo";     // OK
$strict->protectedProp = "foo";  // this statement must display error
$strict->privateProp = "foo";    // this statement must display error
$strict->undefinedProp = "foo";  // this statement must display error

echo $strict->publicProp;     // OK
echo $strict->protectedProp;  // this statement must display error
echo $strict->privateProp;    // this statement must display error
echo $strict->undefinedProp;  // this statement must display error

$anno = new MyClassWithAnnotation1;
$anno->publicProp = "foo";     // OK
$anno->protectedProp = "foo";  // OK
$anno->privateProp = "foo";    // OK
$anno->undefinedProp = "foo";  // OK

echo $anno->publicProp;     // OK
echo $anno->protectedProp;  // OK
echo $anno->privateProp;    // OK
echo $anno->undefinedProp;  // OK

$magic = new MyClassWithMagicMethods1;
$magic->publicProp = "foo";     // OK
$magic->protectedProp = "foo";  // OK
$magic->privateProp = "foo";    // OK
$magic->undefinedProp = "foo";  // OK

echo $magic->publicProp;     // OK
echo $magic->protectedProp;  // OK
echo $magic->privateProp;    // OK
echo $magic->undefinedProp;  // OK

function myFunc(
    Test51           $strict,
    MyClassWithAnnotation1   $anno,
    MyClassWithMagicMethods1 $magic,
    ) {
        $strict->publicProp = "foo";     // OK
        $strict->protectedProp = "foo";  // this statement must display error
        $strict->privateProp = "foo";    // this statement must display error
        $strict->undefinedProp = "foo";  // this statement must display error

        echo $strict->publicProp;     // OK
        echo $strict->protectedProp;  // this statement must display error
        echo $strict->privateProp;    // this statement must display error
        echo $strict->undefinedProp;  // this statement must display error

        $anno->publicProp = "foo";     // OK
        $anno->protectedProp = "foo";  // OK
        $anno->privateProp = "foo";    // OK
        $anno->undefinedProp = "foo";  // OK

        echo $anno->publicProp;     // OK
        echo $anno->protectedProp;  // OK
        echo $anno->privateProp;    // OK
        echo $anno->undefinedProp;  // OK

        $magic->publicProp = "foo";     // OK
        $magic->protectedProp = "foo";  // OK
        $magic->privateProp = "foo";    // OK
        $magic->undefinedProp = "foo";  // OK

        echo $magic->publicProp;     // OK
        echo $magic->protectedProp;  // OK
        echo $magic->privateProp;    // OK
        echo $magic->undefinedProp;  // OK
}

$strict->fnInstance();
$anno->fnInstance();
$magic->fnInstance();
myFunc($strict, $anno, $magic);
(new MyStrictClass2)->fnInstance();
(new MyClassWithAnnotation2)->fnInstance();
(new MyClassWithMagicMethods2)->fnInstance();