Skip to content

Commit

Permalink
If a resource/library/variable import is not found and its name has v…
Browse files Browse the repository at this point in the history
…ariables, show the resolved name.
  • Loading branch information
fabioz committed Aug 1, 2022
1 parent 3418417 commit 5e5cbce
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 12 deletions.
4 changes: 2 additions & 2 deletions robotframework-ls/.settings/org.python.pydev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ MULTI_BLOCK_COMMENT_CHAR: '='
MULTI_BLOCK_COMMENT_SHOW_ONLY_CLASS_NAME: true
MULTI_BLOCK_COMMENT_SHOW_ONLY_FUNCTION_NAME: true
PYDEV_TEST_RUNNER: '2'
PYDEV_TEST_RUNNER_DEFAULT_PARAMETERS: --capture=no -W ignore::DeprecationWarning -n auto --tb=native -vv --force-regen
# PYDEV_TEST_RUNNER_DEFAULT_PARAMETERS: --capture=no -W ignore::DeprecationWarning -n auto --tb=native -vv --force-regen
# PYDEV_TEST_RUNNER_DEFAULT_PARAMETERS: --capture=no -W ignore::DeprecationWarning -n auto --tb=native -vv
# PYDEV_TEST_RUNNER_DEFAULT_PARAMETERS: --capture=no -W ignore::DeprecationWarning -n 0 --tb=native -vv
PYDEV_TEST_RUNNER_DEFAULT_PARAMETERS: --capture=no -W ignore::DeprecationWarning -n 0 --tb=native -vv
# PYDEV_TEST_RUNNER_DEFAULT_PARAMETERS: --capture=no -W ignore::DeprecationWarning -n 0 --tb=native -vv --force-regen
PYDEV_USE_PYUNIT_VIEW: true
SAVE_ACTIONS_ONLY_ON_WORKSPACE_FILES: true
Expand Down
18 changes: 14 additions & 4 deletions robotframework-ls/src/robotframework_ls/impl/code_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ def on_unresolved_library(
col_offset: int,
end_col_offset: int,
error_msg: Optional[str],
resolved_name: str,
):
from robotframework_ls.impl.robot_lsp_constants import (
OPTION_ROBOT_LINT_UNDEFINED_LIBRARIES,
Expand Down Expand Up @@ -304,6 +305,9 @@ def on_unresolved_library(
if re.search(pattern, error_msg):
additional = f'\nConsider adding the needed paths to the "robot.pythonpath" setting\nand calling the "Robot Framework: Clear caches and restart" action.'

if "{" in library_name and resolved_name:
error_msg += f"\nNote: resolved name: {resolved_name}"

errors.append(
ast_utils.Error(
f"Unresolved library: {library_name}.{error_msg}{additional}".strip(),
Expand All @@ -314,12 +318,13 @@ def on_unresolved_library(

def on_unresolved_resource(
completion_context: ICompletionContext,
library_name: str,
resource_name: str,
lineno: int,
end_lineno: int,
col_offset: int,
end_col_offset: int,
error_msg: Optional[str],
resolved_name: str,
):
from robotframework_ls.impl.robot_lsp_constants import (
OPTION_ROBOT_LINT_UNDEFINED_RESOURCES,
Expand All @@ -335,7 +340,9 @@ def on_unresolved_resource(
start = (lineno - 1, col_offset)
end = (end_lineno - 1, end_col_offset)
if not error_msg:
error_msg = f"Unresolved resource: {library_name}"
error_msg = f"Unresolved resource: {resource_name}"
if "{" in resource_name and resolved_name:
error_msg += f"\nNote: resolved name: {resolved_name}"

errors.append(ast_utils.Error(error_msg, start, end))

Expand Down Expand Up @@ -585,12 +592,13 @@ def _collect_undefined_variables_errors(initial_completion_context):

def on_unresolved_variable_import(
completion_context: ICompletionContext,
library_name: str,
variable_import_name: str,
lineno: int,
end_lineno: int,
col_offset: int,
end_col_offset: int,
error_msg: Optional[str],
resolved_name: str,
):
from robotframework_ls.impl.robot_lsp_constants import (
OPTION_ROBOT_LINT_UNDEFINED_VARIABLE_IMPORTS,
Expand All @@ -606,7 +614,9 @@ def on_unresolved_variable_import(
start = (lineno - 1, col_offset)
end = (end_lineno - 1, end_col_offset)
if not error_msg:
error_msg = f"Unresolved variable import: {library_name}"
error_msg = f"Unresolved variable import: {variable_import_name}"
if "{" in variable_import_name and resolved_name:
error_msg += f"\nNote: resolved name: {resolved_name}"

unresolved_variable_import_errors.append(
ast_utils.Error(error_msg, start, end)
Expand Down
10 changes: 8 additions & 2 deletions robotframework-ls/src/robotframework_ls/impl/collect_keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def _collect_libraries_keywords(

if node_name_tok is not None:
(
_value,
value,
token_errors,
) = completion_context.token_value_and_unresolved_resolving_variables(
node_name_tok
Expand All @@ -395,6 +395,7 @@ def _collect_libraries_keywords(
token_error.col_offset,
token_error.end_col_offset,
f"\nUnable to statically resolve variable: {token_error.value}.\nPlease set the `{token_error.value[2:-1]}` value in `robot.variables`.",
value,
)
else:
collector.on_unresolved_library(
Expand All @@ -405,6 +406,7 @@ def _collect_libraries_keywords(
node_name_tok.col_offset,
node_name_tok.end_col_offset,
error_msg,
value,
)
else:
collector.on_unresolved_library(
Expand All @@ -415,6 +417,7 @@ def _collect_libraries_keywords(
node.col_offset,
node.end_col_offset,
error_msg,
"",
)


Expand Down Expand Up @@ -447,7 +450,7 @@ def _collect_from_context(
if node_name_tok is not None:

(
_value,
value,
token_errors,
) = completion_context.token_value_and_unresolved_resolving_variables(
node_name_tok
Expand All @@ -463,6 +466,7 @@ def _collect_from_context(
token_error.col_offset,
token_error.end_col_offset,
f"\nUnable to statically resolve variable: {token_error.value}.\nPlease set the `{token_error.value[2:-1]}` value in `robot.variables`.",
value,
)

else:
Expand All @@ -474,6 +478,7 @@ def _collect_from_context(
node_name_tok.col_offset,
node_name_tok.end_col_offset,
None,
value,
)
else:
collector.on_unresolved_resource(
Expand All @@ -484,6 +489,7 @@ def _collect_from_context(
node.col_offset,
node.end_col_offset,
None,
"",
)
continue
completion_context.check_cancelled()
Expand Down
6 changes: 6 additions & 0 deletions robotframework-ls/src/robotframework_ls/impl/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ def on_unresolved_library(
col_offset: int,
end_col_offset: int,
error_msg: Optional[str],
resolved_name: str,
):
pass

Expand All @@ -637,6 +638,7 @@ def on_unresolved_resource(
col_offset: int,
end_col_offset: int,
error_msg: Optional[str],
resolved_name: str,
):
pass

Expand All @@ -659,6 +661,7 @@ def on_unresolved_library(
col_offset: int,
end_col_offset: int,
error_msg: Optional[str],
resolved_name: str,
):
pass

Expand All @@ -671,6 +674,7 @@ def on_unresolved_resource(
col_offset: int,
end_col_offset: int,
error_msg: Optional[str],
resolved_name: str,
):
pass

Expand Down Expand Up @@ -1171,6 +1175,7 @@ def on_unresolved_variable_import(
col_offset: int,
end_col_offset: int,
error_msg: Optional[str],
resolved_name: str,
):
pass

Expand All @@ -1196,6 +1201,7 @@ def on_unresolved_variable_import(
col_offset: int,
end_col_offset: int,
error_msg: Optional[str],
resolved_name: str,
):
pass

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ def collect_global_variables_from_document_dependencies(
if node_name_tok is not None:

(
_value,
value,
token_errors,
) = completion_context.token_value_and_unresolved_resolving_variables(
node_name_tok
Expand All @@ -307,6 +307,7 @@ def collect_global_variables_from_document_dependencies(
token_error.col_offset,
token_error.end_col_offset,
f"\nUnable to statically resolve variable: {token_error.value}.\nPlease set the `{token_error.value[2:-1]}` value in `robot.variables`.",
value,
)

else:
Expand All @@ -318,6 +319,7 @@ def collect_global_variables_from_document_dependencies(
node_name_tok.col_offset,
node_name_tok.end_col_offset,
None,
value,
)
else:
collector.on_unresolved_variable_import(
Expand All @@ -328,6 +330,7 @@ def collect_global_variables_from_document_dependencies(
node.col_offset,
node.end_col_offset,
None,
"",
)
continue
_collect_variables_from_variable_import_doc(variable_doc, collector)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
Test Template Variable should not exist
Resource ${IMPORT 1}.robot
#! ^^^^^^^^^^^^^^^^^ Unresolved resource: ${IMPORT 1}.robot
#! ^^^^^^^^^^^^^^^^^ Note: resolved name: ${IMPORT 2}.robot
Library ${IMPORT 2}.py
#! ^^^^^^^^^^^^^^ Unresolved library: ${IMPORT 2}.py.
#! ^^^^^^^^^^^^^^ Error generating libspec:
#! ^^^^^^^^^^^^^^ Importing library '${IMPORT 1}' failed: ModuleNotFoundError: No module named '${IMPORT 1}'
#! ^^^^^^^^^^^^^^ Note: resolved name: ${IMPORT 1}.py
#! ^^^^^^^^^^^^^^ Consider adding the needed paths to the "robot.pythonpath" setting
#! ^^^^^^^^^^^^^^ and calling the "Robot Framework: Clear caches and restart" action.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ ${NONEX 3} This ${NON EXISTING VARIABLE} is used in imports.
*** Settings ***
Resource ${NONEX 3}
#! ^^^^^^^^^^ Unresolved resource: ${NONEX 3}
#! ^^^^^^^^^^ Note: resolved name: This ${NON EXISTING VARIABLE} is used in imports.
Library ${NONEX 3}
#! ^^^^^^^^^^ Unresolved library: ${NONEX 3}.
#! ^^^^^^^^^^ Error generating libspec:
#! ^^^^^^^^^^ Importing library 'This ${NON EXISTING VARIABLE} is used in imports.' failed: ModuleNotFoundError: No module named 'This ${NON EXISTING VARIABLE} is used in imports'
#! ^^^^^^^^^^ Note: resolved name: This ${NON EXISTING VARIABLE} is used in imports.
#! ^^^^^^^^^^ Consider adding the needed paths to the "robot.pythonpath" setting
#! ^^^^^^^^^^ and calling the "Robot Framework: Clear caches and restart" action.
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ ${NONEX 3} This ${NON EXISTING VARIABLE} is used in imports.
*** Settings ***
Resource ${NONEX 3}
#! ^^^^^^^^^^ Unresolved resource: ${NONEX 3}
#! ^^^^^^^^^^ Note: resolved name: This ${NON EXISTING VARIABLE} is used in imports.
Library ${NONEX 3}
#! ^^^^^^^^^^ Unresolved library: ${NONEX 3}.
#! ^^^^^^^^^^ Error generating libspec:
#! ^^^^^^^^^^ Importing library 'This ${NON EXISTING VARIABLE} is used in imports.' failed: ModuleNotFoundError: No module named 'This ${NON EXISTING VARIABLE} is used in imports'
#! ^^^^^^^^^^ Note: resolved name: This ${NON EXISTING VARIABLE} is used in imports.
#! ^^^^^^^^^^ Consider adding the needed paths to the "robot.pythonpath" setting
#! ^^^^^^^^^^ and calling the "Robot Framework: Clear caches and restart" action.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import pytest


def _collect_errors(workspace, doc, data_regression, basename=None, config=None):
def _collect_errors(
workspace, doc, data_regression, basename=None, config=None, transform_errors=None
):
from robotframework_ls.impl.completion_context import CompletionContext
from robotframework_ls.impl.code_analysis import collect_analysis_errors

Expand All @@ -12,6 +14,8 @@ def _collect_errors(workspace, doc, data_regression, basename=None, config=None)
error.to_lsp_diagnostic()
for error in collect_analysis_errors(completion_context)
]
if transform_errors is not None:
errors = transform_errors(errors)

def key(diagnostic):
return (
Expand Down Expand Up @@ -2244,7 +2248,28 @@ def test_resolve_caches(workspace, libspec_manager, data_regression):
Log ${COMMON_2} console=True
"""

_collect_errors(workspace, doc, data_regression)
def transform_errors(errors):
ret = []
for dct in errors:
message = dct["message"]
# Change something as:
# Note: resolved name: c:\\Users\\xxx\\pytest-5350\\res áéíóú0\\case_vars_file\\not there now\\common variables.yaml
# to:
# Note: resolved name: xxx
if "resolved name" in message:
import re

assert "common variables.yaml" in message

message = re.sub(
"Note: resolved name: (.*)", "Note: resolved name: xxx", message
)
dct["message"] = message

ret.append(dct)
return ret

_collect_errors(workspace, doc, data_regression, transform_errors=transform_errors)
event = threading.Event()

def on_file_changed(src_path):
Expand Down Expand Up @@ -2461,3 +2486,38 @@ def test_keyword_regexp(workspace, libspec_manager, data_regression):
No operation
"""
_collect_errors(workspace, doc, data_regression, basename="no_error")


@pytest.mark.parametrize("found", [False, True])
def test_code_analysis_environment_variable_in_resource_import(
workspace, libspec_manager, data_regression, found
):

import os

if found:
os.environ["ENV_VAR_IN_RESOURCE_IMPORT"] = "./my"
else:
os.environ["ENV_VAR_IN_RESOURCE_IMPORT"] = "./my_not_found"

workspace.set_root("case2", libspec_manager=libspec_manager)
doc = workspace.put_doc("my/keywords.resource")
doc.source = """
*** Keywords ***
Common Keyword
Log to console Common keyword"""

doc = workspace.put_doc("case2.robot")
doc.source = """
*** Settings ***
Resource %{ENV_VAR_IN_RESOURCE_IMPORT}/keywords.resource
*** Test Cases ***
Dummy Test Case
Common Keyword
"""

_collect_errors(
workspace, doc, data_regression, basename="no_error" if found else None
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
- message: 'Unresolved resource: %{ENV_VAR_IN_RESOURCE_IMPORT}/keywords.resource
Note: resolved name: ./my_not_found/keywords.resource'
range:
end:
character: 63
line: 2
start:
character: 16
line: 2
severity: 1
source: robotframework
- message: 'Undefined keyword: Common Keyword.'
range:
end:
character: 18
line: 7
start:
character: 4
line: 7
severity: 1
source: robotframework
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
- message: 'Unresolved variable import: ${CURDIR}${/}not there now${/}common variables.yaml'
- message: 'Unresolved variable import: ${CURDIR}${/}not there now${/}common variables.yaml
Note: resolved name: xxx'
range:
end:
character: 71
Expand Down

0 comments on commit 5e5cbce

Please sign in to comment.