@@ -15,6 +15,7 @@ import PackageModel
1515import SwiftParser
1616import SwiftSyntax
1717import SwiftSyntaxBuilder
18+ import struct TSCUtility. Version
1819
1920/// Add a target to a manifest's source code.
2021public struct AddTarget {
@@ -53,7 +54,7 @@ public struct AddTarget {
5354 target. dependencies. append ( contentsOf: macroTargetDependencies)
5455 }
5556
56- let manifestEdits = try packageCall. appendingToArrayArgument (
57+ var newPackageCall = try packageCall. appendingToArrayArgument (
5758 label: " targets " ,
5859 trailingLabels: Self . argumentLabelsAfterTargets,
5960 newElement: target. asSyntax ( )
@@ -66,7 +67,11 @@ public struct AddTarget {
6667 }
6768
6869 guard let outerDirectory else {
69- return PackageEditResult ( manifestEdits: manifestEdits)
70+ return PackageEditResult (
71+ manifestEdits: [
72+ . replace( packageCall, with: newPackageCall. description)
73+ ]
74+ )
7075 }
7176
7277 let outerPath = try RelativePath ( validating: outerDirectory)
@@ -82,31 +87,47 @@ public struct AddTarget {
8287 )
8388
8489 // Perform any other actions that are needed for this target type.
90+ var extraManifestEdits : [ SourceEdit ] = [ ]
8591 switch target. type {
8692 case . macro:
87- // Macros need a file that introduces the main entrypoint
88- // describing all of the macros.
89- auxiliaryFiles. addSourceFile (
90- path: outerPath. appending (
91- components: [ target. name, " ProvidedMacros.swift " ]
92- ) ,
93- sourceCode: """
94- import SwiftCompilerPlugin
95-
96- @main
97- struct \( raw: target. name) Macros: CompilerPlugin {
98- let providingMacros: [Macro.Type] = [
99- \( raw: target. name) .self,
100- ]
101- }
102- """
93+ addProvidedMacrosSourceFile (
94+ outerPath: outerPath,
95+ target: target,
96+ to: & auxiliaryFiles
10397 )
10498
99+ if !manifest. description. contains ( " swift-syntax " ) {
100+ newPackageCall = try AddPackageDependency
101+ . addPackageDependencyLocal (
102+ . swiftSyntax,
103+ to: newPackageCall
104+ )
105+
106+ // Look for the first import declaration and insert an
107+ // import of `CompilerPluginSupport` there.
108+ let newImport = " import CompilerPluginSupport \n "
109+ for node in manifest. statements {
110+ if let importDecl = node. item. as ( ImportDeclSyntax . self) {
111+ let insertPos = importDecl
112+ . positionAfterSkippingLeadingTrivia
113+ extraManifestEdits. append (
114+ SourceEdit (
115+ range: insertPos..< insertPos,
116+ replacement: newImport
117+ )
118+ )
119+ break
120+ }
121+ }
122+ }
123+
105124 default : break ;
106125 }
107126
108127 return PackageEditResult (
109- manifestEdits: manifestEdits,
128+ manifestEdits: [
129+ . replace( packageCall, with: newPackageCall. description)
130+ ] + extraManifestEdits,
110131 auxiliaryFiles: auxiliaryFiles
111132 )
112133 }
@@ -191,6 +212,30 @@ public struct AddTarget {
191212 sourceCode: sourceFileText
192213 )
193214 }
215+
216+ /// Add a file that introduces the main entrypoint and provided macros
217+ /// for a macro target.
218+ fileprivate static func addProvidedMacrosSourceFile(
219+ outerPath: RelativePath ,
220+ target: TargetDescription ,
221+ to auxiliaryFiles: inout AuxiliaryFiles
222+ ) {
223+ auxiliaryFiles. addSourceFile (
224+ path: outerPath. appending (
225+ components: [ target. name, " ProvidedMacros.swift " ]
226+ ) ,
227+ sourceCode: """
228+ import SwiftCompilerPlugin
229+
230+ @main
231+ struct \( raw: target. name) Macros: CompilerPlugin {
232+ let providingMacros: [Macro.Type] = [
233+ \( raw: target. name) .self,
234+ ]
235+ }
236+ """
237+ )
238+ }
194239}
195240
196241fileprivate extension TargetDescription . Dependency {
@@ -225,3 +270,27 @@ fileprivate let macroTargetDependencies: [TargetDescription.Dependency] = [
225270 . product( name: " SwiftCompilerPlugin " , package : " swift-syntax " ) ,
226271 . product( name: " SwiftSyntaxMacros " , package : " swift-syntax " ) ,
227272]
273+
274+ /// The package dependency for swift-syntax, for use in macros.
275+ fileprivate extension PackageDependency {
276+ /// Source control URL for the swift-syntax package.
277+ static var swiftSyntaxURL : SourceControlURL {
278+ " https://github.com/apple/swift-syntax.git "
279+ }
280+
281+ /// Package dependency on the swift-syntax package.
282+ static var swiftSyntax : PackageDependency {
283+ let swiftSyntaxVersionDefault = InstalledSwiftPMConfiguration
284+ . default
285+ . swiftSyntaxVersionForMacroTemplate
286+ let swiftSyntaxVersion = Version ( swiftSyntaxVersionDefault. description) !
287+
288+ return . sourceControl(
289+ identity: PackageIdentity ( url: swiftSyntaxURL) ,
290+ nameForTargetDependencyResolutionOnly: nil ,
291+ location: . remote( swiftSyntaxURL) ,
292+ requirement: . range( . upToNextMajor( from: swiftSyntaxVersion) ) ,
293+ productFilter: . everything
294+ )
295+ }
296+ }
0 commit comments