def resolve(node: Node, parentScope: Scope): nodeType = node.nodeType node.parentScope = parentScope resolveClass(node, parentScope) resolveFunction(node, parentScope) if nodeType in [NodeType.FUNCTION, NodeType.CLASS]: parentScope = node.scope if not node.resolvedType: if nodeType in [NodeType.ASSIGN, NodeType.ANN_ASSIGN]: value = node.getChild('value') resolve(value, parentScope) type_ = value.resolvedType if node.getChild('annotation'): annotation = node.getChild('annotation') type_ = getAnnotationType(parentScope, annotation) if nodeType == NodeType.ASSIGN: targets = node.getChild('targets') else: targets = [node.getChild('target')] for target in targets: resolveAssign(parentScope, target, type_) elif node.isExpression(): node.resolvedType = getExpressionType(node) elif nodeType == NodeType.WHILE: scope = Scope(parentScope) scope.isLoop = True parentScope = node.scope = scope elif nodeType in [NodeType.FOR, NodeType.COMP]: scope = Scope(parentScope) scope.isLoop = nodeType == NodeType.FOR parentScope = node.scope = scope target = node.getChild('target') iter_ = node.getChild('iter') resolve(iter_, parentScope) type_ = iter_.resolvedType resolveAssign(parentScope, target, type_.elementTypes[0], addVar=False) elif nodeType == NodeType.BLOCK: if node.parent.nodeType not in [ NodeType.CLASS, NodeType.FUNCTION, NodeType.FOR, NodeType.WHILE ]: scope = Scope(parentScope) parentScope = node.scope = scope else: parentScope = node.scope = node.parent.scope elif nodeType == NodeType.ARGUMENTS: args = node.getChild('args') for i, arg in enumerate(args): arg.parentScope = parentScope type_ = getArgumentType(arg, i) name = arg.getChild('arg') symbol = Symbol(name, type_) arg.resolvedType = type_ parentScope.define(symbol) for child_node in node.getChildNodes(): resolve(child_node, parentScope)