@@ -100,27 +100,33 @@ class PythonAddDeclarationsPass(ctx: TranslationContext) : ComponentPass(ctx), L
100
100
}
101
101
102
102
// Look for a potential scope modifier for this reference
103
- // lookupScope
104
103
var targetScope =
105
104
scopeManager.currentScope?.predefinedLookupScopes[ref.name.toString()]?.targetScope
106
105
107
- // There are a couple of things to consider now
106
+ // Try to see whether our symbol already exists. There are basically three rules to follow
107
+ // here.
108
108
var symbol =
109
- // Since this is a WRITE access, we need to look for a local symbol, unless
110
- // - a global keyword is present for this symbol and scope
111
- // - the name is qualified
112
- if (targetScope != null ) {
109
+ when {
113
110
// When a target scope is set, then we have a `global` or `nonlocal` keyword for
114
111
// this symbol, and we need to start looking in this scope
115
- scopeManager.lookupSymbolByNodeName(ref, targetScope)
116
- } else {
117
- scopeManager.lookupSymbolByNodeName(ref) {
118
- // Otherwise, we need to stick to the current scope unless the name is qualified
119
- it.scope == scopeManager.currentScope || ref.name.isQualified()
120
- }
112
+ targetScope != null -> scopeManager.lookupSymbolByNodeName(ref, targetScope)
113
+ // When we have a qualified reference (such as `self.a`), we do not have any
114
+ // specific restrictions, because the lookup will anyway be a qualified lookup,
115
+ // and it will consider only the scope of `self`.
116
+ ref.name.isQualified() -> scopeManager.lookupSymbolByNodeName(ref)
117
+ // In any other case, we need to restrict the lookup to the current scope. The
118
+ // main reason for this is that Python requires the `global` keyword in functions
119
+ // for assigning to global variables. See
120
+ // https://docs.python.org/3/reference/simple_stmts.html#the-global-statement. So
121
+ // basically we need to ignore all global variables at this point and only look
122
+ // for local ones.
123
+ else ->
124
+ scopeManager.lookupSymbolByNodeName(ref) {
125
+ it.scope == scopeManager.currentScope
126
+ }
121
127
}
122
128
123
- // Nothing to create
129
+ // If the symbol is already defined in the designed scope, there is nothing to create
124
130
if (symbol.isNotEmpty()) return null
125
131
126
132
// First, check if we need to create a field
0 commit comments