@@ -216,20 +216,23 @@ namespace pxt.py {
216216 }
217217
218218 function addImport ( a : AST , name : string , scope ?: ScopeDef ) {
219- const v = defvar ( name , { isPlainImport : true } , scope )
220219 const sym = lookupGlobalSymbol ( name )
221220 if ( ! sym )
222221 error ( a , U . lf ( "No module named '{0}'" , name ) )
223- else
224- unify ( a , v . type , symbolType ( sym ) )
225- return v
222+ return sym
226223 }
227224
228225 function defvar ( n : string , opts : py . VarDescOptions , scope ?: ScopeDef ) {
229- let scopeDef = scope || currentScope ( )
230- let v = scopeDef . vars [ n ]
226+ if ( ! scope )
227+ scope = currentScope ( )
228+ let v = scope . vars [ n ]
231229 if ( ! v ) {
232- v = scopeDef . vars [ n ] = { type : mkType ( ) , name : n }
230+ let qn = getFullName ( scope ) + "." + n
231+ if ( isLocalScope ( scope ) )
232+ v = mkSymbol ( SK . Variable , qn )
233+ else
234+ v = addSymbol ( SK . Variable , qn )
235+ scope . vars [ n ] = v
233236 }
234237 for ( let k of Object . keys ( opts ) ) {
235238 ( v as any ) [ k ] = ( opts as any ) [ k ]
@@ -245,6 +248,7 @@ namespace pxt.py {
245248 return t
246249 }
247250
251+ // TODO cache it?
248252 function getFullName ( n : py . AST ) : string {
249253 let s = n as py . ScopeDef
250254 let pref = ""
@@ -381,29 +385,48 @@ namespace pxt.py {
381385 }
382386 }
383387
384- function addSymbol ( kind : SK , qname : string ) {
385- let sym = internalApis [ qname ]
386- if ( sym ) return sym
388+ function mkSymbol ( kind : SK , qname : string ) : SymbolInfo {
387389 let m = / ( .* ) \. ( .* ) / . exec ( qname )
388- sym = {
390+ return {
389391 kind : kind ,
390392 name : m ? m [ 2 ] : qname ,
391393 qName : qname ,
392394 namespace : m ? m [ 1 ] : "" ,
393395 attributes : { } as any ,
394- pyRetType : mkType ( ) ,
396+ pyRetType : mkType ( )
395397 } as any
398+ }
399+
400+ function addSymbol ( kind : SK , qname : string ) {
401+ let sym = internalApis [ qname ]
402+ if ( sym ) return sym
403+ sym = mkSymbol ( kind , qname )
396404 internalApis [ sym . qName ] = sym
397405 return sym
398406 }
399407
400- function addSymbolFor ( k : SK , n : py . Symbol ) {
408+ function isLocalScope ( scope : ScopeDef ) {
409+ while ( scope ) {
410+ if ( scope . kind == "FunctionDef" )
411+ return true
412+ scope = scope . parent
413+ }
414+ return false
415+ }
416+
417+ function addSymbolFor ( k : SK , n : py . Symbol , scope ?: ScopeDef ) {
401418 if ( ! n . symInfo ) {
402419 let qn = getFullName ( n )
403420 if ( U . endsWith ( qn , ".__init__" ) )
404421 qn = qn . slice ( 0 , - 9 ) + ".__constructor"
405- n . symInfo = addSymbol ( k , qn )
406- n . symInfo . pyAST = n
422+ scope = scope || currentScope ( )
423+ if ( isLocalScope ( scope ) )
424+ n . symInfo = mkSymbol ( k , qn )
425+ else
426+ n . symInfo = addSymbol ( k , qn )
427+ const sym = n . symInfo
428+ sym . pyAST = n
429+ scope . vars [ sym . name ] = sym
407430 }
408431 return n . symInfo
409432 }
@@ -482,10 +505,9 @@ namespace pxt.py {
482505
483506 function getClassDef ( e : py . Expr ) {
484507 let n = getName ( e )
485- let v = lookupVar ( n )
486- if ( v )
487- return v . classdef
488- let s = lookupGlobalSymbol ( n )
508+ let s = lookupVar ( n )
509+ if ( ! s )
510+ s = lookupGlobalSymbol ( n )
489511 if ( s && s . pyAST && s . pyAST . kind == "ClassDef" )
490512 return s . pyAST as py . ClassDef
491513 return null
@@ -616,8 +638,8 @@ namespace pxt.py {
616638
617639 let lst = n . symInfo . parameters . map ( p => {
618640 let v = defvar ( p . name , { isParam : true } )
619- unify ( n , v . type , p . pyType )
620- let res = [ quote ( p . name ) , typeAnnot ( v . type ) ]
641+ unify ( n , symbolType ( v ) , p . pyType )
642+ let res = [ quote ( p . name ) , typeAnnot ( p . pyType ) ]
621643 if ( p . default ) {
622644 res . push ( B . mkText ( " = " + p . default ) )
623645 }
@@ -760,7 +782,7 @@ namespace pxt.py {
760782 if ( funname == "__set__" && vv ) {
761783 let cf = getClassField ( ctx . currClass . symInfo , "__get__" )
762784 if ( cf . pyAST && cf . pyAST . kind == "FunctionDef" )
763- unify ( n , vv . type , cf . pyRetType )
785+ unify ( n , vv . pyRetType , cf . pyRetType )
764786 }
765787 funname = funname . replace ( / _ / g, "" )
766788 }
@@ -780,10 +802,8 @@ namespace pxt.py {
780802 doArgs ( n , isMethod ) ,
781803 n . returns ? typeAnnot ( compileType ( n . returns ) ) : B . mkText ( "" ) )
782804
783- if ( ! isMethod ) {
784- const v = defvar ( n . name , { fundef : n } )
785- unify ( n , symbolType ( sym ) , v . type )
786- }
805+ // make sure type is initialized
806+ symbolType ( sym )
787807
788808 let body = n . body . map ( stmt )
789809 if ( n . name == "__init__" ) {
@@ -805,9 +825,7 @@ namespace pxt.py {
805825 ClassDef : ( n : py . ClassDef ) => guardedScope ( n , ( ) => {
806826 setupScope ( n )
807827
808- const cv = defvar ( n . name , { classdef : n } )
809828 const sym = addSymbolFor ( SK . Class , n )
810- unify ( n , cv . type , symbolType ( sym ) )
811829
812830 U . assert ( ! ctx . currClass )
813831 let topLev = isTopLevel ( )
@@ -1009,7 +1027,7 @@ namespace pxt.py {
10091027 let v = defvar ( id , { isLocal : true } )
10101028 id = quoteStr ( id )
10111029 res . push ( B . mkStmt ( B . mkText ( "const " + id + " = " ) , devRef ) )
1012- unifyTypeOf ( it . context_expr , v . type )
1030+ unifyTypeOf ( it . context_expr , v . pyRetType )
10131031 devRef = B . mkText ( id )
10141032 }
10151033 res . push ( B . mkStmt ( B . mkInfix ( devRef , "." , B . mkText ( "begin()" ) ) ) )
@@ -1138,7 +1156,7 @@ namespace pxt.py {
11381156 } else {
11391157 n . isdef = false
11401158 }
1141- unify ( n , n . tsType , curr . type )
1159+ unify ( n , n . tsType , curr . pyRetType )
11421160 }
11431161
11441162 if ( n . isdef )
@@ -1526,7 +1544,7 @@ namespace pxt.py {
15261544
15271545 let v = lookupVar ( n . id )
15281546 if ( v ) {
1529- unify ( n , n . tsType , v . type )
1547+ unify ( n , n . tsType , symbolType ( v ) )
15301548 if ( v . isImport )
15311549 return quote ( n . id ) // it's import X = Y.Z.X, use X not Y.Z.X
15321550 } else if ( currIteration > 0 ) {
0 commit comments