eclipse-pdt / pdt

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

Missing error on autovivification on value other than undefined, null or array #202

Open the-liquid-metal opened 1 year ago

the-liquid-metal commented 1 year ago

Bug Description Missing error on autovivification on value other than undefined, null or array.

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;

use closure;
use stdClass;

class Test26 {
    public array   $propArray = [];
    public null    $propNull = null;
    public int     $propint = 10;
    public float   $propFloat = 20.34;
    public bool    $propBool = false;
    public string  $propString = "Hello";
    public object  $propObject;
    public closure $propClosure;
    /**
     * @var callable
     */
    public $propCallable;

    public static function statFunc() {
        echo "from statFunc\n";
    }
    public function __construct() {
        $this->propObject = new stdClass;
        $this->propCallable = [self::class, "statFunc"];
    }
}

function returnArray(): array {
    return [];
}

function returnNull(): null{
    return null;
}

function returnInt(): int {
    return 10;
}

function returnFloat(): float{
    return 20.34;
}

function returnBool(): bool {
    return false;
}

function returnString(): bool {
    return false;
}

function returnObject(): object {
    return new Test26;
}

function returnClosure(): closure {
    return fn($a) => $a;
}

function returnCallable(): callable {
    return [Test26::class, "statFunc"];
}

$myInst = new Test26;

// --- array value ------------------------------------------------------------
$var1a = [];
$var1a[] = 100; // OK

$var1b = returnArray();
$var1b[] = 100; // OK

$var1c = $myInst->propArray;
$var1c[] = 100; // OK

$closure1a = function() use ($var1a) {
    $var1a[] = 100; // OK
};

$closure1b = fn() => $var1a[] = 100; // OK

// --- null value -------------------------------------------------------------
$var2a = null;
$var2a[] = 100; // OK

$var2b = returnNull();
$var2b[] = 100; // OK

$var2c = $myInst->propNull;
$var2c[] = 100; // OK

$closure2a = function() use ($var2a) {
    $var2a[] = 100; // OK
};

$closure2b = fn() => $var2a[] = 100; // OK

// --- undefined variable -----------------------------------------------------
$var3[] = 100; // OK

// --- boolean value ----------------------------------------------------------
$var4a = false;
$var4a[] = 100; // this statement must trigger error

$var4b = returnBool();
$var4b[] = 100; // this statement must trigger error

$var4c = $myInst->propBool;
$var4c[] = 100; // this statement must trigger error

$closure4a = function() use ($var4a) {
    $var4a[] = 100; // this statement must trigger error
};

$closure4b = fn() => $var4a[] = 100; // this statement must trigger error

// --- int value --------------------------------------------------------------
$var5a = 10;
$var5a[] = 100; // this statement must trigger error

$var5b = returnInt();
$var5b[] = 100; // this statement must trigger error

$var5c = $myInst->propInt;
$var5c[] = 100; // this statement must trigger error

$closure5a = function() use ($var5a) {
    $var5a[] = 100; // this statement must trigger error
};

$closure5b = fn() => $var5a[] = 100; // this statement must trigger error

// --- float value ------------------------------------------------------------
$var6a = 20.34;
$var6a[] = 100; // this statement must trigger error

$var6b = returnFloat();
$var6b[] = 100; // this statement must trigger error

$var6c = $myInst->propFloat;
$var6c[] = 100; // this statement must trigger error

$closure6a = function() use ($var6a) {
    $var6a[] = 100; // this statement must trigger error
};

$closure6b = fn() => $var6a[] = 100; // this statement must trigger error

// --- string value -----------------------------------------------------------
$var7a = "Hello";
$var7a[] = 100; // this statement must trigger error

$var7b = returnString();
$var7b[] = 100; // this statement must trigger error

$var7c = $myInst->propString;
$var7c[] = 100; // this statement must trigger error

$closure7a = function() use ($var7a) {
    $var7a[] = 100; // this statement must trigger error
};

$closure7b = fn() => $var7a[] = 100; // this statement must trigger error

// --- object value -----------------------------------------------------------
$var8a = new Test26;
$var8a[] = 100; // this statement must trigger error

$var8b = returnObject();
$var8b[] = 100; // this statement must trigger error

$var8c = $myInst->propObject;
$var8c[] = 100; // this statement must trigger error

$closure8a = function() use ($var8a) {
    $var8a[] = 100; // this statement must trigger error
};

$closure8b = fn() => $var8a[] = 100; // this statement must trigger error

// --- closure value ----------------------------------------------------------
$var9a = fn($a) => $a*10;
$var9a[] = 100; // this statement must trigger error

$var9b = returnClosure();
$var9b[] = 100; // this statement must trigger error

$var9c = $myInst->propClosure;
$var9c[] = 100; // this statement must trigger error

$closure9a = function() use ($var9a) {
    $var9a[] = 100; // this statement must trigger error
};

$closure9b = fn() => $var9a[] = 100; // this statement must trigger error

// --- callable value ---------------------------------------------------------
$var10a = returnCallable();
$var10a[] = 100; // this statement must trigger error

$var10b = $myInst->propCallable;
$var10b[] = 100; // this statement must trigger error

$closure10a = function() use ($var10a) {
    $var10a[] = 100; // this statement must trigger error
};

$closure10b = fn() => $var10a[] = 100; // this statement must trigger error

// ----------------------------------------------------------------------------

function test(
    array    $argArray,
    null     $argNull,
    int      $argInt,
    float    $argFloat,
    bool     $argBool,
    string   $argString,
    object   $argObject,
    closure  $argClosure,
    callable $argCallable,
    ) {
        $argArray[] = 100;    // OK
        $argNull[] = 100;     // OK
        $argInt[] = 100;      // this statement must trigger error
        $argFloat[] = 100;    // this statement must trigger error
        $argBool[] = 100;     // this statement must trigger error
        $argString[] = 100;   // this statement must trigger error
        $argObject[] = 100;   // this statement must trigger error
        $argClosure[] = 100;  // this statement must trigger error
        $argCallable[] = 100; // this statement must trigger error
}

var_dump($var1a, $var1b, $var1c, $closure1a, $closure1b);
var_dump($var2a, $var2b, $var2c, $closure2a, $closure2b);
var_dump($var3);
var_dump($var4a, $var4b, $var4c, $closure4a, $closure4b);
var_dump($var5a, $var5b, $var5c, $closure5a, $closure5b);
var_dump($var6a, $var6b, $var6c, $closure6a, $closure6b);
var_dump($var7a, $var7b, $var7c, $closure7a, $closure7b);
var_dump($var8a, $var8b, $var8c, $closure8a, $closure8b);
var_dump($var9a, $var9b, $var9c, $closure9a, $closure9b);
var_dump($var10a, $var10b, $closure10a, $closure10b);