-
-
Notifications
You must be signed in to change notification settings - Fork 196
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
43 changed files
with
1,362 additions
and
9 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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
35 changes: 35 additions & 0 deletions
35
Sources/PeripheryKit/CodeRemoval/EmptyExtensionSyntaxRemover.swift
This file contains 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,35 @@ | ||
import Foundation | ||
import Foundation | ||
import SwiftParser | ||
import SwiftSyntax | ||
import SystemPackage | ||
|
||
final class EmptyExtensionSyntaxRemover: SyntaxRewriter, TriviaSplitting { | ||
private let locationBuilder: SourceLocationBuilder | ||
|
||
init(locationBuilder: SourceLocationBuilder) { | ||
self.locationBuilder = locationBuilder | ||
} | ||
|
||
func perform(syntax: SourceFileSyntax) -> SourceFileSyntax { | ||
visit(syntax) | ||
} | ||
|
||
override func visit(_ node: CodeBlockItemListSyntax) -> CodeBlockItemListSyntax { | ||
let newChildren = node.compactMap { child -> CodeBlockItemSyntax? in | ||
guard let extDecl = child.item.as(ExtensionDeclSyntax.self) else { return child } | ||
|
||
let members = extDecl.memberBlock.members | ||
let hasMembers = !(members.count == 0 || (members.count == 1 && members.first?.decl.is(MissingDeclSyntax.self) ?? false)) | ||
let hasInheritance = extDecl.inheritanceClause != nil | ||
|
||
if !hasMembers, !hasInheritance { | ||
return remainingTriviaDecl(from: child.item.leadingTrivia) | ||
} | ||
|
||
return child | ||
} | ||
|
||
return CodeBlockItemListSyntax(newChildren) | ||
} | ||
} |
This file contains 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,30 @@ | ||
import Foundation | ||
import Foundation | ||
import SwiftParser | ||
import SwiftSyntax | ||
import SystemPackage | ||
|
||
final class EmptyFileVisitor: SyntaxVisitor, TriviaSplitting { | ||
private var isEmpty = false | ||
|
||
init() { | ||
super.init(viewMode: .sourceAccurate) | ||
} | ||
|
||
func perform(syntax: SourceFileSyntax) -> Bool { | ||
walk(syntax) | ||
return isEmpty | ||
} | ||
|
||
override func visit(_ node: SourceFileSyntax) -> SyntaxVisitorContinueKind { | ||
if node.statements.count == 0 { | ||
isEmpty = true | ||
} else { | ||
isEmpty = node.statements.allSatisfy { | ||
$0.item.is(ImportDeclSyntax.self) || $0.item.is(MissingDeclSyntax.self) | ||
} | ||
} | ||
|
||
return .skipChildren | ||
} | ||
} |
194 changes: 194 additions & 0 deletions
194
Sources/PeripheryKit/CodeRemoval/PublicAccessibilitySyntaxRemover.swift
This file contains 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,194 @@ | ||
import Foundation | ||
import SwiftParser | ||
import SwiftSyntax | ||
import SystemPackage | ||
|
||
final class PublicAccessibilitySyntaxRemover: SyntaxRewriter, SyntaxRemover { | ||
private let resultLocation: SourceLocation | ||
private let locationBuilder: SourceLocationBuilder | ||
|
||
init(resultLocation: SourceLocation, replacements: [String], locationBuilder: SourceLocationBuilder) { | ||
self.resultLocation = resultLocation | ||
self.locationBuilder = locationBuilder | ||
} | ||
|
||
func perform(syntax: SourceFileSyntax) -> SourceFileSyntax { | ||
visit(syntax) | ||
} | ||
|
||
override func visit(_ node: ClassDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.name.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.classKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: StructDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.name.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.structKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: EnumDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.name.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.enumKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: ExtensionDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.extendedType.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.extensionKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: ProtocolDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.name.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.protocolKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: InitializerDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.initKeyword.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.initKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: FunctionDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.name.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.funcKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: SubscriptDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.subscriptKeyword.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.subscriptKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: TypeAliasDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.name.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.typealiasKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: VariableDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.bindings.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.bindingSpecifier | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: ActorDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.name.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.actorKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: AssociatedTypeDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.name.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.associatedtypeKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
override func visit(_ node: PrecedenceGroupDeclSyntax) -> DeclSyntax { | ||
let newNode = removePublicModifier( | ||
from: node, | ||
at: node.name.positionAfterSkippingLeadingTrivia, | ||
triviaRecipient: \.precedencegroupKeyword | ||
) | ||
return super.visit(newNode) | ||
} | ||
|
||
// MARK: - Private | ||
|
||
private func removePublicModifier<T: PublicModifiedDecl, Output: SyntaxProtocol>( | ||
from node: T, | ||
at position: AbsolutePosition, | ||
triviaRecipient: WritableKeyPath<T, Output> | ||
) -> T { | ||
var removedLeadingTrivia = Trivia(pieces: []) | ||
var didRemove = false | ||
|
||
var newModifiers = node.modifiers.filter { modifier in | ||
if locationBuilder.location(at: position) == resultLocation, | ||
modifier.name.text == "public" { | ||
didRemove = true | ||
removedLeadingTrivia = modifier.leadingTrivia | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
var newNode = node | ||
|
||
if didRemove { | ||
if newModifiers.count == 0 { | ||
let triviaRecipientNode = node[keyPath: triviaRecipient] | ||
let newTriviaRecipientNode = triviaRecipientNode | ||
.with(\.leadingTrivia, removedLeadingTrivia + newModifiers.leadingTrivia) | ||
newNode = newNode.with(triviaRecipient, newTriviaRecipientNode) | ||
} else { | ||
newModifiers = newModifiers | ||
.with(\.leadingTrivia, removedLeadingTrivia + newModifiers.leadingTrivia) | ||
} | ||
|
||
return newNode.with(\.modifiers, newModifiers) | ||
} else { | ||
return node | ||
} | ||
} | ||
} | ||
|
||
protocol PublicModifiedDecl: SyntaxProtocol { | ||
var modifiers: DeclModifierListSyntax { get set } | ||
} | ||
|
||
extension ClassDeclSyntax: PublicModifiedDecl {} | ||
extension StructDeclSyntax: PublicModifiedDecl {} | ||
extension EnumDeclSyntax: PublicModifiedDecl {} | ||
extension EnumCaseDeclSyntax: PublicModifiedDecl {} | ||
extension ExtensionDeclSyntax: PublicModifiedDecl {} | ||
extension ProtocolDeclSyntax: PublicModifiedDecl {} | ||
extension InitializerDeclSyntax: PublicModifiedDecl {} | ||
extension FunctionDeclSyntax: PublicModifiedDecl {} | ||
extension SubscriptDeclSyntax: PublicModifiedDecl {} | ||
extension TypeAliasDeclSyntax: PublicModifiedDecl {} | ||
extension VariableDeclSyntax: PublicModifiedDecl {} | ||
extension ActorDeclSyntax: PublicModifiedDecl {} | ||
extension AssociatedTypeDeclSyntax: PublicModifiedDecl {} | ||
extension PrecedenceGroupDeclSyntax: PublicModifiedDecl {} |
Oops, something went wrong.