Incorrect scope visibility of locals defined with IF <var> IS <type? VAR <local>
See below, the scope of VAR variables is wrong:
FUNCTION Start() AS VOID
LOCAL o AS OBJECT
o := 123
IF o IS INT VAR n
END IF
? n // no compiler error, n shouldn't be visible here
o := "abc"
IF o IS INT VAR nnn
ELSEIF o IS STRING VAR ccc
ELSE
// ? nnn // error XS0103: The name 'nnn' does not exist in the current context, CORRECT
? ccc // no compiler error, ccc shouldn't be visible here
ENDIF
// ? nnn // error XS0103 CORRECT
// ? ccc // error XS0103 CORRECT
This may be a difficult one to solve. Take this example
IF o IS INT VAR nnn
? nnn
ELSEIF o IS STRING VAR ccc
? ccc
ELSE
? "Something else"
ENDIF
You could consider to transform this to:
IF o IS INT
VAR nnn := (INT) o
? nnn
ELSEIF o IS STRING
VAR ccc := (STRING) o
? ccc
ELSE
? "Something else"
ENDIF
That would work. But how to solve this
IF o IS INT VAR nnn .and. nnn > 100
? nnn
ELSE
? "Something else"
ENDIF
In that case, we need nnn available before the second condition is checked. Of course, we could do something like this
IF o IS INT
VAR nnn := (INT) o
IF nnn > 100
? nnn
GOTO $Label2
ELSE
GOTO $Label1 // not really needed
ENDIF
ENDIF
$Label1
? "Something else"
$Label2
But that quickly becomes complicated.
Btw: this problem was introduced with the code change for the DO CASE with 1000s of CASE branches, which could not be solved recursively anymore because it was generating a stack overflow. Internally IF ELSEIF ELSE is the same as DO CASE, CASE, OTHERWISE.
Robert,
I've given this some thought and played with it a bit, don't really like it being able to use an expression after the VAR
I'd prefer if the scope of the variables was correct instead, because as it is now, it's really bad, with some vars being visible out of scope and others not, in a seemingly random way.
I'll be showing this in my session in Munich, maybe something to discuss "live" with people in Munich.