i-slint-compiler 1.18.0

Internal Slint Compiler Library
Documentation
// Copyright © 2026 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>, author Nathan Collins <nathan.collins@kdab.com>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0

// Conformance validation for `implement I <=> self`: the element must itself declare (or inherit)
// every member of `I` with a matching type, visibility and purity.

interface ValidInterface {
    in-out property <int> value;
    callback speak();
    public function reset();
}

interface OutOnlyInterface {
    out property <int> count;
}

interface Inverter {
    pure callback invert(bool) -> bool;
}

interface Calculator {
    public pure function add(a: int, b: int) -> int;
    public function format(value: int) -> string;
    public function reset();

    in-out property <int> value;
    callback notify();
}

// A correct self-implementation compiles cleanly, including satisfying a member via a two-way binding.
export component CorrectImpl {
    implement ValidInterface <=> self;

    in-out property <int> backing: 24;
    in-out property <int> value <=> self.backing;
    callback speak();
    public function reset() {
        self.backing = 0;
    }
}

export component CorrectCalculator {
    implement Calculator <=> self;

    in-out property <int> value;
    callback notify();

    // The function is correct even though the parameter names differ
    pure public function add(x: int, y: int) -> int {
        return x + y;
    }
    public function format(value: int) -> string {
        return "Value: " + value;
    }
    public function reset() {
        self.value = 0;
    }
}

// Missing members - property, callback and function each report distinctly.
export component MissingProperty {
    implement ValidInterface <=> self;
//            >             <error{Cannot implement 'ValidInterface'.↵- missing 'in-out property <int> value;'}

    callback speak();
    public function reset() {}
}

export component MissingCallback {
    implement ValidInterface <=> self;
//            >             <error{Cannot implement 'ValidInterface'.↵- missing 'callback speak();'}

    in-out property <int> value;
    public function reset() {}
}

export component MissingFunction {
    implement Calculator <=> self;
//            >         <error{Cannot implement 'Calculator'.↵- missing 'pure public function add(int, int) -> int { }'}

    in-out property <int> value;
    callback notify();

    public function format(value: int) -> string {
        return "";
    }
    public function reset() {}
}

// Locally declared members with the wrong type / visibility / purity.
export component IncorrectPropertyType {
    implement ValidInterface <=> self;
//            >             <error{Cannot implement 'ValidInterface'.↵- 'value' must be a 'int' property (found a 'float' property)}

    in-out property <float> value;
//                   >   <note{'IncorrectPropertyType' declares 'value' here, 'ValidInterface' expects 'in-out property <int> value;'}
    callback speak();
    public function reset() {}
}

export component IncorrectCallbackType {
    implement ValidInterface <=> self;
//            >             <error{Cannot implement 'ValidInterface'.↵- 'speak' must be 'callback speak();' (found 'callback speak(string);')}

    in-out property <int> value;
    callback speak(string);
//                 >    <note{'IncorrectCallbackType' declares 'speak' here, 'ValidInterface' expects 'callback speak();'}
    public function reset() {}
}

export component IncorrectPropertyVisibility {
    implement OutOnlyInterface <=> self;
//            >               <error{Cannot implement 'OutOnlyInterface'.↵- 'count' must be 'out' (found 'in-out')}

    // Intentionally use `in_out` to verify that keywords with underscores are correctly normalized.
    in_out property <int> count;
//  >    <note{'IncorrectPropertyVisibility' declares 'count' here, 'OutOnlyInterface' expects 'out property <int> count;'}
}


interface ImpureFunctionInterface {
    public function bar(i: int, s: string) -> bool;
}

export component IncorrectCallbackPurity {
    implement Inverter <=> self;
//            >       <error{Cannot implement 'Inverter'.↵- 'invert' must be 'pure'}
    implement ImpureFunctionInterface <=> self;

    callback invert(bool) -> bool;
//           >    <note{'IncorrectCallbackPurity' declares 'invert' here, 'Inverter' expects 'pure callback invert(bool) -> bool;'}

    // Implementation is pure, interface is not - this should not raise an error
    public pure function bar(i: int, s: string) -> bool {
        return false;
    }
}

// Function mismatches: purity, visibility, arguments and return type.
export component ImpureFunction {
    implement Calculator <=> self;
//            >         <error{Cannot implement 'Calculator'.↵- 'add' must be 'pure'}

    in-out property <int> value;
    callback notify();

    public function add(a: int, b: int) -> int {
//                  > <note{'ImpureFunction' declares 'add' here, 'Calculator' expects 'pure public function add(int, int) -> int { }'}
        return a + b;
    }
    public function format(value: int) -> string {
        return "";
    }
    public function reset() {}
}

export component IncorrectFunctionArguments {
    implement Calculator <=> self;
//            >         <error{Cannot implement 'Calculator'.↵- 'format' must be 'public function format(int) -> string { }' (found 'public function format(string, int) -> string { }')}

    in-out property <int> value;
    callback notify();

    pure public function add(a: int, b: int) -> int {
        return a + b;
    }
    public function format(fmt: string, value: int) -> string {
//                              >    <note{'IncorrectFunctionArguments' declares 'format' here, 'Calculator' expects 'public function format(int) -> string { }'}
        return "";
    }
    public function reset() {}
}

// Too few arguments: there is no offending argument to point at, so the note falls back to the name.
export component MissingFunctionArguments {
    implement Calculator <=> self;
//            >         <error{Cannot implement 'Calculator'.↵- 'add' must be 'pure public function add(int, int) -> int { }' (found 'pure public function add(int) -> int { }')}

    in-out property <int> value;
    callback notify();

    pure public function add(a: int) -> int {
//                       > <note{'MissingFunctionArguments' declares 'add' here, 'Calculator' expects 'pure public function add(int, int) -> int { }'}
        return a;
    }
    public function format(value: int) -> string {
        return "";
    }
    public function reset() {}
}

export component IncorrectFunctionReturnType {
    implement Calculator <=> self;
//            >         <error{Cannot implement 'Calculator'.↵- 'format' must be 'public function format(int) -> string { }' (found 'public function format(int) { }')}

    in-out property <int> value;
    callback notify();

    pure public function add(a: int, b: int) -> int {
        return a + b;
    }
    public function format(value: int) {
//                  >    <note{'IncorrectFunctionReturnType' declares 'format' here, 'Calculator' expects 'public function format(int) -> string { }'}
    }
    public function reset() {}
}

export component IncorrectFunctionVisibility {
    implement Calculator <=> self;
//            >         <error{Cannot implement 'Calculator'.↵- 'reset' must be 'public' (found 'protected')}

    in-out property <int> value;
    callback notify();

    pure public function add(a: int, b: int) -> int {
        return a + b;
    }
    public function format(value: int) -> string {
        return "";
    }
    protected function reset() {}
//  >       <note{'IncorrectFunctionVisibility' declares 'reset' here, 'Calculator' expects 'public function reset() { }'}
}

// A member name resolving to the wrong kind (function name declared as a property / callback).
export component CannotOverrideFunction {
    implement Calculator <=> self;
//            >         <error{Cannot implement 'Calculator'.↵- 'format' must be 'public function format(int) -> string { }' (found a 'string' property)↵- 'reset' must be 'public function reset() { }' (found 'callback reset();')}

    in-out property <int> value;
    callback notify();

    pure public function add(a: int, b: int) -> int {
        return a + b;
    }
    in property <string> format;
//                       >    <note{'CannotOverrideFunction' declares 'format' here, 'Calculator' expects 'public function format(int) -> string { }'}
    callback reset();
//           >   <note{'CannotOverrideFunction' declares 'reset' here, 'Calculator' expects 'public function reset() { }'}
}

// Conflicts with an inherited (non-local) member: property, callback and function variants.
component BaseWithMembers {
    in-out property <float> value;
//                   >   <note{'BaseWithMembers' declares 'value' here, 'ValidInterface' expects 'in-out property <int> value;'}
    callback speak(string);
//                 >    <note{'BaseWithMembers' declares 'speak' here, 'ValidInterface' expects 'callback speak();'}
    public function reset() {}
    @children
}

export component DerivedConflicts inherits BaseWithMembers {
    implement ValidInterface <=> self;
//            >             <error{Cannot implement 'ValidInterface'.↵- 'speak' must be 'callback speak();' (found 'callback speak(string);')↵- 'value' must be a 'int' property (found a 'float' property)}
}

interface CallbackInterface {
    callback action();
}

component BaseWithFunction {
    public function action() {}
//                  >    <note{'BaseWithFunction' declares 'action' here, 'CallbackInterface' expects 'callback action();'}
    @children
}

export component ImplementFunctionConflict inherits BaseWithFunction {
    implement CallbackInterface <=> self;
//            >                <error{Cannot implement 'CallbackInterface'.↵- 'action' must be 'callback action();' (found 'public function action() { }')}
}

// Each member declared as the wrong kind of member.
export component CrossKindMismatch {
    implement ValidInterface <=> self;
//            >             <error{Cannot implement 'ValidInterface'.↵- 'reset' must be 'public function reset() { }' (found a 'int' property)↵- 'speak' must be 'callback speak();' (found a 'int' property)↵- 'value' must be 'in-out property <int> value;' (found 'callback value();')}

    callback value();
//           >   <note{'CrossKindMismatch' declares 'value' here, 'ValidInterface' expects 'in-out property <int> value;'}
    in-out property <int> speak;
//                        >   <note{'CrossKindMismatch' declares 'speak' here, 'ValidInterface' expects 'callback speak();'}
    in-out property <int> reset;
//                        >   <note{'CrossKindMismatch' declares 'reset' here, 'ValidInterface' expects 'public function reset() { }'}
}

// A single member that violates several constraints at once, joined into one message.
export component MultipleViolations {
    implement OutOnlyInterface <=> self;
//            >               <error{Cannot implement 'OutOnlyInterface'.↵- 'count' must be a 'int' property (found a 'float' property)↵- 'count' must be 'out' (found 'in-out')}

    in-out property <float> count;
//                   >   <note{'MultipleViolations' declares 'count' here, 'OutOnlyInterface' expects 'out property <int> count;'}
//  >    <^note{'MultipleViolations' declares 'count' here, 'OutOnlyInterface' expects 'out property <int> count;'}
}

interface Viewport {
    in-out property <float> viewport-x;
    in-out property <float> viewport-y;
}

// The Viewport interface properties conflict with the properties on the built-in Flickable component
export component ConflictsWithBuiltIn inherits Flickable {
    implement Viewport <=> self;
//            >       <error{Cannot implement 'Viewport'.↵- 'viewport-x' must be a 'float' property (found a 'length' property)↵- 'viewport-y' must be a 'float' property (found a 'length' property)}
}