Coverage for  / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / codegen / inline / declaration_edits.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-11-15 07:18 +0800

1# Copyright 2026 Huawei Technologies Co., Ltd 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14# ============================================================================ 

15"""Render top-level imports and source snippets from inline patch IR.""" 

16 

17from __future__ import annotations 

18 

19from collections import defaultdict 

20from collections.abc import Iterable 

21 

22from hyper_parallel.codegen.astkit.edits import TextEdit, insert_after_imports 

23from hyper_parallel.codegen.inline.ir import ImportPatch, ModuleSnippetPatch 

24 

25 

26def declaration_edits( 

27 source_text: str, 

28 import_end: int | None, 

29 docstring_end: int | None, 

30 imports: Iterable[ImportPatch], 

31 snippets: Iterable[ModuleSnippetPatch], 

32) -> list[TextEdit]: 

33 """Build ordered edits for generated imports and top-level snippets.""" 

34 edits = [] 

35 lines = _render_imports(source_text, imports) 

36 if lines: 

37 edits.append(insert_after_imports( 

38 source_text, 

39 import_end, 

40 "\n" + "\n".join(lines) + "\n", 

41 default_offset=docstring_end or 0, 

42 )) 

43 parts = [snippet.text.strip("\n") for snippet in snippets if snippet.text.strip()] 

44 if parts: 

45 edits.append(insert_after_imports( 

46 source_text, 

47 import_end, 

48 "\n\n" + "\n\n".join(parts) + "\n", 

49 default_offset=docstring_end or 0, 

50 )) 

51 return edits 

52 

53 

54def _render_imports( 

55 source_text: str, imports: Iterable[ImportPatch] 

56) -> list[str]: 

57 """Render import patches as deduplicated, grouped import lines.""" 

58 grouped: dict[str, set[str]] = defaultdict(set) 

59 lines: list[str] = [] 

60 for patch in imports: 

61 if patch.raw: 

62 if patch.raw not in source_text: 

63 lines.append(patch.raw) 

64 continue 

65 grouped[patch.module].update(patch.names) 

66 for module in sorted(grouped): 

67 line = f"from {module} import {', '.join(sorted(grouped[module]))}" 

68 if line not in source_text: 

69 lines.append(line) 

70 return lines 

71 

72 

73__all__ = ["declaration_edits"]