portico/Sources/PorticoGen/Model.swift

97 lines
4.1 KiB
Swift

/// Whether a ``WidgetModel`` describes a class or a `Widget`-refining protocol.
enum WidgetKind: Equatable { case widgetClass, interface }
/// Represents a single initializer parameter.
struct Param: Equatable {
let label: String
let type: String
}
/// A convenience initializer extracted from a generated wrapper.
struct InitModel: Equatable {
let params: [Param]
/// Full `///` doc lines from the upstream convenience init, or `[]`.
let doc: [String]
}
/// A settable property extracted from a generated wrapper.
struct PropertyModel: Equatable {
let name: String
let type: String
/// The setter method name, e.g. `setSize` or `setSelected`.
let setterName: String
/// The argument label used when calling the setter, e.g. `size` or `position`.
let setterLabel: String
/// The zero-argument getter method to read this property back through, e.g.
/// `getActive`. `nil` when the wrapper declares no compatible getter method,
/// in which case the computed `var` is the only read path.
let getterName: String?
/// Whether the compatible getter returns exactly one additional optional layer
/// beyond the property's declared type, e.g. a `Gtk.Stack` property read back
/// through `getStack() -> Gtk.Stack?`. `false` when the getter's return type
/// matches the declared type exactly, including when both are already optional.
let getterIsOptional: Bool
}
/// A signal extracted from a generated wrapper.
struct SignalModel: Equatable {
/// Signal name with `connect` prefix stripped, e.g. `Clicked`.
let baseName: String
/// The GTK signal string, e.g. `"clicked"`.
let signalName: String
/// Closure argument types after dropping the widget-self first parameter.
let argTypes: [String]
/// Closure return type, e.g. `Void` or `Bool`.
let returnType: String
}
/// A method that accepts a widget child.
struct ChildAdder: Equatable {
/// The method name, such as `append` or `add`.
let methodName: String
/// The argument label used by the wrapper method.
let label: String
/// Whether the method returns a value that must be discarded.
let returnsValue: Bool
}
/// The complete model of a widget extracted from a generated wrapper file.
struct WidgetModel {
let className: String
let module: String
let kind: WidgetKind
/// Full `///` doc lines from the upstream class or protocol.
let docLines: [String]
let inits: [InitModel]
/// The no-arg convenience init, when the generated class has one.
let noArgInit: InitModel?
let properties: [PropertyModel]
let signals: [SignalModel]
/// Methods that add widget children.
let childAdders: [ChildAdder]
/// The generic child-add method backing the leading `children:` builder.
///
/// Only `append`, `add`, and `addChild` add to a widget's generic content area.
/// Region-specific adders (`addPrefix`, `addSuffix`, `addOverlay`, `addTopBar`,
/// `addBottomBar`, `addAction`, `addRow`, `addActionWidget`, `appendPinned`, ...)
/// target a named part of the widget, so they are never the unlabeled trailing
/// builder; ``generateChildAdderModifiers(widget:)`` exposes them as modifiers only.
var primaryAdder: ChildAdder? {
let priority = ["append", "add", "addChild"]
return priority.compactMap { name in childAdders.first { $0.methodName == name } }.first
}
/// Every parameter label used by any convenience initializer on this class.
///
/// A label in this set is never emitted as a defaulted parameter, on any
/// initializer of the class. This keeps generated defaulted initializers
/// from shadowing or making ambiguous an upstream initializer with the same label.
var reservedInitLabels: Set<String> {
Set(inits.flatMap { $0.params.map(\.label) })
}
/// The inherited superclass name, e.g. "Widget", "ActionRow", "GLibObject".
let parentClass: String
/// Member name full doc lines for every documented `public var` and
/// `public func` on the class or interface extension.
let memberDocs: [String: [String]]
}