Skip to content

Commit

Permalink
Add warning on unknown operator
Browse files Browse the repository at this point in the history
  • Loading branch information
vemel committed Oct 28, 2019
1 parent 42a3cec commit 9257818
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 48 deletions.
65 changes: 33 additions & 32 deletions docs/handsdown/ast_parser/analyzers/expression_analyzer.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Prepares `parts` for `NodeRecord.render` method.

#### Attributes

- `UNKNOWN` - dummy value to replace unknown nodes and operators: `'...'`
- `BINOP_SYMBOLS` - representation map for binary operators: `{ast.Add: '+', ast.Sub: '-', ast.Mult: '*', ast...`
- `BOOLOP_SYMBOLS` - representation map for boolean operators: `{ast.And: 'and', ast.Or: 'or'}`
- `CMPOP_SYMBOLS` - representation map for comparison operators: `{ast.Eq: '==', ast.NotEq: '!=', ast.Lt: '<', as...`
Expand All @@ -65,7 +66,7 @@ Prepares `parts` for `NodeRecord.render` method.

### ExpressionAnalyzer().generic_visit

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L740)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L761)

```python
def generic_visit(node: ast.AST) -> None:
Expand All @@ -81,7 +82,7 @@ Logs warning with node class.

### ExpressionAnalyzer().visit_Attribute

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L168)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L171)

```python
def visit_Attribute(node: ast.Attribute) -> None:
Expand All @@ -101,7 +102,7 @@ my_object.attribute

### ExpressionAnalyzer().visit_BinOp

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L400)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L408)

```python
def visit_BinOp(node: ast.BinOp) -> None:
Expand All @@ -122,7 +123,7 @@ value + 1

### ExpressionAnalyzer().visit_BoolOp

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L419)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L432)

```python
def visit_BoolOp(node: ast.BoolOp) -> None:
Expand All @@ -143,7 +144,7 @@ a and b

### ExpressionAnalyzer().visit_Bytes

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L82)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L85)

```python
def visit_Bytes(node: ast.Bytes) -> None:
Expand All @@ -163,7 +164,7 @@ b"my_string"

### ExpressionAnalyzer().visit_Call

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L262)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L265)

```python
def visit_Call(node: ast.Call) -> None:
Expand All @@ -177,7 +178,7 @@ Parse info from `ast.Call` node and put it to `parts`.

### ExpressionAnalyzer().visit_Compare

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L379)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L382)

```python
def visit_Compare(node: ast.Compare) -> None:
Expand All @@ -198,7 +199,7 @@ value < 5

### ExpressionAnalyzer().visit_Dict

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L354)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L357)

```python
def visit_Dict(node: ast.Dict) -> None:
Expand All @@ -212,7 +213,7 @@ Parse info from `ast.Dict` node and put it to `parts`.

### ExpressionAnalyzer().visit_DictComp

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L662)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L683)

```python
def visit_DictComp(node: ast.DictComp) -> None:
Expand All @@ -232,7 +233,7 @@ Parse info from `ast.DictComp` node and put it to `parts`.

### ExpressionAnalyzer().visit_Ellipsis

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L564)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L585)

```python
def visit_Ellipsis(_node: ast.ASTEllipsis) -> None:
Expand All @@ -252,7 +253,7 @@ Parse info from `ast.Ellipsis` node and put it to `parts`.

### ExpressionAnalyzer().visit_FormattedValue

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L626)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L647)

```python
def visit_FormattedValue(node: ast.FormattedValue) -> None:
Expand All @@ -272,7 +273,7 @@ f"{formatted_value}"

### ExpressionAnalyzer().visit_GeneratorExp

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L721)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L742)

```python
def visit_GeneratorExp(node: ast.GeneratorExp) -> None:
Expand All @@ -292,7 +293,7 @@ Parse info from `ast.GeneratorExp` node and put it to `parts`.

### ExpressionAnalyzer().visit_Index

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L546)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L567)

```python
def visit_Index(node: ast.Index) -> None:
Expand All @@ -313,7 +314,7 @@ Union[Text]

### ExpressionAnalyzer().visit_JoinedStr

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L603)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L624)

```python
def visit_JoinedStr(node: ast.JoinedStr) -> None:
Expand All @@ -333,7 +334,7 @@ f'str: {my_string}'

### ExpressionAnalyzer().visit_Lambda

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L461)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L482)

```python
def visit_Lambda(node: ast.Lambda) -> None:
Expand All @@ -353,7 +354,7 @@ lambda x: x + 5

### ExpressionAnalyzer().visit_List

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L214)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L217)

```python
def visit_List(node: ast.List) -> None:
Expand All @@ -373,7 +374,7 @@ Parse info from `ast.List` node and put it to `parts`.

### ExpressionAnalyzer().visit_ListComp

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L683)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L704)

```python
def visit_ListComp(node: ast.ListComp) -> None:
Expand All @@ -393,7 +394,7 @@ Parse info from `ast.ListComp` node and put it to `parts`.

### ExpressionAnalyzer().visit_Name

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L113)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L116)

```python
def visit_Name(node: ast.Name) -> None:
Expand All @@ -413,7 +414,7 @@ my_value

### ExpressionAnalyzer().visit_NameConstant

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L128)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L131)

```python
def visit_NameConstant(node: ast.NameConstant) -> None:
Expand All @@ -434,7 +435,7 @@ True

### ExpressionAnalyzer().visit_Num

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L97)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L100)

```python
def visit_Num(node: ast.Num) -> None:
Expand All @@ -455,7 +456,7 @@ Parse info from `ast.Num` node and put it to `parts`.

### ExpressionAnalyzer().visit_Set

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L230)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L233)

```python
def visit_Set(node: ast.Set) -> None:
Expand All @@ -475,7 +476,7 @@ Parse info from `ast.Set` node and put it to `parts`.

### ExpressionAnalyzer().visit_SetComp

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L702)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L723)

```python
def visit_SetComp(node: ast.SetComp) -> None:
Expand All @@ -495,7 +496,7 @@ Parse info from `ast.SetComp` node and put it to `parts`.

### ExpressionAnalyzer().visit_Slice

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L578)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L599)

```python
def visit_Slice(node: ast.Slice) -> None:
Expand All @@ -519,7 +520,7 @@ Parse info from `ast.Slice` node and put it to `parts`.

### ExpressionAnalyzer().visit_Starred

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L317)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L320)

```python
def visit_Starred(node: ast.Starred) -> None:
Expand All @@ -539,7 +540,7 @@ Parse info from `ast.Starred` node and put it to `parts`.

### ExpressionAnalyzer().visit_Str

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L65)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L68)

```python
def visit_Str(node: ast.Str) -> None:
Expand All @@ -559,7 +560,7 @@ Parse info from `ast.Str` node and put it to `parts`.

### ExpressionAnalyzer().visit_Subscript

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L143)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L146)

```python
def visit_Subscript(node: ast.Subscript) -> None:
Expand All @@ -582,7 +583,7 @@ list[1:4]

### ExpressionAnalyzer().visit_Tuple

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L246)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L249)

```python
def visit_Tuple(node: ast.Tuple) -> None:
Expand All @@ -602,7 +603,7 @@ Parse info from `ast.Tuple` node and put it to `parts`.

### ExpressionAnalyzer().visit_UnaryOp

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L440)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L457)

```python
def visit_UnaryOp(node: ast.UnaryOp) -> None:
Expand All @@ -625,7 +626,7 @@ not True

### ExpressionAnalyzer().visit_arg

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L528)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L549)

```python
def visit_arg(node: ast.arg) -> None:
Expand All @@ -646,7 +647,7 @@ def my_func(arg: Text)

### ExpressionAnalyzer().visit_arguments

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L478)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L499)

```python
def visit_arguments(node: ast.arguments) -> None:
Expand All @@ -666,7 +667,7 @@ def my_func(arg, *args, **kwargs)

### ExpressionAnalyzer().visit_comprehension

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L642)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L663)

```python
def visit_comprehension(node: ast.comprehension) -> None:
Expand All @@ -686,7 +687,7 @@ for k in range(3) if k > 0 if True

### ExpressionAnalyzer().visit_keyword

[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L332)
[[find in source code]](https://github.com/vemel/handsdown/blob/master/handsdown/ast_parser/analyzers/expression_analyzer.py#L335)

```python
def visit_keyword(node: ast.keyword) -> None:
Expand Down
37 changes: 29 additions & 8 deletions handsdown/ast_parser/analyzers/expression_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ def __init__(self):
self._logger = get_logger()
self.parts = [] # type: List[DirtyRenderExpr]

# dummy value to replace unknown nodes and operators
UNKNOWN = "..."

# representation map for binary operators
BINOP_SYMBOLS = {
ast.Add: "+",
Expand Down Expand Up @@ -391,9 +394,14 @@ def visit_Compare(self, node):
"""
self.parts.append(node.left)
for index, right in enumerate(node.comparators):
operator = node.ops[index]
operator_class = type(node.ops[index])
self.parts.append(" ")
self.parts.append(self.CMPOP_SYMBOLS[type(operator)])
operator = self.CMPOP_SYMBOLS.get(operator_class, self.UNKNOWN)
if operator == self.UNKNOWN:
self._logger.warning(
"Unknown omparison operator: {}".format(operator_class.__name__)
)
self.parts.append(operator)
self.parts.append(" ")
self.parts.append(right)

Expand All @@ -412,7 +420,12 @@ def visit_BinOp(self, node):
"""
self.parts.append(node.left)
self.parts.append(" ")
self.parts.append(self.BINOP_SYMBOLS[type(node.op)])
operator = self.BINOP_SYMBOLS.get(type(node.op), self.UNKNOWN)
if operator == self.UNKNOWN:
self._logger.warning(
"Unknown binary operator: {}".format(node.op.__class__.__name__)
)
self.parts.append(operator)
self.parts.append(" ")
self.parts.append(node.right)

Expand All @@ -429,7 +442,11 @@ def visit_BoolOp(self, node):
Arguments:
node -- AST node.
"""
operator = self.BOOLOP_SYMBOLS[type(node.op)]
operator = self.BOOLOP_SYMBOLS.get(type(node.op), self.UNKNOWN)
if operator == self.UNKNOWN:
self._logger.warning(
"Unknown boolean operator: {}".format(node.op.__class__.__name__)
)
for index, value in enumerate(node.values):
if index:
self.parts.append(" ")
Expand All @@ -452,7 +469,11 @@ def visit_UnaryOp(self, node):
Arguments:
node -- AST node.
"""
operator = self.UNARYOP_SYMBOLS[type(node.op)]
operator = self.UNARYOP_SYMBOLS.get(type(node.op), self.UNKNOWN)
if operator == self.UNKNOWN:
self._logger.warning(
"Unknown unary operator: {}".format(node.op.__class__.__name__)
)
self.parts.append(operator)
if operator == "not":
self.parts.append(" ")
Expand Down Expand Up @@ -748,8 +769,8 @@ def generic_visit(self, node):
node -- AST node.
"""
self._logger.warning(
"Could not render node {}, replaced with `...`".format(
node.__class__.__name__
"Could not render node {}, replaced with `{}`".format(
node.__class__.__name__, self.UNKNOWN
)
)
self.parts.append("...")
self.parts.append(self.UNKNOWN)
Loading

0 comments on commit 9257818

Please sign in to comment.