1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import LanguageServerProtocol
import SwiftRefactor
import SwiftSyntax
extension IntegerLiteralExprSyntax.Radix {
static let allCases: [Self] = [.binary, .octal, .decimal, .hex]
}
/// Syntactic code action provider to convert integer literals between
/// different bases.
struct ConvertIntegerLiteral: SyntaxCodeActionProvider {
static func codeActions(in scope: SyntaxCodeActionScope) -> [CodeAction] {
guard
let token = scope.innermostNodeContainingRange,
let integerExpr = token.parent?.as(IntegerLiteralExprSyntax.self),
let integerValue = Int(
integerExpr.split().value.filter { $0 != "_" },
radix: integerExpr.radix.size
)
else {
return []
}
var actions = [CodeAction]()
let currentRadix = integerExpr.radix
for radix in IntegerLiteralExprSyntax.Radix.allCases {
guard radix != currentRadix else {
continue
}
//TODO: Add this to swift-syntax?
let prefix: String
switch radix {
case .binary:
prefix = "0b"
case .octal:
prefix = "0o"
case .hex:
prefix = "0x"
case .decimal:
prefix = ""
}
let convertedValue: ExprSyntax =
"\(raw: prefix)\(raw: String(integerValue, radix: radix.size))"
let edit = TextEdit(
range: scope.snapshot.range(of: integerExpr),
newText: convertedValue.description
)
actions.append(
CodeAction(
title: "Convert \(integerExpr) to \(convertedValue)",
kind: .refactorInline,
edit: WorkspaceEdit(changes: [scope.snapshot.uri: [edit]])
)
)
}
return actions
}
}
|