@@ -16,7 +16,7 @@ import SwiftSyntaxBuilder
16
16
17
17
/// Add a target to a manifest's source code.
18
18
@_spi ( PackageRefactor)
19
- public struct AddPackageTarget : ManifestEditRefactoringProvider {
19
+ public struct AddPackageTarget : EditRefactoringProvider {
20
20
public struct Context {
21
21
public let target : PackageTarget
22
22
public var testHarness : TestHarness
@@ -57,10 +57,10 @@ public struct AddPackageTarget: ManifestEditRefactoringProvider {
57
57
/// Add the given target to the manifest, producing a set of edit results
58
58
/// that updates the manifest and adds some source files to stub out the
59
59
/// new target.
60
- public static func manifestRefactor (
60
+ public static func textRefactor (
61
61
syntax manifest: SourceFileSyntax ,
62
62
in context: Context
63
- ) throws -> PackageEdit {
63
+ ) throws -> [ SourceEdit ] {
64
64
guard let packageCall = manifest. findCall ( calleeName: " Package " ) else {
65
65
throw ManifestEditError . cannotFindPackage
66
66
}
@@ -86,44 +86,10 @@ public struct AddPackageTarget: ManifestEditRefactoringProvider {
86
86
newElement: target. asSyntax ( )
87
87
)
88
88
89
- let outerDirectory : String ?
90
- switch target. type {
91
- case . binary, . plugin, . system: outerDirectory = nil
92
- case . executable, . library, . macro: outerDirectory = " Sources "
93
- case . test: outerDirectory = " Tests "
94
- }
95
-
96
- guard let outerDirectory else {
97
- return PackageEdit (
98
- manifestEdits: [
99
- . replace( packageCall, with: newPackageCall. description)
100
- ]
101
- )
102
- }
103
-
104
- let outerPath = outerDirectory
105
-
106
- /// The set of auxiliary files this refactoring will create.
107
- var auxiliaryFiles : AuxiliaryFiles = [ ]
108
-
109
- // Add the primary source file. Every target type has this.
110
- addPrimarySourceFile (
111
- outerPath: outerPath,
112
- target: target,
113
- in: context,
114
- to: & auxiliaryFiles
115
- )
116
-
117
89
// Perform any other actions that are needed for this target type.
118
90
var extraManifestEdits : [ SourceEdit ] = [ ]
119
91
switch target. type {
120
92
case . macro:
121
- addProvidedMacrosSourceFile (
122
- outerPath: outerPath,
123
- target: target,
124
- to: & auxiliaryFiles
125
- )
126
-
127
93
if !manifest. containsStringLiteral ( " swift-syntax " ) {
128
94
newPackageCall =
129
95
try AddPackageDependency
@@ -153,159 +119,9 @@ public struct AddPackageTarget: ManifestEditRefactoringProvider {
153
119
default : break
154
120
}
155
121
156
- return PackageEdit (
157
- manifestEdits: [
158
- . replace( packageCall, with: newPackageCall. description)
159
- ] + extraManifestEdits,
160
- auxiliaryFiles: auxiliaryFiles
161
- )
162
- }
163
-
164
- /// Add the primary source file for a target to the list of auxiliary
165
- /// source files.
166
- fileprivate static func addPrimarySourceFile(
167
- outerPath: String ,
168
- target: PackageTarget ,
169
- in context: Context ,
170
- to auxiliaryFiles: inout AuxiliaryFiles
171
- ) {
172
- let sourceFilePath = " \( outerPath) / \( target. name) / \( target. name) .swift "
173
-
174
- // Introduce imports for each of the dependencies that were specified.
175
- var importModuleNames = target. dependencies. map {
176
- $0. name
177
- }
178
-
179
- // Add appropriate test module dependencies.
180
- if target. type == . test {
181
- switch context. testHarness {
182
- case . none:
183
- break
184
-
185
- case . xctest:
186
- importModuleNames. append ( " XCTest " )
187
-
188
- case . swiftTesting:
189
- importModuleNames. append ( " Testing " )
190
- }
191
- }
192
-
193
- let importDecls = importModuleNames. lazy. sorted ( ) . map { name in
194
- DeclSyntax ( " import \( raw: name) \n " )
195
- }
196
-
197
- let imports = CodeBlockItemListSyntax {
198
- for importDecl in importDecls {
199
- importDecl
200
- }
201
- }
202
-
203
- let sourceFileText : SourceFileSyntax
204
- switch target. type {
205
- case . binary, . plugin, . system:
206
- fatalError ( " should have exited above " )
207
-
208
- case . macro:
209
- sourceFileText = """
210
- \( imports)
211
- struct \( raw: target. sanitizedName) : Macro {
212
- /// TODO: Implement one or more of the protocols that inherit
213
- /// from Macro. The appropriate macro protocol is determined
214
- /// by the " macro " declaration that \( raw: target. sanitizedName) implements.
215
- /// Examples include:
216
- /// @freestanding(expression) macro --> ExpressionMacro
217
- /// @attached(member) macro --> MemberMacro
218
- }
219
- """
220
-
221
- case . test:
222
- switch context. testHarness {
223
- case . none:
224
- sourceFileText = """
225
- \( imports)
226
- // Test code here
227
- """
228
-
229
- case . xctest:
230
- sourceFileText = """
231
- \( imports)
232
- class \( raw: target. sanitizedName) Tests: XCTestCase {
233
- func test \( raw: target. sanitizedName) () {
234
- XCTAssertEqual(42, 17 + 25)
235
- }
236
- }
237
- """
238
-
239
- case . swiftTesting:
240
- sourceFileText = """
241
- \( imports)
242
- @Suite
243
- struct \( raw: target. sanitizedName) Tests {
244
- @Test( " \( raw: target. sanitizedName) tests " )
245
- func example() {
246
- #expect(42 == 17 + 25)
247
- }
248
- }
249
- """
250
- }
251
-
252
- case . library:
253
- sourceFileText = """
254
- \( imports)
255
- """
256
-
257
- case . executable:
258
- sourceFileText = """
259
- \( imports)
260
- @main
261
- struct \( raw: target. sanitizedName) Main {
262
- static func main() {
263
- print( " Hello, world " )
264
- }
265
- }
266
- """
267
- }
268
-
269
- auxiliaryFiles. addSourceFile (
270
- path: sourceFilePath,
271
- sourceCode: sourceFileText
272
- )
273
- }
274
-
275
- /// Add a file that introduces the main entrypoint and provided macros
276
- /// for a macro target.
277
- fileprivate static func addProvidedMacrosSourceFile(
278
- outerPath: String ,
279
- target: PackageTarget ,
280
- to auxiliaryFiles: inout AuxiliaryFiles
281
- ) {
282
- auxiliaryFiles. addSourceFile (
283
- path: " \( outerPath) / \( target. name) /ProvidedMacros.swift " ,
284
- sourceCode: """
285
- import SwiftCompilerPlugin
286
-
287
- @main
288
- struct \( raw: target. sanitizedName) Macros: CompilerPlugin {
289
- let providingMacros: [Macro.Type] = [
290
- \( raw: target. sanitizedName) .self,
291
- ]
292
- }
293
- """
294
- )
295
- }
296
- }
297
-
298
- /// The array of auxiliary files that can be added by a package editing
299
- /// operation.
300
- private typealias AuxiliaryFiles = [ ( String , SourceFileSyntax ) ]
301
-
302
- fileprivate extension AuxiliaryFiles {
303
- /// Add a source file to the list of auxiliary files.
304
- mutating func addSourceFile(
305
- path: String ,
306
- sourceCode: SourceFileSyntax
307
- ) {
308
- self . append ( ( path, sourceCode) )
122
+ return [
123
+ . replace( packageCall, with: newPackageCall. description)
124
+ ] + extraManifestEdits
309
125
}
310
126
}
311
127
0 commit comments