Exemple #1
0
    def processMacro(self, element: Element, *args: typing.Any) -> str:
        """
		Process a macro already defined.
		"""

        sequence = element.getNestedSequence("nested")
        assert sequence

        # Build the argument list
        argList = []
        argument = element.getNestedSequence("argument")
        assert argument is not None
        for arg in argument:
            Error.assertHasAttr(element=arg, attr="name")
            argList.append(arg.getAttr("name").value)

        # Sanity check
        Error.assertTrue(
            element=element,
            condition=len(argList) == len(args),
            message="Wrong number of argument(s), expected {}: {}".format(
                len(argList), ", ".join(argList)))

        for i, name in enumerate(argList):
            self.substitutions.register(element=element,
                                        key=name,
                                        value=args[i])

        # Process the template
        result = self._visit(sequence=sequence)

        for name in argList:
            self.substitutions.unregister(name)

        return "".join(result)
Exemple #2
0
    def visitSubstitution(self, element: Element, result: ResultType) -> None:
        """
		Handle substitution.
		"""
        Error.assertHasAttr(element=element, attr="name")
        name = element.getAttr("name").value

        # Check if callable and if there are arguments
        arguments = element.getNestedSequence("argument")
        if arguments is None:
            value = self.resolveName(name=name)
        else:
            # Resolve all arguments
            args = []
            for arg in arguments:
                args.append(self.readValue(element=arg))
            value = self.resolveName(name, True, *args)

        # Process the pipes if any.
        pipes = element.getNestedSequence("pipe")
        if pipes:
            for pipe in pipes:
                Error.assertHasAttr(element=pipe, attr="name")
                value = self.resolveName(
                    pipe.getAttr("name").value, True, value)

        # Save the output
        assert isinstance(
            value, (int, float, str, pathlib.Path)
        ), "The resulting substitued value must be a number, a string or a path."
        self.appendSubstitution(element=element,
                                result=result,
                                string=str(value))
Exemple #3
0
def elementToEntity(element: Element,
	extension: typing.Optional[typing.Dict[str, typing.Type[EntityType]]] = None) -> EntityType:
	"""
	Instantiate an entity from an element.
	"""

	Error.assertHasAttr(element=element, attr="category")
	category = element.getAttr("category").value

	if extension and category in extension:
		return extension[category](element=element)

	if category not in CATEGORY_TO_ENTITY:
		Error.handleFromElement(element=element, message="Unexpected element category: {}".format(category))

	return CATEGORY_TO_ENTITY[category](element=element)
Exemple #4
0
	def __init__(self,
		element: Element,
		kind: str,
		underlyingType: typing.Optional[str] = None,
		template: typing.Optional[str] = None,
		argumentTemplate: typing.Optional[str] = None,
		contract: typing.Optional[str] = None,
		const: typing.Optional[str] = None) -> None:

		Error.assertHasAttr(element=element, attr=kind)
		self.element = element
		self.kindAttr = kind
		self.underlyingTypeAttr = underlyingType
		self.templateAttr = template
		self.argumentTemplateAttr = argumentTemplate
		self.contractAttr = contract
		self.constAttr = const
Exemple #5
0
    def visitForBlock(self, element: Element) -> ResultType:
        """
		Handle for loop block.
		"""

        Error.assertHasAttr(element=element, attr="value1")
        Error.assertHasAttr(element=element, attr="iterable")
        Error.assertHasSequence(element=element, sequence="nested")

        value1 = element.getAttr("value1").value
        value2 = element.getAttrValue("value2")

        sequence = element.getNestedSequence(kind="nested")
        assert sequence

        block: ResultType = []

        # Loop through the elements
        iterable = self.resolveName(name=element.getAttr("iterable").value)
        if value2 is None:
            for value in iterable:
                self.substitutions.register(element=element,
                                            key=value1,
                                            value=value)
                block += self._visit(sequence=sequence)
                self.substitutions.unregister(value1)
        else:
            iterablePair = iterable.items() if isinstance(
                iterable, dict) else enumerate(iterable)
            for key, value in iterablePair:
                self.substitutions.register(element=element,
                                            key=value1,
                                            value=key)
                self.substitutions.register(element=element,
                                            key=value2,
                                            value=value)
                block += self._visit(sequence=sequence)
                self.substitutions.unregister(value2)
                self.substitutions.unregister(value1)

        return block
Exemple #6
0
    def readValue(self, element: Element) -> typing.Any:
        """
		Read a value from an element.
		"""

        Error.assertHasAttr(element=element, attr="value")
        Error.assertHasAttr(element=element, attr="type")
        valueType = element.getAttr("type").value
        value = element.getAttr("value").value
        if valueType == "name":
            return self.resolveName(value)
        elif valueType == "number":
            return float(value)
        elif valueType == "string":
            return value
        elif valueType == "true":
            return True
        elif valueType == "false":
            return False
        Error.handleFromElement(element=element,
                                message="Unsupported value type.")
Exemple #7
0
    def visitMacro(self, element: Element) -> None:
        """
		Handle macro definition block.
		"""
        Error.assertHasSequence(element=element, sequence="argument")
        Error.assertHasSequence(element=element, sequence="nested")
        Error.assertHasAttr(element=element, attr="name")

        name = element.getAttr("name").value
        Error.assertTrue(
            element=element,
            attr="name",
            condition=(name not in self.substitutions),
            message=
            "Name conflict with macro and an already existing name: '{}'.".
            format(name))

        # Register the macro
        self.substitutions.register(
            element=element,
            key=name,
            value=lambda *args: self.processMacro(element, *args))
Exemple #8
0
	def visitElement(self, element: Element, result: typing.List[str],
		nested: typing.Optional[typing.List[str]]) -> typing.List[str]:

		if element.isAttr("type"):

			entity = Type(element=element,
				kind="type",
				underlyingType="fqn_type",
				template="template_resolved" if self.isResolved else "template",
				argumentTemplate="argument_template_resolved" if self.isResolved else None,
				const="const")
			output = self.visitType(entity=entity,
				nested=[] if nested is None else nested,
				parameters=entity.parametersTemplateResolved)

		else:
			Error.assertHasAttr(element=element, attr="value")
			Error.assertTrue(element=element, condition=not nested, message="Value cannot have nested entities.")
			output = self.visitValue(value=element.getAttr("value").value, comment=element.getAttrValue("comment"))

		result.append(output)

		return result
Exemple #9
0
 def __init__(self, element: Element) -> None:
     super().__init__(element, Role.Type)
     Error.assertHasAttr(element=element, attr="name")
Exemple #10
0
    def visitElement(self, element: Element, result: ResultType) -> ResultType:
        """
		Go through all elements and dispatch the action.
		"""

        Error.assertHasAttr(element=element, attr="category")
        category = element.getAttr("category").value

        try:

            # Raw content
            if category == "content":
                Error.assertHasAttr(element=element, attr="content")
                string = element.getAttr("content").value
                result.append(string)

            # Substitution
            elif category == "substitution":
                self.visitSubstitution(element=element, result=result)

            # Comments
            elif category == "comment":
                pass

            # End statement
            elif category == "end":
                # Reset the else flag here to make sure nested if without else do not trigger.
                self.followElse = False

            # For loop block
            elif category == "for":
                block = self.visitForBlock(element=element)
                self.appendBlock(element=element, result=result, block=block)

            # If block
            elif category == "if":
                Error.assertHasAttr(element=element, attr="condition")
                conditionStr = element.getAttr("condition").value
                block = self.visitIfBlock(element=element,
                                          conditionStr=conditionStr)
                self.appendBlock(element=element, result=result, block=block)

            # Else block
            elif category == "else":
                block = []
                if self.followElse:
                    conditionStr = element.getAttrValue("condition",
                                                        "True")  # type: ignore
                    block = self.visitIfBlock(element=element,
                                              conditionStr=conditionStr)
                self.appendBlock(element=element, result=result, block=block)

            # Macro block
            elif category == "macro":
                self.visitMacro(element=element)

            elif category == "include":
                block = self.visitInclude(element=element)
                self.appendBlock(element=element, result=result, block=block)

            else:
                raise Exception("Unsupported category: '{}'.".format(category))

        # Propagate processed exception to the top layer
        except ExceptionParser as e:
            raise e

        except Exception as e:
            Error.handleFromElement(element=element, message=str(e))

        return result
Exemple #11
0
 def __init__(self, element: Element) -> None:
     super().__init__(element, Role.Type)
     Error.assertHasAttr(element=element, attr="name")
     Error.assertHasSequence(element=element, sequence="values")
Exemple #12
0
 def visitElement(self, element: Element,
                  result: typing.List[str]) -> typing.List[str]:
     Error.assertHasAttr(element=element, attr="name")
     result.append(element.getAttr("name").value)
     return result
Exemple #13
0
    def __init__(self, element: Element) -> None:

        super().__init__(element, Role.Meta)
        Error.assertHasAttr(element=element, attr="value")
Exemple #14
0
    def __init__(self, element: Element) -> None:

        Error.assertHasAttr(element=element, attr="type")
        self.element = element
Exemple #15
0
	def inheritanceList(self) -> typing.List[Type]:
		inheritanceList: typing.List[Type] = []
		for element in self.element.getNestedSequenceOrEmpty("inheritance"):
			Error.assertHasAttr(element=element, attr="symbol")
			inheritanceList.append(Type(element=element, kind="symbol"))
		return inheritanceList
Exemple #16
0
	def __init__(self, element: Element) -> None:

		super().__init__(element, Role.Type)
		Error.assertHasAttr(element=element, attr="type")
		self.assertTrue(condition=self.type in TYPES, message="Unsupported nested type: '{}'.".format(self.type))