From a6533a0ec1a62648d085ee94ee0c301a7d981590 Mon Sep 17 00:00:00 2001 From: Mattt Date: Wed, 6 May 2020 12:12:12 -0700 Subject: [PATCH] Change lazy properties to be conventional --- Sources/SwiftDoc/Interface.swift | 185 +++++++++++++++---------------- Sources/SwiftDoc/Module.swift | 14 +-- 2 files changed, 93 insertions(+), 106 deletions(-) diff --git a/Sources/SwiftDoc/Interface.swift b/Sources/SwiftDoc/Interface.swift index 9370790d..c05e17ea 100644 --- a/Sources/SwiftDoc/Interface.swift +++ b/Sources/SwiftDoc/Interface.swift @@ -2,135 +2,124 @@ import Foundation import SwiftSemantics import struct SwiftSemantics.Protocol -public final class Interface: Codable { +public final class Interface { public let imports: [Import] public let symbols: [Symbol] public required init(imports: [Import], symbols: [Symbol]) { self.imports = imports self.symbols = symbols.filter { $0.isPublic } - } - - // MARK: - - - public lazy var symbolsGroupedByIdentifier: [Symbol.ID: [Symbol]] = { - return Dictionary(grouping: symbols, by: { $0.id }) - }() - public lazy var symbolsGroupedByQualifiedName: [String: [Symbol]] = { - return Dictionary(grouping: symbols, by: { $0.id.description }) - }() + self.symbolsGroupedByIdentifier = Dictionary(grouping: symbols, by: { $0.id }) + self.symbolsGroupedByQualifiedName = Dictionary(grouping: symbols, by: { $0.id.description }) + self.topLevelSymbols = symbols.filter { $0.api is Type || $0.id.pathComponents.isEmpty } - public private(set) lazy var topLevelSymbols: [Symbol] = { - return symbols.filter { $0.api is Type || $0.id.pathComponents.isEmpty } - }() + self.relationships = { + let extensionsByExtendedType: [String: [Extension]] = Dictionary(grouping: symbols.flatMap { $0.context.compactMap { $0 as? Extension } }, by: { $0.extendedType }) - public private(set) lazy var baseClasses: [Symbol] = { - return symbols.filter { $0.api is Class && - typesInherited(by: $0).isEmpty } - }() + var relationships: Set = [] + for symbol in symbols { + let lastDeclarationScope = symbol.context.last(where: { $0 is Extension || $0 is Symbol }) + + if let container = lastDeclarationScope as? Symbol { + let predicate: Relationship.Predicate - public private(set) lazy var classHierarchies: [Symbol: Set] = { - var classClusters: [Symbol: Set] = [:] + switch container.api { + case is Protocol: + if symbol.api.modifiers.contains(where: { $0.name == "optional" }) { + predicate = .optionalRequirementOf + } else { + predicate = .requirementOf + } + default: + predicate = .memberOf + } - for baseClass in baseClasses { - var superclasses = Set(CollectionOfOne(baseClass)) + relationships.insert(Relationship(subject: symbol, predicate: predicate, object: container)) + } - while !superclasses.isEmpty { - let subclasses = Set(superclasses.flatMap { typesInheriting(from: $0) }.filter { $0.isPublic }) - defer { superclasses = subclasses } - classClusters[baseClass, default: []].formUnion(subclasses) - } - } + if let `extension` = lastDeclarationScope as? Extension { + if let extended = symbols.first(where: { $0.api is Type && $0.id.matches(`extension`.extendedType) }) { - return classClusters - }() + let predicate: Relationship.Predicate + switch extended.api { + case is Protocol: + predicate = .defaultImplementationOf + default: + predicate = .memberOf + } - private lazy var extensionsByExtendedType: [String: [Extension]] = { - return Dictionary(grouping: symbols.flatMap { $0.context.compactMap { $0 as? Extension } }) { - $0.extendedType - } - }() - - public private(set) lazy var relationships: [Relationship] = { - var relationships: Set = [] - for symbol in symbols { - let lastDeclarationScope = symbol.context.last(where: { $0 is Extension || $0 is Symbol }) - - if let container = lastDeclarationScope as? Symbol { - let predicate: Relationship.Predicate - - switch container.api { - case is Protocol: - if symbol.api.modifiers.contains(where: { $0.name == "optional" }) { - predicate = .optionalRequirementOf - } else { - predicate = .requirementOf + relationships.insert(Relationship(subject: symbol, predicate: predicate, object: extended)) } - default: - predicate = .memberOf } - relationships.insert(Relationship(subject: symbol, predicate: predicate, object: container)) - } - - if let `extension` = lastDeclarationScope as? Extension { - if let extended = symbols.first(where: { $0.api is Type && $0.id.matches(`extension`.extendedType) }) { + if let type = symbol.api as? Type { + var inheritedTypeNames: Set = [] + inheritedTypeNames.formUnion(type.inheritance.flatMap { $0.split(separator: "&").map { $0.trimmingCharacters(in: .whitespaces) } + }) - let predicate: Relationship.Predicate - switch extended.api { - case is Protocol: - predicate = .defaultImplementationOf - default: - predicate = .memberOf + for `extension` in extensionsByExtendedType[symbol.id.description] ?? [] { + inheritedTypeNames.formUnion(`extension`.inheritance) } - relationships.insert(Relationship(subject: symbol, predicate: predicate, object: extended)) + inheritedTypeNames = Set(inheritedTypeNames.flatMap { $0.split(separator: "&").map { $0.trimmingCharacters(in: .whitespaces) } }) + + for name in inheritedTypeNames { + let inheritedTypes = symbols.filter({ ($0.api is Class || $0.api is Protocol) && $0.id.description == name }) + if inheritedTypes.isEmpty { + let inherited = Symbol(api: Unknown(name: name), context: [], declaration: nil, documentation: nil, sourceLocation: nil) + relationships.insert(Relationship(subject: symbol, predicate: .conformsTo, object: inherited)) + } else { + for inherited in inheritedTypes { + let predicate: Relationship.Predicate + if symbol.api is Class, inherited.api is Class { + predicate = .inheritsFrom + } else { + predicate = .conformsTo + } + + relationships.insert(Relationship(subject: symbol, predicate: predicate, object: inherited)) + } + } + } } } - if let type = symbol.api as? Type { - var inheritedTypeNames: Set = [] - inheritedTypeNames.formUnion(type.inheritance.flatMap { $0.split(separator: "&").map { $0.trimmingCharacters(in: .whitespaces) } - }) + return Array(relationships) + }() - for `extension` in extensionsByExtendedType[symbol.id.description] ?? [] { - inheritedTypeNames.formUnion(`extension`.inheritance) - } + self.relationshipsBySubject = Dictionary(grouping: relationships, by: { $0.subject.id }) + self.relationshipsByObject = Dictionary(grouping: relationships, by: { $0.object.id }) + } - inheritedTypeNames = Set(inheritedTypeNames.flatMap { $0.split(separator: "&").map { $0.trimmingCharacters(in: .whitespaces) } }) - - for name in inheritedTypeNames { - let inheritedTypes = symbols.filter({ ($0.api is Class || $0.api is Protocol) && $0.id.description == name }) - if inheritedTypes.isEmpty { - let inherited = Symbol(api: Unknown(name: name), context: [], declaration: nil, documentation: nil, sourceLocation: nil) - relationships.insert(Relationship(subject: symbol, predicate: .conformsTo, object: inherited)) - } else { - for inherited in inheritedTypes { - let predicate: Relationship.Predicate - if symbol.api is Class, inherited.api is Class { - predicate = .inheritsFrom - } else { - predicate = .conformsTo - } + // MARK: - - relationships.insert(Relationship(subject: symbol, predicate: predicate, object: inherited)) - } - } - } + public let symbolsGroupedByIdentifier: [Symbol.ID: [Symbol]] + public let symbolsGroupedByQualifiedName: [String: [Symbol]] + public let topLevelSymbols: [Symbol] + public var baseClasses: [Symbol] { + symbols.filter { $0.api is Class && typesInherited(by: $0).isEmpty } + } + public var classHierarchies: [Symbol: Set] { + var classClusters: [Symbol: Set] = [:] + + for baseClass in baseClasses { + var superclasses = Set(CollectionOfOne(baseClass)) + + while !superclasses.isEmpty { + let subclasses = Set(superclasses.flatMap { typesInheriting(from: $0) }.filter { $0.isPublic }) + defer { superclasses = subclasses } + classClusters[baseClass, default: []].formUnion(subclasses) } } - return Array(relationships) - }() + return classClusters - public private(set) lazy var relationshipsBySubject: [Symbol.ID: [Relationship]] = { - Dictionary(grouping: relationships, by: { $0.subject.id }) - }() + } - public private(set) lazy var relationshipsByObject: [Symbol.ID: [Relationship]] = { - Dictionary(grouping: relationships, by: { $0.object.id }) - }() + public let relationships: [Relationship] + public let relationshipsBySubject: [Symbol.ID: [Relationship]] + public let relationshipsByObject: [Symbol.ID: [Relationship]] // MARK: - diff --git a/Sources/SwiftDoc/Module.swift b/Sources/SwiftDoc/Module.swift index 009346ed..0b09eb8d 100644 --- a/Sources/SwiftDoc/Module.swift +++ b/Sources/SwiftDoc/Module.swift @@ -2,20 +2,18 @@ import Foundation import SwiftSemantics import struct SwiftSemantics.Protocol -public final class Module: Codable { +public final class Module { public let name: String - public let sourceFiles: [SourceFile] - - public lazy var interface: Interface = { - let imports = sourceFiles.flatMap { $0.imports } - let symbols = sourceFiles.flatMap { $0.symbols } - return Interface(imports: imports, symbols: symbols) - }() + public let interface: Interface public required init(name: String = "Anonymous", sourceFiles: [SourceFile]) { self.name = name self.sourceFiles = sourceFiles + + let imports = sourceFiles.flatMap { $0.imports } + let symbols = sourceFiles.flatMap { $0.symbols } + self.interface = Interface(imports: imports, symbols: symbols) } public convenience init(name: String = "Anonymous", paths: [String]) throws {