wafer-lsp 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/.gitignore +34 -1
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/PKG-INFO +4 -1
- wafer_lsp-0.1.2/pyproject.toml +73 -0
- wafer_lsp-0.1.0/pyproject.toml → wafer_lsp-0.1.2/pyproject.toml.bak +7 -1
- wafer_lsp-0.1.2/src/wafer_lsp/handlers/__init__.py +30 -0
- wafer_lsp-0.1.2/src/wafer_lsp/handlers/diagnostics.py +41 -0
- wafer_lsp-0.1.2/src/wafer_lsp/handlers/document_symbol.py +176 -0
- wafer_lsp-0.1.2/src/wafer_lsp/handlers/hip_diagnostics.py +303 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/handlers/hover.py +45 -9
- wafer_lsp-0.1.2/src/wafer_lsp/handlers/inlay_hint.py +245 -0
- wafer_lsp-0.1.2/src/wafer_lsp/handlers/semantic_tokens.py +224 -0
- wafer_lsp-0.1.2/src/wafer_lsp/languages/detector.py +107 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/languages/registry.py +22 -1
- wafer_lsp-0.1.2/src/wafer_lsp/parsers/__init__.py +36 -0
- wafer_lsp-0.1.2/src/wafer_lsp/parsers/hip_parser.py +688 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/services/__init__.py +17 -0
- wafer_lsp-0.1.2/src/wafer_lsp/services/hip_docs.py +806 -0
- wafer_lsp-0.1.2/src/wafer_lsp/services/hip_hover_service.py +412 -0
- wafer_lsp-0.1.2/tests/fixtures/example.hip +265 -0
- wafer_lsp-0.1.2/tests/test_hip_diagnostics.py +335 -0
- wafer_lsp-0.1.2/tests/test_hip_hover.py +374 -0
- wafer_lsp-0.1.2/tests/test_hip_parser.py +384 -0
- wafer_lsp-0.1.2/tests/test_lsp_e2e.py +591 -0
- wafer_lsp-0.1.2/uv.lock +1732 -0
- wafer_lsp-0.1.0/src/wafer_lsp/handlers/diagnostics.py +0 -16
- wafer_lsp-0.1.0/src/wafer_lsp/handlers/document_symbol.py +0 -87
- wafer_lsp-0.1.0/src/wafer_lsp/handlers/inlay_hint.py +0 -65
- wafer_lsp-0.1.0/src/wafer_lsp/handlers/semantic_tokens.py +0 -124
- wafer_lsp-0.1.0/src/wafer_lsp/languages/detector.py +0 -34
- wafer_lsp-0.1.0/src/wafer_lsp/parsers/__init__.py +0 -18
- wafer_lsp-0.1.0/src/wafer_lsp/utils/__init__.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/README.md +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/__init__.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/__main__.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/analyzers/__init__.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/analyzers/compiler_integration.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/analyzers/docs_index.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/handlers/code_action.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/handlers/code_lens.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/handlers/completion.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/handlers/workspace_symbol.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/languages/README.md +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/languages/__init__.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/languages/converter.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/languages/parser_manager.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/languages/types.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/parsers/base_parser.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/parsers/cuda_parser.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/parsers/cutedsl_parser.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/server.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/services/analysis_service.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/services/docs_service.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/services/document_service.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/services/hover_service.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/services/language_registry_service.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/services/position_service.py +0 -0
- {wafer_lsp-0.1.0/src/wafer_lsp/handlers → wafer_lsp-0.1.2/src/wafer_lsp/utils}/__init__.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/src/wafer_lsp/utils/lsp_helpers.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/tests/__init__.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/tests/test_converter.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/tests/test_cutedsl_parser.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/tests/test_language_detector.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/tests/test_lsp_handlers.py +0 -0
- {wafer_lsp-0.1.0 → wafer_lsp-0.1.2}/tests/test_parser_manager.py +0 -0
|
@@ -40,6 +40,12 @@ experiments/emilio/cutedsl-quack-eval/eval_results/*.txt
|
|
|
40
40
|
experiments/emilio/cutedsl-quack-eval/eval_results/*.json
|
|
41
41
|
experiments/emilio/cutedsl-quack-eval/eval_results/*.py
|
|
42
42
|
research/evals/kernelbench/results/
|
|
43
|
+
research/evals/retrieval_eval_project/results/
|
|
44
|
+
research/evals/trace_analyze_eval/results/
|
|
45
|
+
research/evals/**/uv.lock
|
|
46
|
+
|
|
47
|
+
# Large trace files
|
|
48
|
+
**/pmc_perf.csv
|
|
43
49
|
wafer_artifacts/
|
|
44
50
|
**/wafer_artifacts/
|
|
45
51
|
/.deps/
|
|
@@ -61,11 +67,14 @@ npm-debug.log*
|
|
|
61
67
|
.npmrc
|
|
62
68
|
|
|
63
69
|
# Yarn artifacts
|
|
64
|
-
|
|
70
|
+
**/.yarn/install-state.gz
|
|
65
71
|
|
|
66
72
|
# NSYS report files (can be very large)
|
|
67
73
|
*.nsys-rep
|
|
68
74
|
|
|
75
|
+
# ROCprofiler artifacts
|
|
76
|
+
.rocprofv3/
|
|
77
|
+
|
|
69
78
|
# Turbo build cache
|
|
70
79
|
.turbo/
|
|
71
80
|
**/.turbo/
|
|
@@ -80,6 +89,30 @@ supabase/.temp/
|
|
|
80
89
|
research/evals/kernelbench/kernelbench/results/
|
|
81
90
|
research/evals/retrieval_eval_project/retrieval_eval/results/
|
|
82
91
|
research/evals/retrieval_eval_project/*.log
|
|
92
|
+
research/evals/ask_domain_eval/results/
|
|
93
|
+
research/evals/optimize_performance_eval/results/
|
|
94
|
+
research/evals/**/eval_output*.log
|
|
83
95
|
|
|
84
96
|
# Wafer extension trace files
|
|
85
97
|
.wafer/traces/
|
|
98
|
+
|
|
99
|
+
# Test coverage
|
|
100
|
+
coverage/
|
|
101
|
+
**/coverage/
|
|
102
|
+
.coverage
|
|
103
|
+
*.coverage
|
|
104
|
+
coverage.xml
|
|
105
|
+
*.lcov
|
|
106
|
+
htmlcov/
|
|
107
|
+
experiments/steve/amd-model-practice/workloads/**/*.csv
|
|
108
|
+
experiments/steve/amd-model-practice/liquid_profile.json
|
|
109
|
+
|
|
110
|
+
# Local files
|
|
111
|
+
logs/
|
|
112
|
+
todo.md
|
|
113
|
+
|
|
114
|
+
# Claude Code context/handoffs
|
|
115
|
+
.claude/context/
|
|
116
|
+
.claude/handoffs/
|
|
117
|
+
KernelBench/
|
|
118
|
+
HIP-Benchmarks-Results/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wafer-lsp
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Language Server Protocol server for GPU programming languages
|
|
5
5
|
Author-email: Wafer <support@wafer.ai>
|
|
6
6
|
License: MIT
|
|
@@ -16,6 +16,9 @@ Requires-Python: >=3.12
|
|
|
16
16
|
Requires-Dist: lsprotocol>=2024.0.0
|
|
17
17
|
Requires-Dist: pygls>=1.0.0
|
|
18
18
|
Requires-Dist: wafer-core
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
19
22
|
Description-Content-Type: text/markdown
|
|
20
23
|
|
|
21
24
|
# Wafer LSP
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "wafer-lsp"
|
|
3
|
+
version = "0.1.2"
|
|
4
|
+
description = "Language Server Protocol server for GPU programming languages"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"pygls>=1.0.0",
|
|
9
|
+
"lsprotocol>=2024.0.0",
|
|
10
|
+
"wafer-core", # For core analysis utilities
|
|
11
|
+
]
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Wafer", email = "support@wafer.ai" }
|
|
14
|
+
]
|
|
15
|
+
license = { text = "MIT" }
|
|
16
|
+
keywords = ["lsp", "language-server", "gpu", "cuda", "cutedsl", "c++"]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
24
|
+
"Topic :: Text Editors :: Integrated Development Environments (IDE)",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
dev = [
|
|
29
|
+
"pytest>=8.0.0",
|
|
30
|
+
"pytest-asyncio>=0.23.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[build-system]
|
|
34
|
+
requires = ["hatchling"]
|
|
35
|
+
build-backend = "hatchling.build"
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
wafer-lsp = "wafer_lsp.__main__:main"
|
|
39
|
+
|
|
40
|
+
[tool.hatch.build.targets.wheel]
|
|
41
|
+
packages = ["src/wafer_lsp"]
|
|
42
|
+
|
|
43
|
+
[tool.ruff]
|
|
44
|
+
line-length = 100
|
|
45
|
+
target-version = "py312"
|
|
46
|
+
preview = true
|
|
47
|
+
|
|
48
|
+
[tool.ruff.lint]
|
|
49
|
+
select = [
|
|
50
|
+
"E", # pycodestyle errors
|
|
51
|
+
"W", # pycodestyle warnings
|
|
52
|
+
"F", # pyflakes
|
|
53
|
+
"I", # isort
|
|
54
|
+
"B", # flake8-bugbear
|
|
55
|
+
"C4", # flake8-comprehensions
|
|
56
|
+
"UP", # pyupgrade
|
|
57
|
+
"ARG", # flake8-unused-arguments
|
|
58
|
+
"SIM", # flake8-simplify
|
|
59
|
+
"PLR", # pylint refactor
|
|
60
|
+
"PLW", # pylint warnings
|
|
61
|
+
"PT", # flake8-pytest-style
|
|
62
|
+
"RUF", # Ruff-specific rules
|
|
63
|
+
]
|
|
64
|
+
ignore = [
|
|
65
|
+
"E501", # line too long (handled by formatter)
|
|
66
|
+
"B008", # do not perform function calls in argument defaults
|
|
67
|
+
"PLR0913", # too many arguments
|
|
68
|
+
"PLR2004", # magic value used in comparison
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
[tool.ruff.format]
|
|
72
|
+
quote-style = "double"
|
|
73
|
+
indent-style = "space"
|
|
@@ -7,7 +7,7 @@ requires-python = ">=3.12"
|
|
|
7
7
|
dependencies = [
|
|
8
8
|
"pygls>=1.0.0",
|
|
9
9
|
"lsprotocol>=2024.0.0",
|
|
10
|
-
"wafer-core", # For
|
|
10
|
+
"wafer-core", # For core analysis utilities
|
|
11
11
|
]
|
|
12
12
|
authors = [
|
|
13
13
|
{ name = "Wafer", email = "support@wafer.ai" }
|
|
@@ -24,6 +24,12 @@ classifiers = [
|
|
|
24
24
|
"Topic :: Text Editors :: Integrated Development Environments (IDE)",
|
|
25
25
|
]
|
|
26
26
|
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
dev = [
|
|
29
|
+
"pytest>=8.0.0",
|
|
30
|
+
"pytest-asyncio>=0.23.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
27
33
|
[build-system]
|
|
28
34
|
requires = ["hatchling"]
|
|
29
35
|
build-backend = "hatchling.build"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from .code_action import handle_code_action
|
|
2
|
+
from .code_lens import handle_code_lens
|
|
3
|
+
from .completion import handle_completion
|
|
4
|
+
from .diagnostics import handle_diagnostics
|
|
5
|
+
from .document_symbol import handle_document_symbol
|
|
6
|
+
from .hip_diagnostics import (
|
|
7
|
+
HIPDiagnosticsProvider,
|
|
8
|
+
create_hip_diagnostics_provider,
|
|
9
|
+
get_hip_diagnostics,
|
|
10
|
+
)
|
|
11
|
+
from .hover import handle_hover
|
|
12
|
+
from .inlay_hint import handle_inlay_hint
|
|
13
|
+
from .semantic_tokens import handle_semantic_tokens, SEMANTIC_TOKENS_LEGEND
|
|
14
|
+
from .workspace_symbol import handle_workspace_symbol
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"handle_code_action",
|
|
18
|
+
"handle_code_lens",
|
|
19
|
+
"handle_completion",
|
|
20
|
+
"handle_diagnostics",
|
|
21
|
+
"handle_document_symbol",
|
|
22
|
+
"handle_hover",
|
|
23
|
+
"handle_inlay_hint",
|
|
24
|
+
"handle_semantic_tokens",
|
|
25
|
+
"handle_workspace_symbol",
|
|
26
|
+
"SEMANTIC_TOKENS_LEGEND",
|
|
27
|
+
"HIPDiagnosticsProvider",
|
|
28
|
+
"create_hip_diagnostics_provider",
|
|
29
|
+
"get_hip_diagnostics",
|
|
30
|
+
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
from lsprotocol.types import Diagnostic
|
|
3
|
+
|
|
4
|
+
from ..languages.registry import get_language_registry
|
|
5
|
+
from .hip_diagnostics import get_hip_diagnostics
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def handle_diagnostics(
|
|
9
|
+
uri: str,
|
|
10
|
+
content: str,
|
|
11
|
+
enable_wavefront_diagnostics: bool = True,
|
|
12
|
+
) -> list[Diagnostic]:
|
|
13
|
+
"""Handle diagnostics for a document.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
uri: Document URI
|
|
17
|
+
content: Document content
|
|
18
|
+
enable_wavefront_diagnostics: Whether to enable HIP wavefront warnings
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
List of diagnostics
|
|
22
|
+
"""
|
|
23
|
+
diagnostics: list[Diagnostic] = []
|
|
24
|
+
|
|
25
|
+
registry = get_language_registry()
|
|
26
|
+
language_info = registry.parse_file(uri, content)
|
|
27
|
+
|
|
28
|
+
if not language_info:
|
|
29
|
+
return diagnostics
|
|
30
|
+
|
|
31
|
+
# Add HIP-specific diagnostics for HIP, CUDA, and C++ files
|
|
32
|
+
# (C++ files might contain HIP code if they have HIP markers)
|
|
33
|
+
if language_info.language in ("hip", "cuda", "cpp"):
|
|
34
|
+
hip_diagnostics = get_hip_diagnostics(
|
|
35
|
+
content,
|
|
36
|
+
uri,
|
|
37
|
+
enable_wavefront_diagnostics=enable_wavefront_diagnostics,
|
|
38
|
+
)
|
|
39
|
+
diagnostics.extend(hip_diagnostics)
|
|
40
|
+
|
|
41
|
+
return diagnostics
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
|
|
2
|
+
from lsprotocol.types import DocumentSymbol, Position, Range, SymbolKind
|
|
3
|
+
|
|
4
|
+
from ..languages.registry import get_language_registry
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def handle_document_symbol(uri: str, content: str) -> list[DocumentSymbol]:
|
|
8
|
+
registry = get_language_registry()
|
|
9
|
+
language_info = registry.parse_file(uri, content)
|
|
10
|
+
|
|
11
|
+
if not language_info:
|
|
12
|
+
return []
|
|
13
|
+
|
|
14
|
+
symbols: list[DocumentSymbol] = []
|
|
15
|
+
lines = content.split("\n")
|
|
16
|
+
|
|
17
|
+
# Kernels
|
|
18
|
+
for kernel in language_info.kernels:
|
|
19
|
+
kernel_line = lines[kernel.line] if kernel.line < len(lines) else ""
|
|
20
|
+
name_start = kernel_line.find(kernel.name)
|
|
21
|
+
name_end = name_start + len(kernel.name) if name_start >= 0 else 0
|
|
22
|
+
|
|
23
|
+
selection_range = Range(
|
|
24
|
+
start=Position(line=kernel.line, character=max(0, name_start)),
|
|
25
|
+
end=Position(line=kernel.line, character=name_end)
|
|
26
|
+
)
|
|
27
|
+
full_range = Range(
|
|
28
|
+
start=Position(line=kernel.line, character=0),
|
|
29
|
+
end=Position(line=min(kernel.line + 10, len(lines) - 1), character=0)
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Different detail based on language
|
|
33
|
+
if kernel.language == "hip":
|
|
34
|
+
detail = "🚀 HIP Kernel (AMD GPU)"
|
|
35
|
+
elif kernel.language in ("cuda", "cpp"):
|
|
36
|
+
detail = "🚀 CUDA Kernel"
|
|
37
|
+
else:
|
|
38
|
+
detail = f"GPU Kernel ({registry.get_language_name(kernel.language)})"
|
|
39
|
+
|
|
40
|
+
symbols.append(DocumentSymbol(
|
|
41
|
+
name=kernel.name,
|
|
42
|
+
kind=SymbolKind.Function,
|
|
43
|
+
range=full_range,
|
|
44
|
+
selection_range=selection_range,
|
|
45
|
+
detail=detail,
|
|
46
|
+
))
|
|
47
|
+
|
|
48
|
+
# Layouts (CuTeDSL)
|
|
49
|
+
for layout in language_info.layouts:
|
|
50
|
+
layout_line = lines[layout.line] if layout.line < len(lines) else ""
|
|
51
|
+
name_start = layout_line.find(layout.name)
|
|
52
|
+
name_end = name_start + len(layout.name) if name_start >= 0 else 0
|
|
53
|
+
|
|
54
|
+
detail = f"Layout: {layout.shape}" if layout.shape else "Layout"
|
|
55
|
+
|
|
56
|
+
selection_range = Range(
|
|
57
|
+
start=Position(line=layout.line, character=max(0, name_start)),
|
|
58
|
+
end=Position(line=layout.line, character=name_end)
|
|
59
|
+
)
|
|
60
|
+
full_range = Range(
|
|
61
|
+
start=Position(line=layout.line, character=0),
|
|
62
|
+
end=Position(line=layout.line, character=len(layout_line))
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
symbols.append(DocumentSymbol(
|
|
66
|
+
name=layout.name,
|
|
67
|
+
kind=SymbolKind.Variable,
|
|
68
|
+
range=full_range,
|
|
69
|
+
selection_range=selection_range,
|
|
70
|
+
detail=detail,
|
|
71
|
+
))
|
|
72
|
+
|
|
73
|
+
# Structs
|
|
74
|
+
for struct in language_info.structs:
|
|
75
|
+
struct_line = lines[struct.line] if struct.line < len(lines) else ""
|
|
76
|
+
name_start = struct_line.find(struct.name)
|
|
77
|
+
name_end = name_start + len(struct.name) if name_start >= 0 else 0
|
|
78
|
+
|
|
79
|
+
selection_range = Range(
|
|
80
|
+
start=Position(line=struct.line, character=max(0, name_start)),
|
|
81
|
+
end=Position(line=struct.line, character=name_end)
|
|
82
|
+
)
|
|
83
|
+
full_range = Range(
|
|
84
|
+
start=Position(line=struct.line, character=0),
|
|
85
|
+
end=Position(line=min(struct.line + 10, len(lines) - 1), character=0)
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
symbols.append(DocumentSymbol(
|
|
89
|
+
name=struct.name,
|
|
90
|
+
kind=SymbolKind.Struct,
|
|
91
|
+
range=full_range,
|
|
92
|
+
selection_range=selection_range,
|
|
93
|
+
detail=f"Struct ({registry.get_language_name(struct.language)})",
|
|
94
|
+
))
|
|
95
|
+
|
|
96
|
+
# HIP-specific: Device functions and shared memory
|
|
97
|
+
if language_info.language in ("hip", "cuda", "cpp"):
|
|
98
|
+
symbols.extend(_get_hip_symbols(language_info.raw_data, lines))
|
|
99
|
+
|
|
100
|
+
return symbols
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _get_hip_symbols(raw_data: dict, lines: list[str]) -> list[DocumentSymbol]:
|
|
104
|
+
"""Extract HIP-specific symbols: device functions, shared memory allocations."""
|
|
105
|
+
symbols: list[DocumentSymbol] = []
|
|
106
|
+
|
|
107
|
+
# Device functions (from HIP parser)
|
|
108
|
+
device_functions = raw_data.get("device_functions", [])
|
|
109
|
+
for func in device_functions:
|
|
110
|
+
if not hasattr(func, "line") or not hasattr(func, "name"):
|
|
111
|
+
continue
|
|
112
|
+
|
|
113
|
+
func_line = lines[func.line] if func.line < len(lines) else ""
|
|
114
|
+
name_start = func_line.find(func.name)
|
|
115
|
+
name_end = name_start + len(func.name) if name_start >= 0 else 0
|
|
116
|
+
|
|
117
|
+
end_line = getattr(func, "end_line", func.line + 10)
|
|
118
|
+
|
|
119
|
+
selection_range = Range(
|
|
120
|
+
start=Position(line=func.line, character=max(0, name_start)),
|
|
121
|
+
end=Position(line=func.line, character=name_end)
|
|
122
|
+
)
|
|
123
|
+
full_range = Range(
|
|
124
|
+
start=Position(line=func.line, character=0),
|
|
125
|
+
end=Position(line=min(end_line, len(lines) - 1), character=0)
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
return_type = getattr(func, "return_type", "void")
|
|
129
|
+
detail = f"⚡ Device Function -> {return_type}"
|
|
130
|
+
|
|
131
|
+
symbols.append(DocumentSymbol(
|
|
132
|
+
name=func.name,
|
|
133
|
+
kind=SymbolKind.Method,
|
|
134
|
+
range=full_range,
|
|
135
|
+
selection_range=selection_range,
|
|
136
|
+
detail=detail,
|
|
137
|
+
))
|
|
138
|
+
|
|
139
|
+
# Shared memory allocations
|
|
140
|
+
shared_memory = raw_data.get("shared_memory", [])
|
|
141
|
+
for shared in shared_memory:
|
|
142
|
+
if not hasattr(shared, "line") or not hasattr(shared, "name"):
|
|
143
|
+
continue
|
|
144
|
+
|
|
145
|
+
shared_line = lines[shared.line] if shared.line < len(lines) else ""
|
|
146
|
+
name_start = shared_line.find(shared.name)
|
|
147
|
+
name_end = name_start + len(shared.name) if name_start >= 0 else 0
|
|
148
|
+
|
|
149
|
+
selection_range = Range(
|
|
150
|
+
start=Position(line=shared.line, character=max(0, name_start)),
|
|
151
|
+
end=Position(line=shared.line, character=name_end)
|
|
152
|
+
)
|
|
153
|
+
full_range = Range(
|
|
154
|
+
start=Position(line=shared.line, character=0),
|
|
155
|
+
end=Position(line=shared.line, character=len(shared_line))
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
type_str = getattr(shared, "type_str", "")
|
|
159
|
+
size_bytes = getattr(shared, "size_bytes", None)
|
|
160
|
+
if size_bytes:
|
|
161
|
+
if size_bytes >= 1024:
|
|
162
|
+
detail = f"📦 __shared__ {type_str} ({size_bytes / 1024:.1f} KB)"
|
|
163
|
+
else:
|
|
164
|
+
detail = f"📦 __shared__ {type_str} ({size_bytes} bytes)"
|
|
165
|
+
else:
|
|
166
|
+
detail = f"📦 __shared__ {type_str}"
|
|
167
|
+
|
|
168
|
+
symbols.append(DocumentSymbol(
|
|
169
|
+
name=shared.name,
|
|
170
|
+
kind=SymbolKind.Variable,
|
|
171
|
+
range=full_range,
|
|
172
|
+
selection_range=selection_range,
|
|
173
|
+
detail=detail,
|
|
174
|
+
))
|
|
175
|
+
|
|
176
|
+
return symbols
|