|
32 | 32 |
|
33 | 33 | from mypy.nodes import (MypyFile, ImportBase, Import, ImportFrom, ImportAll)
|
34 | 34 | from mypy.semanal_pass1 import SemanticAnalyzerPass1
|
| 35 | +from mypy.newsemanal.semanal_pass1 import ReachabilityAnalyzer |
35 | 36 | from mypy.semanal import SemanticAnalyzerPass2, apply_semantic_analyzer_patches
|
36 | 37 | from mypy.semanal_pass3 import SemanticAnalyzerPass3
|
| 38 | +from mypy.newsemanal.semanal import NewSemanticAnalyzer |
| 39 | +from mypy.newsemanal.semanal_main import semantic_analysis_for_scc |
37 | 40 | from mypy.checker import TypeChecker
|
38 | 41 | from mypy.indirection import TypeIndirectionVisitor
|
39 | 42 | from mypy.errors import Errors, CompileError, report_internal_error
|
@@ -502,10 +505,21 @@ def __init__(self, data_dir: str,
|
502 | 505 | self.modules = {} # type: Dict[str, MypyFile]
|
503 | 506 | self.missing_modules = set() # type: Set[str]
|
504 | 507 | self.plugin = plugin
|
505 |
| - self.semantic_analyzer = SemanticAnalyzerPass2(self.modules, self.missing_modules, |
506 |
| - self.errors, self.plugin) |
507 |
| - self.semantic_analyzer_pass3 = SemanticAnalyzerPass3(self.modules, self.errors, |
508 |
| - self.semantic_analyzer) |
| 508 | + if options.new_semantic_analyzer: |
| 509 | + # Set of namespaces (module or class) that are being populated during semantic |
| 510 | + # analysis and may have missing definitions. |
| 511 | + self.incomplete_namespaces = set() # type: Set[str] |
| 512 | + self.new_semantic_analyzer = NewSemanticAnalyzer( |
| 513 | + self.modules, |
| 514 | + self.missing_modules, |
| 515 | + self.incomplete_namespaces, |
| 516 | + self.errors, |
| 517 | + self.plugin) |
| 518 | + else: |
| 519 | + self.semantic_analyzer = SemanticAnalyzerPass2(self.modules, self.missing_modules, |
| 520 | + self.errors, self.plugin) |
| 521 | + self.semantic_analyzer_pass3 = SemanticAnalyzerPass3(self.modules, self.errors, |
| 522 | + self.semantic_analyzer) |
509 | 523 | self.all_types = {} # type: Dict[Expression, Type] # Enabled by export_types
|
510 | 524 | self.indirection_detector = TypeIndirectionVisitor()
|
511 | 525 | self.stale_modules = set() # type: Set[str]
|
@@ -1721,21 +1735,44 @@ def parse_file(self) -> None:
|
1721 | 1735 |
|
1722 | 1736 | modules[self.id] = self.tree
|
1723 | 1737 |
|
1724 |
| - # Do the first pass of semantic analysis: add top-level |
1725 |
| - # definitions in the file to the symbol table. We must do |
1726 |
| - # this before processing imports, since this may mark some |
1727 |
| - # import statements as unreachable. |
1728 |
| - first = SemanticAnalyzerPass1(manager.semantic_analyzer) |
1729 |
| - with self.wrap_context(): |
1730 |
| - first.visit_file(self.tree, self.xpath, self.id, self.options) |
| 1738 | + self.semantic_analysis_pass1() |
1731 | 1739 |
|
1732 |
| - # Initialize module symbol table, which was populated by the |
1733 |
| - # semantic analyzer. |
1734 |
| - # TODO: Why can't SemanticAnalyzerPass1 .analyze() do this? |
1735 |
| - self.tree.names = manager.semantic_analyzer.globals |
| 1740 | + if not self.options.new_semantic_analyzer: |
| 1741 | + # Initialize module symbol table, which was populated by the |
| 1742 | + # semantic analyzer. |
| 1743 | + # TODO: Why can't SemanticAnalyzerPass1 .analyze() do this? |
| 1744 | + self.tree.names = manager.semantic_analyzer.globals |
1736 | 1745 |
|
1737 | 1746 | self.check_blockers()
|
1738 | 1747 |
|
| 1748 | + def semantic_analysis_pass1(self) -> None: |
| 1749 | + """Perform pass 1 of semantic analysis, which happens immediately after parsing. |
| 1750 | +
|
| 1751 | + This pass can't assume that any other modules have been processed yet. |
| 1752 | + """ |
| 1753 | + options = self.options |
| 1754 | + assert self.tree is not None |
| 1755 | + if options.new_semantic_analyzer: |
| 1756 | + # Do the first pass of semantic analysis: analyze the reachability |
| 1757 | + # of blocks and import statements. We must do this before |
| 1758 | + # processing imports, since this may mark some import statements as |
| 1759 | + # unreachable. |
| 1760 | + # |
| 1761 | + # TODO: Once we remove the old semantic analyzer, this no longer should |
| 1762 | + # be considered as a semantic analysis pass -- it's an independent |
| 1763 | + # pass. |
| 1764 | + analyzer = ReachabilityAnalyzer() |
| 1765 | + with self.wrap_context(): |
| 1766 | + analyzer.visit_file(self.tree, self.xpath, self.id, options) |
| 1767 | + else: |
| 1768 | + # Do the first pass of semantic analysis: add top-level |
| 1769 | + # definitions in the file to the symbol table. We must do |
| 1770 | + # this before processing imports, since this may mark some |
| 1771 | + # import statements as unreachable. |
| 1772 | + first = SemanticAnalyzerPass1(self.manager.semantic_analyzer) |
| 1773 | + with self.wrap_context(): |
| 1774 | + first.visit_file(self.tree, self.xpath, self.id, options) |
| 1775 | + |
1739 | 1776 | def compute_dependencies(self) -> None:
|
1740 | 1777 | """Compute a module's dependencies after parsing it.
|
1741 | 1778 |
|
@@ -2649,12 +2686,15 @@ def process_stale_scc(graph: Graph, scc: List[str], manager: BuildManager) -> No
|
2649 | 2686 | typing_mod = graph['typing'].tree
|
2650 | 2687 | assert typing_mod, "The typing module was not parsed"
|
2651 | 2688 | manager.semantic_analyzer.add_builtin_aliases(typing_mod)
|
2652 |
| - for id in stale: |
2653 |
| - graph[id].semantic_analysis() |
2654 |
| - for id in stale: |
2655 |
| - graph[id].semantic_analysis_pass_three() |
2656 |
| - for id in stale: |
2657 |
| - graph[id].semantic_analysis_apply_patches() |
| 2689 | + if manager.options.new_semantic_analyzer: |
| 2690 | + semantic_analysis_for_scc(graph, scc) |
| 2691 | + else: |
| 2692 | + for id in stale: |
| 2693 | + graph[id].semantic_analysis() |
| 2694 | + for id in stale: |
| 2695 | + graph[id].semantic_analysis_pass_three() |
| 2696 | + for id in stale: |
| 2697 | + graph[id].semantic_analysis_apply_patches() |
2658 | 2698 | for id in stale:
|
2659 | 2699 | graph[id].type_check_first_pass()
|
2660 | 2700 | more = True
|
|
0 commit comments