Coverage for src/robotide/namespace/local_namespace.py: 86%

65 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-06 10:40 +0100

1# Copyright 2008-2015 Nokia Networks 

2# Copyright 2016- Robot Framework Foundation 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

13# See the License for the specific language governing permissions and 

14# limitations under the License. 

15 

16from robotide import utils 1df

17from robotide.spec.iteminfo import LocalVariableInfo 1df

18 

19 

20def local_namespace(controller, namespace, row=None): 1df

21 if row is not None: # can be 0! 1dophqlijrsmtuvwxkzAygnbBcea

22 return LocalRowNamespace(controller, namespace, row) 1ophqlijrsmtuvwxkgnbcea

23 return LocalMacroNamespace(controller, namespace) 1dzAyB

24 

25 

26class LocalMacroNamespace(object): 1df

27 

28 def __init__(self, controller, namespace): 1df

29 self._controller = controller 1dophqlijrsmtuvwxkzAygnbBcea

30 self.namespace = namespace 1dophqlijrsmtuvwxkzAygnbBcea

31 

32 def get_suggestions(self, start): 1df

33 # print(f"DEBUG: local_namespace.py LocalMacroNamespace get_suggestions ENTER start={start}") 

34 return self.namespace.get_suggestions_for(self._controller, start) 1zbcea

35 

36 def has_name(self, value): 1df

37 for sug in self.namespace.get_suggestions_for(self._controller, value): 1ophqlijrsmtuvwxkAygn

38 if sug.name == value: 38 ↛ 40line 38 didn't jump to line 40 because the condition on line 38 was always true1hjyg

39 return True 1hjyg

40 try: 

41 if value in sug.assign: 

42 return True 

43 except AttributeError: 

44 pass 

45 return False 1ophqlijrsmtuvwxkAn

46 

47 def update_words_cache(self, words_list: list, reset=False): 1df

48 return self.namespace.update_words_cache(words_list, reset) 1dz

49 

50 

51class LocalRowNamespace(LocalMacroNamespace): 1df

52 

53 def __init__(self, controller, namespace, row): 1df

54 LocalMacroNamespace.__init__(self, controller, namespace) 1ophqlijrsmtuvwxkgnbcea

55 self._row = row 1ophqlijrsmtuvwxkgnbcea

56 

57 def get_suggestions(self, start): 1df

58 suggestions = LocalMacroNamespace.get_suggestions(self, start) 1bcea

59 # print(f"DEBUG: suggesters.py LocalRowNamespace get_suggestions after LocalMacroNamespace start={start}\n" 

60 # f"suggestions={suggestions}") 

61 if self._could_be_variable(start): 1bcea

62 suggestions = self._harvest_local_variables(start, suggestions) 1bcea

63 else: 

64 suggestions = self._harvest_local_variables('${'+start, suggestions) 1a

65 suggestions = self._harvest_local_variables('@{'+start, suggestions) 1a

66 suggestions = self._harvest_local_variables('&{'+start, suggestions) 1a

67 return suggestions 1bcea

68 

69 def _harvest_local_variables(self, start, suggestions): 1df

70 matching_assignments = set() 1bcea

71 for row, step in enumerate(self._controller.steps): 71 ↛ 77line 71 didn't jump to line 77 because the loop on line 71 didn't complete1bcea

72 if self._row == row: 1bcea

73 break 1bcea

74 matching_assignments = matching_assignments.union( 1bcea

75 val.replace('=', '').strip() for val in step.assignments if 

76 val.startswith(start)) 

77 if matching_assignments: 1bcea

78 local_variables = [LocalVariableInfo(name) for name 1bca

79 in matching_assignments] 

80 suggestions = sorted(self._remove_duplicates(suggestions, 1bca

81 local_variables)) 

82 return suggestions 1bcea

83 

84 @staticmethod 1df

85 def _could_be_variable(start): 1df

86 return len(start) == 0 or start[0] in ['$', '@', '&'] 1bcea

87 

88 def has_name(self, value): 1df

89 if self._row is not None: 89 ↛ 95line 89 didn't jump to line 95 because the condition on line 89 was always true1ophqlijrsmtuvwxkgn

90 for row, step in enumerate(self._controller.steps): 90 ↛ 95line 90 didn't jump to line 95 because the loop on line 90 didn't complete1ophqlijrsmtuvwxkgn

91 if self._row == row: 1ophqlijrsmtuvwxkgn

92 break 1ophqlijrsmtuvwxkgn

93 if step.is_assigning(value): 1limkgn

94 return True 1ikg

95 return LocalMacroNamespace.has_name(self, value) 1ophqlijrsmtuvwxkgn

96 

97 @staticmethod 1df

98 def _remove_duplicates(suggestions, local_variables): 1df

99 def is_unique(gvar): 1bca

100 if hasattr(gvar, 'name'): 100 ↛ 103line 100 didn't jump to line 103 because the condition on line 100 was always true1bca

101 return utils.normalize(gvar.name) not in [utils.normalize(lvar.name) for lvar in local_variables] 1bca

102 else: 

103 return utils.normalize(gvar) not in [utils.normalize(lvar.name) for lvar in local_variables] 

104 unique = [gvar for gvar in suggestions if is_unique(gvar)] 1bca

105 return unique + local_variables 1bca