Type checking with fglcomp compiler
The fglcomp compiler is more strict regarding type checking.
Starting with Genero 3.10, the fglcomp compiler is now more strict when assigning complex types.
Any assignment potentially throwing runtime error -1260 is subject to the new compiler error -6631.
Note:
Assignments using primitive types such as CHAR
to INTEGER
are not checked, except for DATETIME
, INTERVAL
,
TEXT
and BYTE
assignments, which are candidates for runtime error
-1260.
Type checking errors are raised on:
- incompatible assignments in
LET variable = value
. - passing incompatible values to functions (user functions, built-in functions, C extensions).
- returned types of functions when the
FUNCTION
is defined with theRETURNS
clause.
Better type checks include:
- better predictions (for autocompletion in vim and Studio)
- being able to call methods on return values of methods.
For example, when assigning invalid object references to variables defined with a different
class:
$ cat tc1.4gl
MAIN
DEFINE sb base.StringBuffer
LET sb = "foo" -- illegal: assigns a String to a StringBuffer
END MAIN
With versions prior to 3.10, you get no compiler error, but an error at
runtime:
$ fglcomp -V
fglcomp 3.10.14
...
$ fglcomp tc1
$ fglrun tc1
Program stopped at 'tc1.4gl', line number 3.
FORMS statement error number -1260.
It is not possible to convert between the specified types.
With version 3.10, you get now a compiler
error:
$ fglcomp -V
fglcomp 3.10.03
...
$ fglcomp -M tc1
tc1.4gl:3:5:3:18:error:(-6631) incompatible types, found: CHAR, required: base. StringBuffer.
In the following example, the type returned by
base.Channel.create()
does not
match the variable
definition:$ cat tc2.4gl
MAIN
DEFINE sb base.StringBuffer
LET sb = base.Channel.create() -- what's the return type of base.Channel.create()?
END MAIN
$ fglcomp -M tc2
tc1.4gl:3:5:3:18:error:(-6631) incompatible types, found: base.Channel, required: base. StringBuffer.
This example tries to pass a
STRING
to a method whereas an
om.DomNode
is
expected:$ cat tc3.4gl
MAIN
DEFINE doc om.DomDocument
DEFINE n1, n2 om.DomNode
LET doc = om.DomDocument.createFromString("<Foo><Bar/></Foo>")
LET n1 = doc.getDocumentElement()
LET n2 = doc.getDocumentElement().getFirstChild()
LET n2 = n1.getFirstChild()
CALL n1.removeChild(n2) -- legal: n2 is an om.DomNode
CALL n1.removeChild("Bar") -- illegal: n2 is a STRING
END MAIN
$ fglcomp -M tc3.4gl
tc3.4gl:9:26:9:30:error:(-6631) incompatible types, found: CHAR, required: om.DomNode.
This example uses the return value of FGL-functions:
$ cat tc4.4gl
MAIN
DEFINE s STRING
LET s = function1() -- unchecked: return type unknown
LET s = function2() -- illegal: returns a base.Channel
LET s = function3() -- legal: returns a STRING
END MAIN
FUNCTION function1()
RETURN base.Channel.create()
END FUNCTION
FUNCTION function2() RETURNS base.Channel
RETURN base.Channel.create()
END FUNCTION
FUNCTION function3() RETURNS STRING
RETURN "foo"
END FUNCTION
$ fglcomp tc4.4gl
The compilation was not successful. Errors found: 1.
The file 'tc4.err' has been written.
$ cat tc4.err
MAIN
DEFINE s STRING
LET s = function1() -- unchecked: return type unknown
LET s = function2() -- illegal: returns a base.Channel
| incompatible types, found: base.Channel, required: STRING.
| See error number -6631.
LET s = function3() -- legal: returns a STRING
END MAIN
...