Skip to content

Commit

Permalink
start to add Rust
Browse files Browse the repository at this point in the history
  • Loading branch information
terryyin committed Dec 25, 2019
1 parent 7f9bbdc commit 366cbb6
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 30 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ A list of supported languages:
- C/C++ (works with C++14)
- Java
- C# (C Sharp)
- JavaScript
- JavaScript (With ES6)
- Objective-C
- Swift
- Python
Expand Down
4 changes: 3 additions & 1 deletion lizard_languages/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .gdscript import GDScriptReader
from .go import GoReader
from .lua import LuaReader
from .rust import RustReader


def languages():
Expand All @@ -31,7 +32,8 @@ def languages():
ScalaReader,
GDScriptReader,
GoReader,
LuaReader
LuaReader,
RustReader
]


Expand Down
31 changes: 3 additions & 28 deletions lizard_languages/go.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from .code_reader import CodeReader, CodeStateMachine
from .clike import CCppCommentsMixin
from .golike import GoLikeStates


class GoReader(CodeReader, CCppCommentsMixin):
Expand All @@ -17,31 +18,5 @@ def __init__(self, context):
self.parallel_states = [GoStates(context)]


class GoStates(CodeStateMachine): # pylint: disable=R0903
def _state_global(self, token):
if token == 'func':
self._state = self._function_name
self.context.start_new_function('')

def _function_name(self, token):
if token == '(':
return self.next(self._member_function, token)
self.context.add_to_function_name(token)
self._state = self._function_dec

@CodeStateMachine.read_inside_brackets_then("()", '_function_name')
def _member_function(self, tokens):
self.context.add_to_long_function_name(tokens)

@CodeStateMachine.read_inside_brackets_then("()", '_expect_function_impl')
def _function_dec(self, token):
if token not in '()':
self.context.parameter(token)

def _expect_function_impl(self, token):
self.next_if(self._function_impl, token, '{')

@CodeStateMachine.read_inside_brackets_then("{}")
def _function_impl(self, _):
self._state = self._state_global
self.context.end_of_function()
class GoStates(GoLikeStates): # pylint: disable=R0903
pass
38 changes: 38 additions & 0 deletions lizard_languages/golike.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'''
Language parser for Go lang
'''

from .code_reader import CodeStateMachine


class GoLikeStates(CodeStateMachine): # pylint: disable=R0903

FUNC_KEYWORD = 'func'

def _state_global(self, token):
if token == self.FUNC_KEYWORD:
self._state = self._function_name
self.context.start_new_function('')

def _function_name(self, token):
if token == '(':
return self.next(self._member_function, token)
self.context.add_to_function_name(token)
self._state = self._function_dec

@CodeStateMachine.read_inside_brackets_then("()", '_function_name')
def _member_function(self, tokens):
self.context.add_to_long_function_name(tokens)

@CodeStateMachine.read_inside_brackets_then("()", '_expect_function_impl')
def _function_dec(self, token):
if token not in '()':
self.context.parameter(token)

def _expect_function_impl(self, token):
self.next_if(self._function_impl, token, '{')

@CodeStateMachine.read_inside_brackets_then("{}")
def _function_impl(self, _):
self._state = self._state_global
self.context.end_of_function()
24 changes: 24 additions & 0 deletions lizard_languages/rust.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'''
Language parser for Go lang
'''

from .code_reader import CodeReader
from .clike import CCppCommentsMixin
from .golike import GoLikeStates


class RustReader(CodeReader, CCppCommentsMixin):
# pylint: disable=R0903

ext = ['rs']
language_names = ['rust']
_conditions = set(['if', 'for', 'while', '&&', '||', '?', 'catch',
'case', 'match'])

def __init__(self, context):
super(RustReader, self).__init__(context)
self.parallel_states = [RustStates(context)]


class RustStates(GoLikeStates): # pylint: disable=R0903
FUNC_KEYWORD = 'fn'
41 changes: 41 additions & 0 deletions test/test_languages/testRust.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import unittest
from lizard import analyze_file, FileAnalyzer, get_extensions


def get_rust_fileinfo(source_code):
return analyze_file.analyze_source_code("a.rs", source_code)


def get_rust_function_list(source_code):
return get_rust_fileinfo(source_code).function_list


class TestRust(unittest.TestCase):

def test_main(self):
result = get_rust_function_list('''
fn main() {
println!("Hello, world!");
}
''')
self.assertEqual(1, len(result))
self.assertEqual('main', result[0].name)

def test_return(self):
result = get_rust_function_list('''
fn plus_one(x: i32) -> i32 {
x + 1;
}
''')
self.assertEqual(1, len(result))
self.assertEqual('plus_one', result[0].name)

def test_if(self):
result = get_rust_function_list('''
fn main() {
match a() {}
}
''')
self.assertEqual(1, len(result))
self.assertEqual(2, result[0].cyclomatic_complexity)

3 changes: 3 additions & 0 deletions to_do.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## ES6

Support interpolating in string literal.

0 comments on commit 366cbb6

Please sign in to comment.