compiler: impl syntax error detect for global kind

This commit fixes `test_global_parap_err_first` test in
[test_syntax.py](https://github.com/RustPython/RustPython/blob/master/Lib/test/test_syntax.py#L678) and implement the other syntax errors detection as cpython 3.8 provided for global symbol.

Below syntax error conditions are added.
* name {} is parameter and global
```python
>>>>> def test(a):
.....   global a
.....
SyntaxError: name 'a' is parameter and global at line 2 column 2
        global a
```
* annotated name {} can't be global
```python
>>>>> def test():
.....   a: int
.....   global a
.....
SyntaxError: annotated name 'a' can't be global at line 3 column 2
        global a
```
* name {} is assigned to before global description
```python
>>>>> a = 100
>>>>> def test():
.....   a = 10
.....   global a
.....
SyntaxError: name 'a' is assigned to before global declaration at line 3 column 2
        global a
```
* name {} is used prior to global declaration
```python
>>>>> a = 10
>>>>> def test():
.....   print(a)
.....   global a
.....
SyntaxError: name 'a' is used prior to global declaration at line 3 column 2
        global a
```

Signed-off-by: snowapril <sinjihng@gmail.com>
This commit is contained in:
snowapril committed 2021-08-17 21:14:13 +09:00
1 parent 25eeba86b8
commit 13bbefdd4e
2 files changed
+22 -3

No files matched your search

-2
View File
@@ -673,8 +673,6 @@ class SyntaxTestCase(unittest.TestCase):
def test_assign_del(self):
self._check_error("del f()", "delete")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_global_param_err_first(self):
source = """if 1:
def error(a):
+22 -1
View File
@@ -1120,12 +1120,33 @@ impl SymbolTableBuilder {
// Role already set..
match role {
SymbolUsage::Global => {
if !symbol.is_global() {
if symbol.is_parameter {
return Err(SymbolTableError {
error: format!("name '{}' is parameter and global", name),
location,
});
}
if symbol.is_referenced {
return Err(SymbolTableError {
error: format!("name '{}' is used prior to global declaration", name),
location,
});
}
if symbol.is_annotated {
return Err(SymbolTableError {
error: format!("annotated name '{}' can't be global", name),
location,
});
}
if symbol.is_assigned {
return Err(SymbolTableError {
error: format!(
"name '{}' is assigned to before global declaration",
name
),
location,
});
}
}
SymbolUsage::Nonlocal => {
if symbol.is_parameter {