Skip to content

Commit

Permalink
Adds support for swift 5.9 and Bazel
Browse files Browse the repository at this point in the history
Adds support for swift 5.9 and Bazel
  • Loading branch information
maxwellE committed Apr 4, 2024
1 parent 6db73ae commit 5fd4122
Show file tree
Hide file tree
Showing 11 changed files with 414 additions and 67 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ Packages/
Package.pins
Package.resolved
.build/

# Bazel
bazel-*
57 changes: 57 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
load(
"@build_bazel_rules_swift//swift:swift.bzl",
"swift_binary",
"swift_library",
)

swift_library(
name = "NeedleFoundation",
srcs = glob(
["Sources/NeedleFoundation/**/*.swift"],
allow_empty = False,
),
module_name = "NeedleFoundation",
visibility = ["//visibility:public"],
)

swift_binary(
name = "needle",
visibility = ["//visibility:public"],
deps = [
":NeedleLib",
],
)

swift_library(
name = "NeedleLib",
srcs = glob(
[
"Generator/Sources/needle/**/*.swift",
],
allow_empty = False,
),
copts = ["-suppress-warnings"],
module_name = "Needle",
deps = [
":NeedleFramework",
"@SwiftToolsSupportCore//:TSCBasic",
"@UberSwiftCommon//:CommandFramework",
],
)

swift_library(
name = "NeedleFramework",
srcs = glob(
[
"Generator/Sources/NeedleFramework/**/*.swift",
],
allow_empty = False,
),
copts = ["-suppress-warnings"],
module_name = "NeedleFramework",
deps = [
"@SwiftSyntax//:SwiftParser_opt",
"@UberSwiftCommon//:SourceParsingFramework",
"@UberSwiftConcurrency//:Concurrency",
],
)
62 changes: 31 additions & 31 deletions Generator/Sources/NeedleFramework/Entry/Generator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,17 @@ public class Generator {
/// concurrently. `nil` if no limit is set.
/// - throws: `GenericError`.
public final func generate(from sourceRootPaths: [String], withSourcesListFormat sourcesListFormatValue: String? = nil, excludingFilesEndingWith exclusionSuffixes: [String], excludingFilesWithPaths exclusionPaths: [String], with additionalImports: [String], _ headerDocPath: String?, to destinationPath: String, shouldCollectParsingInfo: Bool, parsingTimeout: TimeInterval, exportingTimeout: TimeInterval, retryParsingOnTimeoutLimit: Int, concurrencyLimit: Int?, emitInputsDepsFile: Bool) throws {
let processor: ProcessorType = .generateSource(additionalImports: additionalImports,
headerDocPath: headerDocPath,
destinationPath: destinationPath,
let processor: ProcessorType = .generateSource(additionalImports: additionalImports,
headerDocPath: headerDocPath,
destinationPath: destinationPath,
exportingTimeout: exportingTimeout)
try processSourceCode(from: sourceRootPaths,
withSourcesListFormat: sourcesListFormatValue,
excludingFilesEndingWith: exclusionSuffixes,
excludingFilesWithPaths: exclusionPaths,
shouldCollectParsingInfo: shouldCollectParsingInfo,
parsingTimeout: parsingTimeout,
retryParsingOnTimeoutLimit: retryParsingOnTimeoutLimit,
try processSourceCode(from: sourceRootPaths,
withSourcesListFormat: sourcesListFormatValue,
excludingFilesEndingWith: exclusionSuffixes,
excludingFilesWithPaths: exclusionPaths,
shouldCollectParsingInfo: shouldCollectParsingInfo,
parsingTimeout: parsingTimeout,
retryParsingOnTimeoutLimit: retryParsingOnTimeoutLimit,
concurrencyLimit: concurrencyLimit,
processorType: processor,
emitInputsDepsFile: emitInputsDepsFile)
Expand Down Expand Up @@ -108,22 +108,22 @@ public class Generator {
/// concurrently. `nil` if no limit is set.
/// - throws: `GenericError`.
public final func printDependencyTree(from sourceRootPaths: [String],
withSourcesListFormat sourcesListFormatValue: String? = nil,
excludingFilesEndingWith exclusionSuffixes: [String],
withSourcesListFormat sourcesListFormatValue: String? = nil,
excludingFilesEndingWith exclusionSuffixes: [String],
excludingFilesWithPaths exclusionPaths: [String],
shouldCollectParsingInfo: Bool,
shouldCollectParsingInfo: Bool,
parsingTimeout: TimeInterval,
retryParsingOnTimeoutLimit: Int,
retryParsingOnTimeoutLimit: Int,
concurrencyLimit: Int?,
rootComponentName: String) throws {
let processor: ProcessorType = .printDIStructure(rootComponentName: rootComponentName)
try processSourceCode(from: sourceRootPaths,
withSourcesListFormat: sourcesListFormatValue,
excludingFilesEndingWith: exclusionSuffixes,
excludingFilesWithPaths: exclusionPaths,
shouldCollectParsingInfo: shouldCollectParsingInfo,
parsingTimeout: parsingTimeout,
retryParsingOnTimeoutLimit: retryParsingOnTimeoutLimit,
try processSourceCode(from: sourceRootPaths,
withSourcesListFormat: sourcesListFormatValue,
excludingFilesEndingWith: exclusionSuffixes,
excludingFilesWithPaths: exclusionPaths,
shouldCollectParsingInfo: shouldCollectParsingInfo,
parsingTimeout: parsingTimeout,
retryParsingOnTimeoutLimit: retryParsingOnTimeoutLimit,
concurrencyLimit: concurrencyLimit,
processorType: processor,
emitInputsDepsFile: false)
Expand All @@ -139,7 +139,7 @@ public class Generator {
}

// MARK: - Private

private enum ProcessorType {
case generateSource(additionalImports: [String], headerDocPath: String?, destinationPath: String, exportingTimeout: TimeInterval)
case printDIStructure(rootComponentName: String)
Expand All @@ -154,19 +154,19 @@ public class Generator {
}

private func processSourceCode(from sourceRootPaths: [String],
withSourcesListFormat sourcesListFormatValue: String? = nil,
excludingFilesEndingWith exclusionSuffixes: [String],
excludingFilesWithPaths exclusionPaths: [String],
shouldCollectParsingInfo: Bool,
withSourcesListFormat sourcesListFormatValue: String? = nil,
excludingFilesEndingWith exclusionSuffixes: [String],
excludingFilesWithPaths exclusionPaths: [String],
shouldCollectParsingInfo: Bool,
parsingTimeout: TimeInterval,
retryParsingOnTimeoutLimit: Int,
retryParsingOnTimeoutLimit: Int,
concurrencyLimit: Int?,
processorType: ProcessorType,
emitInputsDepsFile: Bool) throws {
let sourceRootUrls = sourceRootPaths.map { (path: String) -> URL in
URL(path: path)
}

let executor = createExecutor(withName: "Needle.generate", shouldTrackTaskId: shouldCollectParsingInfo, concurrencyLimit: concurrencyLimit)

var retryParsingCount = 0
Expand Down Expand Up @@ -198,9 +198,9 @@ public class Generator {
}

private func printDIStructure(from sourceRootUrls: [URL],
withSourcesListFormat sourcesListFormatValue: String? = nil,
excludingFilesEndingWith exclusionSuffixes: [String],
excludingFilesWithPaths exclusionPaths: [String],
withSourcesListFormat sourcesListFormatValue: String? = nil,
excludingFilesEndingWith exclusionSuffixes: [String],
excludingFilesWithPaths exclusionPaths: [String],
withExecutor executor: SequenceExecutor,
withParsingTimeout parsingTimeout: TimeInterval,
withRootComponentName rootComponentName: String) throws {
Expand Down
24 changes: 14 additions & 10 deletions Generator/Sources/NeedleFramework/Parsing/BaseVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@ class BaseVisitor: SyntaxVisitor {
var varNestingLevel = 0

let filePath: String

init(filePath: String) {
self.filePath = filePath
super.init(viewMode: .sourceAccurate)
}

/// Whether we are parsing the line of code which declares a Component.
/// We need this flag to determine if the generic argument we parse later is for the Component.
var isParsingComponentDeclarationLine: Bool = false

override func visitPost(_ node: FunctionCallExprSyntax) {
if let callexpr = node.calledExpression.firstToken?.text,
let currentEntityName = currentEntityNode?.typeName {
componentToCallExprs[currentEntityName, default: []].insert(callexpr)
}
}

override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind {
varNestingLevel += 1
return .visitChildren
Expand All @@ -71,20 +71,24 @@ class BaseVisitor: SyntaxVisitor {
return Property(name: propertyName, type: propertyType, isInternal: isInternal)
}
}

propertiesDict[currentEntityName, default: []].append(contentsOf: memberProperties)
}

override func visitPost(_ node: ImportDeclSyntax) {
let importStatement = node.withoutTrivia().description.trimmed
imports.append(importStatement)
#if swift(>=5.9)
let importStatement = node.trimmed
#else
let importStatement = node.withoutTrivia()
#endif
imports.append(importStatement.description.trimmed)
}

override func visit(_ node: MemberDeclBlockSyntax) -> SyntaxVisitorContinueKind {
isParsingComponentDeclarationLine = false
return .visitChildren
}

override func visitPost(_ node: SourceFileSyntax) {
if currentEntityNode == nil {
imports = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
import Concurrency
import Foundation
import SourceParsingFramework
#if swift(>=5.6)
#if swift(>=5.9)
import SwiftParser
#elseif swift(>=5.6)
import SwiftSyntaxParser
#else
import SwiftSyntax
Expand All @@ -42,7 +44,11 @@ class ASTProducerTask: AbstractTask<AST> {
/// - returns: The `AST` data model.
/// - throws: Any error occurred during execution.
override func execute() throws -> AST {
#if swift(>=5.9)
let syntax = try Parser.parse(source: sourceContent)
#else
let syntax = try SyntaxParser.parse(sourceUrl)
#endif
return AST(sourceHash: MD5(string: sourceContent), sourceFileSyntax: syntax, filePath: sourceUrl.path)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class DeclarationsParserTask: AbstractTask<DependencyGraphNode> {
// MARK: - Private

private let ast: AST

private func parseSyntax() throws -> ([ASTComponent], [Dependency], [String]) {
let visitor = Visitor(sourceHash: ast.sourceHash, filePath: ast.filePath)
visitor.walk(ast.sourceFileSyntax)
Expand All @@ -56,14 +56,14 @@ class DeclarationsParserTask: AbstractTask<DependencyGraphNode> {
private final class Visitor: BaseVisitor {
private(set) var dependencies: [Dependency] = []
private(set) var components: [ASTComponent] = []

private let sourceHash: String

init(sourceHash: String, filePath: String) {
self.sourceHash = sourceHash
super.init(filePath: filePath)
}

override func visit(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind {
if node.isDependency {
currentEntityNode = node
Expand All @@ -72,7 +72,7 @@ private final class Visitor: BaseVisitor {
return .skipChildren
}
}

override func visitPost(_ node: ProtocolDeclSyntax) {
let protocolName = node.typeName
if protocolName == currentEntityNode?.typeName {
Expand All @@ -82,7 +82,7 @@ private final class Visitor: BaseVisitor {
dependencies.append(dependency)
}
}

override func visit(_ node: ClassDeclSyntax) ->SyntaxVisitorContinueKind {
if node.isComponent {
isParsingComponentDeclarationLine = true
Expand All @@ -92,7 +92,7 @@ private final class Visitor: BaseVisitor {
return .skipChildren
}
}

override func visitPost(_ node: ClassDeclSyntax) {
let componentName = node.typeName
if componentName == currentEntityNode?.typeName {
Expand All @@ -109,12 +109,12 @@ private final class Visitor: BaseVisitor {
components.append(component)
}
}

override func visitPost(_ node: GenericArgumentListSyntax) {
guard isParsingComponentDeclarationLine else {return }
currentDependencyProtocol = node.first?.argumentType.description.trimmed.removingModulePrefix
}

override func visit(_ node: ExtensionDeclSyntax) -> SyntaxVisitorContinueKind {
return .skipChildren
}
Expand Down
Loading

0 comments on commit 5fd4122

Please sign in to comment.