Merge a new version of a module AST and symbol table to older versions of those.
When the source code of a module has a change in fine-grained incremental mode, we build a new AST from the updated source. However, other parts of the program may have direct references to parts of the old AST (namely, those nodes exposed in the module symbol table). The merge operation changes the identities of new AST nodes that have a correspondence in the old AST to the old ones so that existing cross-references in other modules will continue to point to the correct nodes. Also internal cross-references within the new AST are replaced. AST nodes that aren't externally visible will get new, distinct object identities. This applies to most expression and statement nodes, for example.
We perform this merge operation so that we don't have to update all external references (which would be slow and fragile) or always perform translation when looking up references (which would be hard to retrofit).
The AST merge operation is performed after semantic analysis. Semantic analysis has to deal with potentially multiple aliases to certain AST nodes (in particular, MypyFile nodes). Type checking assumes that we don't have multiple variants of a single AST node visible to the type checker.
Discussion of some notable special cases:
See the main entry point merge_asts for more details.
Class | NodeReplaceVisitor |
Transform some nodes to new identities in an AST. |
Class | TypeReplaceVisitor |
Similar to NodeReplaceVisitor, but for type objects. |
Function | merge_asts |
Merge a new version of a module AST to a previous version. |
Function | replace_nodes_in_ast |
Replace all references to replacement map keys within an AST node, recursively. |
Function | replace_nodes_in_symbol_table |
Undocumented |
Function | replacement_map_from_symbol_table |
Create a new-to-old object identity map by comparing two symbol table revisions. |
Constant | SN |
Undocumented |
Merge a new version of a module AST to a previous version.
The main idea is to preserve the identities of externally visible nodes in the old AST (that have a corresponding node in the new AST). All old node state (outside identity) will come from the new AST.
When this returns, 'old' will refer to the merged AST, but 'new_symbols' will be the new symbol table. 'new' and 'old_symbols' will no longer be valid.
Parameters | |
old:MypyFile | Undocumented |
old_symbols:SymbolTable | Undocumented |
new:MypyFile | Undocumented |
new_symbols:SymbolTable | Undocumented |
Replace all references to replacement map keys within an AST node, recursively.
Also replace the identity of any nodes that have replacements. Return the replaced version of the argument node (which may have a different identity, if it's included in the replacement map).
Parameters | |
node:SymbolNode | Undocumented |
replacements:Dict[ | Undocumented |
Returns | |
SymbolNode | Undocumented |
Undocumented
Parameters | |
symbols:SymbolTable | Undocumented |
replacements:Dict[ | Undocumented |
Create a new-to-old object identity map by comparing two symbol table revisions.
Both symbol tables must refer to revisions of the same module id. The symbol tables are compared recursively (recursing into nested class symbol tables), but only within the given module prefix. Don't recurse into other modules accessible through the symbol table.
Parameters | |
old:SymbolTable | Undocumented |
new:SymbolTable | Undocumented |
prefix:str | Undocumented |
Returns | |
Dict[ | Undocumented |