Skip to content

Commit 3fc7deb

Browse files
lsp: Code-review fixups.
1 parent b22d149 commit 3fc7deb

File tree

2 files changed

+39
-37
lines changed

2 files changed

+39
-37
lines changed

libsolidity/lsp/LanguageServer.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,24 @@ using namespace solidity::lsp;
5353
using namespace solidity::langutil;
5454
using namespace solidity::frontend;
5555

56+
namespace fs = boost::filesystem;
57+
5658
namespace
5759
{
5860

61+
bool resolvesToRegularFile(boost::filesystem::path _path)
62+
{
63+
fs::file_status fileStatus = fs::status(_path);
64+
65+
while (fileStatus.type() == fs::file_type::symlink_file)
66+
{
67+
_path = boost::filesystem::read_symlink(_path);
68+
fileStatus = fs::status(_path);
69+
}
70+
71+
return fileStatus.type() == fs::file_type::regular_file;
72+
}
73+
5974
int toDiagnosticSeverity(Error::Type _errorType)
6075
{
6176
// 1=Error, 2=Warning, 3=Info, 4=Hint
@@ -198,22 +213,18 @@ void LanguageServer::changeConfiguration(Json::Value const& _settings)
198213

199214
vector<boost::filesystem::path> LanguageServer::allSolidityFilesFromProject() const
200215
{
201-
namespace fs = boost::filesystem;
202-
203-
std::vector<fs::path> collectedPaths{};
216+
vector<fs::path> collectedPaths{};
204217

205218
// We explicitly decided against including all files from include paths but leave the possibility
206219
// open for a future PR to enable such a feature to be optionally enabled (default disabled).
207220

208221
auto directoryIterator = fs::recursive_directory_iterator(m_fileRepository.basePath(), fs::symlink_option::recurse);
209222
for (fs::directory_entry const& dirEntry: directoryIterator)
210-
{
211223
if (
212-
dirEntry.status().type() == fs::file_type::regular_file &&
213-
dirEntry.path().extension() == ".sol"
224+
dirEntry.path().extension() == ".sol" &&
225+
(dirEntry.status().type() == fs::file_type::regular_file || resolvesToRegularFile(dirEntry.path()))
214226
)
215-
collectedPaths.push_back(dirEntry.path());
216-
}
227+
collectedPaths.push_back(dirEntry.path());
217228

218229
return collectedPaths;
219230
}

test/lsp.py

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -539,16 +539,9 @@ def at_end(self):
539539
return self.current_line_tuple is None
540540

541541
class FileLoadStrategy(Enum):
542-
Undefined = auto()
543-
ProjectDirectory = auto()
544-
DirectlyOpenedAndOnImport = auto()
545-
546-
def lsp_name(self):
547-
if self == FileLoadStrategy.ProjectDirectory:
548-
return 'project-directory'
549-
elif self == FileLoadStrategy.DirectlyOpenedAndOnImport:
550-
return 'directly-opened-and-on-import'
551-
return None
542+
Undefined = None
543+
ProjectDirectory = 'project-directory'
544+
DirectlyOpenedAndOnImport = 'directly-opened-and-on-import'
552545

553546
class FileTestRunner:
554547
"""
@@ -932,7 +925,6 @@ def setup_lsp(
932925
# Enable traces to receive the amount of expected diagnostics before
933926
# actually receiving them.
934927
'trace': 'messages',
935-
# 'initializationOptions': {},
936928
'capabilities': {
937929
'textDocument': {
938930
'publishDiagnostics': {'relatedInformation': True}
@@ -949,7 +941,7 @@ def setup_lsp(
949941

950942
if file_load_strategy != FileLoadStrategy.Undefined:
951943
params['initializationOptions'] = {}
952-
params['initializationOptions']['file-load-strategy'] = file_load_strategy.lsp_name()
944+
params['initializationOptions']['file-load-strategy'] = file_load_strategy.value
953945

954946
if custom_include_paths is not None and len(custom_include_paths) != 0:
955947
if params['initializationOptions'] is None:
@@ -1337,7 +1329,7 @@ def user_interaction_failed_autoupdate(self, test, sub_dir):
13371329
# }}}
13381330

13391331
# {{{ actual tests
1340-
def test_analyze_all_project_files1(self, solc: JsonRpcProcess) -> None:
1332+
def test_analyze_all_project_files_flat(self, solc: JsonRpcProcess) -> None:
13411333
"""
13421334
Tests the option (default) to analyze all .sol project files even when they have not been actively
13431335
opened yet. This is how other LSPs (at least for C++) work too and it makes cross-unit tasks
@@ -1370,42 +1362,41 @@ def test_analyze_all_project_files1(self, solc: JsonRpcProcess) -> None:
13701362
self.expect_equal(report['uri'], self.get_test_file_uri('E', SUBDIR), "Correct file URI")
13711363
self.expect_equal(len(report['diagnostics']), 0, "no diagnostics")
13721364

1373-
def test_analyze_all_project_files2(self, solc: JsonRpcProcess) -> None:
1365+
def test_analyze_all_project_files_nested(self, solc: JsonRpcProcess) -> None:
13741366
"""
13751367
Same as first test on that matter but with deeper nesting levels.
13761368
"""
13771369
SUBDIR = 'include-paths-nested'
1378-
EXPECTED_FILES = [
1370+
EXPECTED_FILES = {
13791371
"A/B/C/foo",
13801372
"A/B/foo",
13811373
"A/foo",
13821374
"foo",
1383-
]
1384-
EXPECTED_URIS = [self.get_test_file_uri(x, SUBDIR) for x in EXPECTED_FILES]
1375+
}
1376+
EXPECTED_URIS = {self.get_test_file_uri(x, SUBDIR) for x in EXPECTED_FILES}
13851377
self.setup_lsp(
13861378
solc,
13871379
file_load_strategy=FileLoadStrategy.ProjectDirectory,
13881380
project_root_subdir=SUBDIR
13891381
)
13901382
published_diagnostics = self.wait_for_diagnostics(solc)
13911383
self.expect_equal(len(published_diagnostics), len(EXPECTED_FILES), "Test number of files analyzed.")
1392-
for report in published_diagnostics:
1393-
self.expect_true(report['uri'] in EXPECTED_URIS, "Correct file URI")
1394-
self.expect_equal(len(report['diagnostics']), 0, "no diagnostics")
1384+
self.expect_equal({report['uri'] for report in published_diagnostics}, EXPECTED_URIS)
1385+
self.expect_equal([len(report['diagnostics']) for report in published_diagnostics], [0] * len(EXPECTED_URIS))
13951386

1396-
def test_analyze_all_project_files3(self, solc: JsonRpcProcess) -> None:
1387+
def test_analyze_all_project_files_nested_with_include_paths(self, solc: JsonRpcProcess) -> None:
13971388
"""
13981389
Same as first test on that matter but with deeper nesting levels.
13991390
"""
14001391
SUBDIR = 'include-paths-nested-2'
1401-
EXPECTED_FILES = [
1392+
EXPECTED_FILES = {
14021393
"A/B/C/foo",
14031394
"A/B/foo",
14041395
"A/foo",
14051396
"foo",
1406-
]
1397+
}
14071398
IMPLICITLY_LOADED_FILE_COUNT = 1
1408-
EXPECTED_URIS = [self.get_test_file_uri(x, SUBDIR) for x in EXPECTED_FILES]
1399+
EXPECTED_URIS = {self.get_test_file_uri(x, SUBDIR) for x in EXPECTED_FILES}
14091400
self.setup_lsp(
14101401
solc,
14111402
file_load_strategy=FileLoadStrategy.ProjectDirectory,
@@ -1426,9 +1417,9 @@ def test_analyze_all_project_files3(self, solc: JsonRpcProcess) -> None:
14261417

14271418
# Check last report (should be the custom imported lib).
14281419
# This file is analyzed because it was imported via "A/B/C/foo.sol".
1429-
report = published_diagnostics[len(EXPECTED_URIS)]
1430-
self.expect_equal(report['uri'], f"{self.project_root_uri}/other-include-dir/otherlib/second.sol", "Correct file URI")
1431-
self.expect_equal(len(report['diagnostics']), 0, "no diagnostics")
1420+
last_report = published_diagnostics[len(EXPECTED_URIS)]
1421+
self.expect_equal(last_report['uri'], self.get_test_file_uri('second', 'other-include-dir/otherlib'), "Correct file URI")
1422+
self.expect_equal(len(last_report['diagnostics']), 0, "no diagnostics")
14321423

14331424

14341425
def test_publish_diagnostics_errors_multiline(self, solc: JsonRpcProcess) -> None:
@@ -1545,7 +1536,7 @@ def test_custom_includes(self, solc: JsonRpcProcess) -> None:
15451536

15461537
def test_custom_includes_with_full_project(self, solc: JsonRpcProcess) -> None:
15471538
"""
1548-
Tests loading all all project files while having custom include directories configured.
1539+
Tests loading all project files while having custom include directories configured.
15491540
In such a scenario, all project files should be analyzed and those being included via search path
15501541
but not those include files that are not directly nor indirectly included.
15511542
"""
@@ -1577,7 +1568,7 @@ def test_custom_includes_with_full_project(self, solc: JsonRpcProcess) -> None:
15771568
report = published_diagnostics[1]
15781569
self.expect_equal(report['uri'], f"{self.project_root_uri}/other-include-dir/otherlib/otherlib.sol")
15791570
diagnostics = report['diagnostics']
1580-
self.expect_equal(len(diagnostics), 1, "no diagnostics")
1571+
self.expect_equal(len(diagnostics), 1)
15811572
self.expect_diagnostic(diagnostics[0], code=2018, lineNo=5, startEndColumns=(4, 62))
15821573

15831574
def test_didChange_in_A_causing_error_in_B(self, solc: JsonRpcProcess) -> None:

0 commit comments

Comments
 (0)