[swift] Make Macro expansion an expression

Add parser tests
This commit is contained in:
Andreas Dangel
2023-12-11 09:56:18 +01:00
parent 10ae2fae96
commit dbfde44b92
6 changed files with 662 additions and 5 deletions

View File

@ -211,7 +211,6 @@ declaration
| constantDeclaration ';'?
| variableDeclaration ';'?
| typealiasDeclaration ';'?
| macroExpansionExpression ';'?
| functionDeclaration ';'?
| enumDeclaration ';'?
| structDeclaration ';'?
@ -298,10 +297,6 @@ typealiasHead : attributes? accessLevelModifier? 'typealias' typealiasName gener
typealiasName : identifier ;
typealiasAssignment : '=' sType ;
// GRAMMAR OF A MACRO DECLARATION
macroExpansionExpression: '#' identifier genericArgumentClause? functionCallArgumentClause? ;
// GRAMMAR OF A FUNCTION DECLARATION
/* HACK: functionBody? is intentionally not used to force the parser to try and match a functionBody first
@ -601,6 +596,7 @@ primaryExpression
| implicitMemberExpression
// | implicit_member_expression disallow as ambig with explicit member expr in postfix_expression
| wildcardExpression
| macroExpansionExpression
| selectorExpression
| keyPathExpression
;
@ -690,6 +686,11 @@ tupleElement: (identifier ':')? expression ;
wildcardExpression : '_' ;
// GRAMMAR OF A MACRO EXPANSION EXPRESSION
// https://docs.swift.org/swift-book/documentation/the-swift-programming-language/expressions#Macro-Expansion-Expression
// https://github.com/apple/swift-evolution/blob/main/proposals/0382-expression-macros.md#macro-expansion
macroExpansionExpression: '#' identifier genericArgumentClause? functionCallArgumentClause? ;
// GRAMMAR OF A SELECTOR EXPRESSION
selectorExpression

View File

@ -18,4 +18,13 @@ class SwiftParserTests extends BaseSwiftTreeDumpTest {
doTest("BTree");
}
@Test
void swift59() {
doTest("Swift5.9");
}
@Test
void macroExpansions() {
doTest("MacroExpansionExpressions");
}
}

View File

@ -0,0 +1,11 @@
// Samples from https://github.com/apple/swift-evolution/blob/main/proposals/0382-expression-macros.md#macro-expansion
// macro expansion expression with one argument
let _: (Int, String) = #addBlocker(x + y * z)
// macro expansion expressions within macro arguments
let _: (Int, String) = #addBlocker(#stringify(1 + 2))
// default built-in macros
let _: String = #fileID
let _: Int = #line

View File

@ -0,0 +1,207 @@
+- TopLevel
+- Statements
| +- Statement
| | +- Declaration
| | +- ConstantDeclaration
| | +- T-let
| | +- PatternInitializerList
| | +- PatternInitializer
| | +- Pattern
| | | +- WildcardPattern
| | | | +- T-underscore
| | | +- TypeAnnotation
| | | +- T-colon
| | | +- SType
| | | +- TupleType
| | | +- T-lparen
| | | +- TupleTypeElementList
| | | | +- TupleTypeElement
| | | | | +- SType
| | | | | +- TypeIdentifier
| | | | | +- TypeName
| | | | | +- Identifier
| | | | | +- T-Identifier
| | | | +- T-comma
| | | | +- TupleTypeElement
| | | | +- SType
| | | | +- TypeIdentifier
| | | | +- TypeName
| | | | +- Identifier
| | | | +- T-Identifier
| | | +- T-rparen
| | +- Initializer
| | +- T-eq
| | +- Expression
| | +- PrefixExpression
| | +- PostfixExpression
| | +- PrimaryExpression
| | +- MacroExpansionExpression
| | +- T-hash
| | +- Identifier
| | | +- T-Identifier
| | +- FunctionCallArgumentClause
| | +- T-lparen
| | +- FunctionCallArgumentList
| | | +- FunctionCallArgument
| | | +- Expression
| | | +- PrefixExpression
| | | | +- PostfixExpression
| | | | +- PrimaryExpression
| | | | +- Identifier
| | | | +- T-Identifier
| | | +- BinaryExpression
| | | | +- BinaryOperator
| | | | | +- Operator
| | | | | +- OperatorHead
| | | | | +- T-OperatorHead
| | | | +- PrefixExpression
| | | | +- PostfixExpression
| | | | +- PrimaryExpression
| | | | +- Identifier
| | | | +- T-Identifier
| | | +- BinaryExpression
| | | +- BinaryOperator
| | | | +- Operator
| | | | +- OperatorHead
| | | | +- T-star
| | | +- PrefixExpression
| | | +- PostfixExpression
| | | +- PrimaryExpression
| | | +- Identifier
| | | +- T-Identifier
| | +- T-rparen
| +- Statement
| | +- Declaration
| | +- ConstantDeclaration
| | +- T-let
| | +- PatternInitializerList
| | +- PatternInitializer
| | +- Pattern
| | | +- WildcardPattern
| | | | +- T-underscore
| | | +- TypeAnnotation
| | | +- T-colon
| | | +- SType
| | | +- TupleType
| | | +- T-lparen
| | | +- TupleTypeElementList
| | | | +- TupleTypeElement
| | | | | +- SType
| | | | | +- TypeIdentifier
| | | | | +- TypeName
| | | | | +- Identifier
| | | | | +- T-Identifier
| | | | +- T-comma
| | | | +- TupleTypeElement
| | | | +- SType
| | | | +- TypeIdentifier
| | | | +- TypeName
| | | | +- Identifier
| | | | +- T-Identifier
| | | +- T-rparen
| | +- Initializer
| | +- T-eq
| | +- Expression
| | +- PrefixExpression
| | +- PostfixExpression
| | +- PrimaryExpression
| | +- MacroExpansionExpression
| | +- T-hash
| | +- Identifier
| | | +- T-Identifier
| | +- FunctionCallArgumentClause
| | +- T-lparen
| | +- FunctionCallArgumentList
| | | +- FunctionCallArgument
| | | +- Expression
| | | +- PrefixExpression
| | | +- PostfixExpression
| | | +- PrimaryExpression
| | | +- MacroExpansionExpression
| | | +- T-hash
| | | +- Identifier
| | | | +- T-Identifier
| | | +- FunctionCallArgumentClause
| | | +- T-lparen
| | | +- FunctionCallArgumentList
| | | | +- FunctionCallArgument
| | | | +- Expression
| | | | +- PrefixExpression
| | | | | +- PostfixExpression
| | | | | +- PrimaryExpression
| | | | | +- LiteralExpression
| | | | | +- Literal
| | | | | +- NumericLiteral
| | | | | +- IntegerLiteral
| | | | | +- T-DecimalLiteral
| | | | +- BinaryExpression
| | | | +- BinaryOperator
| | | | | +- Operator
| | | | | +- OperatorHead
| | | | | +- T-OperatorHead
| | | | +- PrefixExpression
| | | | +- PostfixExpression
| | | | +- PrimaryExpression
| | | | +- LiteralExpression
| | | | +- Literal
| | | | +- NumericLiteral
| | | | +- IntegerLiteral
| | | | +- T-DecimalLiteral
| | | +- T-rparen
| | +- T-rparen
| +- Statement
| | +- Declaration
| | +- ConstantDeclaration
| | +- T-let
| | +- PatternInitializerList
| | +- PatternInitializer
| | +- Pattern
| | | +- WildcardPattern
| | | | +- T-underscore
| | | +- TypeAnnotation
| | | +- T-colon
| | | +- SType
| | | +- TypeIdentifier
| | | +- TypeName
| | | +- Identifier
| | | +- T-Identifier
| | +- Initializer
| | +- T-eq
| | +- Expression
| | +- PrefixExpression
| | +- PostfixExpression
| | +- PrimaryExpression
| | +- Keyword
| | +- T-directive-file
| +- Statement
| | +- Expression
| | +- PrefixExpression
| | +- PostfixExpression
| | +- PrimaryExpression
| | +- Identifier
| | +- T-Identifier
| +- Statement
| +- Declaration
| +- ConstantDeclaration
| +- T-let
| +- PatternInitializerList
| +- PatternInitializer
| +- Pattern
| | +- WildcardPattern
| | | +- T-underscore
| | +- TypeAnnotation
| | +- T-colon
| | +- SType
| | +- TypeIdentifier
| | +- TypeName
| | +- Identifier
| | +- T-Identifier
| +- Initializer
| +- T-eq
| +- Expression
| +- PrefixExpression
| +- PostfixExpression
| +- PrimaryExpression
| +- Keyword
| +- T-directive-line
+- EOF

View File

@ -0,0 +1,43 @@
import SwiftUI
struct ContentView: View {
var body: some View {
TabBarView()
}
}
#Preview {
ContentView()
}
// Macro Expansion: https://github.com/apple/swift-evolution/blob/main/proposals/0382-expression-macros.md#macro-expansion
let _: Font = #fontLiteral(name: "SF Mono", size: 14, weight: .regular)
// Parameter packs
func all<each Wrapped>(_ optional: repeat (each Wrapped)?) -> (repeat each Wrapped)?
func useAll() {
if let (int, double, string, bool) = all(optionalInt, optionalDouble, optionalString, optionalBool) {
print(int, double, string, bool)
}
else {
print("got a nil")
}
}
// return value on if/else if/else
statusBar.text = if !hasConnection { "Disconnected" }
else if let error = lastError { error.localizedDescription }
else { "Ready" }
// https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/
@attached(member)
@attached(conformance)
public macro OptionSet<RawType>() = #externalMacro(module: "SwiftMacros", type: "OptionSetMacro")
import SwiftUI
#Preview {
Text()
.padding()
}

File diff suppressed because it is too large Load Diff