Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for Julia language #52

Merged
merged 1 commit into from
Jan 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nirjas/languages/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@
"swift",
"text",
"typescript",
"julia",
]
140 changes: 140 additions & 0 deletions nirjas/languages/julia.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020 Soham Banerjee (sohambanerjee4abc@hotmail.com),

SPDX-License-Identifier: LGPL-2.1

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""

from nirjas.binder import CommentSyntax, contSingleLines
from nirjas.output import ScanOutput, SingleLine, MultiLine


def juliaExtractor(file):
"""
Extract comments from julia file.
:param file: File to scan
:type file: string
:return: Scan output
:rtype: ScanOutput
"""
result = CommentSyntax()
single_line_comment = result.hash(file)
multiline_single_comment = result.singleQuotes(file)
multiline_double_comment = result.doubleQuotes(file)
cont_single_line_comment = contSingleLines(single_line_comment)
file = file.split("/")
output = ScanOutput()
output.filename = file[-1]
output.lang = "Julia"
output.total_lines = single_line_comment[1]
output.total_lines_of_comments = (
single_line_comment[3] + multiline_single_comment[3] + multiline_double_comment[3])
output.blank_lines = single_line_comment[2]

if cont_single_line_comment:
single_line_comment = cont_single_line_comment[0]

for i in single_line_comment[0]:
output.single_line_comment.append(SingleLine(i[0], i[1]))

for idx, _ in enumerate(cont_single_line_comment[1]):
output.cont_single_line_comment.append(
MultiLine(
cont_single_line_comment[1][idx],
cont_single_line_comment[2][idx],
cont_single_line_comment[3][idx],
)
)

try:
for idx, _ in enumerate(multiline_single_comment[0]):
output.multi_line_comment.append(
MultiLine(
multiline_single_comment[0][idx],
multiline_single_comment[1][idx],
multiline_single_comment[2][idx],
)
)
except BaseException:
pass

try:
for idx, _ in enumerate(multiline_double_comment[0]):
output.multi_line_comment.append(
MultiLine(
multiline_double_comment[0][idx],
multiline_double_comment[1][idx],
multiline_double_comment[2][idx],
)
)
except BaseException:
pass

return output


def juliaSource(file, new_file: str):
"""
Extract source from Julia file and put at new_file.
:param file: File to process
:type file: string
:param new_file: File to put source at
:type new_file: string
:return: Path to new file
:rtype: string
"""
copy = True
with open(new_file, "w+") as f1:
with open(file) as f:
for line in f:
content = ""
found = False
if '"""' in line:
if copy:
pos = line.find('"""')
content = line[:pos].rstrip()
line = line[pos:]
copy = False
found = True
else:
content = content + line[line.rfind('"""') + 3:]
line = content
copy = True
found = True
if "'''" in line:
if copy:
pos = line.find("'''")
content = line[:pos].rstrip()
line = line[pos:]
copy = False
found = True
else:
content = content + line[line.rfind("'''") + 3:]
line = content
copy = True
found = True
if "#" in line:
content = line[: line.find("#")].rstrip() + "\n"
found = True
if not found:
content = line
if copy and content.strip() != "":
f1.write(content)
f.close()
f1.close()
return new_file
131 changes: 131 additions & 0 deletions nirjas/languages/tests/test_julia.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
SPDX-License-Identifier: LGPL-2.1

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""

import unittest
import os
from nirjas.languages import julia
from nirjas.binder import readSingleLine, readMultiLineSame, contSingleLines


class JuliaTest(unittest.TestCase):
"""
Test cases for Julia language.
:ivar testfile: Location of test file
"""

testfile = os.path.join(
os.path.abspath(os.path.dirname(__file__)), "TestFiles/textcomment.jl"
)

def test_output(self):
"""
Check for the scan correctness.
"""
regex = r"""(?<!["'`])#+\s*(.*)"""
syntax_single = "'''"
syntax_double = '"""'
comment_multi_single = readMultiLineSame(self.testfile, syntax_single)
comment_single = readSingleLine(self.testfile, regex)
comment_multi_double = readMultiLineSame(self.testfile, syntax_double)
comment_contSingleline = contSingleLines(comment_single)
self.assertTrue(comment_single)
self.assertTrue(comment_multi_single)
self.assertTrue(comment_multi_double)
self.assertTrue(comment_contSingleline)

def test_outputFormat(self):
"""
Check for the output format correctness.
"""
regex = r"""(?<!["'`])#+\s*(.*)"""
syntax_single = "'''"
syntax_double = '"""'
expected = julia.juliaExtractor(self.testfile).get_dict()
comment_single = readSingleLine(self.testfile, regex)
comment_multi_single = readMultiLineSame(self.testfile, syntax_single)
comment_multi_double = readMultiLineSame(self.testfile, syntax_double)
comment_contSingleline = contSingleLines(comment_single)
file = self.testfile.split("/")
output = {
"metadata": {
"filename": file[-1],
"lang": "Julia",
"total_lines": comment_single[1],
"total_lines_of_comments": comment_single[3] + comment_multi_single[3] + comment_multi_double[3],
"blank_lines": comment_single[2],
"sloc": comment_single[1] - (
comment_single[3] + comment_multi_single[3] + comment_multi_double[3] + comment_single[2]
),
},
"single_line_comment": [],
"cont_single_line_comment": [],
"multi_line_comment": [],
}

if comment_contSingleline:
comment_single = comment_contSingleline[0]

if comment_single:
for i in comment_single[0]:
output["single_line_comment"].append(
{"line_number": i[0], "comment": i[1]}
)

if comment_contSingleline:
for idx, _ in enumerate(comment_contSingleline[1]):
output["cont_single_line_comment"].append(
{
"start_line": comment_contSingleline[1][idx],
"end_line": comment_contSingleline[2][idx],
"comment": comment_contSingleline[3][idx],
}
)

if comment_multi_single:
for idx, _ in enumerate(comment_multi_single[0]):
output["multi_line_comment"].append(
{
"start_line": comment_multi_single[0][idx],
"end_line": comment_multi_single[1][idx],
"comment": comment_multi_single[2][idx],
}
)

if comment_multi_double:
for idx, _ in enumerate(comment_multi_double[0]):
output["multi_line_comment"].append(
{
"start_line": comment_multi_double[0][idx],
"end_line": comment_multi_double[1][idx],
"comment": comment_multi_double[2][idx],
}
)

self.assertEqual(output, expected)

def test_Source(self):
"""
Test the source code extraction.
Call the source function and check if new file exists.
"""
name = "source.txt"
newfile = julia.juliaSource(self.testfile, name)

self.assertTrue(newfile)
1 change: 1 addition & 0 deletions nirjas/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class LanguageMapper:
".install": "text",
".OSS": "text",
".gl": "text",
".jl": "julia",
}

@staticmethod
Expand Down
3 changes: 2 additions & 1 deletion testScript.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def download_files(cwd):
"https://raw.githubusercontent.com/flutter/plugins/e61e9d45bcaadc3e409d529d30735cb4db75c5c5/packages/android_alarm_manager/lib/android_alarm_manager.dart",
"https://raw.githubusercontent.com/microsoft/TypeScript/c33a14d66d0a452673ce77256e178bf84e875d2b/tests/cases/user/formik/index.tsx",
"https://raw.githubusercontent.com/twbs/bootstrap/9488978fb55286ba83e8193a871d1ff9815045b9/scss/_reboot.scss",
"https://raw.githubusercontent.com/its-sushant/SQL/a4bf2972905c8df89d6a60752a2c60920a4b9465/check.sql"
"https://raw.githubusercontent.com/svaksha/Julia.jl/898f3d46c79a3b1fe939416fa96a8db9b2069596/src/scrape.jl",
"https://raw.githubusercontent.com/its-sushant/SQL/a4bf2972905c8df89d6a60752a2c60920a4b9465/check.sql",
]

directory = os.path.join(cwd, "nirjas/languages/tests/TestFiles")
Expand Down