-
-
Notifications
You must be signed in to change notification settings - Fork 16
Add Wrappers for Class, Actor, Extension #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
stackotter
merged 8 commits into
stackotter:main
from
ajkolean:Add-Missing-Group-Wrappers
May 30, 2024
Merged
Changes from 4 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
78d29e2
add missing wrappers
ajkolean fc363e2
swift-format
ajkolean 473a533
add inherited types
ajkolean a3551fb
swift-format
ajkolean 95b8c29
Remove RawRepresentable Conformance
ajkolean f0d003e
remove AnyDeclProtocol
ajkolean 9b12009
swift-format
ajkolean 3a18d77
swift-format is whack
ajkolean File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import SwiftSyntax | ||
|
||
/// Wraps an `actor` declaration. | ||
public struct Actor: DeclGroupProtocol { | ||
/// The underlying syntax node for the `actor` declaration. | ||
public var rawValue: ActorDeclSyntax | ||
|
||
/// The identifier (name) of the `actor`. | ||
public var identifier: String { | ||
_syntax.name.withoutTrivia().text | ||
} | ||
|
||
/// Initializes an `Actor` instance with the given syntax node. | ||
/// | ||
/// - Parameter syntax: The syntax node representing the `actor` declaration. | ||
public init(_ syntax: ActorDeclSyntax) { | ||
rawValue = syntax | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import SwiftSyntax | ||
|
||
/// Wraps a `class` declaration. | ||
public struct Class: DeclGroupProtocol { | ||
/// The underlying syntax node for the `class` declaration. | ||
public var rawValue: ClassDeclSyntax | ||
|
||
/// The identifier (name) of the `class`. | ||
public var identifier: String { | ||
_syntax.name.withoutTrivia().text | ||
} | ||
|
||
/// Initializes a `Class` instance with the given syntax node. | ||
/// | ||
/// - Parameter syntax: The syntax node representing the `class` declaration. | ||
public init(_ syntax: ClassDeclSyntax) { | ||
rawValue = syntax | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import SwiftSyntax | ||
|
||
/// An enumeration representing different types of declaration groups (e.g., `struct`, `class`, `enum`, `actor`, `extension`). | ||
/// This enum conforms to `DeclGroupProtocol` and wraps specific declaration group types. | ||
public enum DeclGroup: DeclGroupProtocol { | ||
case `struct`(Struct) | ||
case `enum`(Enum) | ||
case `class`(Class) | ||
case actor(Actor) | ||
case `extension`(Extension) | ||
|
||
/// A private computed property that returns the wrapped `DeclGroupProtocol` instance. | ||
private var wrapped: any DeclGroupProtocol { | ||
switch self { | ||
case .struct(let wrapped): return wrapped | ||
case .enum(let wrapped): return wrapped | ||
case .class(let wrapped): return wrapped | ||
case .actor(let wrapped): return wrapped | ||
case .extension(let wrapped): return wrapped | ||
} | ||
} | ||
|
||
/// Initializes a `DeclGroup` instance from a `DeclGroupSyntax`. | ||
/// | ||
/// - Parameter rawValue: The syntax node representing the declaration group. | ||
/// - Note: This initializer will fatalError if the syntax node does not match any known declaration group type. | ||
public init(_ rawValue: any DeclGroupSyntax) { | ||
switch rawValue { | ||
case let syntax as ActorDeclSyntax: | ||
self = .actor(Actor(syntax)) | ||
case let syntax as ClassDeclSyntax: | ||
self = .class(Class(syntax)) | ||
case let syntax as EnumDeclSyntax: | ||
self = .enum(Enum(syntax)) | ||
case let syntax as ExtensionDeclSyntax: | ||
self = .extension(Extension(syntax)) | ||
case let syntax as StructDeclSyntax: | ||
self = .struct(Struct(syntax)) | ||
default: | ||
fatalError("Unhandled decl group type '\(type(of: rawValue))'") | ||
} | ||
} | ||
|
||
/// The underlying syntax node for the declaration group. | ||
public var rawValue: any DeclGroupSyntax { | ||
switch self { | ||
case .struct(let wrapped): return wrapped.rawValue | ||
case .enum(let wrapped): return wrapped.rawValue | ||
case .class(let wrapped): return wrapped.rawValue | ||
case .actor(let wrapped): return wrapped.rawValue | ||
case .extension(let wrapped): return wrapped.rawValue | ||
} | ||
} | ||
|
||
/// The identifier of the declaration group. | ||
public var identifier: String { wrapped.identifier } | ||
|
||
/// The members of the declaration group. | ||
public var members: [Decl] { wrapped.members } | ||
|
||
/// The properties declared in the declaration group. | ||
public var properties: [Property] { wrapped.properties } | ||
|
||
/// The types inherited in the declaration group. | ||
public var inheritedTypes: [Type] { wrapped.inheritedTypes } | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import SwiftSyntax | ||
|
||
/// A protocol for declaration groups (e.g., `struct`, `class`, `enum`) that can contain members and properties. | ||
/// Declaration groups are higher-level constructs compared to regular declarations such as `var`. | ||
public protocol DeclGroupProtocol: RawRepresentable { | ||
stackotter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// The underlying syntax node for the declaration group. | ||
var rawValue: RawValue { get } | ||
|
||
/// The declaration's identifier. | ||
/// | ||
/// Note: SwiftSyntax's `DeclGroupSyntax` protocol does not include the declaration's identifier. | ||
/// This must be implemented manually for each declaration wrapper. This omission might be due to | ||
/// the fact that extensions technically do not have a name, even though they are always attached to a specific identifier. | ||
var identifier: String { get } | ||
|
||
/// The members of the declaration group. | ||
var members: [Decl] { get } | ||
|
||
/// The properties declared in the declaration group. | ||
var properties: [Property] { get } | ||
|
||
/// The inherited types of the declaration group. | ||
var inheritedTypes: [Type] { get } | ||
|
||
/// Initializes the declaration group with the given syntax node. | ||
/// | ||
/// - Parameter syntax: The underlying syntax node representing the declaration group. | ||
init(_ syntax: RawValue) | ||
} | ||
|
||
/// Default implementations and helper initializers for `DeclGroupProtocol`. | ||
extension DeclGroupProtocol { | ||
/// The underlying syntax node for the declaration group. | ||
public var _syntax: RawValue { | ||
rawValue | ||
} | ||
|
||
/// Initializes the declaration group with the given raw value. | ||
/// | ||
/// - Parameter rawValue: The raw value representing the declaration group. | ||
public init?(rawValue: RawValue) { | ||
self.init(rawValue) | ||
} | ||
} | ||
|
||
/// Additional functionality for `DeclGroupProtocol` where the raw value conforms to `DeclGroupSyntax`. | ||
extension DeclGroupProtocol where RawValue: DeclGroupSyntax { | ||
/// Attempts to initialize the wrapper from an arbitrary declaration group. | ||
/// | ||
/// - Parameter syntax: The syntax node representing the declaration group. | ||
/// - Note: This initializer will return `nil` if the syntax node does not match the expected type. | ||
public init?(_ syntax: any DeclGroupSyntax) { | ||
guard let rawValue = syntax as? RawValue else { return nil } | ||
self.init(rawValue: rawValue) | ||
} | ||
|
||
/// The members of the declaration group. | ||
public var members: [Decl] { | ||
_syntax.memberBlock.members.map(\.decl).map(Decl.init) | ||
} | ||
|
||
/// The properties declared in the declaration group. | ||
public var properties: [Property] { | ||
members.compactMap(\.asVariable).flatMap { variable in | ||
var bindings = variable._syntax.bindings.flatMap { binding in | ||
Property.properties(from: binding, in: variable) | ||
} | ||
// For the declaration `var a, b: Int` where `a` doesn't have an annotation, | ||
// `a` gets given the type of `b` (`Int`). To implement this, we 'drag' the | ||
// type annotations backwards over the non-annotated bindings. | ||
var lastSeenType: Type? | ||
for (i, binding) in bindings.enumerated().reversed() { | ||
if let type = binding.type { | ||
lastSeenType = type | ||
} else { | ||
bindings[i].type = lastSeenType | ||
} | ||
} | ||
return bindings | ||
} | ||
} | ||
|
||
/// The types inherited from or conformed to by the declaration group. | ||
/// | ||
/// - Note: This does not include conformances added by other declaration groups such as extensions. | ||
public var inheritedTypes: [Type] { | ||
_syntax.inheritanceClause?.inheritedTypes.map(\.type).map(Type.init) ?? [] | ||
} | ||
|
||
/// The access level of the declaration group. | ||
public var accessLevel: AccessModifier? { | ||
AccessModifier(modifiers: _syntax.modifiers) | ||
} | ||
|
||
/// The context-specific modifiers of the declaration group. | ||
public var declarationContext: DeclarationContextModifier? { | ||
DeclarationContextModifier(modifiers: _syntax.modifiers) | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import SwiftSyntax | ||
|
||
/// Wraps an `extension` declaration. | ||
public struct Extension: DeclGroupProtocol { | ||
/// The underlying syntax node for the `extension` declaration. | ||
public var rawValue: ExtensionDeclSyntax | ||
|
||
/// The identifier (extended type) of the `extension`. | ||
public var identifier: String { | ||
_syntax.extendedType.withoutTrivia().description | ||
} | ||
|
||
/// Initializes an `Extension` instance with the given syntax node. | ||
/// | ||
/// - Parameter syntax: The syntax node representing the `extension` declaration. | ||
public init(_ syntax: ExtensionDeclSyntax) { | ||
rawValue = syntax | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import SwiftSyntax | ||
|
||
/// Wraps a `struct` declaration. | ||
public struct Struct: DeclGroupProtocol { | ||
/// The underlying syntax node for the `struct` declaration. | ||
public var rawValue: StructDeclSyntax | ||
|
||
/// The identifier (name) of the `struct`. | ||
public var identifier: String { | ||
_syntax.name.withoutTrivia().text | ||
} | ||
|
||
/// Initializes a `Struct` instance with the given syntax node. | ||
/// | ||
/// - Parameter syntax: The syntax node representing the `struct` declaration. | ||
public init(_ syntax: StructDeclSyntax) { | ||
rawValue = syntax | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.