Skip to content

Commit dd1f9fc

Browse files
committed
Issue: #444
feat: Add support for C# expression-bodied members in CSharpStates This commit introduces functionality to handle C# expression-bodied members (using the '=>' syntax) in the CSharpStates class. It includes methods to confirm new functions and process expression bodies until the end of the method. Additionally, new tests have been added to verify the detection and complexity calculation of expression-bodied methods, ensuring accurate representation in the function list.
1 parent b585a89 commit dd1f9fc

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

lizard_languages/csharp.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,22 @@ def try_new_function(self, name):
4242
if self.class_name and self.context.current_function:
4343
self.context.current_function.name = f"{self.class_name}::{name}"
4444

45+
def _state_dec_to_imp(self, token):
46+
"""Override to handle C# expression-bodied members (=>)"""
47+
if token == '=>':
48+
# Expression-bodied member: confirm function and enter expression body
49+
self.context.confirm_new_function()
50+
self._state = self._state_expression_body
51+
else:
52+
super(CSharpStates, self)._state_dec_to_imp(token)
53+
54+
def _state_expression_body(self, token):
55+
"""Read the expression body until semicolon, processing tokens for complexity"""
56+
if token == ';':
57+
# End of expression-bodied method, finalize function and return to global state
58+
self.context.end_of_function()
59+
self._state = self._state_global
60+
4561
def _state_global(self, token):
4662
if token in ("class", "struct", "record"):
4763
self.class_name = None

test/test_languages/testCsharp.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,81 @@ def test_primary_constructor_vs_traditional(self):
139139
"Method should have complexity of 1")
140140
self.assertEqual(1, constructor_func.cyclomatic_complexity,
141141
"Constructor should have complexity of 1")
142+
143+
def test_expression_bodied_methods(self):
144+
"""Test that expression-bodied methods (lambda-style syntax) are detected."""
145+
result = get_csharp_function_list('''
146+
using System;
147+
148+
public class SimpleCalculator
149+
{
150+
public int Add(int a, int b) => a + b;
151+
152+
public int Subtract(int a, int b)
153+
{
154+
int result = a - b;
155+
return result;
156+
}
157+
158+
public static void Main(string[] args)
159+
{
160+
var calc = new SimpleCalculator();
161+
Console.WriteLine($"Addition: {calc.Add(30, 15)}");
162+
Console.WriteLine($"Subtraction: {calc.Subtract(30, 15)}");
163+
}
164+
}
165+
''')
166+
167+
function_names = [f.name for f in result]
168+
self.assertIn("SimpleCalculator::Add", function_names,
169+
f"Expected to find 'SimpleCalculator::Add' but only found: {function_names}")
170+
self.assertIn("SimpleCalculator::Subtract", function_names,
171+
f"Expected to find 'SimpleCalculator::Subtract' but only found: {function_names}")
172+
self.assertIn("SimpleCalculator::Main", function_names,
173+
f"Expected to find 'SimpleCalculator::Main' but only found: {function_names}")
174+
175+
self.assertEqual(3, len(result),
176+
f"Expected 3 functions but found {len(result)}: {function_names}")
177+
178+
add_func = next(f for f in result if f.name == "SimpleCalculator::Add")
179+
self.assertEqual(1, add_func.cyclomatic_complexity,
180+
"Expression-bodied Add method should have complexity of 1")
181+
182+
def test_expression_bodied_methods(self):
183+
"""Test that expression-bodied methods (lambda-style syntax) are detected."""
184+
result = get_csharp_function_list('''
185+
using System;
186+
187+
public class SimpleCalculator
188+
{
189+
public int Add(int a, int b) => a + b;
190+
191+
public int Subtract(int a, int b)
192+
{
193+
int result = a - b;
194+
return result;
195+
}
196+
197+
public static void Main(string[] args)
198+
{
199+
var calc = new SimpleCalculator();
200+
Console.WriteLine($"Addition: {calc.Add(30, 15)}");
201+
Console.WriteLine($"Subtraction: {calc.Subtract(30, 15)}");
202+
}
203+
}
204+
''')
205+
206+
function_names = [f.name for f in result]
207+
self.assertIn("SimpleCalculator::Add", function_names,
208+
f"Expected to find 'SimpleCalculator::Add' but only found: {function_names}")
209+
self.assertIn("SimpleCalculator::Subtract", function_names,
210+
f"Expected to find 'SimpleCalculator::Subtract' but only found: {function_names}")
211+
self.assertIn("SimpleCalculator::Main", function_names,
212+
f"Expected to find 'SimpleCalculator::Main' but only found: {function_names}")
213+
214+
self.assertEqual(3, len(result),
215+
f"Expected 3 functions but found {len(result)}: {function_names}")
216+
217+
add_func = next(f for f in result if f.name == "SimpleCalculator::Add")
218+
self.assertEqual(1, add_func.cyclomatic_complexity,
219+
"Expression-bodied Add method should have complexity of 1")

0 commit comments

Comments
 (0)