We have completed the Java code generator for all of the blockly blocks such that it runs
all of the unit test cases properly now that the mutators have been fixed for the dropdowns. You can see it
https://github.com/toebes-extreme/blocklyHowever before making a pull request, it is important to point out a couple of things that had to be done to make this work:
- We added a getVarsTypes: function to blocks which referenced variables so that the code generator could determine the type of the variable.
- We added Blockly.Variables.allVariablesTypes which calls the function and then determines the optimal type for the variable. If the blockly code shows conflicting types (such as treating x as both a String and a Number as the unit test cases do) then the function declares the variable to be of type Var.
- Because of the need for types, we changed arguments_ in procedures.js to be an array of hash of 'name' and 'type' instead of just being an array. This change was also made in the code generators. We looked at several options and realized that one thing that would be
very useful to have is the ability for a user to specify the types of
parameters in their blockly code so that they can take advantage of the
same type checking for the core blockly blocks with their own
procedures. For this we would need to know the type. Technically this
will require changing the UI to allow the user to specify the type, but
for now we wanted to get the code generator working without that change,
but allow for the possibility of it working in the future.
- In variables.js we added an onchange: function to determine if a variable is actually a local parameter to a subroutine and not a global variable (as demonstrated by the variable func a in function1 of the procedures.xml test case. One nice side effect of this change is that local parameter references automatically change their color to match the color of the procedure definition block as you can see in the attached screenshot.
- The Java code generator in generators/java.js overrides the workspaceToCode method in order to wrap the generated code with the proper imports/package/class definition and extended classes. This allows generating completely stand alone code with the exception of the standard JRE.
- Because Blockly assumes a typeless language, we created a new Java Var class which does comparisons and mutation of types consistent with the typeless environment when necessary. However the generate code is what a normal Java programmer would expect to see.
- When generating a function or procedure, the code generator generates different types for the parameters. However, it still generates a global variable of the same name even if it isn't referenced outside of the procedure.
- To determine the type of a parameter for a procedure, the code generator looks at both the usage of the local variable (if any) as well as all of the callers to see what type of parameter is passed in. Likewise the same algorithm is applied to looking at the return type from a function.
Some nice features of the generated Java code to be aware of
- We have carefully constructed the code to be what a Java programmer would write in their normal IDE including proper comments and indentation.
- The system optimizes the import of external Java classes to generate the minimum compiled code (i.e. no import something.*).
- Each generated file is put into a separate class and the generator can also be told of any base class to extend from by calling Blockly.Java.setBaseClass
With this amount of change - specifically with the types, I wanted to get some feedback on the best approach to proceed with a Pull request so that we can add Java to the list of standard languages. The current code base also includes the mutator and typeblock changes which would take some unmixing...
-- John