Repository: LordGolias/sqf

Issue:
scope warning when using _this in spawned code block
`[2,13]:warning:Local variable "_this" is not from this scope (not private)` when running sqflint over

```sqf
_this spawn {
    hint str _this;
};
```
it does *not* complain when the code block is *call*ed, though.


Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/18793148/badge)](https://coveralls.io/builds/18793148)

Coverage increased (+0.001%) to 98.92% when pulling **85dd0013e90f63127e2afd18cc4f3631b3c03a1a on gruppe-adler:scopefix** into **a9a1de31e439742cc5391c6ca7e4cd7f2c2bdf15 on LordGolias:master**.

LordGolias: Thanks a lot for this PR. 

I like the idea. I think that we can do better than this though: when spawn is called, `_this` has the type passed by its argument. Therefore, we know the type of `_this`.

For example, 

```
"foo" spawn {sleep _this}
```
should return a type error as `_this` is of type String instead of Number.

What do you think? Do you see any reason to not have this altogether?
Fusselwurm: @LordGolias works, I guess :)

Patch:
diff --git a/sqf/analyzer.py b/sqf/analyzer.py
index 1c55885..b4ceea7 100644
--- a/sqf/analyzer.py
+++ b/sqf/analyzer.py
@@ -426,7 +426,7 @@ class Analyzer(BaseInterpreter):
             elif case_found.keyword == Keyword('catch'):
                 extra_scope = {'_exception': Anything()}
             elif case_found.keyword == Keyword('spawn'):
-                extra_scope = {'_thisScript': Script()}
+                extra_scope = {'_thisScript': Script(), '_this': values[0]}
             elif case_found.keyword == Keyword('do') and type(values[0]) == ForType:
                 extra_scope = {values[0].variable.value: Number()}
             for value, t_or_v in zip(values, case_found.types_or_values):


Test patch:
diff --git a/tests/test_analyzer.py b/tests/test_analyzer.py
index b12b769..91bc548 100644
--- a/tests/test_analyzer.py
+++ b/tests/test_analyzer.py
@@ -1052,11 +1052,21 @@ class SpecialContext(TestCase):
         analyzer = analyze(parse(code))
         self.assertEqual(analyzer.exceptions, [])
 
-    def test_spawn(self):
+    def test_spawn_thisScript(self):
         code = '[] spawn {x = _thisScript}'
         analyzer = analyze(parse(code))
         self.assertEqual(len(analyzer.exceptions), 0)
 
+    def test_spawn_this_typing_correct(self):
+        code = '"" spawn {hint _this}'
+        analyzer = analyze(parse(code))
+        self.assertEqual(len(analyzer.exceptions), 0)
+
+    def test_spawn_this_typing_error(self):
+        code = '[] spawn {hint _this}'
+        analyzer = analyze(parse(code))
+        self.assertEqual(len(analyzer.exceptions), 1)
+
     def test_spawn_local_vars(self):
         # spawn should not use local variables because they may become undefined (error 1). Likewise,
         # the local variable becomes unused (error 2).