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

Visitors for TypeScript #566

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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
6 changes: 3 additions & 3 deletions tested/dsl/ast_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
)
from tested.parsing import get_converter
from tested.serialisation import (
Assignment,
AbstractAssignment,
Expression,
FunctionCall,
FunctionType,
Expand Down Expand Up @@ -95,7 +95,7 @@ def _is_type_cast(node: ast.expr) -> bool:
return any(node.func.id in x.__members__.values() for x in get_args(AllTypes))


def _convert_ann_assignment(node: ast.AnnAssign) -> Assignment:
def _convert_ann_assignment(node: ast.AnnAssign) -> AbstractAssignment:
if not isinstance(node.target, ast.Name):
actual = ast.dump(node)
raise InvalidDslError(
Expand Down Expand Up @@ -127,7 +127,7 @@ def _convert_ann_assignment(node: ast.AnnAssign) -> Assignment:
)


def _convert_assignment(node: ast.Assign) -> Assignment:
def _convert_assignment(node: ast.Assign) -> AbstractAssignment:
if n := len(node.targets) != 1:
raise InvalidDslError(
f"You must assign to exactly one variable, but got {n} variables."
Expand Down
2 changes: 1 addition & 1 deletion tested/languages/kotlin/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
)
from tested.languages.utils import convert_unknown_type
from tested.serialisation import (
Assignment,
AbstractAssignment,
Expression,
FunctionCall,
FunctionType,
Expand Down
6 changes: 3 additions & 3 deletions tested/languages/preparation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
submission_name,
)
from tested.serialisation import (
Assignment,
AbstractAssignment,
Expression,
FunctionCall,
FunctionType,
Expand Down Expand Up @@ -201,7 +201,7 @@ def prepare_argument(
return prepare_expression(bundle, argument)


def prepare_assignment(bundle: Bundle, assignment: Assignment) -> Assignment:
def prepare_assignment(bundle: Bundle, assignment: AbstractAssignment) -> AbstractAssignment:
if isinstance(assignment, VariableAssignment):
if isinstance(assignment.type, VariableType):
class_type = conventionalize_class(bundle.language, assignment.type.data)
Expand Down Expand Up @@ -409,7 +409,7 @@ def prepare_testcase(
names.append(evaluator_name)
if result_channel == IgnoredChannel.IGNORED:
value_function_call = None
elif isinstance(testcase.input, Assignment):
elif isinstance(testcase.input, AbstractAssignment):
command = prepare_assignment(bundle, testcase.input)
assert (
result_channel == IgnoredChannel.IGNORED
Expand Down
2 changes: 1 addition & 1 deletion tested/languages/python/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
)
from tested.languages.utils import convert_unknown_type
from tested.serialisation import (
Assignment,
AbstractAssignment,
Expression,
FunctionCall,
FunctionType,
Expand Down
72 changes: 52 additions & 20 deletions tested/serialisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import logging
import math
import operator
from abc import abstractmethod

Check notice

Code scanning / CodeQL

Unused import Note test

Import of 'abstractmethod' is not used.
from collections.abc import Iterable
from decimal import Decimal
from enum import StrEnum, auto, unique
Expand Down Expand Up @@ -52,7 +53,7 @@
resolve_to_basic,
)
from tested.features import Construct, FeatureSet, WithFeatures, combine_features
from tested.parsing import parse_json_value

Check failure

Code scanning / CodeQL

Module-level cyclic import Error test

'flatten' may not be defined if module
tested.utils
is imported before module
tested.serialisation
, as the
definition
of flatten occurs after the cyclic
import
of tested.serialisation.

Check failure

Code scanning / CodeQL

Module-level cyclic import Error test

'sorted_no_duplicates' may not be defined if module
tested.utils
is imported before module
tested.serialisation
, as the
definition
of sorted_no_duplicates occurs after the cyclic
import
of tested.serialisation.
from tested.utils import flatten, sorted_no_duplicates

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -152,8 +153,38 @@
NEG_INFINITY = "-inf"


# class Statement(WithFeatures, WithFunctions):
# """
# Base class for representing Statements which represent Expressions and Assignments
# """
#
# def accept(self, visitor: "ConvertStatementVisitor") -> None:
# visitor.visit(self)
Comment on lines +156 to +162

Check notice

Code scanning / CodeQL

Commented-out code Note test

This comment appears to contain commented-out code.
#

class Expression(WithFeatures, WithFunctions):
"""
Base class for representing Expressions which represent Values, Identifiers
and FunctionCalls.
"""

type: Any
data: Any
diagnostic: Any

#
#
# # These visitors are defined for the generation files of each language.
# @define
# class ConvertStatementVisitor:
#
# @abstractmethod
# def visit(self, statement: Statement) -> str:
# raise AssertionError(f"Unknown statement: {statement!r}")


@define
class NumberType(WithFeatures, WithFunctions):
class NumberType(Expression):
type: NumericTypes = field(validator=validators.instance_of(NumericTypes))
data: SpecialNumbers | int | float | Decimal = field(
validator=validators.instance_of(Union[SpecialNumbers, int, float, Decimal])
Expand All @@ -162,15 +193,15 @@

def __attrs_post_init__(self):
if (
isinstance(self.data, SpecialNumbers)
and resolve_to_basic(self.type) == BasicNumericTypes.INTEGER
isinstance(self.data, SpecialNumbers)
and resolve_to_basic(self.type) == BasicNumericTypes.INTEGER
):
raise ValueError(
f"SpecialNumber '{self.data}' is only supported for " f"real numbers."
)

if resolve_to_basic(self.type) == BasicNumericTypes.INTEGER and isinstance(
self.data, Decimal
self.data, Decimal
):
self.data = self.data.to_integral_value()

Expand All @@ -182,7 +213,7 @@


@define
class StringType(WithFeatures, WithFunctions):
class StringType(Expression):
type: StringTypes = field(validator=validators.instance_of(StringTypes))
data: str = field(validator=validators.instance_of(str))

Expand All @@ -200,7 +231,7 @@


@define
class BooleanType(WithFeatures, WithFunctions):
class BooleanType(Expression):
type: BooleanTypes = field(validator=validators.instance_of(BooleanTypes))
data: bool = field(validator=validators.instance_of(bool))
diagnostic: Literal[None] = None # Unused in this type.
Expand All @@ -213,7 +244,7 @@


@define
class SequenceType(WithFeatures, WithFunctions):
class SequenceType(Expression):
type: SequenceTypes = field(validator=validators.instance_of(SequenceTypes))
data: list["Expression"]
diagnostic: Literal[None] = None # Unused in this type.
Expand Down Expand Up @@ -276,7 +307,7 @@


@define
class ObjectType(WithFeatures, WithFunctions):
class ObjectType(Expression):
type: ObjectTypes = field(validator=validators.instance_of(ObjectTypes))
data: list[ObjectKeyValuePair]
diagnostic: Literal[None] = None # Unused in this type.
Expand Down Expand Up @@ -312,7 +343,7 @@


@define
class NothingType(WithFeatures, WithFunctions):
class NothingType(Expression):
type: NothingTypes = field(
default=BasicNothingTypes.NOTHING,
validator=validators.instance_of(NothingTypes), # type: ignore
Expand All @@ -333,7 +364,7 @@
]


class Identifier(str, WithFeatures, WithFunctions):
class Identifier(str, Expression):
"""Represents an variable name."""

is_raw: bool
Expand Down Expand Up @@ -391,7 +422,7 @@


@define
class FunctionCall(WithFeatures, WithFunctions):
class FunctionCall(Expression):
"""
Represents a function expression.
"""
Expand All @@ -413,8 +444,8 @@

# Get OOP features.
if self.type in (
FunctionType.PROPERTY,
FunctionType.CONSTRUCTOR,
FunctionType.PROPERTY,
FunctionType.CONSTRUCTOR,
) or not isinstance(self.namespace, (Identifier, NoneType)):
constructs.add(Construct.OBJECTS)

Expand Down Expand Up @@ -544,6 +575,7 @@
# If changing this, also update is_statement_strict in the utils.
Statement = Assignment | Expression


# Update the forward references, which fixes the schema generation.
resolve_types(ObjectType)
resolve_types(SequenceType)
Expand Down Expand Up @@ -597,8 +629,8 @@
if isinstance(value.type, SimpleTypes):
# If we have floats or ints, convert them to Python.
if value.type in (
AdvancedNumericTypes.SINGLE_PRECISION,
AdvancedNumericTypes.DOUBLE_PRECISION,
AdvancedNumericTypes.SINGLE_PRECISION,
AdvancedNumericTypes.DOUBLE_PRECISION,
):
return float(str(value.data))
if value.type != AdvancedNumericTypes.FIXED_PRECISION:
Expand Down Expand Up @@ -740,11 +772,11 @@
assert isinstance(value, NumberType)
return value.data
if basic_type in (
BasicBooleanTypes.BOOLEAN,
BasicStringTypes.TEXT,
BasicNothingTypes.NOTHING,
BasicStringTypes.ANY,
BasicStringTypes.UNKNOWN,
BasicBooleanTypes.BOOLEAN,
BasicStringTypes.TEXT,
BasicNothingTypes.NOTHING,
BasicStringTypes.ANY,
BasicStringTypes.UNKNOWN,
):
return value.data

Expand Down
8 changes: 4 additions & 4 deletions tested/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from typing import get_args as typing_get_args

if TYPE_CHECKING:
from tested.serialisation import Assignment
from tested.serialisation import AbstractAssignment

Check warning on line 14 in tested/utils.py

View check run for this annotation

Codecov / codecov/patch

tested/utils.py#L14

Added line #L14 was not covered by tests

Check failure

Code scanning / CodeQL

Module-level cyclic import Error test

'AbstractAssignment' may not be defined if module
tested.serialisation
is imported before module
tested.utils
, as the
definition
of AbstractAssignment occurs after the cyclic
import
of tested.utils.
'AbstractAssignment' may not be defined if module
tested.serialisation
is imported before module
tested.utils
, as the
definition
of AbstractAssignment occurs after the cyclic
import
of tested.utils.

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -316,14 +316,14 @@
return no_dup


def is_statement_strict(statement: Any) -> TypeGuard["Assignment"]:
def is_statement_strict(statement: Any) -> TypeGuard["AbstractAssignment"]:
"""
Check that the given value is a strict statement: it must be a statement but
not an expression.

:param statement: The potential statement to check.
:return: True if it is, False otherwise.
"""
from tested.serialisation import Assignment
from tested.serialisation import AbstractAssignment

return isinstance(statement, Assignment)
return isinstance(statement, AbstractAssignment)
Loading