Allows you to intercept method calls before the type checker performs its own checks. This is useful if you want to replace the default type checking with a custom one for a limited scope. In that case, you must set the handled flag to true, so that the type checker skips its own checks.

afterMethodCall

Called When

Called once the type checker has finished type checking a method call

Arguments

MethodCall call

Usage

Code Block

afterMethodCall { call ->
// ...
}

Allow you to perform additional checks after the type checker has done its own checks. This is in particular useful if you want to perform the standard type checking tests but also want to ensure additional type safety, for example checking the arguments against each other.

Note that afterMethodCall is called even if you did beforeMethodCall and set the handled flag to true.

onMethodSelection

Called When

Called by the type checker when it finds a method appropriate for a method call

The type checker works by inferring argument types of a method call, then chooses a target method. If it finds one that corresponds, then it triggers this event. It is for example interesting if you want to react on a specific method call, such as entering the scope of a method that takes a closure as argument (as in builders).

Please note that this event may be thrown for various types of expressions, not only method calls (binary expressions for example).

methodNotFound

Called When

Called by the type checker when it fails to find an appropriate method for a method call

methodNotFound { receiver, name, argList, argTypes, call ->
// receiver is the inferred type of the receiver
// name is the name of the called method
// argList is the list of arguments the method was called with
// argTypes is the array of inferred types for each argument
// call is the method call for which we couldn't find a target method
}

Unlike onMethodSelection, this event is sent when the type checker cannot find a target method for a method call (instance or static). It gives you the chance to intercept the error before it is sent to the user, but also set the target method.

For this, you need to return a list of MethodNode. In most situations, you would either return:

an empty list, meaning that you didn't find a corresponding method

a list with exactly one element, saying that there's no doubt about the target method

If you return more than one MethodNode, then the compiler would throw an error to the user stating that the method call is ambiguous, listing the possible methods.

For convenience, if you want to return only one method, you are allowed to return it directly instead of wrapping it into a list.

The type checker will call this method before starting to type check a method body. If you want, for example, to perform type checking by yourself instead of letting the type checker do it, you have to set the handled flag to true.

This event can also be used to help defining the scope of your extension (for example, applying it only if you are inside method foo).

afterVisitMethod

Called When

Called by the type checker after type checking a method body

Arguments

MethodNode node

Usage

Code Block

afterVisitMethod { methodNode ->
// ...
}

Gives you the opportunity to perform additional checks after a method body is visited by the type checker. This is useful if you collect information, for example, and want to perform additional checks once everything has been collected.

beforeVisitClass

Called When

Called by the type checker before type checking a class

Arguments

ClassNode node

Usage

Code Block

beforeVisitClass { classNode ->
// ...
}

If a class is annotated with @TypeChecked, then before visiting the class, this event will be sent. It is also the case for inner classes defined inside a class annotated with @TypeChecked. It can help you define the scope of your extension, or you can even totally replace the visit of the type checker with a custom type checking implementation. For that, you would have to set the handled flag to true.

afterVisitClass

Called When

Called by the type checker after having finished the visit of a type checked class

Arguments

ClassNode node

Usage

Code Block

afterVisitClass { classNode ->
// perform additional checks
}

Called for every class being type checked after the type checker finished its work. This includes classes annotated with @TypeChecked and any inner/anonymous class defined in the same class with is not skipped.

incompatibleAssignment

Called When

Called when the type checker thinks that an assignment is incorrect, meaning that the right hand side of an assignment is incompatible with the left hand side.

Gives the developper the ability to handle incorrect assignments. This is for example useful if a class overrides setProperty, because in that case it is possible that assigning a variable of one type to a property of another type is handled through that runtime mechanism.

In that case, you can help the type checker just by telling it that the assignment is valid (using handled set to true).

ds

wsd

qw

qw

Of course, an extension script may consist of several blocks, and you can have multiple blocks responding to the same event. This makes the DSL look nicer and easier to write. However, reacting to events is far from sufficient. If you know you can react to events, you also need to deal with the errors, which implies several "helper" methods that will make things easier.