Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent chpl-language-server from providing type inserts for loops #25151

Merged
merged 5 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions tools/chpl-language-server/src/chpl-language-server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,7 @@ def _get_type_inlays(

name_rng = location_to_range(decl.node.name_location())
type_str = ": " + str(type_)
text_edits = [TextEdit(Range(name_rng.end, name_rng.end), type_str)]
colon_label = InlayHintLabelPart(": ")
label = InlayHintLabelPart(str(type_))
if isinstance(type_, chapel.CompositeType):
Expand All @@ -1154,13 +1155,20 @@ def _get_type_inlays(
label.location = location_to_location(typedecl.name_location())
elif typedecl:
label.location = location_to_location(typedecl.location())

# if the inlay hint is for a loop index type, we cannot insert the type
# as it would be a syntax error
parent_loop = decl.node.parent()
if parent_loop and isinstance(parent_loop, chapel.IndexableLoop):
index = parent_loop.index()
if index and index.unique_id() == decl.node.unique_id():
text_edits = None

return [
InlayHint(
position=name_rng.end,
label=[colon_label, label],
text_edits=[
TextEdit(Range(name_rng.end, name_rng.end), type_str)
],
text_edits=text_edits,
)
]

Expand Down
12 changes: 6 additions & 6 deletions tools/chpl-language-server/test/type_inlays.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,11 @@ async def test_type_inlays_loops(client: LanguageClient):
"""

inlays = [
(pos((0, 5)), "int(64)"),
(pos((1, 8)), "int(64)"),
(pos((2, 10)), "int(64)"),
(pos((3, 9)), "int(64)"),
(pos((4, 2)), "int(64)"),
(pos((0, 5)), "int(64)", False),
(pos((1, 8)), "int(64)", False),
(pos((2, 10)), "int(64)", False),
(pos((3, 9)), "int(64)", False),
(pos((4, 2)), "int(64)", False),
]

async with source_file(client, file) as doc:
Expand All @@ -305,7 +305,7 @@ class C { }

inlays = [
(pos((2, 5)), "owned C?"),
(pos((5, 5)), "int(64)"),
(pos((5, 5)), "int(64)", False),
]

async with source_file(client, file) as doc:
Expand Down
43 changes: 31 additions & 12 deletions tools/chpl-language-server/test/util/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,25 +522,44 @@ async def check_type_inlay_hints(
client: LanguageClient,
doc: TextDocumentIdentifier,
rng: Range,
expected_inlays: Sequence[typing.Tuple[Position, str]],
expected_inlays: Sequence[
typing.Union[
typing.Tuple[Position, str], typing.Tuple[Position, str, bool]
]
],
) -> typing.List[InlayHint]:
"""
Helper method for `check_inlay_hints`. Adds the `: ` prefix.

Also checks that inlays are insertable
"""
# we current do not make use of InlayHintKind.Type for type inlays in CLS
inlays = [(pos, f": {text}", None) for pos, text in expected_inlays]
actual_inlays = await check_inlay_hints(client, doc, rng, inlays)
`expected_inlays` is a list of tuples. The tuples can be either of length 2
or 3.
- If the tuple is of length 2, the first element is the expected position
and the second element is the expected text of the type. This implies that
the inlay hint is insertable.
- If the tuple is of length 3, then the first two elements are the same as
the 2-tuple. The third element is a boolean that indicates whether the
inlay hint is insertable.
"""
# we currently do not make use of InlayHintKind.Type for type inlays in CLS
inlays_with_colon = [(i[0], f": {i[1]}", None) for i in expected_inlays]
inlays = [
(i[0], f": {i[1]}", i[2] if len(i) >= 3 else True)
for i in expected_inlays
]
actual_inlays = await check_inlay_hints(client, doc, rng, inlays_with_colon)

# Check that the inlays are insertable
for expected, actual in zip(inlays, actual_inlays):
# the list of inlay text edits should have one element and have the
# same text/range as the inlay
assert actual.text_edits is not None
assert len(actual.text_edits) == 1
assert actual.text_edits[0].range.start == expected[0]
assert actual.text_edits[0].new_text == expected[1]
if expected[2]:
# the list of inlay text edits should have one element and have the
# same text/range as the inlay
assert actual.text_edits is not None
assert len(actual.text_edits) == 1
assert actual.text_edits[0].range.start == expected[0]
assert actual.text_edits[0].new_text == expected[1]
else:
# the inlay should not be insertable
assert actual.text_edits is None

return actual_inlays

Expand Down
Loading