Giter Site home page Giter Site logo

haxe-checkstyle's Introduction

logo

License Release Haxe-Checkstyle Linux Codecov

Haxe Checkstyle is a static analysis tool to help developers write Haxe code that adheres to a coding standard.

It automates the process of checking Haxe code to spare developers of this boring (but important) task.

Code conventions improve readability, allowing team members to understand each other's code better.

Ideal for any project that wants to enforce coding conventions.

Static analysis is usually performed as part of a code review.

Code Climate

Haxe Checkstyle is available on the Code Climate platform (free for open source projects). It requires a .codeclimate.yml file and an optional but recommended checkstyle.json file to be added to the root of your repository - see here for more details.

When everything is set up, Code Climate automatically runs Haxe Checkstyle for you on each new commit (also on pull requests if configured that way).

The current number of issues can be tracked via a badge:

Immediate results, right in your pull requests.

codeclimate-pr

Installation

haxelib install checkstyle

Basic Usage

haxelib run checkstyle -s src

Automatic detection of your coding style (experimental)

haxelib run checkstyle -s src --detect detectedCheckstyle.json

VSCode integration

There is a VSCode extension for haxe-checkstyle available in the VSCode marketplace. It is currently built with haxe-checkstyle v2.4.1 and tokentree v1.0.1. You can view the development version here: vscode-checkstyle

Compiling checkstyle

git clone https://github.com/HaxeCheckstyle/haxe-checkstyle.git
npm install
lix download
haxe buildAll.hxml # for Neko and NodeJS version + run Unittests and create schema
haxe buildCpp.hxml # for C++ version

Compiling with Haxe 3

git clone https://github.com/HaxeCheckstyle/haxe-checkstyle.git
mv haxe_libraries haxe4_libraries
mv haxe3_libraries haxe_libraries
npm install
lix use haxe 3.4.7
lix download
haxe buildAll.hxml # for Neko and NodeJS version + run Unittests and create schema
haxe buildCpp.hxml # for C++ version

Reference

More information and reference.

Issues Stories in Ready

Found any bug? Please create a new issue.

Coverage

codecov.io

Licensing Information

This content is released under the MIT license.

This project was derived from haxelint created by @mcheshkov.

Contributor Code of Conduct

Code of Conduct is adapted from Contributor Covenant, version 1.4

haxe-checkstyle's People

Contributors

4emodan avatar adireddy avatar alexhaxe avatar chipshort avatar francoisvn avatar gama11 avatar nickbanspach avatar pypmannetjies avatar qwertykg avatar realyuniquename avatar seraku24 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

haxe-checkstyle's Issues

Default naming conventions

@AlexHaxe Hey Alex, I have just noticed that you are allowing underscore _ for lot of naming checks like Classes, Typedefs, Interfaces, Parameters, Members, etc.

Can you please change that and not allow underscore by default. Underscore should only be used for constants and everything else should be upper/lower camel case.

I don't think we should even allow customisation of these regular expressions but for now I am fine with it.

For example check the java coding conventions
http://www.oracle.com/technetwork/java/codeconventions-135099.html

I also think there is some level of duplication in naming checks and we should refactor them.

Let me know what you think.

Wrong curly braces issue reporting with macro reification.

Following code will raise an issue, but such usage of curly is correct:

var str = 'Hello, world';
var expr = macro for (i in 0...10) trace($v{str});

Issue:

Warning: LINE - 148: Left curly should be at EOL (only linebreak or comment after curly)

Macro reification can be determined by $ followed by one or zero characters. e.g.:

$varName;
$a{varName};
${varName.fieldVar};

If...else if... braces

Using else if construction:

if (condition) {
    someAction();
} else if (condition2) {
    anotherAction();
}

produces an issue:

Warning: LINE - 264: No braces used for body of else branch

Related part of checkstyle config:

       {
            "type"  : "NeedBraces",
            "props" : {
                "severity"                 : "WARNING",
                "allowSingleLineStatement" : true,
                "tokens"                   : ["IF", "ELSE_IF", "FOR", "WHILE", "TRY", "CATCH"]
            }
        },

Is there a way to allow else if without surrounding if with curly braces?

Check for if / switch / for / while spacing

There are (at least) two different styles you might want to enforce here:

if ( / switch ( / for ( and while (

or

if( / switch( / for( and while(

I don't think there currently is a check that handles this.

Check for spaces around assignment

There are two different styles you might want to enforce here:

var c:Int = 0;

function foo(b:Bool = false)
{
    var a = b;
}

and

var c:Int=0;

function foo(b:Bool=false)
{
    var a=b;
}

Check for function parameters with default value null

I prefer this:

function foo(?a:Array<Int>) {}

to this:

function foo(a:Array<Int> = null) {}

Both are effectively the same - one might want to enforce one or the other depending on preference.

There's also the possibility of having both, which is redundant:

function foo(?a:Array<Int> = null) {}

Single line class declaration when no fields needed

Is there a way to make one line type declaration code pass LeftCurly checks when declared type has no fields?

class MyChild1 extends MyParent {}
class MyChild2 extends MyParent {}
class MyChild3 extends MyParent {}

I have following rule which fails on above code:

{
            "type"  : "LeftCurly",
            "props" : {
                "severity" : "WARNING",
                "option"   : "nl",
                "tokens"   : [
                    "CLASS_DEF",
                    "ENUM_DEF",
                    "ABSTRACT_DEF",
                    "INTERFACE_DEF"
                ]
            }
        }

Produces these errors:

Warning: LINE - 12: LeftCurly - Left curly should be on new line (only whitespace before curly)
Warning: LINE - 13: LeftCurly - Left curly should be on new line (only whitespace before curly)
Warning: LINE - 14: LeftCurly - Left curly should be on new line (only whitespace before curly)

WhitespaceAround: "Invalid field access : tok"

This one needs surprisingly much code to be reproduced.

#if true
@:forward
abstract Test(Int) {
    function foo(nullableArg:Null<Int>) {}
}
#else
import haxe.ds.ArraySort;
class Test {}
#end
./source/Test.hx:1: character 0 : Error: Check WhitespaceAround failed: Invalid field access : tok

Refactor AnonymousCheck

AnonymousCheck is currently using string search to determine if Anonymous structure is used and this should be refactored.

MemberName doesn't work on properties

class Test
{
    public var Example(default, null):Int;
}
{
    "type": "MemberName",
    "props": {
        "severity": "WARNING",
        "format": "^[a-z][a-zA-Z0-9]*$",
        "tokens": [
            "CLASS",
            "PUBLIC"
        ]
    }
}

The check produces a match if the (default, null) is removed. Looks like the check only matches FVar, but not FProp.

token-tree branch

@AlexHaxe Just creating this to keep track of changes in token-tree branch

I am thinking of releasing v2 will all the new checks and features from token-tree branch.

Please prepare release notes highlighting breaking changes if any and let me know whenever you want to release it.

Post all the details here for tracking until we release it.

WhitespaceAround gets stuck on conditionals

class Test
{
    public function new()
    {
        trace(#if true cast #end "text");
    }
}
{
    "checks": [
        {
            "type": "WhitespaceAround",
            "props": {
                "severity": "WARNING",
                "tokens": ["="]
            }
        }
    ]
}

Seems to got into an endless loop with that code.

"Error: Buffer.add: cannot grow buffer" with large amount of source files

By a large amount, I mean my entire haxelib directory - seemed like a good way to find potential bugs. files.length in Checker#process() traces 9940.

It looks like checkstyle walks through the directories alphabetically - it gets to nape (4002 source files) before it stops with Error: Buffer.add: cannot grow buffer message. At that point The memory usage of the neko process is 144.000 K according to the task manager.

actuate: [1.8.4]
box2d: [1.2.3]
checkstyle: 1.2.2 [git]
compiletime: [2.5.1]
crashdumper: git [dev:C:\HaxeToolkit\haxe\lib/crashdumper/git]
createjs: [1.5.8]
csv: [0.4.0]
dox: git [dev:C:\HaxeToolkit\haxe\lib/dox/git]
firetongue: [git]
flixel-addons: [git]
flixel-demos: [git]
flixel-docs: git
flixel-editors: git [dev:C:\HaxeToolkit\haxe\lib/flixel-editors/git]
flixel-templates: [git]
flixel-tools: [git]
flixel-ui: [git]
flixel: 4.0.0 [git]
format: 3.0.5 3.1.1 [3.1.2]
gm2d: [3.3.4]
hamcrest: [1.2.1]
haxelib_client: 3.1.0-rc.3 3.1.0-rc.4 [3.2.0-rc.3]
hscript: [2.0.5]
hxargs: 1.0.0 3.0.0 git [dev:C:\HaxeToolkit\haxe\lib/hxargs/git]
hxcpp: 3.1.48 [3.2.102] 3.2.27 3.2.37 3.2.94 git
hxcs: [3.2.0]
hxjava: [3.2.0]
hxparse: 3.0.0 git [dev:C:\HaxeToolkit\haxe\lib/hxparse/git]
hxparser: git [dev:C:\HaxeToolkit\haxe\lib/hxparser/git]
hxtemplo: 3.0.0 git [dev:C:\HaxeToolkit\haxe\lib/hxtemplo/git]
layout: [1.2.0]
lime-samples: [2.3.0]
lime: 2.7.0 2.8.2 2.8.3 [2.9.0] git
linc_dialogs: git [dev:C:\HaxeToolkit\haxe\lib/linc_dialogs/git]
markdown: [1.0.0]
mconsole: [1.6.0]
mcover: [2.0.3] 2.1.1
mlib: [2.0.2]
munit: 2.1.0 [2.1.2]
nape: [2.0.17] 2.0.18 diff
openfl-bitfive: git [dev:C:\HaxeToolkit\haxe\lib/openfl-bitfive/git]
openfl-samples: [2.2.2]
openfl: 3.4.0 3.5.2 3.5.3 3.6.0 [git]
poly2trihx: [0.1.4]
random: [1.4.1]
spinehaxe: git [dev:C:\HaxeToolkit\haxe\lib/spinehaxe/git]
spinehx: [0.2.0]
spritesheet: [1.2.0]
svg: 1.0.7 [1.0.8]
swf: 1.0.2 1.2.4 1.4.1 [1.8.4]
systools: [1.1.0]
task: [1.0.6]

Exit code

Could please add proper exit codes if any issues spotted?
Right now i have to parse report to find out if checks didn't pass.

BlockFormat fails with "return macro"

class Macro
{
    function build()
    {
        return macro
        {
            while (true)
                trace("");
        }
    }
}

Results in:

./source/Macro.hx:7:4: warning: First line of multiline block should contain only {
./source/Macro.hx:7:4: warning: Last line of multiline block should contain only } and maybe , or ;
./source/Macro.hx:7:4: warning: First line of multiline block should contain only {
./source/Macro.hx:7:4: warning: Last line of multiline block should contain only } and maybe , or ;

I don't think this should fail. No warnings reported without the macro, so I guess that's where the issue lies.

Checkstyle version: 191bf0c

Parsing failed: Unexpected extern

This one comes from the import haxe.extern.EitherType; I believe.

Stacktrace: 
Called from haxeparser/HaxeParser.hx line 602
Called from haxeparser/HaxeParser.hx line 513
Called from haxeparser/HaxeParser.hx line 504
Called from haxeparser/HaxeParser.hx line 504
Called from haxeparser/HaxeParser.hx line 495
Called from haxeparser/HaxeParser.hx line 261
Called from Checker.hx line 103
Called from Checker.hx line 122

Add a RedundantParenthesesCheck

Some people use cast /return / throw like functions by putting extra parens around them, which is misleading:

return (false);
var a:Array<Int> = cast(b);
throw("Something went wrong");

There might be more expressions than just these three.

Add a check for arguments with optional basic types and a non-null default

In almost all cases of code that looks like this, the author is not aware that ? implicitly turns basic types into Null<T> (non-basic types too, but that shouldn't really have any run-time implications for those).

function foo(?arg:Int = 0)  {} // the user probably didn't want a nullable type here

Nullable basic types on their own are fine, but them being nullable is pointless if they have a non-null default value as well. You can't get the argument to be null anyway (see here).

Note that there may be a use-case for nullable basic types with default-values if you want them to be skippable (skipping is only allowed for nullable arguments).

Duplicate checks: line length

LeftCurly does the same job as LineLength by checking the length of the line.
It would be better to remove that and only check for the position to keep things isolated.

Problems with `@:enum abstract`

Using token-tree branch against this code:

package sx.properties;


/**
 * Indicates orientation.
 *
 */
@:enum abstract Orientation (String)
{

    var Vertical   = 'vertical';
    var Horizontal = 'horizontal';

}//abstract Orientation

leads to various exceptions:

    Error: LINE - 1: Checker - Check LeftCurly failed: bad token Kwd(KwdEnum) != Const(CIdent(_))
Stacktrace: 
Called from TokenStream.hx line 33
Called from TokenTreeBuilder.hx line 95
Called from TokenTreeBuilder.hx line 39
Called from TokenTreeBuilder.hx line 23
Called from Checker.hx line 43
Called from checks/block/LeftCurlyCheck.hx line 62
Called from checks/Check.hx line 22
Called from Checker.hx line 155
    Error: LINE - 1: Checker - Check LeftCurly failed: bad token Kwd(KwdEnum) != Const(CIdent(_))
Stacktrace: 
Called from TokenStream.hx line 33
Called from TokenTreeBuilder.hx line 95
Called from TokenTreeBuilder.hx line 39
Called from TokenTreeBuilder.hx line 23
Called from Checker.hx line 43
Called from checks/block/LeftCurlyCheck.hx line 62
Called from checks/Check.hx line 22
Called from Checker.hx line 155
    Error: LINE - 11: MemberName - Invalid member signature: Vertical (name should be ~/^__[a-z][a-zA-Z0-9]*$/)
    Error: LINE - 12: MemberName - Invalid member signature: Horizontal (name should be ~/^__[a-z][a-zA-Z0-9]*$/)
    Error: LINE - 1: Checker - Check NeedBraces failed: bad token Kwd(KwdEnum) != Const(CIdent(_))
Stacktrace: 
Called from TokenStream.hx line 33
Called from TokenTreeBuilder.hx line 95
Called from TokenTreeBuilder.hx line 39
Called from TokenTreeBuilder.hx line 23
Called from Checker.hx line 43
Called from checks/block/NeedBracesCheck.hx line 50
Called from checks/Check.hx line 22
Called from Checker.hx line 155

Related rules:

{
            "type"  : "LeftCurly",
            "props" : {
                "severity" : "WARNING",
                "option"   : "eol",
                "tokens"   : [
                    "TYPEDEF_DEF",
                    "FOR",
                    "IF",
                    "WHILE",
                    "SWITCH",
                    "TRY",
                    "CATCH"
                ]
            }
        },
        {
            "type"  : "LeftCurly",
            "props" : {
                "severity" : "WARNING",
                "option"   : "nl",
                "tokens"   : [
                    "CLASS_DEF",
                    "ENUM_DEF",
                    "ABSTRACT_DEF",
                    "INTERFACE_DEF"
                ]
            }
        },
{
            "type"  : "MemberName",
            "props" : {
                "severity" : "ERROR",
                "format"   : "^[a-z][a-zA-Z0-9]*$",
                "tokens"   : [
                    "PUBLIC",
                    "TYPEDEF"
                ]
            }
        },
        {
            "type"  : "MemberName",
            "props" : {
                "severity" : "ERROR",
                "format"   : "^__[a-z][a-zA-Z0-9]*$",
                "tokens"   : [
                    "PRIVATE"
                ]
            }
        },
{
            "type"  : "NeedBraces",
            "props" : {
                "severity"                 : "WARNING",
                "allowSingleLineStatement" : true,
                "tokens"                   : ["IF", "FOR", "ELSE_IF", "WHILE", "TRY", "CATCH"]
            }
        },

Also all fields of such abstract declared like var SomeField = 'someValue' should be treated as enum fields, but now they are treated as private members. Please, notice that such abstracts can have other 'normal' fields as well. For example:

@:enum abstract MyAbstract(Int) from Int to Int
{
    static public inline var NORMAL_CONST = 'hello, world';

    var EnumConstructor1 = 1;
    var EnumConstructor2 = 2;
    var EnumConstructor2 = 3;

    static public function doSomething () : Void trace(NORMAL_CONST);
}

ListenerName always check second parameter

the ListenerName check only checks the second argument of to validate the function name, not every API has the callback in the 2' argument.

also, it seems that it can't be suppressed

WhitespaceAround: * token triggers on star imports

I think star imports should be ignored when checking the * token, having whitespace there doesn't really make a lot of sense.

import haxe.macro.*;
./source/Test.hx:1: characters 18-19 : Warning: No whitespace around "*"

No license found

Hello,

I've noticed there's no license for your project. It may be worth adding one to clarify whether people can use it or not.

WhitespaceAround fails with multi var declarations

class Test
{
    function foo()
    {
        var x:Int, y:Int;
    }
}
{
    "type": "WhitespaceAround",
    "props": {
        "severity": "WARNING",
        "tokens": ["="]
    }
}
./source/Test.hx:1: character 0 : Error: Check WhitespaceAround failed: bad token Comma != Semicolon

Multiline IF conditions triggers an info

The following IF statement would result in an INFO.

if ( conditionOne == true &&
conditionTwo == true &&
conditionThree == true ||
(numberOne > 10 && numberTwo < 25) ) {
_coSomething();
}

the following will not result in any INFO or WARNING but it is more difficult to read for the developer.

if ( conditionOne == true && conditionTwo == true && conditionThree == true || (numberOne > 10 && numberTwo < 25)) {
_coSomething();
}

WhitespaceAround fails on conditional extends

class Base {}

class Test #if true extends Base #end {

}
./source/Test.hx:1: character 0 : Error: Check WhitespaceAround failed: bad token Sharp(if) != BrOpen

I have a feeling I'll find a lot more conditional-related issues if I keep looking.

Token tree builder

Just ran dev branch on one of my projects and saw the following. Tested HiddenFieldCheck and AvoidStarImport.

Error: LINE - 1: Checker - Check HiddenField failed: bad token POpen != Semicolon
Stacktrace: 
Called from TokenStream.hx line 46
Called from TokenTreeBuilder.hx line 258
Called from TokenTreeBuilder.hx line 116
Called from TokenTreeBuilder.hx line 52
Called from TokenTreeBuilder.hx line 41
Called from TokenTreeBuilder.hx line 23
Called from Checker.hx line 43
Called from checks/HiddenFieldCheck.hx line 28
Called from checks/Check.hx line 22
Called from Checker.hx line 155

Let me know if you need any more info.

I also created token-tree branch so that we can use dev branch for minor releases. Please use token-tree branch to continue your work.

BlockFormat check: allow comments after opening brace

Hi! Thanks for your tool, it's really one of the things Haxe needs most, I am looking into integrating it into our company workflow, however I found quite a bit of code like the following:

if (someComplexCheck) { // description of what the check actually means
   // ...
}

And I think it's not unreasonable to place those comments after the opening brace, so do you think checkstyle could have an option for the BlockFormat checker to allow comments after the opening brace?

refactor ReturnCheck

ReturnCheck is currently using string search to determine if a return occurs inside a field and this should be refactored.
e.g. anonymous functions inside a field body that return a value, even though the field itself returns Void (see CyclomaticComplexityChecks for false positives)

FlashDevelop-compatible character position output

For Flixel, I've setup a FlashDevelop .hxproj file to run checkstyle, which means the results are parsed and appear in the results panel, which is quite convenient (a double click takes you to the file at the specified line number).

However, this only works for the line numbers, not character positions - FlashDevelop expects a different format there.

Here's a Haxe error message (FD can handle this format):

C:/HaxeToolkit/haxe/lib/flixel/git/flixel/input/FlxBaseKeyList.hx:24: characters 1-8 : Unexpected private

I guess the question is mostly whether the output can simply be changed in the current text reporter, or if there's a need for a new reporter to maintain backwards compatibility.

BlockFormat: invalid field access with extra parens around cast

class Test
{
    function test()
    {
        cast (Type.createInstance(Array, []));
    }
}
./source/Test.hx:1:1: error: Check BlockFormat failed: Invalid field access : index
Stacktrace: 
Called from ExprUtils.hx line 138
Called from ExprUtils.hx line 198
Called from ExprUtils.hx line 163
Called from ExprUtils.hx line 190
Called from ExprUtils.hx line 173
Called from ExprUtils.hx line 109
Called from ExprUtils.hx line 130
Called from ExprUtils.hx line 51
Called from ExprUtils.hx line 20
Called from ExprUtils.hx line 14
Called from checks/BlockFormatCheck.hx line 31
Called from checks/Check.hx line 22
Called from Checker.hx line 155
Build succeeded

No issues with cast Type.createInstance(Array, []);.

Checkstyle version: 191bf0c

WhitespaceAround fails with @:overload

Reduced example from Promise.hx in the standard library:

extern class Promise<T>
{
    @:overload(function<T>(promise : Promise<T>) : Promise<T> {})
    @:overload(function<T>(thenable : Thenable<T>) : Promise<T> {})
    static function resolve<T>( value : T ) : Promise<T>;
}
./source/Test.hx:1: character 0 : Error: Check WhitespaceAround failed: bad token Const(CIdent(T)) != POpen

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.