Skip to content

Commit

Permalink
feat: add to allow use comments in other scopes that is not from a fu…
Browse files Browse the repository at this point in the history
…nction
  • Loading branch information
NiumXp committed Nov 15, 2023
1 parent 11cfe4a commit 2f4e4d4
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 33 deletions.
2 changes: 1 addition & 1 deletion norminette/norm_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"BRACE_NEWLINE": "Expected newline before brace",
"EXP_NEWLINE": "Expected newline after control structure",
"ARG_TYPE_UKN": "Unrecognized variable type",
"COMMENT_ON_INSTR": "Comment must be on its own line",
"COMMENT_ON_INSTR": "Comment must be on its own line or at end of a line",
"COMMA_START_LINE": "Comma at line start",
"MIXED_SPACE_TAB": "Mixed spaces and tabs",
"ATTR_EOL": "Function attribute must be at the end of line",
Expand Down
72 changes: 47 additions & 25 deletions norminette/rules/check_comment.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,56 @@
from norminette.rules import Rule

allowed_on_comment = ["COMMENT", "MULT_COMMENT", "SPACE", "TAB"]


class CheckComment(Rule):
def __init__(self):
super().__init__()
self.depends_on = []

def run(self, context):
"""
Comments are only allowed in GlobalScope.
Comments are forbidden inside functions and in the middle of instructions.
"""
i = context.skip_ws(0)
has_comment = False
while (
context.peek_token(i) is not None
and context.check_token(i, "NEWLINE") is False
):
if context.check_token(i, allowed_on_comment) is False:
if has_comment is True:
context.new_error("COMMENT_ON_INSTR", context.peek_token(i))
return True, i
elif context.check_token(i, ["COMMENT", "MULT_COMMENT"]) is True:
if (
context.scope.name != "GlobalScope"
or context.history[-1] == "IsFuncDeclaration"
):
context.new_error("WRONG_SCOPE_COMMENT", context.peek_token(i))
has_comment = True

tokens = []
while context.peek_token(i) and not context.check_token(i, "NEWLINE"):
token = context.peek_token(i)
tokens.append(token)
i += 1
i = context.skip_ws(0)
return False, 0

for index, token in enumerate(tokens):
if token.type in ("COMMENT", "MULT_COMMENT"):
if self.is_inside_a_function(context):
context.new_error("WRONG_SCOPE_COMMENT", token)
if index == 0 or self.is_last_token(token, tokens[index+1:]):
continue
context.new_error("COMMENT_ON_INSTR", token)

def is_inside_a_function(self, context):
if context.history[-2:] == ["IsFuncDeclaration", "IsBlockStart"]:
return True
if context.scope.__class__.__name__.lower() == "function":
return True
# Sometimes the context scope is a `ControlStructure` scope instead of
# `Function` scope, so, to outsmart this bug, we need check manually
# the `context.history`.
last = None
for index, record in enumerate(reversed(context.history)):
if record == "IsFuncDeclaration" and last == "IsBlockStart":
# Since the limited history API, we can't say if we're in a
# nested function to reach the first enclosing function, so,
# we'll consider that the user just declared a normal function
# in global scope.
stack = 1
index -= 1 # Jumps to next record after `IsBlockStart`
while index > 0 and stack > 0:
record = context.history[-index]
index -= 1
if record not in ("IsBlockStart", "IsBlockEnd"):
continue
stack = stack + (1, -1)[record == "IsBlockEnd"]
return bool(stack)
last = record
return False

def is_last_token(self, token, foward):
expected = ("SPACE", "TAB")
if token.type == "MULT_COMMENT":
expected += ("COMMENT", "MULT_COMMENT")
return all(it.type in ("SPACE", "TAB", "COMMENT", "MULT_COMMENT") for it in foward)
2 changes: 1 addition & 1 deletion norminette/rules/check_func_arguments_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def check_arg_format(self, context, pos):
p = 0
stop = ["COMMA", "RPARENTHESIS"]
if context.check_token(i, ["COMMENT", "MULT_COMMENT"]):
context.new_error("WRONG_SCOPE_COMMENT", context.peek_token(i))
# context.new_error("WRONG_SCOPE_COMMENT", context.peek_token(i))
i += 1
# if context.check_token(i, "NEWLINE"):
# context.new_error("NEWLINE_IN_DECL", context.peek_token(i))
Expand Down
10 changes: 5 additions & 5 deletions tests/rules/samples/test_file_1019.out
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,20 @@ test_file_1019.c: Error!
Error: INVALID_HEADER (line: 1, col: 1): Missing or invalid 42 header
Error: RETURN_PARENTHESIS (line: 8, col: 12): Return value must be in parenthesis
Error: FORBIDDEN_CHAR_NAME (line: 28, col: 9): user defined identifiers should contain only lowercase characters, digits or '_'
Error: COMMENT_ON_INSTR (line: 35, col: 25): Comment must be on its own line
Error: COMMENT_ON_INSTR (line: 35, col: 6): Comment must be on its own line or at end of a line
Error: COMMENT_ON_INSTR (line: 41, col: 10): Comment must be on its own line or at end of a line
Error: WRONG_SCOPE_COMMENT (line: 41, col: 10): Comment is invalid in this scope
Error: COMMENT_ON_INSTR (line: 41, col: 29): Comment must be on its own line
Error: COMMENT_ON_INSTR (line: 42, col: 10): Comment must be on its own line or at end of a line
Error: WRONG_SCOPE_COMMENT (line: 42, col: 10): Comment is invalid in this scope
Error: COMMENT_ON_INSTR (line: 42, col: 29): Comment must be on its own line
Error: TOO_MANY_FUNCS (line: 46, col: 1): Too many functions in file
Error: GOTO_FBIDDEN (line: 50, col: 1): Goto statements are forbidden
Error: LABEL_FBIDDEN (line: 52, col: 1): Label statements are forbidden
Error: TOO_MANY_FUNCS (line: 56, col: 1): Too many functions in file
Error: COMMENT_ON_INSTR (line: 62, col: 27): Comment must be on its own line or at end of a line
Error: WRONG_SCOPE_COMMENT (line: 62, col: 27): Comment is invalid in this scope
Error: COMMENT_ON_INSTR (line: 62, col: 47): Comment must be on its own line
Error: TOO_MANY_FUNCS (line: 66, col: 1): Too many functions in file
Error: COMMENT_ON_INSTR (line: 70, col: 14): Comment must be on its own line or at end of a line
Error: WRONG_SCOPE_COMMENT (line: 70, col: 14): Comment is invalid in this scope
Error: COMMENT_ON_INSTR (line: 70, col: 32): Comment must be on its own line
Error: TOO_MANY_FUNCS (line: 73, col: 1): Too many functions in file
Error: SPC_BEFORE_NL (line: 73, col: 17): Space before newline
Error: TOO_MANY_FUNCS (line: 78, col: 1): Too many functions in file
Expand Down
1 change: 0 additions & 1 deletion tests/rules/samples/test_file_210128.out
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
<RBRACE> <NEWLINE>
test_file_210128.c: Error!
Error: INVALID_HEADER (line: 1, col: 1): Missing or invalid 42 header
Error: WRONG_SCOPE_COMMENT (line: 1, col: 15): Comment is invalid in this scope
Error: WRONG_SCOPE_COMMENT (line: 5, col: 14): Comment is invalid in this scope
Error: WRONG_SCOPE_COMMENT (line: 5, col: 14): Comment is invalid in this scope
Error: WRONG_SCOPE_COMMENT (line: 5, col: 63): Comment is invalid in this scope
Expand Down

0 comments on commit 2f4e4d4

Please sign in to comment.