ExpressionVisitor and specific Javascript constructs

Denis Steckelmacher steckdenis at
Wed Apr 9 09:44:33 UTC 2014


Yesterday, I played a bit with the QML/JS plugin and its 
ExpressionVisitor class, and I have found a Javascript construct that is 
widely used but that I cannot easily parse using ExpressionVisitor:

var a = function() {
     var b = 5;
     return b;

This snippet exposes three areas where ExpressionVisitor has 
difficulties to find the type of expressions:

* In order to find the type of "a", I will create an ExpressionVisitor 
that will recursively visit the FunctionExpression and its child nodes, 
including the declaration of b and the return statement. When 
DeclarationBuilder will encounter "var b = 5", a new ExpressionVisitor 
will be created in order to find the type of "5", but this type was 
already found (and lost) by the first expression visitor.
* The return statement needs to change the return type of its enclosing 
function. As functions can be nested, I need a stack of FunctionType 
objects. This looks like an AbstractTypeBuilder.
* The return statement uses a variable, which was not yet declared when 
"var a = function" was encountered. ExpressionVisitor is therefore 
unable to set the return type to "int".

The first point is not a problem if we don't need absolute performance. 
The second and third points can be solved by adding support for 
FunctionExpressions in DeclarationBuilder: first "a" is declared with a 
type of "function void()", then DeclarationBuilder sees the 
FunctionExpression and opens a FunctionType, and finally 
DeclarationBuilder sees the return statement, now that b is declared, 
and can set the return type of the FunctionType of "a".

This is a possible solution, but it isn't very elegant (it duplicates 
type inference mechanisms between ExpressionVisitor and 
DeclarationBuilder). My previous experiment removed ExpressionVisitor 
and computed all the types in DeclarationBuilder. This seems suited to 
Javascript, where declarations frequently occur in expressions. Do you 
know another mean of solving this particular problem?

Denis Steckelmacher

More information about the KDevelop-devel mailing list