Monkey Code Keeper - Tool for developers

Hello, I am currently working on a couple of watchfaces, the last one I have created is My Day 24. And let's say, these tools for developers could be better :) Maybe I am too spoiled from C# and ReSharper plugin, but I wanted to have something better than the current Eclipse SDK.

Currently you can easily make a typo in a variable name, or copy paste some wrong code. The project still compiles and no errors are shown, but the app will crash on a real device in production. It is specially annoying if you have multiple files for each device (one file for Fenix 3, another for Vivoactive) and you change for example the number of parameters of a function, but just in one file. You will not see any crash on your device, but people will report you that it does not work.

So I have created a new tool, a desktop Windows app: http://bit.ly/codekeeper You can select your project folder with .mc files. You can leave this tool opened next to Eclipse, for example on a second monitor. And each time you save an .mc file, the tool will automatically refresh and show the warnings and errors. See screenshots attached.

What's implemented, errors:
- Variable is used, but it was not declared (or it is used before it was declared in the block)
- Function is called, but it was not declared in the same block (on in the global block)
- Function is called, but it has incorrect number of parameters
- Function is called on an instance of a class, but has incorrect number of parameters

Warnings:
- Variable was declared, but not used in the block
- Variable is declared more than once with the same name (for example in a global block and in the function)
- Function is declared more than once with the same number of parameters
- Variable was passed as a parameter of the function, but not used in the function
- Variable was initialized more than once by new keyword

Currently objects are not checked for null reference exception, it would require a better parser (with value propagation into functions and other blocks). I have also not tested yet the new 2.4.0 features like barells and jungle files. Also some weird constructs from the Monkey C language will most likely not work, but you can check it and see it. I have tested multiple Monkey C projects from Github, but there will always be some edge case where it will fail.

You can check the parsed tree (if the code was parsed correctly), or you can edit the list of system functions and variables that should be ignored. And if you are really interested, you will find a donate button on a Help / About screen :)

Download: http://bit.ly/codekeeper

Send me any feedback if you have. community.garmin.com/.../1296466.png community.garmin.com/.../1296467.png community.garmin.com/.../1296468.png community.garmin.com/.../1296469.png community.garmin.com/.../1296470.png
  • Great tool! Thank you!

    Issues found:
    - App does not detect keywords like and, or.
    - Output window is empty, however, specified non-zero warnings.

    community.garmin.com/.../1297271.png
  • Thank you for your report!

    These 3 warnings are those "not used parameters in functions". If you uncheck the last checkbox, you will see them.

    I will look on the keywords "like, and, or". Do you have any example of the code?
  • Error 1:
    Variable and is not declared in else
    I assume all reserved words should be handled properly.
    if (
    info has :altitude and //info.altitude != null and
    info has :pressure and //info.pressure != null and
    info has :temperature // and info.temperature != null
    ) {
    .... some stuff here
    }
    else {
    flInvalid = true;
    }



    Error 2:
    Function method is not declared in class
    String in red is the line with error:
    function onMenu() {
    notify.invoke(lbl_ex_request); // "Executing\nrequest"

    Message does not tell me any valuable info, code works in reality.

    Error 3:
    Variable longZone is not declared in if
    Variable easting is not declared in if
    But there is no if statement here at all.
    function getDigraph1(longZone, easting)
    {
    var a1 = longZone;
    var a2 = 8 * ((a1 - 1) % 3) + 1;

    var a3 = easting;
    var a4 = a2 + ((a3 / 100000).toLong()) - 1;
    return digraph1_get(Math.floor(a4).toNumber());
    }



    NB. I already found one error in my project (code never reached, created by copypaste method). Thanks again!
  • It seems that the "and" keyword has broke it and other errors were just a consequence. I did not see it in the list keywords here, so I forgot to handle it.

    You can try the version 1.02: http://bit.ly/codekeeper
  • Thanks, Error 1 fixed. Others are from different projects and files. You can use SDK Examples (Error 2 is the same in WebRequest) from c:\Garmin\SDK\connectiq-sdk-win-2.4.2\samples\ to train your app.
  • Examples in source code:
    https://github.com/gcoder75/DividedTime

    If function is declared in class, but used before it was declared, app shows an error on string it was used.
  • Thank you, I will look on it. I plan to release a new version in a few days, there were some other problems: static constants in an inner class were not detected correctly, default methods inherited from an Object class were ignored, switch statement was not parsed correctly...
  • Hello, here is a new version 1.0.3: http://bit.ly/codekeeper

    I fixed a couple of issues, the tool now works on all samples in the 2.4.2 SDK.

    There is still one issue detected in your code, but I cannot do much more with it :) This tool was designed to work in 95% cases, but it uses it's own language parser and does not have access to the SDK. Monkey C is a very dynamic language, sometimes I can just guess these types... For your information, this is the error:

    Error: Variable floorsClimbed is not declared in function getFloorClimbed, source\WatchFaceToolBox.mc, line 266

    [FONT=courier new]function getFloorClimbed(info) {
    return (info.floorsClimbed).toString();
    }[/FONT]

    This method is not called from this class, so I don't know what type is the info variable. So I can look to the rest of the project to other classes. In DividedTimeView I can find this:

    [FONT=courier new]upperTextRight = toolBox.getFloorClimbed(info);[/FONT]

    That's nice, so I can look on the declaration. But there is no "info = new MyClass", so the info variable is not an instance of a class from my project. I can find only this:

    [FONT=courier new]var info = Act.getInfo();[/FONT]

    I can look on usings that the Act is just a different name for an ActivityMonitor:

    [FONT=courier new]using Toybox.ActivityMonitor as Act;[/FONT]

    I still don't know which methods this class have, or which type is returned by the Act.getInfo() method, because I don't have access to the SDK, just to the project. So I cannot infer the type of the variable and that means, I need to show an error :)

    But otherwise I think it works fine, for most of the cases.
  • This code was an example, not mine.
    Just like an idea - use native list of variables, constants, functions, available in SDK.
    c:\Garmin\SDK\connectiq-sdk-win-2.4.2\bin\api.debug.xml
    c:\Garmin\SDK\connectiq-sdk-win-2.4.2\bin\api.db
    It should be reworked and include some classification to be suitable for your tool.
    I.e. <entry field="true" id="8389872" symbol="floorsClimbed"/>
    <annotationEntry annotation="minSdk(&quot;2.1.0&quot" class="Info" module="Toybox_ActivityMonitor" symbol="floorsClimbed"/>
    <annotationEntry annotation="hasFloorsClimbed" class="Info" module="Toybox_ActivityMonitor" symbol="floorsClimbed"/>

    So at least you can see, floorsClimbed is a field, available in Toybox->ActivityMonitor->Info class. That's true.

    Checked all projects I have, no issues found anymore. Great tool!
  • May be this tool can be included into SDK some day.