Skip to content

Commit 1aa14e6

Browse files
DougGregorxedin
authored andcommitted
Implement a better "contains string literal" check for a source file
1 parent 11649fd commit 1aa14e6

File tree

1 file changed

+53
-25
lines changed

1 file changed

+53
-25
lines changed

Sources/SwiftRefactor/PackageManifest/AddTarget.swift

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -144,32 +144,30 @@ public struct AddTarget: ManifestEditRefactoringProvider {
144144
to: &auxiliaryFiles
145145
)
146146

147-
if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) {
148-
if manifest.description.firstRange(of: "swift-syntax") == nil {
149-
newPackageCall =
150-
try AddPackageDependency
151-
.addPackageDependencyLocal(
152-
.swiftSyntax(
153-
version: configuration.swiftSyntaxVersion
154-
),
155-
to: newPackageCall
156-
)
157-
158-
// Look for the first import declaration and insert an
159-
// import of `CompilerPluginSupport` there.
160-
let newImport = "import CompilerPluginSupport\n"
161-
for node in manifest.statements {
162-
if let importDecl = node.item.as(ImportDeclSyntax.self) {
163-
let insertPos = importDecl
164-
.positionAfterSkippingLeadingTrivia
165-
extraManifestEdits.append(
166-
SourceEdit(
167-
range: insertPos..<insertPos,
168-
replacement: newImport
169-
)
147+
if !manifest.containsStringLiteral("swift-syntax") {
148+
newPackageCall =
149+
try AddPackageDependency
150+
.addPackageDependencyLocal(
151+
.swiftSyntax(
152+
version: configuration.swiftSyntaxVersion
153+
),
154+
to: newPackageCall
155+
)
156+
157+
// Look for the first import declaration and insert an
158+
// import of `CompilerPluginSupport` there.
159+
let newImport = "import CompilerPluginSupport\n"
160+
for node in manifest.statements {
161+
if let importDecl = node.item.as(ImportDeclSyntax.self) {
162+
let insertPos = importDecl
163+
.positionAfterSkippingLeadingTrivia
164+
extraManifestEdits.append(
165+
SourceEdit(
166+
range: insertPos..<insertPos,
167+
replacement: newImport
170168
)
171-
break
172-
}
169+
)
170+
break
173171
}
174172
}
175173
}
@@ -388,3 +386,33 @@ fileprivate extension TargetDescription {
388386
fileprivate extension String {
389387
func localizedFirstWordCapitalized() -> String { prefix(1).uppercased() + dropFirst() }
390388
}
389+
390+
extension SourceFileSyntax {
391+
private class ContainsLiteralVisitor: SyntaxVisitor {
392+
let string: String
393+
var found: Bool = false
394+
395+
init(string: String) {
396+
self.string = string
397+
super.init(viewMode: .sourceAccurate)
398+
}
399+
400+
override func visit(_ node: StringLiteralExprSyntax) -> SyntaxVisitorContinueKind {
401+
if let representedLiteralValue = node.representedLiteralValue,
402+
representedLiteralValue == string
403+
{
404+
found = true
405+
}
406+
407+
return .skipChildren
408+
}
409+
}
410+
411+
/// Determine whether this source file contains a string literal
412+
/// matching the given contents.
413+
fileprivate func containsStringLiteral(_ contents: String) -> Bool {
414+
let visitor = ContainsLiteralVisitor(string: contents)
415+
visitor.walk(self)
416+
return visitor.found
417+
}
418+
}

0 commit comments

Comments
 (0)