Skip to content

Commit

Permalink
idesupport: IDE languages to use user code (#3725)
Browse files Browse the repository at this point in the history
* Tide languages

* Run black

* Add partial type hints to ide_languages

* CsPlugin: restore imports

* hack for jypeli rerun missing arguments

* TODO comment

* Clean up, add docs

* Revert package-lock.json

* Suplementary files: Do not indent too much

* Tide-language: Correct spelling

* tide: error handling

* tide: use usercode if available

* tide: use usercode if available, correct spelling

* Update timApp/idesupport/ide_languages.py

* Update timApp/idesupport/ide_languages.py

* Update timApp/idesupport/utils.py

---------

Co-authored-by: sijualle <[email protected]>
Co-authored-by: dezhidki <[email protected]>
  • Loading branch information
3 people authored Oct 9, 2024
1 parent d5ded20 commit 90d7c2f
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 115 deletions.
17 changes: 17 additions & 0 deletions timApp/idesupport/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import re
from dataclasses import dataclass

from tim_common.utils import type_splitter


@dataclass
class SupplementaryFile:
Expand Down Expand Up @@ -44,3 +46,18 @@ def is_in_filename(files: list[dict[str, str]], regexp: str) -> bool:
if name and re.match(regexp, name):
return True
return False


def get_task_language(task_type: str | None) -> str | None:
"""
Get the language of the task
:param task_type: Type of the task
:return: Language of the task
"""

if task_type is not None:
type_split = type_splitter.split(task_type.lower())
if len(type_split) > 0:
return type_split[0]

return None
78 changes: 61 additions & 17 deletions timApp/idesupport/ide_languages.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import textwrap
from typing import Any

from timApp.idesupport.files import SupplementaryFile, is_in_filename
from timApp.idesupport.files import SupplementaryFile, is_in_filename, get_task_language
from tim_common.cs_utils import populated

DOTNET_VERSION = "net$(NETCoreAppMaximumVersion)" # "net8.0"
Expand All @@ -28,8 +28,13 @@ class Language:
Should be equivalent to csPlugin language types.
"""

def __init__(self, plugin_json: dict):
self.fileext = ""
def __init__(self, plug_json: dict | None = None):
if plug_json:
plugin_json = plug_json
else:
plugin_json = {}
ext = plugin_json.get("markup", {}).get("type", "")
self.fileext = get_task_language(ext)
"""
File extension to use for the source code files.
"""
Expand All @@ -41,6 +46,8 @@ def __init__(self, plugin_json: dict):
self.plugin_json = plugin_json
self.ide_task_id = ""
self.filename = self.init_filename()
if self.filename is None:
self.filename = self.filename_from_id()

def find_comment_line_characters(self) -> str:
return self.comment_syntax_lookup
Expand All @@ -51,7 +58,15 @@ def init_filename(self) -> str:
:return: The file name to use for the main file of the task.
"""
return self.plugin_json["markup"].get("filename")
return self.plugin_json.get("markup", {}).get("filename")

def filename_from_id(self) -> str:
"""
Give file name from taskID
:return: filename or main
"""
tid = self.plugin_json.get("taskID", "1.main").split(".", 2)[1]
return tid

def get_filename(self) -> str:
"""
Expand All @@ -61,6 +76,11 @@ def get_filename(self) -> str:

@staticmethod
def get_classname(s: str | None) -> str | None:
"""
Tries to find classname from source code
:param s: source code to look
:return: classname if found
"""
if s is None:
return None

Expand All @@ -70,12 +90,30 @@ def get_classname(s: str | None) -> str | None:
return None
return match.group(1)

def try_to_get_classname(self) -> str | None:
clsname = Language.get_classname(self.plugin_json.get("program"))
@staticmethod
def try_to_get_classname_from(d: dict) -> str | None:
"""
Tries to get classname from dict
:param d: dict to look
:return: classname if found
"""
clsname = Language.get_classname(d.get("program"))
if clsname is None:
clsname = Language.get_classname(self.plugin_json.get("by"))
clsname = Language.get_classname(d.get("by"))
if clsname is None:
clsname = Language.get_classname(self.plugin_json.get("byCode"))
clsname = Language.get_classname(d.get("byCode"))
return clsname

def try_to_get_classname(self) -> str | None:
"""
Tries to get classname from plugin_json os markup
:return: classname if found
"""
clsname = Language.try_to_get_classname_from(self.plugin_json)
if clsname is None:
clsname = Language.try_to_get_classname_from(
self.plugin_json.get("markup", {})
)
return clsname

def generate_supplementary_files(
Expand All @@ -91,7 +129,7 @@ def generate_supplementary_files(
return []

@staticmethod
def make_language(ttype: str, plugin_json: Any, ide_task_id: str) -> "Language":
def make_language(ttype: str, plugin_json: dict, ide_task_id: str) -> "Language":
"""
Initialize the language handler for a specific language type.
Expand All @@ -114,10 +152,18 @@ def all_subclasses(cls) -> Any:
return subclasses + [i for sc in subclasses for i in sc.all_subclasses()]


class Text(Language):
ttype: str | list[str] = ["text"]

def __init__(self, plugin_json: dict):
super().__init__(plugin_json)
self.fileext = "txt"


class CS(Language):
ttype: str | list[str] = ["cs", "c#", "csharp"]

def __init__(self, plugin_json: Any):
def __init__(self, plugin_json: dict):
super().__init__(plugin_json)
self.fileext = "cs"
clsname = self.try_to_get_classname()
Expand All @@ -129,8 +175,6 @@ def init_filename(self) -> str:
filename = super().init_filename()
if filename is None:
filename = self.try_to_get_classname()
if filename is None:
filename = "Main.cs" # TODO
return filename

def generate_supplementary_files(
Expand All @@ -157,7 +201,7 @@ def generate_supplementary_files(
class Jypeli(CS):
ttype = "jypeli"

def __init__(self, plugin_json: Any):
def __init__(self, plugin_json: dict):
super().__init__(plugin_json)

def generate_supplementary_files(
Expand Down Expand Up @@ -218,7 +262,7 @@ def generate_supplementary_files(
class PY3(Language):
ttype = ["py", "py3", "python", "python3"]

def __init__(self, plugin_json: Any):
def __init__(self, plugin_json: dict):
super().__init__(plugin_json)
self.comment_syntax_lookup = "#"
self.fileext = "py"
Expand All @@ -227,23 +271,23 @@ def __init__(self, plugin_json: Any):
class CC(Language):
ttype: str | list[str] = "cc"

def __init__(self, plugin_json: Any):
def __init__(self, plugin_json: dict):
super().__init__(plugin_json)
self.fileext = "c"


class CPP(CC):
ttype = ["c++", "cpp"]

def __init__(self, plugin_json: Any):
def __init__(self, plugin_json: dict):
super().__init__(plugin_json)
self.fileext = "cpp"


class Java(Language):
ttype = "java"

def __init__(self, plugin_json: Any):
def __init__(self, plugin_json: dict):
super().__init__(plugin_json)
self.fileext = "java"

Expand Down
Loading

0 comments on commit 90d7c2f

Please sign in to comment.