Files
swift-mirror/test/Macros/member_attribute_macro_availability.swift
Allan Shortlidge 608e8693ab AST: Note the attribute that makes a declaration unavailable.
Previously, the compiler would emit a note pointing to the unavailable
declaration and highlight the range of the attribute that makes the decl
unavailable. Unfortunately the highlight is rarely rendered because most
frontends only show highlights that are on the same line as the location
pointed to by the diagnostic and `@available` is not usually written on the
same line as the declaration it is attached to. Switch to pointing to the
attribute itself so that this crucial information is always rendered.
2026-08-11 08:03:18 -07:00

50 lines
1.8 KiB
Swift

// REQUIRES: swift_swift_parser
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// Build the macro plugin.
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %t/macro.swift -g -no-toolchain-stdlib-rpath
// RUN: %target-swift-frontend -typecheck -verify -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) %t/test.swift
//--- macro.swift
import SwiftSyntax
import SwiftSyntaxMacros
/// Attaches `@available(*, unavailable)` to every member of the annotated type.
public struct UnavailableMembersMacro: MemberAttributeMacro {
public static func expansion(
of node: AttributeSyntax,
attachedTo decl: some DeclGroupSyntax,
providingAttributesFor member: some DeclSyntaxProtocol,
in context: some MacroExpansionContext
) throws -> [AttributeSyntax] {
["@available(*, unavailable, message: \"unavailable via macro\")"]
}
}
//--- test.swift
@attached(memberAttribute)
macro UnavailableMembers() = #externalMacro(module: "MacroDefinition", type: "UnavailableMembersMacro")
@UnavailableMembers
// expected-note@-1 {{in expansion of macro 'UnavailableMembers' on instance method 'member()' here}}
class Base {
func member() {} // expected-note {{'member()' has been explicitly marked unavailable here}}
/*
expected-expansion@-2:3{{
expected-note@1{{'member()' has been explicitly marked unavailable here}}
}}
*/
}
class Sub: Base {
override func member() {} // expected-error {{cannot override 'member' which has been marked unavailable: unavailable via macro}}
// expected-note@-1 {{remove 'override' modifier to declare a new 'member'}}
}
func useBaseMember(_ b: Base) {
b.member() // expected-error {{'member()' is unavailable: unavailable via macro}}
}