diff --git a/Examples/Sources/MacroExamples/Implementation/Expression/SourceLocationMacro.swift b/Examples/Sources/MacroExamples/Implementation/Expression/SourceLocationMacro.swift new file mode 100644 index 00000000000..822913fc9eb --- /dev/null +++ b/Examples/Sources/MacroExamples/Implementation/Expression/SourceLocationMacro.swift @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 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 SwiftSyntax +import SwiftSyntaxMacros + +public struct NativeFileIDMacro: ExpressionMacro { + public static func expansion( + of node: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) -> ExprSyntax { + return context.location( + of: node, + at: .afterLeadingTrivia, + filePathMode: .fileID + )!.file + } +} + +public struct NativeFilePathMacro: ExpressionMacro { + public static func expansion( + of node: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) -> ExprSyntax { + return context.location( + of: node, + at: .afterLeadingTrivia, + filePathMode: .filePath + )!.file + } +} + +public struct NativeLineMacro: ExpressionMacro { + public static func expansion( + of node: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) -> ExprSyntax { + return context.location(of: node)!.line + } +} + +public struct NativeColumnMacro: ExpressionMacro { + public static func expansion( + of node: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) -> ExprSyntax { + return context.location(of: node)!.column + } +} diff --git a/Examples/Sources/MacroExamples/Implementation/Plugin.swift b/Examples/Sources/MacroExamples/Implementation/Plugin.swift index e5960e80712..66375649b10 100644 --- a/Examples/Sources/MacroExamples/Implementation/Plugin.swift +++ b/Examples/Sources/MacroExamples/Implementation/Plugin.swift @@ -31,6 +31,10 @@ struct MyPlugin: CompilerPlugin { FuncUniqueMacro.self, MemberDeprecatedMacro.self, MetaEnumMacro.self, + NativeColumnMacro.self, + NativeFileIDMacro.self, + NativeFilePathMacro.self, + NativeLineMacro.self, NewTypeMacro.self, ObservableMacro.self, ObservablePropertyMacro.self, diff --git a/Examples/Sources/MacroExamples/Interface/SourceLocationMacros.swift b/Examples/Sources/MacroExamples/Interface/SourceLocationMacros.swift new file mode 100644 index 00000000000..baa78caa4be --- /dev/null +++ b/Examples/Sources/MacroExamples/Interface/SourceLocationMacros.swift @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2023 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 +// +//===----------------------------------------------------------------------===// + +@freestanding(expression) +public macro FileID() -> T = + #externalMacro( + module: "MacroExamplesImplementation", + type: "NativeFileIDMacro" + ) + +@freestanding(expression) +public macro FilePath() -> T = + #externalMacro( + module: "MacroExamplesImplementation", + type: "NativeFilePathMacro" + ) + +@freestanding(expression) +public macro Line() -> T = + #externalMacro( + module: "MacroExamplesImplementation", + type: "NativeLineMacro" + ) + +@freestanding(expression) +public macro Column() -> T = + #externalMacro( + module: "MacroExamplesImplementation", + type: "NativeColumnMacro" + ) diff --git a/Examples/Sources/MacroExamples/Playground/SourceLocationMacrosPlayground.swift b/Examples/Sources/MacroExamples/Playground/SourceLocationMacrosPlayground.swift new file mode 100644 index 00000000000..ba07df19118 --- /dev/null +++ b/Examples/Sources/MacroExamples/Playground/SourceLocationMacrosPlayground.swift @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 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 MacroExamplesInterface + +func runSourceLoctionMacrosPlayground() { + print("FileID: \(#FileID as String)") + print("FilePath: \(#FilePath as String)") + print("Line: \(#Line as Int)") + print("Column: \(#Column as Int)") +} diff --git a/Examples/Sources/MacroExamples/Playground/main.swift b/Examples/Sources/MacroExamples/Playground/main.swift index d9af26d3e0e..19ac102630d 100644 --- a/Examples/Sources/MacroExamples/Playground/main.swift +++ b/Examples/Sources/MacroExamples/Playground/main.swift @@ -47,3 +47,7 @@ runMemberMacrosPlayground() // MARK: - Peer Macros runPeerMacrosPlayground() + +// MARK: - SourceLocationMacros + +runSourceLoctionMacrosPlayground() diff --git a/Sources/SwiftCompilerPluginMessageHandling/PluginMacroExpansionContext.swift b/Sources/SwiftCompilerPluginMessageHandling/PluginMacroExpansionContext.swift index 2606d823c7f..db6dfca6546 100644 --- a/Sources/SwiftCompilerPluginMessageHandling/PluginMacroExpansionContext.swift +++ b/Sources/SwiftCompilerPluginMessageHandling/PluginMacroExpansionContext.swift @@ -174,8 +174,9 @@ class SourceManager { let localLocation = base.locationConverter.location(for: localPosition) let positionOffset = base.location.offset + // NOTE '- 1' because base.location.{line|column} are 1-based. let lineOffset = base.location.line - 1 - let columnOffset = localLocation.line == 1 ? base.location.column : 0 + let columnOffset = localLocation.line == 1 ? (base.location.column - 1) : 0 return SourceLocation( // NOTE: IUO because 'localLocation' is created by a location converter