Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we use an ast to extend stylint? #303

Open
lyt9304 opened this issue May 17, 2016 · 5 comments
Open

Can we use an ast to extend stylint? #303

lyt9304 opened this issue May 17, 2016 · 5 comments

Comments

@lyt9304
Copy link

lyt9304 commented May 17, 2016

Stylint is using line scan to check the code.
But I think Line Scan may be not strong enough for check code.
There are many things that we can't decide which one it is just through one line.
Using stylus ast could be easier to check some rules than line scan, and will have more accuracy.

Actually I'm working on extension of stylint because my company is using stylint to check our stylus code, and we have many requirements of stylint rules which is not supported yet.

And I use ast for some checking, it is very easy to check expression and definition.

It's very hard to parse or recognize complicated expression through regex, but using ast it will be very easy to gain the result of parsing expression.

Maybe we can use node scan instead of line scan in some rules, although the cost of time will be increasing.

It's just my little opinion for stylint improvment, may be it's not good.

Thank you for your time and opinions!

@SimenB
Copy link
Owner

SimenB commented May 17, 2016

I think using AST would be much preferable to regexes. I tried (for like an hour) some months ago to use the core stylus package to parse files, but I didn't get any way with it. Have you had success implementing it?

I suppose the best thing would be if somebody implemented stylus support as a postcss plugin, then you'd be able to use stylelint directly. postcss/postcss#602

@lyt9304
Copy link
Author

lyt9304 commented May 17, 2016

stylus exposed parse module, I tried:

    var Parser = require('stylus').Parser
    var parser = new Parser(file.toString())
    try {
      var ast = parser.parse() // get an ast
      ast = JSON.parse(JSON.stringify(ast))
    }catch(err){
      this.msg( 'Stylus parse error!' )
    }

the stylus code

$size = 1
div
  margin - $size
  font-size -(10px - 20px)

generates ast:

{
  "__type": "Root",
  "nodes": [
    {
      "__type": "Ident",
      "name": "$size",
      "val": {
        "__type": "Expression",
        "lineno": 1,
        "column": 9,
        "nodes": [
          {
            "__type": "Unit",
            "val": 1,
            "lineno": 1,
            "column": 9
          }
        ]
      },
      "mixin": false,
      "lineno": 1,
      "column": 9
    },
    {
      "__type": "Group",
      "nodes": [
        {
          "__type": "Selector",
          "inherits": true,
          "segments": [
            {
              "__type": "Literal",
              "val": "div",
              "string": "div",
              "prefixed": false,
              "lineno": 2,
              "column": 1
            }
          ],
          "optional": false,
          "lineno": 2,
          "column": 1
        }
      ],
      "block": {
        "__type": "Block",
        "scope": true,
        "lineno": 2,
        "column": 1,
        "nodes": [
          {
            "__type": "Property",
            "segments": [
              {
                "__type": "Ident",
                "name": "margin",
                "val": {
                  "__type": "Null"
                },
                "mixin": false,
                "lineno": 3,
                "column": 3
              }
            ],
            "lineno": 3,
            "column": 3,
            "expr": {
              "__type": "Expression",
              "lineno": 3,
              "column": 12,
              "nodes": [
                {
                  "__type": "UnaryOp",
                  "op": "-",
                  "expr": {
                    "__type": "Ident",
                    "name": "$size",
                    "val": {
                      "__type": "Null"
                    },
                    "mixin": false,
                    "lineno": 3,
                    "column": 12
                  },
                  "lineno": 3,
                  "column": 12
                }
              ]
            }
          },
          {
            "__type": "Property",
            "segments": [
              {
                "__type": "Ident",
                "name": "font-size",
                "val": {
                  "__type": "Null"
                },
                "mixin": false,
                "lineno": 4,
                "column": 3
              }
            ],
            "lineno": 4,
            "column": 3,
            "expr": {
              "__type": "Expression",
              "lineno": 4,
              "column": 26,
              "nodes": [
                {
                  "__type": "UnaryOp",
                  "op": "-",
                  "expr": {
                    "__type": "Expression",
                    "lineno": 4,
                    "column": 22,
                    "nodes": [
                      {
                        "__type": "BinOp",
                        "left": {
                          "__type": "Unit",
                          "val": 10,
                          "type": "px",
                          "lineno": 4,
                          "column": 15
                        },
                        "right": {
                          "__type": "Unit",
                          "val": 20,
                          "type": "px",
                          "lineno": 4,
                          "column": 22
                        },
                        "op": "-",
                        "lineno": 4,
                        "column": 22
                      }
                    ]
                  },
                  "lineno": 4,
                  "column": 26
                }
              ]
            }
          }
        ]
      },
      "lineno": 1,
      "column": 10
    }
  ]
}

Then I use BFS/DFS to traversal the tree, and doing some check with node unit.

@rossPatton
Copy link
Collaborator

this would be much preferable to regex. when I started this project I wasn't aware of AST, looking back I would have gone that route instead

i would prefer the postcss route - it seems like things are going in that direction

it might even make more sense to just have a preset for tools like https:/stylelint/stylelint (which I find to be very lacking, but it is an AST powered extendable linter, so we could make it more useful for stylus users)

@PhiLhoSoft
Copy link

CSSLint and Stylelint are merging... CSSLint/csslint#668
Would be nice to add stylint to the effort! 😉

@SimenB
Copy link
Owner

SimenB commented Jul 29, 2016

Great that they're merging, not sure it matters much to this effort though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants