Skip to content

Commit 07bb6b4

Browse files
committed
TextDocument now uses threading.Locks to prioritize document change notifications
1 parent 26895fe commit 07bb6b4

File tree

6 files changed

+38
-39
lines changed

6 files changed

+38
-39
lines changed

robotcode/language_server/common/parts/documents.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ async def _text_document_did_open(self, text_document: TextDocumentItem, *args:
258258

259259
self._documents[uri] = document
260260
else:
261-
text_changed = await document.text() != normalized_text
261+
text_changed = document.text != normalized_text
262262
if text_changed:
263263
await document.apply_full_change(text_document.version, normalized_text)
264264

@@ -326,7 +326,7 @@ async def _text_document_did_save(
326326
if text is not None:
327327
normalized_text = self._normalize_line_endings(text)
328328

329-
text_changed = await document.text() != normalized_text
329+
text_changed = document.text != normalized_text
330330
if text_changed:
331331
await document.save(None, text)
332332
create_sub_task(

robotcode/language_server/common/text_document.py

+15-16
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import collections
44
import inspect
55
import io
6+
import threading
67
import weakref
78
from typing import Any, Awaitable, Callable, Dict, List, Optional, TypeVar, Union, cast
89

@@ -38,7 +39,7 @@ def __init__(
3839
) -> None:
3940
super().__init__()
4041

41-
self._lock = Lock()
42+
self._lock = threading.RLock()
4243
self.document_uri = document_uri
4344
self.uri = Uri(self.document_uri).normalized()
4445
self.language_id = language_id
@@ -70,11 +71,9 @@ def __repr__(self) -> str: # pragma: no cover
7071
f")"
7172
)
7273

73-
def text_sync(self) -> str:
74-
return self._text
75-
76-
async def text(self) -> str:
77-
async with self._lock:
74+
@property
75+
def text(self) -> str:
76+
with self._lock:
7877
return self._text
7978

8079
async def save(self, version: Optional[int], text: Optional[str]) -> None:
@@ -88,13 +87,13 @@ async def revert(self, version: Optional[int]) -> bool:
8887

8988
@_logger.call
9089
async def apply_none_change(self) -> None:
91-
async with self._lock:
90+
with self._lock:
9291
self._lines = None
9392
await self._invalidate_cache()
9493

9594
@_logger.call
9695
async def apply_full_change(self, version: Optional[int], text: Optional[str], *, save: bool = False) -> None:
97-
async with self._lock:
96+
with self._lock:
9897
if version is not None:
9998
self._version = version
10099
if text is not None:
@@ -106,7 +105,7 @@ async def apply_full_change(self, version: Optional[int], text: Optional[str], *
106105

107106
@_logger.call
108107
async def apply_incremental_change(self, version: Optional[int], range: Range, text: str) -> None:
109-
async with self._lock:
108+
with self._lock:
110109
try:
111110
if version is not None:
112111
self._version = version
@@ -148,7 +147,7 @@ def __get_lines(self) -> List[str]:
148147

149148
async def get_lines(self) -> List[str]:
150149
if self._lines is None:
151-
async with self._lock:
150+
with self._lock:
152151
return self.__get_lines()
153152
return self._lines
154153

@@ -167,19 +166,19 @@ async def _invalidate_cache(self) -> None:
167166

168167
@_logger.call
169168
async def invalidate_cache(self) -> None:
170-
async with self._lock:
169+
with self._lock:
171170
await self._invalidate_cache()
172171

173172
async def _invalidate_data(self) -> None:
174173
self._data.clear()
175174

176175
@_logger.call
177176
async def invalidate_data(self) -> None:
178-
async with self._lock:
177+
with self._lock:
179178
await self._invalidate_data()
180179

181180
async def __remove_cache_entry_safe(self, _ref: Any) -> None:
182-
async with self._lock:
181+
with self._lock:
183182
if _ref in self._cache:
184183
self._cache.pop(_ref)
185184

@@ -217,8 +216,8 @@ async def get_cache(
217216

218217
reference = self.__get_cache_reference(entry)
219218

220-
# async with self._lock:
221-
e = self._cache[reference]
219+
with self._lock:
220+
e = self._cache[reference]
222221

223222
async with e.lock:
224223
if not e.has_data:
@@ -252,5 +251,5 @@ async def _clear(self) -> None:
252251

253252
@_logger.call
254253
async def clear(self) -> None:
255-
async with self._lock:
254+
with self._lock:
256255
await self._clear()

robotcode/language_server/robotframework/parts/code_action.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,6 @@ async def _convert_uri(self, uri: str, *args: Any, **kwargs: Any) -> Optional[st
359359
if folder:
360360
path = real_uri.to_path().relative_to(folder.uri.to_path())
361361

362-
return f"http://localhost:{self._documentation_server_port}/{path}"
362+
return f"http://localhost:{self._documentation_server_port}/{path.as_posix()}"
363363

364364
return None

robotcode/language_server/robotframework/parts/discovering.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def get_document_text(source: str) -> str:
139139
if self.parent._loop:
140140
doc = self.parent.documents.get_sync(Uri.from_path(source).normalized())
141141
if doc is not None and doc.opened_in_editor:
142-
return doc.text_sync()
142+
return doc.text
143143

144144
return source
145145

robotcode/language_server/robotframework/parts/documents_cache.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ async def __get_tokens_internal(
222222
get: Callable[[str], List[Token]],
223223
) -> List[Token]:
224224

225-
return get(await document.text())
225+
return get(document.text)
226226

227227
async def get_resource_tokens(self, document: TextDocument, data_only: bool = False) -> List[Token]:
228228
if data_only:

tests/robotcode/language_server/common/test_text_document.py

+18-18
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,25 @@ async def test_apply_full_change_should_work() -> None:
1313
text = """first"""
1414
new_text = """changed"""
1515
document = TextDocument(document_uri="file://test.robot", language_id="robotframework", version=1, text=text)
16-
assert await document.text() == text
16+
assert document.text == text
1717

1818
await document.apply_full_change(1, new_text)
1919

20-
assert await document.text() == new_text
20+
assert document.text == new_text
2121

2222

2323
@pytest.mark.asyncio
2424
async def test_apply_apply_incremental_change_at_begining_should_work() -> None:
2525
text = """first"""
2626
new_text = """changed"""
2727
document = TextDocument(document_uri="file://test.robot", language_id="robotframework", version=1, text=text)
28-
assert await document.text() == text
28+
assert document.text == text
2929

3030
await document.apply_incremental_change(
3131
1, Range(start=Position(line=0, character=0), end=Position(line=0, character=0)), new_text
3232
)
3333

34-
assert await document.text() == new_text + text
34+
assert document.text == new_text + text
3535

3636

3737
@pytest.mark.asyncio
@@ -40,13 +40,13 @@ async def test_apply_apply_incremental_change_at_end_should_work() -> None:
4040
new_text = """changed"""
4141

4242
document = TextDocument(document_uri="file://test.robot", language_id="robotframework", version=1, text=text)
43-
assert await document.text() == text
43+
assert document.text == text
4444

4545
await document.apply_incremental_change(
4646
1, Range(start=Position(line=0, character=len(text)), end=Position(line=0, character=len(text))), new_text
4747
)
4848

49-
assert await document.text() == text + new_text
49+
assert document.text == text + new_text
5050

5151

5252
@pytest.mark.asyncio
@@ -55,21 +55,21 @@ async def test_save_and_revert_should_work() -> None:
5555
new_text = """changed"""
5656

5757
document = TextDocument(document_uri="file://test.robot", language_id="robotframework", version=1, text=text)
58-
assert await document.text() == text
58+
assert document.text == text
5959

6060
assert not await document.revert(None)
6161

6262
await document.apply_incremental_change(
6363
2, Range(start=Position(line=0, character=len(text)), end=Position(line=0, character=len(text))), new_text
6464
)
6565

66-
assert await document.text() == text + new_text
66+
assert document.text == text + new_text
6767
assert document.version == 2
6868

6969
assert await document.revert(None)
7070
assert not await document.revert(None)
7171

72-
assert await document.text() == text
72+
assert document.text == text
7373
assert document.version == 1
7474

7575
await document.apply_incremental_change(
@@ -78,7 +78,7 @@ async def test_save_and_revert_should_work() -> None:
7878

7979
await document.save(None, None)
8080

81-
assert await document.text() == text + new_text
81+
assert document.text == text + new_text
8282
assert document.version == 2
8383

8484

@@ -95,13 +95,13 @@ async def test_apply_apply_incremental_change_in_the_middle_should_work() -> Non
9595
third"""
9696

9797
document = TextDocument(document_uri="file://test.robot", language_id="robotframework", version=1, text=text)
98-
assert await document.text() == text
98+
assert document.text == text
9999

100100
await document.apply_incremental_change(
101101
1, Range(start=Position(line=1, character=7), end=Position(line=1, character=7)), new_text
102102
)
103103

104-
assert await document.text() == expected
104+
assert document.text == expected
105105

106106

107107
@pytest.mark.asyncio
@@ -113,13 +113,13 @@ async def test_apply_apply_incremental_change_with_start_line_eq_len_lines_shoul
113113
new_text = """changed """
114114

115115
document = TextDocument(document_uri="file://test.robot", language_id="robotframework", version=1, text=text)
116-
assert await document.text() == text
116+
assert document.text == text
117117

118118
await document.apply_incremental_change(
119119
1, Range(start=Position(line=3, character=7), end=Position(line=3, character=8)), new_text
120120
)
121121

122-
assert await document.text() == text + new_text
122+
assert document.text == text + new_text
123123

124124

125125
@pytest.mark.asyncio
@@ -128,7 +128,7 @@ async def test_apply_apply_incremental_change_with_wrong_range_should_raise_inva
128128
new_text = """changed"""
129129

130130
document = TextDocument(document_uri="file://test.robot", language_id="robotframework", version=1, text=text)
131-
assert await document.text() == text
131+
assert document.text == text
132132

133133
with pytest.raises(InvalidRangeError):
134134
await document.apply_incremental_change(
@@ -141,11 +141,11 @@ async def test_apply_none_change_should_work() -> None:
141141
text = """first"""
142142

143143
document = TextDocument(document_uri="file://test.robot", language_id="robotframework", version=1, text=text)
144-
assert await document.text() == text
144+
assert document.text == text
145145

146146
await document.apply_none_change()
147147

148-
assert await document.text() == text
148+
assert document.text == text
149149

150150

151151
@pytest.mark.asyncio
@@ -157,7 +157,7 @@ async def test_lines_should_give_the_lines_of_the_document() -> None:
157157
"""
158158

159159
document = TextDocument(document_uri="file://test.robot", language_id="robotframework", version=1, text=text)
160-
assert await document.text() == text
160+
assert document.text == text
161161

162162
await document.apply_none_change()
163163

0 commit comments

Comments
 (0)