...
Number: | GEP-8 |
Title: | Static Type Checking |
Version: | 6 7 |
Type: | Feature |
Status: | Draft |
Leader: | Cédric Champeau |
Created: | 2011-10-08 |
Last modification: | 2011-11-09 |
...
Feature | Example | Behaviour | Status | ||
|---|---|---|---|---|---|
Method does not exist |
| Complains about undefined method | Implemented | ||
Property does not exist |
| Complains about undefined property "y" | Implemented | ||
Assignment type checking |
| Assigning a String to an int is forbidden | Implemented | ||
Incompatible binary expressions |
| Checks that arguments of a binary expression are compatible (here, no 'plus' method is available | Implemented | ||
Possible loose of precision (1/2) |
| Complains about possible loose of precision | Implemented | ||
Possible loose of precision (2/2) |
| Will not complain because '2' can be represented as an int | Implemented | ||
Arrays components |
| Cannot assign an int value in an array of type String[] | Implemented | ||
Method return type check |
| Ensures that assignments are compatible with method return type | Implemented | ||
Explicit return type checking |
| Ensures that returned value is compatible with declared return type | Implemented | ||
Implicit return type checking |
| Ensures that returned value is compatible with declared return type | Implemented | ||
Implicit toString() |
| Implicit call to toString() | Implemented | ||
Basic type inference |
| Method calls as well as property access is checked against inferred type | Implemented | ||
Basic flow analysis |
| Last method call will not complain because type of 'o' at this point can be inferred | Implemented | ||
Instance of |
| Casts should not be necessary when type can be inferred from a previous instanceof check | Implemented | ||
DefaultGroovyMethods support |
| Method calls can be resolved against Groovy extension methods | In progress (no type inference for closure arguments) | ||
with |
| Static type checking should be aware of the "with" structure | In progress | ||
Categories |
| Compiler should be aware that extension method is found in a category | N/A (support will be limited as category support is inherently dynamic | ||
Groovy list constructor |
| Type checks the arguments and the number of arguments | Implemented | ||
Groovy map constructor |
| Type checks the properties and checks for wrong property names | Implemented | ||
Closure parameter types |
| Type checking the arguments when calling a closure | Implemented | ||
Closure return type inference |
| Closure return type can be infered from block | Implemented | ||
Method return type inference |
| Return type can be infered from a method if the method is itself annotated with @TypeChecked (or class is annotated with @TypeChecked) | Implemented | ||
Multiple assignments |
| In case of inline declaration, type check arguments. | Implemented | ||
Multiple assignments from a variable |
| In case of inline declaration, type check arguments. | Unsupported | ||
Generics |
| Type checking of generic parameters | Mostly implemented (some edge cases may fail) | ||
Spread operator |
| Type checking against component type | Implemented |
Open discussions
Closure parameter type inference
With the current version of the checker, idiomatic constructs like :
| Code Block |
|---|
['a','b','c'].collect { it.toUpperCase() } |
Are not properly recognized. You have to explicitly set the type of the "it" parameter inside the closure. It is because the expected parameter types of closures are unknown at compile time. There is a discussion about how to add this type information to source code so that the inference engine can deal with them properly.
Unification Types
In cases of for example "x instanceof A || x instanceof B" with A and B being unrelated we could still make an artificial union kind of type, that contains everthing present in A and B, to allow those kinds of method calls. The alternative to this is to allow only methods from Object here, which is less interesintg. This typing can also be used for multicatch, ensuring that a method call is only valid if it exists on each of the exceptions for the multicatch. In the current implementation (Okt-14-2011) the multicatch is already expanded at the point @TypeChecked will check. Meaning effectively this already represents a kind of union type, as the same code is in each catch block and thus the method call would fail, if the method is not available on each type. The proposed behaviour is therefore to align the instanceof case with multicatch.
...
