Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# Order is important. The last matching pattern has the most precedence.

# Owner of anything in SwiftSyntax not owned by anyone else.
* @ahoppen @bnbarham
* @ahoppen @bnbarham @hamishknight @rintaro

# Macros
/Sources/SwiftSyntaxMacros @DougGregor
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- run: |
if [[ "${{ github.triggering_actor }}" != "ahoppen" ]]; then
if [[ "${{ github.triggering_actor }}" != "bnbarham" ]]; then
echo "${{ github.triggering_actor }} is not allowed to create a release"
exit 1
fi
Expand Down
9 changes: 2 additions & 7 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
name: Pull request

# PRs created by GitHub Actions don't kick off further actions (https://github.com/peter-evans/create-pull-request/blob/d57e551ebc1a16dee0b8c9ea6d24dba7627a6e35/docs/concepts-guidelines.md#triggering-further-workflow-runs).
# As a workaround, we mark automerge PRs that are created by GitHub actions as draft and trigger the GitHub actions by marking the PR as ready for review. We'd prefer not re-triggering testing on a normal user's PR in this case, but skipping them causes the checks to reset.
on:
pull_request:
types: [opened, reopened, synchronize, ready_for_review]
Expand All @@ -11,20 +13,15 @@ concurrency:
jobs:
tests:
name: Test
# PRs created by GitHub Actions don't kick off further actions (https://github.com/peter-evans/create-pull-request/blob/d57e551ebc1a16dee0b8c9ea6d24dba7627a6e35/docs/concepts-guidelines.md#triggering-further-workflow-runs).
# As a workaround, we mark automerge PRs that are created by GitHub actions as draft and trigger the GitHub actions by marking the PR as ready for review. But we don't want to re-trigger testing this when a normal user's PR is marked as ready for review.
if: (github.event.action != 'ready_for_review') || (github.event.action == 'ready_for_review' && github.event.pull_request.user.login == 'github-actions[bot]')
uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main
soundness:
name: Soundness
if: (github.event.action != 'ready_for_review') || (github.event.action == 'ready_for_review' && github.event.pull_request.user.login == 'github-actions[bot]')
uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main
with:
api_breakage_check_enabled: false # https://github.com/swiftlang/swift-syntax/issues/3010
docs_check_additional_arguments: "--disable-parameters-and-returns-validation"
verify_source_code:
name: Validate generated code
if: (github.event.action != 'ready_for_review') || (github.event.action == 'ready_for_review' && github.event.pull_request.user.login == 'github-actions[bot]')
runs-on: ubuntu-latest
container:
image: swift:latest
Expand All @@ -37,7 +34,6 @@ jobs:
run: "./swift-syntax-dev-utils verify-source-code --toolchain /usr"
test_using_swift_syntax_dev_utils_linux:
name: Run tests using swift-syntax-dev-utils (Linux)
if: (github.event.action != 'ready_for_review') || (github.event.action == 'ready_for_review' && github.event.pull_request.user.login == 'github-actions[bot]')
runs-on: ubuntu-latest
container:
image: swift:latest
Expand All @@ -50,7 +46,6 @@ jobs:
run: "./swift-syntax-dev-utils test --enable-rawsyntax-validation --enable-test-fuzzing --toolchain /usr"
test_using_swift_syntax_dev_utils_windows:
name: Run tests using swift-syntax-dev-utils (Windows)
if: (github.event.action != 'ready_for_review') || (github.event.action == 'ready_for_review' && github.event.pull_request.user.login == 'github-actions[bot]')
runs-on: windows-2022
steps:
- name: Pull Docker image
Expand Down
22 changes: 19 additions & 3 deletions CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ public let ATTRIBUTE_NODES: [Node] = [
// Special arguments for keyword decl name e.g. 'subscript(_:)', and availability arguments.
kind: .node(kind: .specializeAttributeArgumentList)
),
Child(
name: "specializedArguments",
// Special arguments for generic where clause.
kind: .node(kind: .specializedAttributeArgument)
),
Child(
name: "objCName",
// Special arguments for Objective-C names. e.g. 'methodNameWithArg1:Arg2:'
Expand Down Expand Up @@ -122,8 +127,7 @@ public let ATTRIBUTE_NODES: [Node] = [
Child(
name: "abiArguments",
// Special arguments for declaration syntax. e.g. @abi(func abiName() -> Int)
kind: .node(kind: .abiAttributeArguments),
experimentalFeature: .abiAttribute
kind: .node(kind: .abiAttributeArguments)
),
]),
documentation: """
Expand Down Expand Up @@ -256,7 +260,6 @@ public let ATTRIBUTE_NODES: [Node] = [
Node(
kind: .abiAttributeArguments,
base: .syntax,
experimentalFeature: .abiAttribute,
nameForDiagnostics: "ABI-providing declaration",
documentation: "The arguments of the '@abi' attribute",
children: [
Expand Down Expand Up @@ -719,6 +722,19 @@ public let ATTRIBUTE_NODES: [Node] = [
]
),

Node(
kind: .specializedAttributeArgument,
base: .syntax,
nameForDiagnostics: "argument to '@specialized",
documentation: "The generic where clause for the `@specialized` attribute",
children: [
Child(
name: "genericWhereClause",
kind: .node(kind: .genericWhereClause)
)
]
),

Node(
kind: .specializeTargetFunctionArgument,
base: .syntax,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public enum ExperimentalFeature: String, CaseIterable {
case nonescapableTypes
case trailingComma
case coroutineAccessors
case abiAttribute
case keypathWithMethodMembers
case oldOwnershipOperatorSpellings
case inlineArrayTypeSugar
Expand All @@ -39,8 +38,6 @@ public enum ExperimentalFeature: String, CaseIterable {
return "TrailingComma"
case .coroutineAccessors:
return "CoroutineAccessors"
case .abiAttribute:
return "ABIAttribute"
case .keypathWithMethodMembers:
return "KeypathWithMethodMembers"
case .oldOwnershipOperatorSpellings:
Expand All @@ -65,8 +62,6 @@ public enum ExperimentalFeature: String, CaseIterable {
return "trailing commas"
case .coroutineAccessors:
return "coroutine accessors"
case .abiAttribute:
return "@abi attribute"
case .keypathWithMethodMembers:
return "keypaths with method members"
case .oldOwnershipOperatorSpellings:
Expand Down
8 changes: 4 additions & 4 deletions CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public enum Keyword: CaseIterable {
case _PackageDescription
case _read
case _RefCountedObject
case specialized
case _specialize
case _spi_available
case _Trivial
Expand Down Expand Up @@ -275,7 +276,6 @@ public enum Keyword: CaseIterable {
case `while`
case willSet
case wrt
case x
case yield

public var spec: KeywordSpec {
Expand Down Expand Up @@ -340,6 +340,8 @@ public enum Keyword: CaseIterable {
return KeywordSpec("_read")
case ._RefCountedObject:
return KeywordSpec("_RefCountedObject")
case .specialized:
return KeywordSpec("specialized")
case ._specialize:
return KeywordSpec("_specialize")
case ._spi_available:
Expand All @@ -357,7 +359,7 @@ public enum Keyword: CaseIterable {
case ._version:
return KeywordSpec("_version")
case .abi:
return KeywordSpec("abi", experimentalFeature: .abiAttribute)
return KeywordSpec("abi")
case .accesses:
return KeywordSpec("accesses")
case .actor:
Expand Down Expand Up @@ -682,8 +684,6 @@ public enum Keyword: CaseIterable {
return KeywordSpec("willSet")
case .wrt:
return KeywordSpec("wrt")
case .x:
return KeywordSpec("x", experimentalFeature: .inlineArrayTypeSugar)
case .yield:
return KeywordSpec("yield")
}
Expand Down
2 changes: 2 additions & 0 deletions CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon
case simpleStringLiteralSegmentList
case someOrAnyType
case sourceFile
case specializedAttributeArgument
case specializeAttributeArgumentList
case specializeAvailabilityArgument
case specializeTargetFunctionArgument
Expand Down Expand Up @@ -454,6 +455,7 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon
case .someOrAnyType: return "constrainedSugarType"
case .simpleTypeSpecifier: return "typeSpecifier"
case .specializeAttributeArgumentList: return "specializeAttributeSpecList"
case .specializedAttributeArgument: return "specializedAttribute"
case .specializeAvailabilityArgument: return "availabilityEntry"
case .specializeTargetFunctionArgument: return "targetFunctionEntry"
case .stringLiteralSegmentList: return "stringLiteralSegments"
Expand Down
6 changes: 3 additions & 3 deletions CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ public let TYPE_NODES: [Node] = [
base: .type,
experimentalFeature: .inlineArrayTypeSugar,
nameForDiagnostics: "inline array type",
documentation: "An inline array type `[3 x Int]`, sugar for `InlineArray<3, Int>`.",
documentation: "An inline array type `[3 of Int]`, sugar for `InlineArray<3, Int>`.",
children: [
Child(
name: "leftSquare",
Expand All @@ -317,12 +317,12 @@ public let TYPE_NODES: [Node] = [
documentation: """
The `count` argument for the inline array type.

- Note: In semantically valid Swift code, this is always an integer or a wildcard type, e.g `_` in `[_ x Int]`.
- Note: In semantically valid Swift code, this is always an integer or a wildcard type, e.g `_` in `[_ of Int]`.
"""
),
Child(
name: "separator",
kind: .token(choices: [.keyword(.x)])
kind: .token(choices: [.keyword(.of)])
),
Child(
name: "element",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,11 @@ class ValidateSyntaxNodes: XCTestCase {
message:
"child 'defaultKeyword' has a single keyword as its only token choice and is followed by a colon. It should thus be named 'defaultLabel'"
),
// 'separator' is more descriptive than 'xKeyword'
// 'separator' is more descriptive than 'ofKeyword'
ValidationFailure(
node: .inlineArrayType,
message: "child 'separator' has a single keyword as its only token choice and should thus be named 'xKeyword'"
message:
"child 'separator' has a single keyword as its only token choice and should thus be named 'ofKeyword'"
),
]
)
Expand Down
36 changes: 20 additions & 16 deletions Sources/SwiftParser/Attributes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extension Parser {
case _effects
case _implements
case _originallyDefinedIn
case specialized
case _specialize
case _spi_available
case `rethrows`
Expand All @@ -63,6 +64,7 @@ extension Parser {
case TokenSpec(._effects): self = ._effects
case TokenSpec(._implements): self = ._implements
case TokenSpec(._originallyDefinedIn): self = ._originallyDefinedIn
case TokenSpec(.specialized): self = .specialized
case TokenSpec(._specialize): self = ._specialize
case TokenSpec(._spi_available): self = ._spi_available
case TokenSpec(.`rethrows`): self = .rethrows
Expand All @@ -89,6 +91,7 @@ extension Parser {
case ._effects: return .keyword(._effects)
case ._implements: return .keyword(._implements)
case ._originallyDefinedIn: return .keyword(._originallyDefinedIn)
case .specialized: return .keyword(.specialized)
case ._specialize: return .keyword(._specialize)
case ._spi_available: return .keyword(._spi_available)
case .`rethrows`: return .keyword(.rethrows)
Expand Down Expand Up @@ -230,9 +233,9 @@ extension Parser {
switch peek(isAtAnyIn: DeclarationAttributeWithSpecialSyntax.self) {
case .abi:
return parseAttribute(argumentMode: .required) { parser in
return parser.parseABIAttributeArguments()
return (nil, .abiArguments(parser.parseABIAttributeArguments()))
} parseMissingArguments: { parser in
return parser.parseABIAttributeArguments(missingLParen: true)
return (nil, .abiArguments(parser.parseABIAttributeArguments(missingLParen: true)))
}
case .available, ._spi_available:
return parseAttribute(argumentMode: .required) { parser in
Expand All @@ -254,6 +257,10 @@ extension Parser {
return parseAttribute(argumentMode: .optional) { parser in
return (nil, .objCName(parser.parseObjectiveCSelector()))
}
case .specialized:
return parseAttribute(argumentMode: .required) { parser in
return (nil, .specializedArguments(parser.parseSpecializedAttributeArgument()))
}
case ._specialize:
return parseAttribute(argumentMode: .required) { parser in
return (nil, .specializeArguments(parser.parseSpecializeAttributeArgumentList()))
Expand Down Expand Up @@ -645,6 +652,11 @@ extension Parser {
}

extension Parser {
mutating func parseSpecializedAttributeArgument() -> RawSpecializedAttributeArgumentSyntax {
let whereClause = self.parseGenericWhereClause()
return RawSpecializedAttributeArgumentSyntax(genericWhereClause: whereClause, arena: self.arena)
}

mutating func parseSpecializeAttributeArgumentList() -> RawSpecializeAttributeArgumentListSyntax {
var elements = [RawSpecializeAttributeArgumentListSyntax.Element]()
// Parse optional "exported" and "kind" labeled parameters.
Expand Down Expand Up @@ -794,9 +806,9 @@ extension Parser {
/// - Parameter missingLParen: `true` if the opening paren for the argument list was missing.
mutating func parseABIAttributeArguments(
missingLParen: Bool = false
) -> (RawUnexpectedNodesSyntax?, RawAttributeSyntax.Arguments) {
func makeMissingProviderArguments(unexpectedBefore: [RawSyntax]) -> RawAttributeSyntax.Arguments {
let args = RawABIAttributeArgumentsSyntax(
) -> RawABIAttributeArgumentsSyntax {
func makeMissingProviderArguments(unexpectedBefore: [RawSyntax]) -> RawABIAttributeArgumentsSyntax {
return RawABIAttributeArgumentsSyntax(
provider: .missing(
RawMissingDeclSyntax(
unexpectedBefore.isEmpty ? nil : RawUnexpectedNodesSyntax(elements: unexpectedBefore, arena: self.arena),
Expand All @@ -808,7 +820,6 @@ extension Parser {
),
arena: self.arena
)
return .abiArguments(args)
}

// Consider the three kinds of mistakes we might see here:
Expand All @@ -824,23 +835,16 @@ extension Parser {
// In lieu of that, we judge that recovering gracefully from #3 is more important than #2 and therefore do not even
// attempt to parse the argument unless we've seen a left paren.
guard !missingLParen && !self.at(.rightParen) else {
return (nil, makeMissingProviderArguments(unexpectedBefore: []))
return makeMissingProviderArguments(unexpectedBefore: [])
}

let decl = parseDeclaration(in: .argumentList)

guard experimentalFeatures.contains(.abiAttribute) else {
return (
RawUnexpectedNodesSyntax([decl], arena: self.arena),
.argumentList(RawLabeledExprListSyntax(elements: [], arena: self.arena))
)
}

guard let provider = RawABIAttributeArgumentsSyntax.Provider(decl) else {
return (nil, makeMissingProviderArguments(unexpectedBefore: [decl.raw]))
return makeMissingProviderArguments(unexpectedBefore: [decl.raw])
}

return (nil, .abiArguments(RawABIAttributeArgumentsSyntax(provider: provider, arena: self.arena)))
return RawABIAttributeArgumentsSyntax(provider: provider, arena: self.arena)
}
}

Expand Down
5 changes: 5 additions & 0 deletions Sources/SwiftParser/Nominals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,11 @@ extension Parser {
arena: self.arena
)
)

// If this was a trailing comma, there are no more elements
if at(prefix: ">") {
break
}
} while keepGoing != nil && self.hasProgressed(&loopProgress)
}
let rangle = self.expectWithoutRecovery(prefix: ">", as: .rightAngle)
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftParser/TokenPrecedence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ enum TokenPrecedence: Comparable {
._effects,
._implements,
._originallyDefinedIn,
.specialized,
._specialize,
._spi_available,
.abi,
Expand Down Expand Up @@ -344,7 +345,6 @@ enum TokenPrecedence: Comparable {
.visibility,
.weak,
.wrt,
.x,
.unsafe:
self = .exprKeyword
#if RESILIENT_LIBRARIES
Expand Down
Loading