171 lines
5.4 KiB
Python
171 lines
5.4 KiB
Python
import re
|
|
from typing import List, Union, Tuple, Dict
|
|
|
|
from .constants import *
|
|
from .enums import FormatterProperty, Argument, FormatterMode
|
|
from abc import ABC, abstractmethod
|
|
|
|
|
|
class MacroReplacement:
|
|
def __init__(
|
|
self,
|
|
replacement: str,
|
|
*args,
|
|
**kwargs,
|
|
):
|
|
if 'format_type' in kwargs.keys():
|
|
self.format_type = kwargs['format_type']
|
|
else:
|
|
self.format_type = '%'
|
|
self.replacement: str = replacement
|
|
self.args = args
|
|
self.kwargs = kwargs
|
|
|
|
def make_format_args(self, formatter, *call_args) -> Tuple[Tuple, Dict]:
|
|
new_args = []
|
|
for arg in self.args:
|
|
if type(arg) == FormatterProperty:
|
|
try:
|
|
new_args.append(formatter.attribute_dict[arg.value])
|
|
except:
|
|
raise NotImplementedError
|
|
elif type(arg) == Argument:
|
|
try:
|
|
new_args.append(call_args[arg.value - 1])
|
|
except:
|
|
raise NotImplementedError
|
|
elif type(arg) == str:
|
|
new_args.append(arg)
|
|
else:
|
|
raise NotImplementedError
|
|
new_kwargs = {}
|
|
for kw in self.kwargs.keys():
|
|
if type(self.kwargs[kw]) == FormatterProperty:
|
|
new_kwargs[kw] = formatter.attribute_dict[self.kwargs[kw].value]
|
|
elif type(self.kwargs[kw]) == Argument:
|
|
new_kwargs[kw] = call_args[self.kwargs[kw].value - 1]
|
|
elif type(self.kwargs[kw]) == str:
|
|
new_kwargs[kw] = self.kwargs[kw]
|
|
else:
|
|
raise NotImplementedError
|
|
return tuple(new_args), new_kwargs
|
|
|
|
def format(self, formatter, *call_args) -> str:
|
|
args, kwargs = self.make_format_args(formatter, *call_args)
|
|
if self.format_type == '%':
|
|
if self.kwargs:
|
|
raise NotImplementedError # Currently, not supported
|
|
return self.replacement % args
|
|
elif self.format_type == '{':
|
|
return self.replacement.format(
|
|
*args, **kwargs, **formatter.attribute_dict
|
|
)
|
|
else:
|
|
raise NotImplementedError
|
|
|
|
|
|
class Macro(ABC):
|
|
@abstractmethod
|
|
def __init__(self):
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
def matches(self, line: str) -> bool:
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
def apply(self, line: str, formatter) -> Union[str, List[str]]:
|
|
raise NotImplementedError
|
|
|
|
|
|
class SimpleMacro(Macro):
|
|
def __init__(
|
|
self,
|
|
macroname: str,
|
|
macro_replacement: MacroReplacement
|
|
):
|
|
self.macroname = macroname
|
|
self.macro_replacement = macro_replacement
|
|
|
|
def matches(self, line: str) -> bool:
|
|
return line.find(FORMATTER_PREFIX + self.macroname) != -1
|
|
|
|
def apply(self, line: str, formatter) -> Union[str, List[str]]:
|
|
return line.replace(
|
|
FORMATTER_PREFIX + self.macroname,
|
|
self.macro_replacement.format(
|
|
formatter
|
|
))
|
|
|
|
|
|
class SingleLineMacro(Macro, ABC):
|
|
def __init__(
|
|
self,
|
|
chars: str,
|
|
strip: str = ' %\n'
|
|
):
|
|
self.chars = chars
|
|
self.strip = strip
|
|
def matches(self, line: str) -> bool:
|
|
if line.find(self.chars) != -1:
|
|
if not line.strip(self.strip) == self.chars:
|
|
raise NotImplementedError
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
class ConfigBeginMacro(SingleLineMacro):
|
|
def __init__(self):
|
|
super(ConfigBeginMacro, self).__init__(FORMATTER_PREFIX + INFILE_CONFIG_BEGIN_CONFIG)
|
|
|
|
def apply(self, line: str, formatter) -> Union[str, List[str]]:
|
|
if not formatter.mode == FormatterMode.normal:
|
|
raise NotImplementedError # invalid config begin
|
|
formatter.mode = FormatterMode.drop
|
|
return []
|
|
|
|
class ConfigEndMacro(SingleLineMacro):
|
|
def __init__(self):
|
|
super(ConfigEndMacro, self).__init__(FORMATTER_PREFIX + INFILE_CONFIG_END_CONFIG)
|
|
|
|
def apply(self, line: str, formatter) -> Union[str, List[str]]:
|
|
if not formatter.mode == FormatterMode.drop:
|
|
raise NotImplementedError # invalid
|
|
formatter.mode = FormatterMode.normal
|
|
return []
|
|
|
|
class ArgumentMacro(Macro):
|
|
def __init__(
|
|
self,
|
|
macroname: str,
|
|
num_args: int,
|
|
macro_replacement: MacroReplacement
|
|
):
|
|
self.macroname = macroname
|
|
self.num_args = num_args
|
|
self.macro_replacement: MacroReplacement = macro_replacement
|
|
self._search_regex = re.compile(r'{keyword}\({arguments}(?<!@)\)'.format(
|
|
keyword=FORMATTER_PREFIX + self.macroname,
|
|
arguments=','.join(['(.*?)'] * self.num_args)
|
|
))
|
|
|
|
def matches(self, line: str) -> bool:
|
|
if line.find('!!') != -1:
|
|
pass
|
|
match = re.search(self._search_regex, line)
|
|
if match is None:
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
def apply(self, line: str, formatter) -> Union[str, List[str]]:
|
|
match = re.search(self._search_regex, line)
|
|
if match is None:
|
|
raise NotImplementedError
|
|
replacement = self.macro_replacement.format(
|
|
formatter, match.groups()
|
|
)
|
|
return line.replace(
|
|
match.group(),
|
|
replacement
|
|
)
|