Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Add sourceRange property to Symbol #237

Merged
merged 6 commits into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
#219 by @Lukas-Stuehrk.
- Added support for documenting default implementations.
#221 by @Lukas-Stuehrk.
- Added `sourceRange` property to `Symbol`.
#237 by @mattt.

### Fixed

Expand All @@ -27,6 +29,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Changed display of code declarations in HTML.
#204 by @mattt.
- Changed serialization of `Symbol` to encode and decode `sourceRange` key
instead of `sourceLocation` key.
#237 by @mattt.

### Deprecated

- Deprecated `Symbol.sourceLocation` property.
Use `Symbol.sourceRange.start` instead.
#237 by @mattt.
- Changed the `generate` command to skip hidden files
and top-level `Tests` directories.
#229 by @mattt.
Expand Down
27 changes: 27 additions & 0 deletions Sources/SwiftDoc/Extensions/SwiftSyntax+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,37 @@ extension SourceLocation: Hashable {

// MARK: -

extension SourceRange: Equatable {
public static func == (lhs: SourceRange, rhs: SourceRange) -> Bool {
return lhs.start == rhs.start && lhs.end == rhs.end
}
}

extension SourceRange: Comparable {
public static func < (lhs: SourceRange, rhs: SourceRange) -> Bool {
return lhs.start < rhs.start
}
}

extension SourceRange: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(start)
hasher.combine(end)
}
}

// MARK: -

protocol SymbolDeclProtocol: SyntaxProtocol {
var declaration: Syntax { get }
}

extension SymbolDeclProtocol {
func sourceRange(using converter: SourceLocationConverter) -> SourceRange {
return SourceRange(start: startLocation(converter: converter), end: endLocation(converter: converter))
}
}

extension AssociatedtypeDeclSyntax: SymbolDeclProtocol {}
extension ClassDeclSyntax: SymbolDeclProtocol {}
extension EnumDeclSyntax: SymbolDeclProtocol {}
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftDoc/Interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public final class Interface {
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: [], documentation: nil, sourceLocation: nil)
let inherited = Symbol(api: Unknown(name: name), context: [], declaration: [], documentation: nil, sourceRange: nil)
relationships.insert(Relationship(subject: symbol, predicate: .conformsTo, object: inherited))
} else {
for inherited in inheritedTypes {
Expand Down
8 changes: 4 additions & 4 deletions Sources/SwiftDoc/SourceFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ public struct SourceFile: Hashable, Codable {
func symbol<Node, Declaration>(_ type: Declaration.Type, _ node: Node) -> Symbol? where Declaration: API & ExpressibleBySyntax, Node == Declaration.Syntax, Node: SymbolDeclProtocol {
guard let api = Declaration(node) else { return nil }
guard let documentation = try? Documentation.parse(node.documentation) else { return nil }
let sourceLocation = sourceLocationConverter.location(for: node.position)
return Symbol(api: api, context: context, declaration: declaration(for: node), documentation: documentation, sourceLocation: sourceLocation)
let sourceRange = node.sourceRange(using: sourceLocationConverter)
return Symbol(api: api, context: context, declaration: declaration(for: node), documentation: documentation, sourceRange: sourceRange)
}

func symbol<Node: SymbolDeclProtocol>(_ node: Node, api: API) -> Symbol? {
guard let documentation = try? Documentation.parse(node.documentation) else { return nil }
let sourceLocation = sourceLocationConverter.location(for: node.position)
return Symbol(api: api, context: context, declaration: declaration(for: node), documentation: documentation, sourceLocation: sourceLocation)
let sourceRange = node.sourceRange(using: sourceLocationConverter)
return Symbol(api: api, context: context, declaration: declaration(for: node), documentation: documentation, sourceRange: sourceRange)
}

func declaration<Node: SymbolDeclProtocol>(for node: Node) -> [Token] {
Expand Down
27 changes: 15 additions & 12 deletions Sources/SwiftDoc/Symbol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@ public final class Symbol {
public let context: [Contextual]
public let declaration: [Token]
public let documentation: Documentation?
public let sourceLocation: SourceLocation?
public let sourceRange: SourceRange?

@available(swift, deprecated: 0.0.1, message: "Use sourceRange instead")
public var sourceLocation: SourceLocation? { sourceRange?.start }

public private(set) lazy var `extension`: Extension? = context.compactMap { $0 as? Extension }.first
public private(set) lazy var conditions: [CompilationCondition] = context.compactMap { $0 as? CompilationCondition }

init(api: API, context: [Contextual], declaration: [Token], documentation: Documentation?, sourceLocation: SourceLocation?) {
init(api: API, context: [Contextual], declaration: [Token], documentation: Documentation?, sourceRange: SourceRange?) {
self.api = api
self.context = context
self.declaration = declaration
self.documentation = documentation
self.sourceLocation = sourceLocation
self.sourceRange = sourceRange
}

public var name: String {
Expand Down Expand Up @@ -114,8 +117,8 @@ public final class Symbol {
extension Symbol: Equatable {
public static func == (lhs: Symbol, rhs: Symbol) -> Bool {
guard lhs.documentation == rhs.documentation,
lhs.sourceLocation == rhs.sourceLocation
else { return false }
lhs.sourceRange == rhs.sourceRange
else { return false }

guard lhs.context.count == rhs.context.count else { return false}
for (lc, rc) in zip(lhs.context, rhs.context) {
Expand Down Expand Up @@ -170,8 +173,8 @@ extension Symbol: Equatable {

extension Symbol: Comparable {
public static func < (lhs: Symbol, rhs: Symbol) -> Bool {
if let lsl = lhs.sourceLocation, let rsl = rhs.sourceLocation {
return lsl < rsl
if let lsr = lhs.sourceRange, let rsr = rhs.sourceRange {
return lsr < rsr
} else {
return lhs.name < rhs.name
}
Expand All @@ -183,7 +186,7 @@ extension Symbol: Comparable {
extension Symbol: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(documentation)
hasher.combine(sourceLocation)
hasher.combine(sourceRange)
switch api {
case let api as AssociatedType:
hasher.combine(api)
Expand Down Expand Up @@ -225,7 +228,7 @@ extension Symbol: Codable {
private enum CodingKeys: String, CodingKey {
case declaration
case documentation
case sourceLocation
case sourceRange

case associatedType
case `case`
Expand Down Expand Up @@ -282,9 +285,9 @@ extension Symbol: Codable {

let declaration = try container.decodeIfPresent([Token].self, forKey: .declaration)
let documentation = try container.decodeIfPresent(Documentation.self, forKey: .documentation)
let sourceLocation = try container.decodeIfPresent(SourceLocation.self, forKey: .sourceLocation)
let sourceRange = try container.decodeIfPresent(SourceRange.self, forKey: .sourceRange)

self.init(api: api, context: [] /* TODO */, declaration: declaration ?? [], documentation: documentation, sourceLocation: sourceLocation)
self.init(api: api, context: [] /* TODO */, declaration: declaration ?? [], documentation: documentation, sourceRange: sourceRange)
}

public func encode(to encoder: Encoder) throws {
Expand Down Expand Up @@ -323,6 +326,6 @@ extension Symbol: Codable {
}

try container.encode(documentation, forKey: .documentation)
try container.encode(sourceLocation, forKey: .sourceLocation)
try container.encode(sourceRange, forKey: .sourceRange)
}
}
6 changes: 3 additions & 3 deletions Sources/swift-doc/Extensions/DCOV+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ extension Entry {
let name = symbol.id.description
let type = String(describing: Swift.type(of: symbol.api))
let documented = symbol.isDocumented
let file = symbol.sourceLocation?.file
let line = symbol.sourceLocation?.line
let column = symbol.sourceLocation?.column
let file = symbol.sourceRange?.start.file
let line = symbol.sourceRange?.start.line
let column = symbol.sourceRange?.start.column

self.init(name: name, type: type, documented: documented, file: file, line: line, column: column)
}
Expand Down