Extracted from gtk-swift monorepo. Previous history contains 38 commits across the full Phase 1 development including GIR XML parsing, IR model, analysis engine, code generation, CLI, plugins, and documentation.
127 lines
5.2 KiB
Swift
127 lines
5.2 KiB
Swift
/// The result of analyzing a GIR repository against a `GenerationConfig`.
|
|
///
|
|
/// Contains the resolved class hierarchy, the classification of each type
|
|
/// (generate, manual, or ignore), and any per-type or per-function overrides
|
|
/// from the configuration. This result drives the subsequent code-generation
|
|
/// phase.
|
|
public struct AnalysisResult {
|
|
/// Maps each type name to its parent type name, forming an inheritance tree.
|
|
///
|
|
/// Keys are fully-qualified type names (e.g. `"Gtk.Widget"`); values are the
|
|
/// fully-qualified parent name.
|
|
public var classHierarchy: [String: String]
|
|
|
|
/// The set of fully-qualified type names that should have Swift bindings generated.
|
|
public var generatedTypes: Set<String>
|
|
|
|
/// The set of fully-qualified type names that are implemented manually and
|
|
/// should be excluded from generation.
|
|
public var manualTypes: Set<String>
|
|
|
|
/// The set of fully-qualified type names that should be skipped entirely.
|
|
public var ignoredTypes: Set<String>
|
|
|
|
/// Per-type overrides keyed by fully-qualified type name.
|
|
public var classOverrides: [String: ObjectOverrides]
|
|
|
|
/// Per-function overrides keyed by `"ClassName.functionName"`.
|
|
public var functionOverrides: [String: FunctionOverrides]
|
|
|
|
/// Creates an analysis result from the given component values.
|
|
///
|
|
/// - Parameters:
|
|
/// - classHierarchy: Inheritance map from each type to its parent.
|
|
/// - generatedTypes: Types that should be generated.
|
|
/// - manualTypes: Types that are implemented manually.
|
|
/// - ignoredTypes: Types that should be omitted.
|
|
/// - classOverrides: Per-type override configuration.
|
|
/// - functionOverrides: Per-function override configuration.
|
|
public init(classHierarchy: [String: String] = [:], generatedTypes: Set<String> = [],
|
|
manualTypes: Set<String> = [], ignoredTypes: Set<String> = [],
|
|
classOverrides: [String: ObjectOverrides] = [:],
|
|
functionOverrides: [String: FunctionOverrides] = [:]) {
|
|
self.classHierarchy = classHierarchy
|
|
self.generatedTypes = generatedTypes
|
|
self.manualTypes = manualTypes
|
|
self.ignoredTypes = ignoredTypes
|
|
self.classOverrides = classOverrides
|
|
self.functionOverrides = functionOverrides
|
|
}
|
|
}
|
|
|
|
/// Analyzes a GIR repository against a `GenerationConfig` to produce an `AnalysisResult`.
|
|
///
|
|
/// The analyzer walks the repository's type hierarchy and applies the
|
|
/// configuration's generate/manual/ignore lists and per-type overrides.
|
|
public struct Analyzer {
|
|
/// The generation configuration that guides the analysis.
|
|
public let config: GenerationConfig
|
|
|
|
/// Creates an analyzer with the given generation configuration.
|
|
///
|
|
/// - Parameter config: The configuration specifying which types to
|
|
/// generate, handle manually, or ignore, along with any overrides.
|
|
public init(config: GenerationConfig) {
|
|
self.config = config
|
|
}
|
|
|
|
/// Analyzes the provided GIR repository and returns the classification result.
|
|
///
|
|
/// The analysis builds a class inheritance hierarchy from the repository,
|
|
/// classifies each type according to the configuration's `generate`,
|
|
/// `manual`, and `ignore` lists, and extracts per-type and per-function
|
|
/// overrides.
|
|
///
|
|
/// - Parameter repository: The parsed GIR repository to analyze.
|
|
/// - Returns: An `AnalysisResult` containing the resolved hierarchy, type
|
|
/// classifications, and overrides.
|
|
public func analyze(repository: Repository) -> AnalysisResult {
|
|
var classHierarchy: [String: String] = [:]
|
|
var generatedTypes: Set<String> = []
|
|
var manualTypes: Set<String> = []
|
|
var ignoredTypes: Set<String> = []
|
|
var classOverrides: [String: ObjectOverrides] = [:]
|
|
var functionOverrides: [String: FunctionOverrides] = [:]
|
|
|
|
for ns in repository.namespaces {
|
|
for cls in ns.classes {
|
|
let fullName = "\(ns.name).\(cls.name)"
|
|
if let parent = cls.parent {
|
|
let parentFullName = parent.contains(".") ? parent : "\(ns.name).\(parent)"
|
|
classHierarchy[fullName] = parentFullName
|
|
}
|
|
}
|
|
}
|
|
|
|
for fullName in config.generate {
|
|
generatedTypes.insert(fullName)
|
|
}
|
|
for fullName in config.manual {
|
|
manualTypes.insert(fullName)
|
|
}
|
|
for fullName in config.ignore {
|
|
ignoredTypes.insert(fullName)
|
|
}
|
|
|
|
for objConfig in config.objects {
|
|
switch objConfig {
|
|
case .object(let name, let overrides):
|
|
classOverrides[name] = overrides
|
|
case .function(let className, let functionName, let overrides):
|
|
let key = "\(className).\(functionName)"
|
|
functionOverrides[key] = overrides
|
|
case .functionPattern, .signal, .property:
|
|
break
|
|
}
|
|
}
|
|
|
|
return AnalysisResult(
|
|
classHierarchy: classHierarchy,
|
|
generatedTypes: generatedTypes,
|
|
manualTypes: manualTypes,
|
|
ignoredTypes: ignoredTypes,
|
|
classOverrides: classOverrides,
|
|
functionOverrides: functionOverrides
|
|
)
|
|
}
|
|
}
|