On this page ...

Customization of the Typer

The typer can be customized per concept.
Your new typer must implement the FreTyper interface.

As a convenience, Freon generates a file ~/freon/typer/CustomYourLanguageNameTyperPart.ts,
which will not be overwritten upon regeneration.
It already contains a class that implements this interface, ready for your extensions.

Adding Typing Methods

In the new typer class, you can add custom logic to one or more methods.
Let the method return null to indicate that the typer from the Freon Definition Level should be used instead.

The following example overrides the conformsList method for lists of Variables.
It checks whether two lists conform when their elements appear in reverse order:
for example, [A, B, C] conforms to [C, B, A].

// CustomizationsProject/src/custom/typer/CustomEntityModelTyperPart.ts

// Generated by the Freon Language Generator.
import { FreNode, FreType, FreTyper } from "@freon4dsl/core";
import {Variable} from "../language/gen/index.js";
import {EntityModelEnvironment} from "../config/gen/EntityModelEnvironment.js";

/**
 * Class 'CustomEntityModelTyperPart' is meant to be a convient place to add any
 * custom code for type checking.
 */
export class CustomEntityModelTyperPart implements FreTyper {
    mainTyper: FreTyper;

    isType(modelelement: FreNode): boolean | null {
        return null;
    }

    inferType(modelelement: FreNode): FreType | null {
        return null;
    }

    equals(type1: FreType, type2: FreType): boolean | null {
        return null;
    }

    conforms(type1: FreType, type2: FreType): boolean | null {
        return null;
    }

    /**
     * Example of custom typings: typelist2 conforms to typelist1 if the elements
     * conform in the opposite direction, i.e. [A, B, C] conforms to [C, B, A]
     * @param typelist1
     * @param typelist2
     */
    conformsList(typelist1: FreType[], typelist2: FreType[]): boolean | null {
        if (typelist1.length > 0 && (typelist1[0] instanceof Variable)) {
            if (typelist1.length !== typelist2.length) return false;
            let result: boolean = true;
            const max_length = typelist1.length;
            for (let i = 0; i < typelist1.length; i++) {
                result = EntityModelEnvironment.getInstance().typer.conforms(typelist1[i], typelist2[max_length - i]);
                if (result == false) return result;
            }
            return result;
        } else {
            return null;
        }
    }

    commonSuper(typelist: FreType[]): FreType | null {
        return null;
    }

    public getSuperTypes(type: FreType): FreType[] | null {
        return null;
    }
}
© 2018 - 2025 Freon contributors - Freon is open source under the MIT License.