Skip to content

Instantly share code, notes, and snippets.

@csmoe
Last active July 31, 2023 13:09
Show Gist options
  • Save csmoe/e5ddf5f06b49db7fa3b6a75192f3fac1 to your computer and use it in GitHub Desktop.
Save csmoe/e5ddf5f06b49db7fa3b6a75192f3fac1 to your computer and use it in GitHub Desktop.
Get the rules of cpplint
# - pip3 install tree_sitter
# - git clone https://github.com/tree-sitter/tree-sitter-python
# - cd tree-sitter-python
# - downlaod cpplint.py into current dir
# - python parse_cpplint.py
import tree_sitter
import json
from pathlib import Path
from tree_sitter import Language, Parser
import sys
if sys.platform.startswith('linux'):
suffix = ".so"
elif sys.platform == "darwin":
suffix = ".dylib"
elif sys.platform == "win32":
suffix = ".dll"
else:
raise "unsupported platform"
Language.build_library(
'build/python' + suffix,
[
'./'
]
)
PY_LANGUAGE = Language('build/python' + suffix, 'python')
parser = tree_sitter.Parser()
parser.set_language(PY_LANGUAGE)
# the lints are emitted by a `error(_,_,err,..)` call, query this kind of call in the cpplint.py,
# the lint content cannot be parsed as its concated at runtime,
# returns the lint kind and callsite linenumber
def lints(code):
doc_query = '''
(call
function: (identifier) @fn
arguments: (argument_list ((_) (_) (string) @lint . (_)))
(#eq? @fn "error")
)
'''
query = PY_LANGUAGE.query(doc_query)
tree = parser.parse(bytes(code, 'utf8'))
lints = []
for node in traverse_tree(tree):
if node.type != "expression_statement":
continue
captures = query.captures(node)
if len(captures) < 2:
continue
else:
fn, _ = captures[0]
lint, _ = captures[1]
lints.append({
"name": code[lint.start_byte:lint.end_byte].strip(),
"url": "https://github.com/google/styleguide/blob/gh-pages/cpplint/cpplint.py#L" + str(fn.start_point[0] + 1)
})
return lints
def traverse_tree(tree):
cursor = tree.walk()
reached_root = False
while reached_root == False:
yield cursor.node
if cursor.goto_first_child():
continue
if cursor.goto_next_sibling():
continue
retracing = True
while retracing:
if not cursor.goto_parent():
retracing = False
reached_root = True
if cursor.goto_next_sibling():
retracing = False
if __name__ == "__main__":
contents = Path("cpplint.py").read_text()
lints = lints(contents.strip())
with open("cpplint.json", "w") as f:
json.dump(lints, f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment