diff --git a/.swiftlint.yml b/.swiftlint.yml index 8481cde..91eed35 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -111,6 +111,10 @@ identifier_name: excluded: - id - no +type_name: + excluded: + - If + - Do excluded: - DerivedData - .build diff --git a/Examples/Completed/concurrency/code.swift b/Examples/Completed/concurrency/code.swift new file mode 100644 index 0000000..1be74cb --- /dev/null +++ b/Examples/Completed/concurrency/code.swift @@ -0,0 +1,42 @@ +enum VendingMachineError: Error { + case invalidSelection + case insufficientFunds(coinsNeeded: Int) + case outOfStock +} + +class VendingMachine { + var inventory = [ + "Candy Bar": Item(price: 12, count: 7), + "Chips": Item(price: 10, count: 4), + "Pretzels": Item(price: 7, count: 11) + ] + var coinsDeposited = 0 + + + func vend(itemNamed name: String) throws { + guard let item = inventory[name] else { + throw VendingMachineError.invalidSelection + } + + + guard item.count > 0 else { + throw VendingMachineError.outOfStock + } + + + guard item.price <= coinsDeposited else { + throw VendingMachineError.insufficientFunds(coinsNeeded: item.price - coinsDeposited) + } + + + coinsDeposited -= item.price + + + var newItem = item + newItem.count -= 1 + inventory[name] = newItem + + + print("Dispensing \(name)") + } +} \ No newline at end of file diff --git a/Examples/Completed/concurrency/dsl.swift b/Examples/Completed/concurrency/dsl.swift new file mode 100644 index 0000000..300a460 --- /dev/null +++ b/Examples/Completed/concurrency/dsl.swift @@ -0,0 +1,48 @@ +Enum("VendingMachineError") { + Case("invalidSelection") + Case("insufficientFunds").associatedValue("coinsNeeded", type: "Int") + Case("outOfStock") +} + +Class("VendingMachine") { + Variable(.var, name: "inventory", equals: Literal.dictionary(Dictionary(uniqueKeysWithValues: [ + ("Candy Bar", Item(price: 12, count: 7)), + ("Chips", Item(price: 10, count: 4)), + ("Pretzels", Item(price: 7, count: 11)) + ]))) + Variable(.var, name: "coinsDeposited", equals: 0) + + Function("vend"){ + Parameter("name", labeled: "itemNamed", type: "String") + } _: { + Guard("let item = inventory[itemNamed]") else: { + Throw( + EnumValue("VendingMachineError", case: "invalidSelection") + ) + } + Guard("item.count > 0") else: { + Throw( + EnumValue("VendingMachineError", case: "outOfStock") + ) + } + Guard("item.price <= coinsDeposited") else: { + Throw( + EnumValue("VendingMachineError", case: "insufficientFunds"){ + ParameterExp("coinsNeeded", value: Infix("-"){ + VariableExp("item").property("price") + VariableExp("coinsDeposited") + }) + } + ) + } + Infix("-=", "coinsDeposited", VariableExp("item").property("price")) + Variable("newItem", equals: VariableExp("item")) + Infix("-=", "newItem.count", 1) + Assignment("inventory[itemNamed]", .ref("newItem")) + Call("print", "Dispensing \\(itemNamed)") + } +} + + + + diff --git a/Examples/Completed/concurrency/syntax.json b/Examples/Completed/concurrency/syntax.json new file mode 100644 index 0000000..b514de5 --- /dev/null +++ b/Examples/Completed/concurrency/syntax.json @@ -0,0 +1 @@ +[{"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeShebang"},{"value":{"text":"nil"},"name":"shebang"},{"value":{"text":"nil"},"name":"unexpectedBetweenShebangAndStatements"},{"value":{"text":"CodeBlockItemListSyntax"},"ref":"CodeBlockItemListSyntax","name":"statements"},{"value":{"text":"nil"},"name":"unexpectedBetweenStatementsAndEndOfFileToken"},{"value":{"text":"","kind":"endOfFile"},"name":"endOfFileToken"},{"value":{"text":"nil"},"name":"unexpectedAfterEndOfFileToken"}],"text":"SourceFile","type":"other","id":0,"range":{"endRow":42,"endColumn":2,"startRow":1,"startColumn":1}},{"id":1,"type":"collection","text":"CodeBlockItemList","parent":0,"range":{"endRow":42,"startRow":1,"startColumn":1,"endColumn":2},"structure":[{"value":{"text":"CodeBlockItemSyntax"},"name":"Element"},{"value":{"text":"2"},"name":"Count"}]},{"id":2,"type":"other","text":"CodeBlockItem","parent":1,"range":{"startColumn":1,"endRow":5,"startRow":1,"endColumn":2},"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","value":{"text":"EnumDeclSyntax"},"ref":"EnumDeclSyntax"},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"id":3,"type":"decl","text":"EnumDecl","parent":2,"range":{"startRow":1,"endColumn":2,"startColumn":1,"endRow":5},"structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"ref":"AttributeListSyntax","name":"attributes","value":{"text":"AttributeListSyntax"}},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"ref":"DeclModifierListSyntax","name":"modifiers","value":{"text":"DeclModifierListSyntax"}},{"name":"unexpectedBetweenModifiersAndEnumKeyword","value":{"text":"nil"}},{"name":"enumKeyword","value":{"text":"enum","kind":"keyword(SwiftSyntax.Keyword.enum)"}},{"name":"unexpectedBetweenEnumKeywordAndName","value":{"text":"nil"}},{"name":"name","value":{"text":"VendingMachineError","kind":"identifier("VendingMachineError")"}},{"name":"unexpectedBetweenNameAndGenericParameterClause","value":{"text":"nil"}},{"name":"genericParameterClause","value":{"text":"nil"}},{"name":"unexpectedBetweenGenericParameterClauseAndInheritanceClause","value":{"text":"nil"}},{"ref":"InheritanceClauseSyntax","name":"inheritanceClause","value":{"text":"InheritanceClauseSyntax"}},{"name":"unexpectedBetweenInheritanceClauseAndGenericWhereClause","value":{"text":"nil"}},{"name":"genericWhereClause","value":{"text":"nil"}},{"name":"unexpectedBetweenGenericWhereClauseAndMemberBlock","value":{"text":"nil"}},{"ref":"MemberBlockSyntax","name":"memberBlock","value":{"text":"MemberBlockSyntax"}},{"name":"unexpectedAfterMemberBlock","value":{"text":"nil"}}]},{"structure":[{"name":"Element","value":{"text":"Element"}},{"value":{"text":"0"},"name":"Count"}],"type":"collection","parent":3,"id":4,"text":"AttributeList","range":{"startRow":1,"startColumn":1,"endColumn":1,"endRow":1}},{"text":"DeclModifierList","range":{"startRow":1,"endRow":1,"endColumn":1,"startColumn":1},"id":5,"parent":3,"structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}],"type":"collection"},{"id":6,"type":"other","text":"enum","range":{"startColumn":1,"endRow":1,"startRow":1,"endColumn":5},"token":{"kind":"keyword(SwiftSyntax.Keyword.enum)","trailingTrivia":"␣<\/span>","leadingTrivia":""},"structure":[],"parent":3},{"parent":3,"structure":[],"type":"other","range":{"startColumn":6,"endRow":1,"startRow":1,"endColumn":25},"text":"VendingMachineError","id":7,"token":{"kind":"identifier("VendingMachineError")","trailingTrivia":"","leadingTrivia":""}},{"text":"InheritanceClause","range":{"startColumn":25,"endRow":1,"startRow":1,"endColumn":32},"id":8,"parent":3,"structure":[{"name":"unexpectedBeforeColon","value":{"text":"nil"}},{"name":"colon","value":{"kind":"colon","text":":"}},{"name":"unexpectedBetweenColonAndInheritedTypes","value":{"text":"nil"}},{"ref":"InheritedTypeListSyntax","name":"inheritedTypes","value":{"text":"InheritedTypeListSyntax"}},{"name":"unexpectedAfterInheritedTypes","value":{"text":"nil"}}],"type":"other"},{"type":"other","text":":","range":{"endRow":1,"endColumn":26,"startColumn":25,"startRow":1},"id":9,"token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"colon"},"structure":[],"parent":8},{"text":"InheritedTypeList","range":{"endRow":1,"endColumn":32,"startColumn":27,"startRow":1},"id":10,"parent":8,"structure":[{"name":"Element","value":{"text":"InheritedTypeSyntax"}},{"name":"Count","value":{"text":"1"}}],"type":"collection"},{"text":"InheritedType","range":{"startColumn":27,"startRow":1,"endRow":1,"endColumn":32},"id":11,"parent":10,"structure":[{"name":"unexpectedBeforeType","value":{"text":"nil"}},{"value":{"text":"IdentifierTypeSyntax"},"name":"type","ref":"IdentifierTypeSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenTypeAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other"},{"text":"IdentifierType","parent":11,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeName"},{"value":{"text":"Error","kind":"identifier("Error")"},"name":"name"},{"value":{"text":"nil"},"name":"unexpectedBetweenNameAndGenericArgumentClause"},{"value":{"text":"nil"},"name":"genericArgumentClause"},{"value":{"text":"nil"},"name":"unexpectedAfterGenericArgumentClause"}],"range":{"endColumn":32,"startColumn":27,"startRow":1,"endRow":1},"id":12,"type":"type"},{"text":"Error","parent":12,"structure":[],"token":{"kind":"identifier("Error")","trailingTrivia":"␣<\/span>","leadingTrivia":""},"range":{"startRow":1,"endRow":1,"endColumn":32,"startColumn":27},"type":"other","id":13},{"text":"MemberBlock","parent":3,"structure":[{"name":"unexpectedBeforeLeftBrace","value":{"text":"nil"}},{"name":"leftBrace","value":{"kind":"leftBrace","text":"{"}},{"name":"unexpectedBetweenLeftBraceAndMembers","value":{"text":"nil"}},{"name":"members","ref":"MemberBlockItemListSyntax","value":{"text":"MemberBlockItemListSyntax"}},{"name":"unexpectedBetweenMembersAndRightBrace","value":{"text":"nil"}},{"name":"rightBrace","value":{"text":"}","kind":"rightBrace"}},{"value":{"text":"nil"},"name":"unexpectedAfterRightBrace"}],"range":{"startRow":1,"endRow":5,"endColumn":2,"startColumn":33},"id":14,"type":"other"},{"type":"other","text":"{","id":15,"token":{"kind":"leftBrace","leadingTrivia":"","trailingTrivia":""},"structure":[],"range":{"startColumn":33,"startRow":1,"endRow":1,"endColumn":34},"parent":14},{"structure":[{"value":{"text":"MemberBlockItemSyntax"},"name":"Element"},{"value":{"text":"3"},"name":"Count"}],"parent":14,"type":"collection","range":{"startColumn":5,"startRow":2,"endRow":4,"endColumn":20},"text":"MemberBlockItemList","id":16},{"structure":[{"name":"unexpectedBeforeDecl","value":{"text":"nil"}},{"name":"decl","ref":"EnumCaseDeclSyntax","value":{"text":"EnumCaseDeclSyntax"}},{"name":"unexpectedBetweenDeclAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"parent":16,"type":"other","range":{"endColumn":26,"startColumn":5,"startRow":2,"endRow":2},"text":"MemberBlockItem","id":17},{"structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","value":{"text":"AttributeListSyntax"},"ref":"AttributeListSyntax"},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","value":{"text":"DeclModifierListSyntax"},"ref":"DeclModifierListSyntax"},{"name":"unexpectedBetweenModifiersAndCaseKeyword","value":{"text":"nil"}},{"name":"caseKeyword","value":{"kind":"keyword(SwiftSyntax.Keyword.case)","text":"case"}},{"name":"unexpectedBetweenCaseKeywordAndElements","value":{"text":"nil"}},{"name":"elements","value":{"text":"EnumCaseElementListSyntax"},"ref":"EnumCaseElementListSyntax"},{"name":"unexpectedAfterElements","value":{"text":"nil"}}],"parent":17,"type":"decl","range":{"startRow":2,"endRow":2,"endColumn":26,"startColumn":5},"text":"EnumCaseDecl","id":18},{"id":19,"range":{"endRow":1,"endColumn":34,"startRow":1,"startColumn":34},"text":"AttributeList","type":"collection","parent":18,"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"0"}}]},{"id":20,"range":{"startRow":1,"startColumn":34,"endRow":1,"endColumn":34},"text":"DeclModifierList","type":"collection","parent":18,"structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"parent":18,"id":21,"range":{"startColumn":5,"startRow":2,"endRow":2,"endColumn":9},"structure":[],"text":"case","token":{"kind":"keyword(SwiftSyntax.Keyword.case)","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"␣<\/span>"},"type":"other"},{"id":22,"range":{"startColumn":10,"startRow":2,"endRow":2,"endColumn":26},"text":"EnumCaseElementList","type":"collection","parent":18,"structure":[{"value":{"text":"EnumCaseElementSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"id":23,"range":{"startRow":2,"endColumn":26,"startColumn":10,"endRow":2},"text":"EnumCaseElement","type":"other","parent":22,"structure":[{"name":"unexpectedBeforeName","value":{"text":"nil"}},{"name":"name","value":{"text":"invalidSelection","kind":"identifier("invalidSelection")"}},{"name":"unexpectedBetweenNameAndParameterClause","value":{"text":"nil"}},{"name":"parameterClause","value":{"text":"nil"}},{"value":{"text":"nil"},"name":"unexpectedBetweenParameterClauseAndRawValue"},{"value":{"text":"nil"},"name":"rawValue"},{"value":{"text":"nil"},"name":"unexpectedBetweenRawValueAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"parent":23,"structure":[],"id":24,"range":{"startColumn":10,"endRow":2,"endColumn":26,"startRow":2},"text":"invalidSelection","token":{"kind":"identifier("invalidSelection")","trailingTrivia":"","leadingTrivia":""},"type":"other"},{"parent":16,"text":"MemberBlockItem","structure":[{"name":"unexpectedBeforeDecl","value":{"text":"nil"}},{"name":"decl","value":{"text":"EnumCaseDeclSyntax"},"ref":"EnumCaseDeclSyntax"},{"name":"unexpectedBetweenDeclAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"type":"other","id":25,"range":{"startColumn":5,"endRow":3,"endColumn":45,"startRow":3}},{"parent":25,"text":"EnumCaseDecl","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeAttributes"},{"value":{"text":"AttributeListSyntax"},"name":"attributes","ref":"AttributeListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenAttributesAndModifiers"},{"value":{"text":"DeclModifierListSyntax"},"name":"modifiers","ref":"DeclModifierListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenModifiersAndCaseKeyword"},{"value":{"text":"case","kind":"keyword(SwiftSyntax.Keyword.case)"},"name":"caseKeyword"},{"value":{"text":"nil"},"name":"unexpectedBetweenCaseKeywordAndElements"},{"value":{"text":"EnumCaseElementListSyntax"},"ref":"EnumCaseElementListSyntax","name":"elements"},{"value":{"text":"nil"},"name":"unexpectedAfterElements"}],"type":"decl","id":26,"range":{"startRow":3,"startColumn":5,"endRow":3,"endColumn":45}},{"id":27,"parent":26,"range":{"startColumn":26,"endRow":2,"endColumn":26,"startRow":2},"text":"AttributeList","structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"type":"collection"},{"id":28,"parent":26,"range":{"endRow":2,"startRow":2,"startColumn":26,"endColumn":26},"text":"DeclModifierList","structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}],"type":"collection"},{"parent":26,"id":29,"range":{"startRow":3,"startColumn":5,"endRow":3,"endColumn":9},"structure":[],"text":"case","token":{"kind":"keyword(SwiftSyntax.Keyword.case)","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"␣<\/span>"},"type":"other"},{"id":30,"parent":26,"range":{"startRow":3,"startColumn":10,"endRow":3,"endColumn":45},"text":"EnumCaseElementList","structure":[{"name":"Element","value":{"text":"EnumCaseElementSyntax"}},{"name":"Count","value":{"text":"1"}}],"type":"collection"},{"id":31,"parent":30,"range":{"endColumn":45,"endRow":3,"startColumn":10,"startRow":3},"text":"EnumCaseElement","structure":[{"name":"unexpectedBeforeName","value":{"text":"nil"}},{"name":"name","value":{"text":"insufficientFunds","kind":"identifier("insufficientFunds")"}},{"name":"unexpectedBetweenNameAndParameterClause","value":{"text":"nil"}},{"value":{"text":"EnumCaseParameterClauseSyntax"},"ref":"EnumCaseParameterClauseSyntax","name":"parameterClause"},{"value":{"text":"nil"},"name":"unexpectedBetweenParameterClauseAndRawValue"},{"value":{"text":"nil"},"name":"rawValue"},{"value":{"text":"nil"},"name":"unexpectedBetweenRawValueAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other"},{"parent":31,"id":32,"range":{"startRow":3,"endColumn":27,"endRow":3,"startColumn":10},"structure":[],"text":"insufficientFunds","token":{"kind":"identifier("insufficientFunds")","leadingTrivia":"","trailingTrivia":""},"type":"other"},{"text":"EnumCaseParameterClause","range":{"startRow":3,"endColumn":45,"endRow":3,"startColumn":27},"id":33,"parent":31,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftParen"},{"value":{"kind":"leftParen","text":"("},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndParameters"},{"value":{"text":"EnumCaseParameterListSyntax"},"name":"parameters","ref":"EnumCaseParameterListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenParametersAndRightParen"},{"value":{"text":")","kind":"rightParen"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedAfterRightParen"}],"type":"other"},{"parent":33,"id":34,"range":{"startColumn":27,"startRow":3,"endRow":3,"endColumn":28},"structure":[],"text":"(","token":{"trailingTrivia":"","leadingTrivia":"","kind":"leftParen"},"type":"other"},{"parent":33,"type":"collection","id":35,"text":"EnumCaseParameterList","range":{"endRow":3,"endColumn":44,"startRow":3,"startColumn":28},"structure":[{"name":"Element","value":{"text":"EnumCaseParameterSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"structure":[{"name":"unexpectedBeforeModifiers","value":{"text":"nil"}},{"name":"modifiers","ref":"DeclModifierListSyntax","value":{"text":"DeclModifierListSyntax"}},{"name":"unexpectedBetweenModifiersAndFirstName","value":{"text":"nil"}},{"name":"firstName","value":{"text":"coinsNeeded","kind":"identifier("coinsNeeded")"}},{"name":"unexpectedBetweenFirstNameAndSecondName","value":{"text":"nil"}},{"name":"secondName","value":{"text":"nil"}},{"name":"unexpectedBetweenSecondNameAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":":","kind":"colon"}},{"name":"unexpectedBetweenColonAndType","value":{"text":"nil"}},{"name":"type","ref":"IdentifierTypeSyntax","value":{"text":"IdentifierTypeSyntax"}},{"name":"unexpectedBetweenTypeAndDefaultValue","value":{"text":"nil"}},{"name":"defaultValue","value":{"text":"nil"}},{"name":"unexpectedBetweenDefaultValueAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"type":"other","id":36,"text":"EnumCaseParameter","range":{"endColumn":44,"startColumn":28,"startRow":3,"endRow":3},"parent":35},{"structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}],"type":"collection","id":37,"text":"DeclModifierList","range":{"endColumn":28,"startColumn":28,"startRow":3,"endRow":3},"parent":36},{"parent":36,"id":38,"range":{"startColumn":28,"startRow":3,"endRow":3,"endColumn":39},"structure":[],"text":"coinsNeeded","token":{"kind":"identifier("coinsNeeded")","trailingTrivia":"","leadingTrivia":""},"type":"other"},{"parent":36,"id":39,"range":{"startColumn":39,"startRow":3,"endRow":3,"endColumn":40},"structure":[],"text":":","token":{"kind":"colon","trailingTrivia":"␣<\/span>","leadingTrivia":""},"type":"other"},{"parent":36,"text":"IdentifierType","range":{"startColumn":41,"startRow":3,"endRow":3,"endColumn":44},"id":40,"structure":[{"name":"unexpectedBeforeName","value":{"text":"nil"}},{"name":"name","value":{"kind":"identifier("Int")","text":"Int"}},{"name":"unexpectedBetweenNameAndGenericArgumentClause","value":{"text":"nil"}},{"name":"genericArgumentClause","value":{"text":"nil"}},{"name":"unexpectedAfterGenericArgumentClause","value":{"text":"nil"}}],"type":"type"},{"parent":40,"id":41,"range":{"endRow":3,"endColumn":44,"startColumn":41,"startRow":3},"structure":[],"text":"Int","token":{"leadingTrivia":"","kind":"identifier("Int")","trailingTrivia":""},"type":"other"},{"parent":33,"id":42,"range":{"endRow":3,"endColumn":45,"startColumn":44,"startRow":3},"structure":[],"text":")","token":{"leadingTrivia":"","kind":"rightParen","trailingTrivia":""},"type":"other"},{"parent":16,"text":"MemberBlockItem","range":{"endRow":4,"endColumn":20,"startColumn":5,"startRow":4},"id":43,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeDecl"},{"value":{"text":"EnumCaseDeclSyntax"},"name":"decl","ref":"EnumCaseDeclSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenDeclAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}],"type":"other"},{"parent":43,"id":44,"range":{"startColumn":5,"endColumn":20,"startRow":4,"endRow":4},"type":"decl","text":"EnumCaseDecl","structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","value":{"text":"AttributeListSyntax"},"ref":"AttributeListSyntax"},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","value":{"text":"DeclModifierListSyntax"},"ref":"DeclModifierListSyntax"},{"name":"unexpectedBetweenModifiersAndCaseKeyword","value":{"text":"nil"}},{"name":"caseKeyword","value":{"kind":"keyword(SwiftSyntax.Keyword.case)","text":"case"}},{"name":"unexpectedBetweenCaseKeywordAndElements","value":{"text":"nil"}},{"name":"elements","value":{"text":"EnumCaseElementListSyntax"},"ref":"EnumCaseElementListSyntax"},{"name":"unexpectedAfterElements","value":{"text":"nil"}}]},{"parent":44,"id":45,"range":{"startColumn":45,"endRow":3,"endColumn":45,"startRow":3},"type":"collection","text":"AttributeList","structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"parent":44,"id":46,"range":{"startRow":3,"endRow":3,"startColumn":45,"endColumn":45},"type":"collection","text":"DeclModifierList","structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"parent":44,"id":47,"range":{"startRow":4,"startColumn":5,"endColumn":9,"endRow":4},"structure":[],"text":"case","token":{"kind":"keyword(SwiftSyntax.Keyword.case)","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"␣<\/span>"},"type":"other"},{"type":"collection","range":{"endRow":4,"startColumn":10,"endColumn":20,"startRow":4},"text":"EnumCaseElementList","structure":[{"value":{"text":"EnumCaseElementSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}],"parent":44,"id":48},{"type":"other","range":{"startRow":4,"endRow":4,"endColumn":20,"startColumn":10},"text":"EnumCaseElement","structure":[{"name":"unexpectedBeforeName","value":{"text":"nil"}},{"name":"name","value":{"kind":"identifier("outOfStock")","text":"outOfStock"}},{"name":"unexpectedBetweenNameAndParameterClause","value":{"text":"nil"}},{"name":"parameterClause","value":{"text":"nil"}},{"name":"unexpectedBetweenParameterClauseAndRawValue","value":{"text":"nil"}},{"name":"rawValue","value":{"text":"nil"}},{"name":"unexpectedBetweenRawValueAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"parent":48,"id":49},{"parent":49,"structure":[],"range":{"endColumn":20,"startColumn":10,"startRow":4,"endRow":4},"id":50,"text":"outOfStock","token":{"trailingTrivia":"","kind":"identifier("outOfStock")","leadingTrivia":""},"type":"other"},{"parent":14,"structure":[],"range":{"endColumn":2,"startColumn":1,"startRow":5,"endRow":5},"id":51,"text":"}","token":{"trailingTrivia":"","kind":"rightBrace","leadingTrivia":"↲<\/span>"},"type":"other"},{"type":"other","range":{"endColumn":2,"startColumn":1,"startRow":7,"endRow":42},"text":"CodeBlockItem","structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"ref":"ClassDeclSyntax","name":"item","value":{"text":"ClassDeclSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"parent":1,"id":52},{"type":"decl","parent":52,"text":"ClassDecl","range":{"endRow":42,"startRow":7,"startColumn":1,"endColumn":2},"id":53,"structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","value":{"text":"AttributeListSyntax"},"ref":"AttributeListSyntax"},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","value":{"text":"DeclModifierListSyntax"},"ref":"DeclModifierListSyntax"},{"name":"unexpectedBetweenModifiersAndClassKeyword","value":{"text":"nil"}},{"name":"classKeyword","value":{"text":"class","kind":"keyword(SwiftSyntax.Keyword.class)"}},{"name":"unexpectedBetweenClassKeywordAndName","value":{"text":"nil"}},{"name":"name","value":{"text":"VendingMachine","kind":"identifier("VendingMachine")"}},{"name":"unexpectedBetweenNameAndGenericParameterClause","value":{"text":"nil"}},{"name":"genericParameterClause","value":{"text":"nil"}},{"name":"unexpectedBetweenGenericParameterClauseAndInheritanceClause","value":{"text":"nil"}},{"name":"inheritanceClause","value":{"text":"nil"}},{"name":"unexpectedBetweenInheritanceClauseAndGenericWhereClause","value":{"text":"nil"}},{"name":"genericWhereClause","value":{"text":"nil"}},{"name":"unexpectedBetweenGenericWhereClauseAndMemberBlock","value":{"text":"nil"}},{"value":{"text":"MemberBlockSyntax"},"ref":"MemberBlockSyntax","name":"memberBlock"},{"value":{"text":"nil"},"name":"unexpectedAfterMemberBlock"}]},{"text":"AttributeList","range":{"startRow":5,"startColumn":2,"endRow":5,"endColumn":2},"type":"collection","id":54,"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"0"}}],"parent":53},{"text":"DeclModifierList","range":{"startColumn":2,"endColumn":2,"startRow":5,"endRow":5},"type":"collection","id":55,"structure":[{"value":{"text":"DeclModifierSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"parent":53},{"parent":53,"id":56,"range":{"startRow":7,"startColumn":1,"endRow":7,"endColumn":6},"structure":[],"text":"class","token":{"kind":"keyword(SwiftSyntax.Keyword.class)","leadingTrivia":"↲<\/span>↲<\/span>","trailingTrivia":"␣<\/span>"},"type":"other"},{"parent":53,"id":57,"range":{"startRow":7,"startColumn":7,"endRow":7,"endColumn":21},"structure":[],"text":"VendingMachine","token":{"kind":"identifier("VendingMachine")","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"type":"other"},{"text":"MemberBlock","range":{"startRow":7,"startColumn":22,"endRow":42,"endColumn":2},"type":"other","id":58,"structure":[{"name":"unexpectedBeforeLeftBrace","value":{"text":"nil"}},{"name":"leftBrace","value":{"kind":"leftBrace","text":"{"}},{"name":"unexpectedBetweenLeftBraceAndMembers","value":{"text":"nil"}},{"name":"members","value":{"text":"MemberBlockItemListSyntax"},"ref":"MemberBlockItemListSyntax"},{"name":"unexpectedBetweenMembersAndRightBrace","value":{"text":"nil"}},{"name":"rightBrace","value":{"kind":"rightBrace","text":"}"}},{"name":"unexpectedAfterRightBrace","value":{"text":"nil"}}],"parent":53},{"parent":58,"id":59,"structure":[],"range":{"startRow":7,"endRow":7,"endColumn":23,"startColumn":22},"text":"{","token":{"leadingTrivia":"","kind":"leftBrace","trailingTrivia":""},"type":"other"},{"id":60,"parent":58,"type":"collection","structure":[{"name":"Element","value":{"text":"MemberBlockItemSyntax"}},{"name":"Count","value":{"text":"3"}}],"range":{"startRow":8,"endRow":41,"endColumn":6,"startColumn":5},"text":"MemberBlockItemList"},{"id":61,"parent":60,"type":"other","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeDecl"},{"value":{"text":"VariableDeclSyntax"},"name":"decl","ref":"VariableDeclSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenDeclAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}],"range":{"startRow":8,"endRow":12,"endColumn":6,"startColumn":5},"text":"MemberBlockItem"},{"id":62,"parent":61,"type":"decl","structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","value":{"text":"AttributeListSyntax"},"ref":"AttributeListSyntax"},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","value":{"text":"DeclModifierListSyntax"},"ref":"DeclModifierListSyntax"},{"name":"unexpectedBetweenModifiersAndBindingSpecifier","value":{"text":"nil"}},{"name":"bindingSpecifier","value":{"kind":"keyword(SwiftSyntax.Keyword.var)","text":"var"}},{"name":"unexpectedBetweenBindingSpecifierAndBindings","value":{"text":"nil"}},{"name":"bindings","value":{"text":"PatternBindingListSyntax"},"ref":"PatternBindingListSyntax"},{"name":"unexpectedAfterBindings","value":{"text":"nil"}}],"range":{"startRow":8,"endColumn":6,"endRow":12,"startColumn":5},"text":"VariableDecl"},{"id":63,"structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"type":"collection","parent":62,"text":"AttributeList","range":{"startRow":7,"endRow":7,"endColumn":23,"startColumn":23}},{"id":64,"structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}],"type":"collection","parent":62,"text":"DeclModifierList","range":{"startRow":7,"endRow":7,"endColumn":23,"startColumn":23}},{"parent":62,"id":65,"structure":[],"range":{"endColumn":8,"startRow":8,"startColumn":5,"endRow":8},"text":"var","token":{"leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.var)","trailingTrivia":"␣<\/span>"},"type":"other"},{"id":66,"structure":[{"value":{"text":"PatternBindingSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}],"type":"collection","parent":62,"text":"PatternBindingList","range":{"endColumn":6,"startRow":8,"startColumn":9,"endRow":12}},{"id":67,"structure":[{"name":"unexpectedBeforePattern","value":{"text":"nil"}},{"name":"pattern","value":{"text":"IdentifierPatternSyntax"},"ref":"IdentifierPatternSyntax"},{"name":"unexpectedBetweenPatternAndTypeAnnotation","value":{"text":"nil"}},{"name":"typeAnnotation","value":{"text":"nil"}},{"name":"unexpectedBetweenTypeAnnotationAndInitializer","value":{"text":"nil"}},{"value":{"text":"InitializerClauseSyntax"},"ref":"InitializerClauseSyntax","name":"initializer"},{"value":{"text":"nil"},"name":"unexpectedBetweenInitializerAndAccessorBlock"},{"value":{"text":"nil"},"name":"accessorBlock"},{"value":{"text":"nil"},"name":"unexpectedBetweenAccessorBlockAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other","parent":66,"text":"PatternBinding","range":{"startColumn":9,"endRow":12,"startRow":8,"endColumn":6}},{"text":"IdentifierPattern","range":{"startRow":8,"startColumn":9,"endRow":8,"endColumn":18},"type":"pattern","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeIdentifier"},{"value":{"text":"inventory","kind":"identifier("inventory")"},"name":"identifier"},{"value":{"text":"nil"},"name":"unexpectedAfterIdentifier"}],"id":68,"parent":67},{"parent":68,"structure":[],"range":{"startColumn":9,"endRow":8,"startRow":8,"endColumn":18},"id":69,"text":"inventory","token":{"leadingTrivia":"","kind":"identifier("inventory")","trailingTrivia":"␣<\/span>"},"type":"other"},{"text":"InitializerClause","range":{"startColumn":19,"endRow":12,"startRow":8,"endColumn":6},"type":"other","structure":[{"name":"unexpectedBeforeEqual","value":{"text":"nil"}},{"name":"equal","value":{"text":"=","kind":"equal"}},{"name":"unexpectedBetweenEqualAndValue","value":{"text":"nil"}},{"ref":"DictionaryExprSyntax","name":"value","value":{"text":"DictionaryExprSyntax"}},{"name":"unexpectedAfterValue","value":{"text":"nil"}}],"id":70,"parent":67},{"parent":70,"structure":[],"range":{"startRow":8,"endRow":8,"endColumn":20,"startColumn":19},"id":71,"text":"=","token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"equal"},"type":"other"},{"text":"DictionaryExpr","range":{"endRow":12,"startRow":8,"endColumn":6,"startColumn":21},"structure":[{"name":"unexpectedBeforeLeftSquare","value":{"text":"nil"}},{"name":"leftSquare","value":{"text":"[","kind":"leftSquare"}},{"name":"unexpectedBetweenLeftSquareAndContent","value":{"text":"nil"}},{"name":"content","ref":"DictionaryElementListSyntax","value":{"text":"DictionaryElementListSyntax"}},{"name":"unexpectedBetweenContentAndRightSquare","value":{"text":"nil"}},{"name":"rightSquare","value":{"kind":"rightSquare","text":"]"}},{"name":"unexpectedAfterRightSquare","value":{"text":"nil"}}],"type":"expr","id":72,"parent":70},{"parent":72,"structure":[],"range":{"endRow":8,"startColumn":21,"endColumn":22,"startRow":8},"id":73,"text":"[","token":{"kind":"leftSquare","trailingTrivia":"","leadingTrivia":""},"type":"other"},{"text":"DictionaryElementList","range":{"endRow":11,"startColumn":9,"endColumn":46,"startRow":9},"structure":[{"name":"Element","value":{"text":"DictionaryElementSyntax"}},{"name":"Count","value":{"text":"3"}}],"type":"collection","id":74,"parent":72},{"text":"DictionaryElement","range":{"startColumn":9,"startRow":9,"endRow":9,"endColumn":48},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeKey"},{"value":{"text":"StringLiteralExprSyntax"},"name":"key","ref":"StringLiteralExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenKeyAndColon"},{"value":{"text":":","kind":"colon"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndValue"},{"value":{"text":"FunctionCallExprSyntax"},"ref":"FunctionCallExprSyntax","name":"value"},{"value":{"text":"nil"},"name":"unexpectedBetweenValueAndTrailingComma"},{"value":{"text":",","kind":"comma"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other","id":75,"parent":74},{"range":{"endColumn":20,"startRow":9,"startColumn":9,"endRow":9},"id":76,"parent":75,"text":"StringLiteralExpr","type":"expr","structure":[{"name":"unexpectedBeforeOpeningPounds","value":{"text":"nil"}},{"name":"openingPounds","value":{"text":"nil"}},{"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote","value":{"text":"nil"}},{"name":"openingQuote","value":{"kind":"stringQuote","text":"""}},{"name":"unexpectedBetweenOpeningQuoteAndSegments","value":{"text":"nil"}},{"name":"segments","value":{"text":"StringLiteralSegmentListSyntax"},"ref":"StringLiteralSegmentListSyntax"},{"name":"unexpectedBetweenSegmentsAndClosingQuote","value":{"text":"nil"}},{"name":"closingQuote","value":{"kind":"stringQuote","text":"""}},{"name":"unexpectedBetweenClosingQuoteAndClosingPounds","value":{"text":"nil"}},{"name":"closingPounds","value":{"text":"nil"}},{"name":"unexpectedAfterClosingPounds","value":{"text":"nil"}}]},{"parent":76,"id":77,"range":{"startRow":9,"endRow":9,"endColumn":10,"startColumn":9},"structure":[],"text":""","token":{"leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"","kind":"stringQuote"},"type":"other"},{"type":"collection","text":"StringLiteralSegmentList","structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"1"}}],"parent":76,"id":78,"range":{"startRow":9,"startColumn":10,"endRow":9,"endColumn":19}},{"type":"other","text":"StringSegment","structure":[{"name":"unexpectedBeforeContent","value":{"text":"nil"}},{"name":"content","value":{"text":"Candy Bar","kind":"stringSegment("Candy Bar")"}},{"name":"unexpectedAfterContent","value":{"text":"nil"}}],"parent":78,"id":79,"range":{"startColumn":10,"endColumn":19,"endRow":9,"startRow":9}},{"parent":79,"structure":[],"id":80,"range":{"endRow":9,"startColumn":10,"startRow":9,"endColumn":19},"text":"Candy␣<\/span>Bar","token":{"leadingTrivia":"","kind":"stringSegment("Candy Bar")","trailingTrivia":""},"type":"other"},{"type":"other","text":""","range":{"endRow":9,"startColumn":19,"startRow":9,"endColumn":20},"id":81,"token":{"leadingTrivia":"","kind":"stringQuote","trailingTrivia":""},"structure":[],"parent":76},{"type":"other","text":":","range":{"endRow":9,"startColumn":20,"startRow":9,"endColumn":21},"id":82,"token":{"leadingTrivia":"","kind":"colon","trailingTrivia":"␣<\/span>"},"structure":[],"parent":75},{"type":"expr","text":"FunctionCallExpr","structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"calledExpression","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenCalledExpressionAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"text":"(","kind":"leftParen"}},{"name":"unexpectedBetweenLeftParenAndArguments","value":{"text":"nil"}},{"ref":"LabeledExprListSyntax","name":"arguments","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenArgumentsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"kind":"rightParen","text":")"}},{"name":"unexpectedBetweenRightParenAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures","value":{"text":"MultipleTrailingClosureElementListSyntax"}},{"name":"unexpectedAfterAdditionalTrailingClosures","value":{"text":"nil"}}],"parent":75,"id":83,"range":{"endRow":9,"startColumn":22,"startRow":9,"endColumn":47}},{"range":{"endRow":9,"startRow":9,"startColumn":22,"endColumn":26},"type":"expr","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"Item","kind":"identifier("Item")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}],"parent":83,"id":84,"text":"DeclReferenceExpr"},{"type":"other","text":"Item","range":{"startColumn":22,"endRow":9,"endColumn":26,"startRow":9},"id":85,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"identifier("Item")"},"structure":[],"parent":84},{"type":"other","text":"(","range":{"startColumn":26,"endRow":9,"endColumn":27,"startRow":9},"id":86,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"leftParen"},"structure":[],"parent":83},{"range":{"startColumn":27,"endRow":9,"endColumn":46,"startRow":9},"type":"collection","structure":[{"value":{"text":"LabeledExprSyntax"},"name":"Element"},{"value":{"text":"2"},"name":"Count"}],"parent":83,"id":87,"text":"LabeledExprList"},{"range":{"endRow":9,"startColumn":27,"endColumn":37,"startRow":9},"type":"other","structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"price","kind":"identifier("price")"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"kind":"colon","text":":"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","value":{"text":"IntegerLiteralExprSyntax"},"ref":"IntegerLiteralExprSyntax"},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"kind":"comma","text":","}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"parent":87,"id":88,"text":"LabeledExpr"},{"type":"other","text":"price","range":{"endRow":9,"startRow":9,"endColumn":32,"startColumn":27},"id":89,"token":{"kind":"identifier("price")","trailingTrivia":"","leadingTrivia":""},"structure":[],"parent":88},{"type":"other","text":":","range":{"endRow":9,"startRow":9,"endColumn":33,"startColumn":32},"id":90,"token":{"kind":"colon","trailingTrivia":"␣<\/span>","leadingTrivia":""},"structure":[],"parent":88},{"id":91,"range":{"endRow":9,"startRow":9,"endColumn":36,"startColumn":34},"structure":[{"name":"unexpectedBeforeLiteral","value":{"text":"nil"}},{"name":"literal","value":{"kind":"integerLiteral("12")","text":"12"}},{"name":"unexpectedAfterLiteral","value":{"text":"nil"}}],"type":"expr","text":"IntegerLiteralExpr","parent":88},{"type":"other","text":"12","range":{"startColumn":34,"endRow":9,"endColumn":36,"startRow":9},"id":92,"token":{"kind":"integerLiteral("12")","leadingTrivia":"","trailingTrivia":""},"structure":[],"parent":91},{"type":"other","text":",","range":{"startColumn":36,"endRow":9,"endColumn":37,"startRow":9},"id":93,"token":{"kind":"comma","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"structure":[],"parent":88},{"id":94,"range":{"startColumn":38,"endRow":9,"endColumn":46,"startRow":9},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"text":"count","kind":"identifier("count")"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"kind":"colon","text":":"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"IntegerLiteralExprSyntax"},"name":"expression","ref":"IntegerLiteralExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other","text":"LabeledExpr","parent":87},{"type":"other","text":"count","range":{"startRow":9,"endColumn":43,"startColumn":38,"endRow":9},"id":95,"token":{"kind":"identifier("count")","trailingTrivia":"","leadingTrivia":""},"structure":[],"parent":94},{"type":"other","text":":","range":{"startRow":9,"endColumn":44,"startColumn":43,"endRow":9},"id":96,"token":{"kind":"colon","trailingTrivia":"␣<\/span>","leadingTrivia":""},"structure":[],"parent":94},{"type":"expr","structure":[{"name":"unexpectedBeforeLiteral","value":{"text":"nil"}},{"name":"literal","value":{"text":"7","kind":"integerLiteral("7")"}},{"name":"unexpectedAfterLiteral","value":{"text":"nil"}}],"id":97,"text":"IntegerLiteralExpr","parent":94,"range":{"startRow":9,"endColumn":46,"startColumn":45,"endRow":9}},{"type":"other","text":"7","range":{"startRow":9,"startColumn":45,"endColumn":46,"endRow":9},"id":98,"token":{"leadingTrivia":"","kind":"integerLiteral("7")","trailingTrivia":""},"structure":[],"parent":97},{"type":"other","text":")","range":{"startRow":9,"startColumn":46,"endColumn":47,"endRow":9},"id":99,"token":{"leadingTrivia":"","kind":"rightParen","trailingTrivia":""},"structure":[],"parent":83},{"type":"collection","structure":[{"name":"Element","value":{"text":"MultipleTrailingClosureElementSyntax"}},{"value":{"text":"0"},"name":"Count"}],"parent":83,"text":"MultipleTrailingClosureElementList","range":{"startColumn":47,"endColumn":47,"startRow":9,"endRow":9},"id":100},{"type":"other","text":",","range":{"endRow":9,"startColumn":47,"startRow":9,"endColumn":48},"id":101,"token":{"kind":"comma","leadingTrivia":"","trailingTrivia":""},"structure":[],"parent":75},{"type":"other","structure":[{"name":"unexpectedBeforeKey","value":{"text":"nil"}},{"name":"key","value":{"text":"StringLiteralExprSyntax"},"ref":"StringLiteralExprSyntax"},{"name":"unexpectedBetweenKeyAndColon","value":{"text":"nil"}},{"name":"colon","value":{"kind":"colon","text":":"}},{"name":"unexpectedBetweenColonAndValue","value":{"text":"nil"}},{"name":"value","value":{"text":"FunctionCallExprSyntax"},"ref":"FunctionCallExprSyntax"},{"name":"unexpectedBetweenValueAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":",","kind":"comma"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"parent":74,"range":{"endRow":10,"startColumn":9,"startRow":10,"endColumn":44},"text":"DictionaryElement","id":102},{"type":"expr","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeOpeningPounds"},{"value":{"text":"nil"},"name":"openingPounds"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote"},{"value":{"kind":"stringQuote","text":"""},"name":"openingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningQuoteAndSegments"},{"ref":"StringLiteralSegmentListSyntax","name":"segments","value":{"text":"StringLiteralSegmentListSyntax"}},{"name":"unexpectedBetweenSegmentsAndClosingQuote","value":{"text":"nil"}},{"name":"closingQuote","value":{"kind":"stringQuote","text":"""}},{"name":"unexpectedBetweenClosingQuoteAndClosingPounds","value":{"text":"nil"}},{"name":"closingPounds","value":{"text":"nil"}},{"name":"unexpectedAfterClosingPounds","value":{"text":"nil"}}],"parent":102,"range":{"startRow":10,"startColumn":9,"endColumn":16,"endRow":10},"text":"StringLiteralExpr","id":103},{"text":""","type":"other","range":{"startColumn":9,"startRow":10,"endRow":10,"endColumn":10},"id":104,"token":{"kind":"stringQuote","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":""},"structure":[],"parent":103},{"range":{"startColumn":10,"startRow":10,"endRow":10,"endColumn":15},"id":105,"parent":103,"text":"StringLiteralSegmentList","structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"1"}}],"type":"collection"},{"range":{"startRow":10,"endRow":10,"endColumn":15,"startColumn":10},"id":106,"parent":105,"text":"StringSegment","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeContent"},{"value":{"text":"Chips","kind":"stringSegment("Chips")"},"name":"content"},{"value":{"text":"nil"},"name":"unexpectedAfterContent"}],"type":"other"},{"text":"Chips","type":"other","range":{"endColumn":15,"endRow":10,"startColumn":10,"startRow":10},"id":107,"token":{"trailingTrivia":"","kind":"stringSegment("Chips")","leadingTrivia":""},"structure":[],"parent":106},{"text":""","type":"other","range":{"endColumn":16,"endRow":10,"startColumn":15,"startRow":10},"id":108,"token":{"trailingTrivia":"","kind":"stringQuote","leadingTrivia":""},"structure":[],"parent":103},{"text":":","type":"other","range":{"endRow":10,"startColumn":16,"startRow":10,"endColumn":17},"id":109,"token":{"kind":"colon","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"structure":[],"parent":102},{"parent":102,"id":110,"range":{"startRow":10,"startColumn":18,"endColumn":43,"endRow":10},"text":"FunctionCallExpr","structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"calledExpression","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenCalledExpressionAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"kind":"leftParen","text":"("}},{"name":"unexpectedBetweenLeftParenAndArguments","value":{"text":"nil"}},{"ref":"LabeledExprListSyntax","name":"arguments","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenArgumentsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"kind":"rightParen","text":")"}},{"name":"unexpectedBetweenRightParenAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures","value":{"text":"MultipleTrailingClosureElementListSyntax"}},{"name":"unexpectedAfterAdditionalTrailingClosures","value":{"text":"nil"}}],"type":"expr"},{"parent":110,"id":111,"range":{"startRow":10,"endColumn":22,"endRow":10,"startColumn":18},"text":"DeclReferenceExpr","structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("Item")","text":"Item"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr"},{"type":"other","text":"Item","range":{"endColumn":22,"startColumn":18,"endRow":10,"startRow":10},"id":112,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"identifier("Item")"},"structure":[],"parent":111},{"type":"other","text":"(","range":{"endColumn":23,"startColumn":22,"endRow":10,"startRow":10},"id":113,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"leftParen"},"structure":[],"parent":110},{"type":"collection","text":"LabeledExprList","id":114,"parent":110,"range":{"endColumn":42,"startColumn":23,"endRow":10,"startRow":10},"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"2"}}]},{"type":"other","text":"LabeledExpr","id":115,"parent":114,"range":{"startColumn":23,"endColumn":33,"endRow":10,"startRow":10},"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"price","kind":"identifier("price")"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"kind":"colon","text":":"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","value":{"text":"IntegerLiteralExprSyntax"},"ref":"IntegerLiteralExprSyntax"},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"kind":"comma","text":","}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"type":"other","text":"price","range":{"endColumn":28,"startRow":10,"startColumn":23,"endRow":10},"id":116,"token":{"kind":"identifier("price")","leadingTrivia":"","trailingTrivia":""},"structure":[],"parent":115},{"text":":","type":"other","range":{"endRow":10,"startRow":10,"startColumn":28,"endColumn":29},"id":117,"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"colon"},"structure":[],"parent":115},{"parent":115,"text":"IntegerLiteralExpr","range":{"endRow":10,"startRow":10,"startColumn":30,"endColumn":32},"id":118,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLiteral"},{"value":{"text":"10","kind":"integerLiteral("10")"},"name":"literal"},{"value":{"text":"nil"},"name":"unexpectedAfterLiteral"}],"type":"expr"},{"type":"other","range":{"startRow":10,"endRow":10,"startColumn":30,"endColumn":32},"structure":[],"id":119,"text":"10","parent":118,"token":{"kind":"integerLiteral("10")","leadingTrivia":"","trailingTrivia":""}},{"type":"other","range":{"startRow":10,"endRow":10,"startColumn":32,"endColumn":33},"structure":[],"id":120,"text":",","parent":115,"token":{"kind":"comma","leadingTrivia":"","trailingTrivia":"␣<\/span>"}},{"parent":114,"text":"LabeledExpr","range":{"startRow":10,"endRow":10,"startColumn":34,"endColumn":42},"id":121,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"text":"count","kind":"identifier("count")"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"text":":","kind":"colon"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"IntegerLiteralExprSyntax"},"name":"expression","ref":"IntegerLiteralExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other"},{"type":"other","range":{"endRow":10,"endColumn":39,"startColumn":34,"startRow":10},"structure":[],"id":122,"text":"count","parent":121,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"identifier("count")"}},{"type":"other","range":{"endRow":10,"endColumn":40,"startColumn":39,"startRow":10},"structure":[],"id":123,"text":":","parent":121,"token":{"kind":"colon","leadingTrivia":"","trailingTrivia":"␣<\/span>"}},{"text":"IntegerLiteralExpr","id":124,"structure":[{"name":"unexpectedBeforeLiteral","value":{"text":"nil"}},{"name":"literal","value":{"text":"4","kind":"integerLiteral("4")"}},{"name":"unexpectedAfterLiteral","value":{"text":"nil"}}],"range":{"endRow":10,"endColumn":42,"startColumn":41,"startRow":10},"parent":121,"type":"expr"},{"type":"other","range":{"endColumn":42,"startColumn":41,"endRow":10,"startRow":10},"structure":[],"id":125,"text":"4","parent":124,"token":{"kind":"integerLiteral("4")","leadingTrivia":"","trailingTrivia":""}},{"type":"other","range":{"endColumn":43,"startColumn":42,"endRow":10,"startRow":10},"structure":[],"id":126,"text":")","parent":110,"token":{"kind":"rightParen","leadingTrivia":"","trailingTrivia":""}},{"text":"MultipleTrailingClosureElementList","id":127,"structure":[{"value":{"text":"MultipleTrailingClosureElementSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"range":{"endColumn":43,"startColumn":43,"endRow":10,"startRow":10},"parent":110,"type":"collection"},{"type":"other","range":{"endRow":10,"endColumn":44,"startRow":10,"startColumn":43},"structure":[],"id":128,"text":",","parent":102,"token":{"leadingTrivia":"","kind":"comma","trailingTrivia":""}},{"text":"DictionaryElement","id":129,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeKey"},{"value":{"text":"StringLiteralExprSyntax"},"name":"key","ref":"StringLiteralExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenKeyAndColon"},{"value":{"kind":"colon","text":":"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndValue"},{"value":{"text":"FunctionCallExprSyntax"},"name":"value","ref":"FunctionCallExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenValueAndTrailingComma"},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"range":{"endRow":11,"endColumn":46,"startRow":11,"startColumn":9},"parent":74,"type":"other"},{"range":{"startColumn":9,"endRow":11,"endColumn":19,"startRow":11},"structure":[{"name":"unexpectedBeforeOpeningPounds","value":{"text":"nil"}},{"name":"openingPounds","value":{"text":"nil"}},{"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote","value":{"text":"nil"}},{"name":"openingQuote","value":{"text":""","kind":"stringQuote"}},{"name":"unexpectedBetweenOpeningQuoteAndSegments","value":{"text":"nil"}},{"name":"segments","value":{"text":"StringLiteralSegmentListSyntax"},"ref":"StringLiteralSegmentListSyntax"},{"name":"unexpectedBetweenSegmentsAndClosingQuote","value":{"text":"nil"}},{"name":"closingQuote","value":{"text":""","kind":"stringQuote"}},{"name":"unexpectedBetweenClosingQuoteAndClosingPounds","value":{"text":"nil"}},{"name":"closingPounds","value":{"text":"nil"}},{"name":"unexpectedAfterClosingPounds","value":{"text":"nil"}}],"id":130,"text":"StringLiteralExpr","type":"expr","parent":129},{"type":"other","range":{"endRow":11,"startColumn":9,"startRow":11,"endColumn":10},"structure":[],"id":131,"text":""","parent":130,"token":{"kind":"stringQuote","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":""}},{"range":{"endRow":11,"startColumn":10,"startRow":11,"endColumn":18},"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"1"}}],"id":132,"text":"StringLiteralSegmentList","type":"collection","parent":130},{"id":133,"text":"StringSegment","structure":[{"name":"unexpectedBeforeContent","value":{"text":"nil"}},{"name":"content","value":{"kind":"stringSegment("Pretzels")","text":"Pretzels"}},{"name":"unexpectedAfterContent","value":{"text":"nil"}}],"type":"other","range":{"startRow":11,"startColumn":10,"endRow":11,"endColumn":18},"parent":132},{"type":"other","range":{"startRow":11,"startColumn":10,"endRow":11,"endColumn":18},"structure":[],"id":134,"text":"Pretzels","parent":133,"token":{"trailingTrivia":"","kind":"stringSegment("Pretzels")","leadingTrivia":""}},{"type":"other","range":{"startRow":11,"startColumn":18,"endRow":11,"endColumn":19},"structure":[],"id":135,"text":""","parent":130,"token":{"trailingTrivia":"","kind":"stringQuote","leadingTrivia":""}},{"type":"other","range":{"startRow":11,"startColumn":19,"endRow":11,"endColumn":20},"structure":[],"id":136,"text":":","parent":129,"token":{"trailingTrivia":"␣<\/span>","kind":"colon","leadingTrivia":""}},{"id":137,"text":"FunctionCallExpr","structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"name":"calledExpression","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenCalledExpressionAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"kind":"leftParen","text":"("}},{"name":"unexpectedBetweenLeftParenAndArguments","value":{"text":"nil"}},{"name":"arguments","ref":"LabeledExprListSyntax","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenArgumentsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"text":")","kind":"rightParen"}},{"name":"unexpectedBetweenRightParenAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures","value":{"text":"MultipleTrailingClosureElementListSyntax"}},{"name":"unexpectedAfterAdditionalTrailingClosures","value":{"text":"nil"}}],"type":"expr","range":{"startRow":11,"startColumn":21,"endRow":11,"endColumn":46},"parent":129},{"parent":137,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"Item","kind":"identifier("Item")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}],"type":"expr","range":{"endRow":11,"endColumn":25,"startRow":11,"startColumn":21},"id":138,"text":"DeclReferenceExpr"},{"type":"other","range":{"startRow":11,"endColumn":25,"endRow":11,"startColumn":21},"structure":[],"id":139,"text":"Item","parent":138,"token":{"kind":"identifier("Item")","leadingTrivia":"","trailingTrivia":""}},{"type":"other","range":{"startRow":11,"endColumn":26,"endRow":11,"startColumn":25},"structure":[],"id":140,"text":"(","parent":137,"token":{"kind":"leftParen","leadingTrivia":"","trailingTrivia":""}},{"parent":137,"structure":[{"value":{"text":"LabeledExprSyntax"},"name":"Element"},{"value":{"text":"2"},"name":"Count"}],"type":"collection","range":{"startRow":11,"endColumn":45,"endRow":11,"startColumn":26},"id":141,"text":"LabeledExprList"},{"parent":141,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"kind":"identifier("price")","text":"price"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"value":{"text":":","kind":"colon"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"IntegerLiteralExprSyntax"},"ref":"IntegerLiteralExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":",","kind":"comma"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other","range":{"startColumn":26,"endColumn":35,"startRow":11,"endRow":11},"id":142,"text":"LabeledExpr"},{"type":"other","range":{"endColumn":31,"startRow":11,"startColumn":26,"endRow":11},"structure":[],"id":143,"text":"price","parent":142,"token":{"trailingTrivia":"","kind":"identifier("price")","leadingTrivia":""}},{"type":"other","range":{"endColumn":32,"startRow":11,"startColumn":31,"endRow":11},"structure":[],"id":144,"text":":","parent":142,"token":{"trailingTrivia":"␣<\/span>","kind":"colon","leadingTrivia":""}},{"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLiteral"},{"value":{"text":"7","kind":"integerLiteral("7")"},"name":"literal"},{"value":{"text":"nil"},"name":"unexpectedAfterLiteral"}],"id":145,"type":"expr","text":"IntegerLiteralExpr","range":{"endColumn":34,"startRow":11,"startColumn":33,"endRow":11},"parent":142},{"type":"other","range":{"endRow":11,"startColumn":33,"endColumn":34,"startRow":11},"structure":[],"id":146,"text":"7","parent":145,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"integerLiteral("7")"}},{"type":"other","range":{"endRow":11,"startColumn":34,"endColumn":35,"startRow":11},"structure":[],"id":147,"text":",","parent":142,"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"comma"}},{"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"kind":"identifier("count")","text":"count"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"text":":","kind":"colon"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"IntegerLiteralExprSyntax"},"ref":"IntegerLiteralExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"id":148,"type":"other","text":"LabeledExpr","range":{"endRow":11,"startColumn":36,"endColumn":45,"startRow":11},"parent":141},{"type":"other","range":{"startRow":11,"endRow":11,"startColumn":36,"endColumn":41},"structure":[],"id":149,"text":"count","parent":148,"token":{"trailingTrivia":"","kind":"identifier("count")","leadingTrivia":""}},{"type":"other","range":{"startRow":11,"endRow":11,"startColumn":41,"endColumn":42},"structure":[],"id":150,"text":":","parent":148,"token":{"trailingTrivia":"␣<\/span>","kind":"colon","leadingTrivia":""}},{"type":"expr","id":151,"structure":[{"name":"unexpectedBeforeLiteral","value":{"text":"nil"}},{"name":"literal","value":{"kind":"integerLiteral("11")","text":"11"}},{"name":"unexpectedAfterLiteral","value":{"text":"nil"}}],"range":{"startRow":11,"endRow":11,"startColumn":43,"endColumn":45},"parent":148,"text":"IntegerLiteralExpr"},{"type":"other","range":{"endRow":11,"endColumn":45,"startRow":11,"startColumn":43},"structure":[],"id":152,"text":"11","parent":151,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"integerLiteral("11")"}},{"type":"other","range":{"endRow":11,"endColumn":46,"startRow":11,"startColumn":45},"structure":[],"id":153,"text":")","parent":137,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"rightParen"}},{"type":"collection","id":154,"structure":[{"name":"Element","value":{"text":"MultipleTrailingClosureElementSyntax"}},{"name":"Count","value":{"text":"0"}}],"range":{"endRow":11,"endColumn":46,"startRow":11,"startColumn":46},"parent":137,"text":"MultipleTrailingClosureElementList"},{"type":"other","structure":[],"parent":72,"token":{"leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"","kind":"rightSquare"},"id":155,"range":{"startRow":12,"startColumn":5,"endRow":12,"endColumn":6},"text":"]"},{"range":{"startRow":13,"endColumn":27,"startColumn":5,"endRow":13},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeDecl"},{"value":{"text":"VariableDeclSyntax"},"name":"decl","ref":"VariableDeclSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenDeclAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}],"id":156,"parent":60,"text":"MemberBlockItem","type":"other"},{"range":{"startColumn":5,"startRow":13,"endColumn":27,"endRow":13},"structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","value":{"text":"AttributeListSyntax"},"ref":"AttributeListSyntax"},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","value":{"text":"DeclModifierListSyntax"},"ref":"DeclModifierListSyntax"},{"name":"unexpectedBetweenModifiersAndBindingSpecifier","value":{"text":"nil"}},{"name":"bindingSpecifier","value":{"kind":"keyword(SwiftSyntax.Keyword.var)","text":"var"}},{"name":"unexpectedBetweenBindingSpecifierAndBindings","value":{"text":"nil"}},{"name":"bindings","value":{"text":"PatternBindingListSyntax"},"ref":"PatternBindingListSyntax"},{"name":"unexpectedAfterBindings","value":{"text":"nil"}}],"id":157,"parent":156,"text":"VariableDecl","type":"decl"},{"range":{"startRow":12,"endColumn":6,"endRow":12,"startColumn":6},"structure":[{"value":{"text":"Element"},"name":"Element"},{"name":"Count","value":{"text":"0"}}],"id":158,"parent":157,"text":"AttributeList","type":"collection"},{"text":"DeclModifierList","range":{"endColumn":6,"startColumn":6,"endRow":12,"startRow":12},"structure":[{"value":{"text":"DeclModifierSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"type":"collection","parent":157,"id":159},{"type":"other","structure":[],"parent":157,"token":{"leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.var)"},"range":{"startRow":13,"endColumn":8,"endRow":13,"startColumn":5},"id":160,"text":"var"},{"text":"PatternBindingList","range":{"startRow":13,"endColumn":27,"endRow":13,"startColumn":9},"structure":[{"name":"Element","value":{"text":"PatternBindingSyntax"}},{"name":"Count","value":{"text":"1"}}],"type":"collection","parent":157,"id":161},{"text":"PatternBinding","range":{"endRow":13,"startColumn":9,"endColumn":27,"startRow":13},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforePattern"},{"ref":"IdentifierPatternSyntax","value":{"text":"IdentifierPatternSyntax"},"name":"pattern"},{"value":{"text":"nil"},"name":"unexpectedBetweenPatternAndTypeAnnotation"},{"value":{"text":"nil"},"name":"typeAnnotation"},{"value":{"text":"nil"},"name":"unexpectedBetweenTypeAnnotationAndInitializer"},{"ref":"InitializerClauseSyntax","value":{"text":"InitializerClauseSyntax"},"name":"initializer"},{"value":{"text":"nil"},"name":"unexpectedBetweenInitializerAndAccessorBlock"},{"value":{"text":"nil"},"name":"accessorBlock"},{"value":{"text":"nil"},"name":"unexpectedBetweenAccessorBlockAndTrailingComma"},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"type":"other","parent":161,"id":162},{"type":"pattern","range":{"endColumn":23,"startRow":13,"startColumn":9,"endRow":13},"parent":162,"id":163,"text":"IdentifierPattern","structure":[{"name":"unexpectedBeforeIdentifier","value":{"text":"nil"}},{"name":"identifier","value":{"text":"coinsDeposited","kind":"identifier("coinsDeposited")"}},{"name":"unexpectedAfterIdentifier","value":{"text":"nil"}}]},{"type":"other","structure":[],"parent":163,"token":{"trailingTrivia":"␣<\/span>","kind":"identifier("coinsDeposited")","leadingTrivia":""},"range":{"endRow":13,"endColumn":23,"startRow":13,"startColumn":9},"id":164,"text":"coinsDeposited"},{"type":"other","range":{"endRow":13,"endColumn":27,"startRow":13,"startColumn":24},"parent":162,"id":165,"text":"InitializerClause","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeEqual"},{"value":{"kind":"equal","text":"="},"name":"equal"},{"value":{"text":"nil"},"name":"unexpectedBetweenEqualAndValue"},{"ref":"IntegerLiteralExprSyntax","value":{"text":"IntegerLiteralExprSyntax"},"name":"value"},{"value":{"text":"nil"},"name":"unexpectedAfterValue"}]},{"type":"other","structure":[],"parent":165,"token":{"leadingTrivia":"","kind":"equal","trailingTrivia":"␣<\/span>"},"range":{"startColumn":24,"endColumn":25,"startRow":13,"endRow":13},"id":166,"text":"="},{"type":"expr","range":{"startColumn":26,"endColumn":27,"startRow":13,"endRow":13},"parent":165,"id":167,"text":"IntegerLiteralExpr","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLiteral"},{"value":{"text":"0","kind":"integerLiteral("0")"},"name":"literal"},{"value":{"text":"nil"},"name":"unexpectedAfterLiteral"}]},{"type":"other","structure":[],"parent":167,"token":{"kind":"integerLiteral("0")","trailingTrivia":"","leadingTrivia":""},"range":{"startColumn":26,"endRow":13,"endColumn":27,"startRow":13},"id":168,"text":"0"},{"range":{"startColumn":5,"endRow":41,"endColumn":6,"startRow":16},"structure":[{"name":"unexpectedBeforeDecl","value":{"text":"nil"}},{"name":"decl","value":{"text":"FunctionDeclSyntax"},"ref":"FunctionDeclSyntax"},{"name":"unexpectedBetweenDeclAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"id":169,"type":"other","text":"MemberBlockItem","parent":60},{"range":{"endColumn":6,"startRow":16,"startColumn":5,"endRow":41},"structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"ref":"AttributeListSyntax","name":"attributes","value":{"text":"AttributeListSyntax"}},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"ref":"DeclModifierListSyntax","name":"modifiers","value":{"text":"DeclModifierListSyntax"}},{"name":"unexpectedBetweenModifiersAndFuncKeyword","value":{"text":"nil"}},{"name":"funcKeyword","value":{"kind":"keyword(SwiftSyntax.Keyword.func)","text":"func"}},{"name":"unexpectedBetweenFuncKeywordAndName","value":{"text":"nil"}},{"name":"name","value":{"kind":"identifier("vend")","text":"vend"}},{"name":"unexpectedBetweenNameAndGenericParameterClause","value":{"text":"nil"}},{"name":"genericParameterClause","value":{"text":"nil"}},{"name":"unexpectedBetweenGenericParameterClauseAndSignature","value":{"text":"nil"}},{"name":"signature","ref":"FunctionSignatureSyntax","value":{"text":"FunctionSignatureSyntax"}},{"name":"unexpectedBetweenSignatureAndGenericWhereClause","value":{"text":"nil"}},{"name":"genericWhereClause","value":{"text":"nil"}},{"name":"unexpectedBetweenGenericWhereClauseAndBody","value":{"text":"nil"}},{"name":"body","ref":"CodeBlockSyntax","value":{"text":"CodeBlockSyntax"}},{"name":"unexpectedAfterBody","value":{"text":"nil"}}],"id":170,"type":"decl","text":"FunctionDecl","parent":169},{"text":"AttributeList","parent":170,"range":{"endColumn":27,"endRow":13,"startColumn":27,"startRow":13},"type":"collection","id":171,"structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"text":"DeclModifierList","parent":170,"range":{"startColumn":27,"endRow":13,"startRow":13,"endColumn":27},"type":"collection","id":172,"structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"type":"other","structure":[],"parent":170,"token":{"kind":"keyword(SwiftSyntax.Keyword.func)","trailingTrivia":"␣<\/span>","leadingTrivia":"↲<\/span>↲<\/span>↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"},"range":{"endColumn":9,"startRow":16,"endRow":16,"startColumn":5},"id":173,"text":"func"},{"type":"other","structure":[],"parent":170,"token":{"kind":"identifier("vend")","trailingTrivia":"","leadingTrivia":""},"range":{"endColumn":14,"startRow":16,"endRow":16,"startColumn":10},"id":174,"text":"vend"},{"text":"FunctionSignature","parent":170,"range":{"endColumn":45,"startRow":16,"endRow":16,"startColumn":14},"type":"other","id":175,"structure":[{"name":"unexpectedBeforeParameterClause","value":{"text":"nil"}},{"name":"parameterClause","ref":"FunctionParameterClauseSyntax","value":{"text":"FunctionParameterClauseSyntax"}},{"value":{"text":"nil"},"name":"unexpectedBetweenParameterClauseAndEffectSpecifiers"},{"value":{"text":"FunctionEffectSpecifiersSyntax"},"ref":"FunctionEffectSpecifiersSyntax","name":"effectSpecifiers"},{"value":{"text":"nil"},"name":"unexpectedBetweenEffectSpecifiersAndReturnClause"},{"value":{"text":"nil"},"name":"returnClause"},{"value":{"text":"nil"},"name":"unexpectedAfterReturnClause"}]},{"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftParen"},{"value":{"text":"(","kind":"leftParen"},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndParameters"},{"value":{"text":"FunctionParameterListSyntax"},"ref":"FunctionParameterListSyntax","name":"parameters"},{"value":{"text":"nil"},"name":"unexpectedBetweenParametersAndRightParen"},{"value":{"kind":"rightParen","text":")"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedAfterRightParen"}],"text":"FunctionParameterClause","parent":175,"type":"other","id":176,"range":{"endRow":16,"startRow":16,"startColumn":14,"endColumn":38}},{"type":"other","structure":[],"parent":176,"token":{"kind":"leftParen","leadingTrivia":"","trailingTrivia":""},"id":177,"range":{"endRow":16,"startRow":16,"startColumn":14,"endColumn":15},"text":"("},{"structure":[{"name":"Element","value":{"text":"FunctionParameterSyntax"}},{"name":"Count","value":{"text":"1"}}],"text":"FunctionParameterList","parent":176,"type":"collection","id":178,"range":{"endRow":16,"startRow":16,"startColumn":15,"endColumn":37}},{"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeAttributes"},{"ref":"AttributeListSyntax","value":{"text":"AttributeListSyntax"},"name":"attributes"},{"value":{"text":"nil"},"name":"unexpectedBetweenAttributesAndModifiers"},{"ref":"DeclModifierListSyntax","value":{"text":"DeclModifierListSyntax"},"name":"modifiers"},{"value":{"text":"nil"},"name":"unexpectedBetweenModifiersAndFirstName"},{"value":{"text":"itemNamed","kind":"identifier("itemNamed")"},"name":"firstName"},{"value":{"text":"nil"},"name":"unexpectedBetweenFirstNameAndSecondName"},{"value":{"text":"name","kind":"identifier("name")"},"name":"secondName"},{"value":{"text":"nil"},"name":"unexpectedBetweenSecondNameAndColon"},{"value":{"text":":","kind":"colon"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndType"},{"ref":"IdentifierTypeSyntax","value":{"text":"IdentifierTypeSyntax"},"name":"type"},{"value":{"text":"nil"},"name":"unexpectedBetweenTypeAndEllipsis"},{"value":{"text":"nil"},"name":"ellipsis"},{"value":{"text":"nil"},"name":"unexpectedBetweenEllipsisAndDefaultValue"},{"value":{"text":"nil"},"name":"defaultValue"},{"value":{"text":"nil"},"name":"unexpectedBetweenDefaultValueAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"text":"FunctionParameter","parent":178,"type":"other","id":179,"range":{"endRow":16,"startRow":16,"endColumn":37,"startColumn":15}},{"type":"collection","id":180,"parent":179,"range":{"startRow":16,"endColumn":15,"startColumn":15,"endRow":16},"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"0"}}],"text":"AttributeList"},{"type":"collection","id":181,"parent":179,"range":{"startColumn":15,"startRow":16,"endColumn":15,"endRow":16},"structure":[{"value":{"text":"DeclModifierSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"text":"DeclModifierList"},{"type":"other","structure":[],"parent":179,"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"identifier("itemNamed")"},"id":182,"range":{"startColumn":15,"endRow":16,"startRow":16,"endColumn":24},"text":"itemNamed"},{"type":"other","structure":[],"parent":179,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"identifier("name")"},"id":183,"range":{"startColumn":25,"endRow":16,"startRow":16,"endColumn":29},"text":"name"},{"type":"other","structure":[],"parent":179,"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"colon"},"id":184,"range":{"startColumn":29,"endRow":16,"startRow":16,"endColumn":30},"text":":"},{"type":"type","id":185,"parent":179,"range":{"startColumn":31,"endRow":16,"startRow":16,"endColumn":37},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeName"},{"value":{"kind":"identifier("String")","text":"String"},"name":"name"},{"value":{"text":"nil"},"name":"unexpectedBetweenNameAndGenericArgumentClause"},{"value":{"text":"nil"},"name":"genericArgumentClause"},{"value":{"text":"nil"},"name":"unexpectedAfterGenericArgumentClause"}],"text":"IdentifierType"},{"type":"other","structure":[],"parent":185,"token":{"trailingTrivia":"","kind":"identifier("String")","leadingTrivia":""},"id":186,"range":{"endRow":16,"startRow":16,"endColumn":37,"startColumn":31},"text":"String"},{"type":"other","structure":[],"parent":176,"token":{"kind":"rightParen","trailingTrivia":"␣<\/span>","leadingTrivia":""},"range":{"endRow":16,"startRow":16,"startColumn":37,"endColumn":38},"id":187,"text":")"},{"parent":175,"text":"FunctionEffectSpecifiers","range":{"endRow":16,"startRow":16,"startColumn":39,"endColumn":45},"type":"other","id":188,"structure":[{"name":"unexpectedBeforeAsyncSpecifier","value":{"text":"nil"}},{"name":"asyncSpecifier","value":{"text":"nil"}},{"name":"unexpectedBetweenAsyncSpecifierAndThrowsClause","value":{"text":"nil"}},{"name":"throwsClause","ref":"ThrowsClauseSyntax","value":{"text":"ThrowsClauseSyntax"}},{"name":"unexpectedAfterThrowsClause","value":{"text":"nil"}}]},{"parent":188,"text":"ThrowsClause","range":{"endColumn":45,"startRow":16,"startColumn":39,"endRow":16},"type":"other","id":189,"structure":[{"name":"unexpectedBeforeThrowsSpecifier","value":{"text":"nil"}},{"name":"throwsSpecifier","value":{"text":"throws","kind":"keyword(SwiftSyntax.Keyword.throws)"}},{"name":"unexpectedBetweenThrowsSpecifierAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"text":"nil"}},{"name":"unexpectedBetweenLeftParenAndType","value":{"text":"nil"}},{"name":"type","value":{"text":"nil"}},{"name":"unexpectedBetweenTypeAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"text":"nil"}},{"name":"unexpectedAfterRightParen","value":{"text":"nil"}}]},{"type":"other","structure":[],"parent":189,"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.throws)"},"range":{"startRow":16,"startColumn":39,"endRow":16,"endColumn":45},"id":190,"text":"throws"},{"parent":170,"text":"CodeBlock","range":{"endRow":41,"endColumn":6,"startRow":16,"startColumn":46},"type":"other","structure":[{"name":"unexpectedBeforeLeftBrace","value":{"text":"nil"}},{"name":"leftBrace","value":{"kind":"leftBrace","text":"{"}},{"name":"unexpectedBetweenLeftBraceAndStatements","value":{"text":"nil"}},{"name":"statements","value":{"text":"CodeBlockItemListSyntax"},"ref":"CodeBlockItemListSyntax"},{"name":"unexpectedBetweenStatementsAndRightBrace","value":{"text":"nil"}},{"name":"rightBrace","value":{"kind":"rightBrace","text":"}"}},{"name":"unexpectedAfterRightBrace","value":{"text":"nil"}}],"id":191},{"type":"other","structure":[],"parent":191,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"leftBrace"},"range":{"startColumn":46,"startRow":16,"endColumn":47,"endRow":16},"id":192,"text":"{"},{"parent":191,"text":"CodeBlockItemList","range":{"startColumn":9,"startRow":17,"endColumn":36,"endRow":40},"type":"collection","structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"8"}}],"id":193},{"parent":193,"text":"CodeBlockItem","range":{"endColumn":10,"endRow":19,"startColumn":9,"startRow":17},"type":"other","structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","ref":"GuardStmtSyntax","value":{"text":"GuardStmtSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"id":194},{"parent":194,"text":"GuardStmt","range":{"endRow":19,"startColumn":9,"startRow":17,"endColumn":10},"type":"other","structure":[{"name":"unexpectedBeforeGuardKeyword","value":{"text":"nil"}},{"name":"guardKeyword","value":{"kind":"keyword(SwiftSyntax.Keyword.guard)","text":"guard"}},{"name":"unexpectedBetweenGuardKeywordAndConditions","value":{"text":"nil"}},{"name":"conditions","value":{"text":"ConditionElementListSyntax"},"ref":"ConditionElementListSyntax"},{"name":"unexpectedBetweenConditionsAndElseKeyword","value":{"text":"nil"}},{"name":"elseKeyword","value":{"text":"else","kind":"keyword(SwiftSyntax.Keyword.else)"}},{"name":"unexpectedBetweenElseKeywordAndBody","value":{"text":"nil"}},{"name":"body","value":{"text":"CodeBlockSyntax"},"ref":"CodeBlockSyntax"},{"name":"unexpectedAfterBody","value":{"text":"nil"}}],"id":195},{"type":"other","structure":[],"parent":195,"token":{"kind":"keyword(SwiftSyntax.Keyword.guard)","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"␣<\/span>"},"id":196,"range":{"endRow":17,"startColumn":9,"endColumn":14,"startRow":17},"text":"guard"},{"parent":195,"structure":[{"name":"Element","value":{"text":"ConditionElementSyntax"}},{"name":"Count","value":{"text":"1"}}],"type":"collection","text":"ConditionElementList","id":197,"range":{"endRow":17,"startColumn":15,"endColumn":41,"startRow":17}},{"parent":197,"structure":[{"name":"unexpectedBeforeCondition","value":{"text":"nil"}},{"name":"condition","value":{"text":"OptionalBindingConditionSyntax"},"ref":"OptionalBindingConditionSyntax"},{"name":"unexpectedBetweenConditionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other","text":"ConditionElement","id":198,"range":{"endRow":17,"startColumn":15,"startRow":17,"endColumn":41}},{"type":"other","structure":[{"name":"unexpectedBeforeBindingSpecifier","value":{"text":"nil"}},{"name":"bindingSpecifier","value":{"text":"let","kind":"keyword(SwiftSyntax.Keyword.let)"}},{"name":"unexpectedBetweenBindingSpecifierAndPattern","value":{"text":"nil"}},{"name":"pattern","ref":"IdentifierPatternSyntax","value":{"text":"IdentifierPatternSyntax"}},{"name":"unexpectedBetweenPatternAndTypeAnnotation","value":{"text":"nil"}},{"name":"typeAnnotation","value":{"text":"nil"}},{"name":"unexpectedBetweenTypeAnnotationAndInitializer","value":{"text":"nil"}},{"name":"initializer","ref":"InitializerClauseSyntax","value":{"text":"InitializerClauseSyntax"}},{"name":"unexpectedAfterInitializer","value":{"text":"nil"}}],"range":{"endRow":17,"startColumn":15,"endColumn":41,"startRow":17},"id":199,"parent":198,"text":"OptionalBindingCondition"},{"type":"other","structure":[],"parent":199,"token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"keyword(SwiftSyntax.Keyword.let)"},"range":{"endRow":17,"startColumn":15,"startRow":17,"endColumn":18},"id":200,"text":"let"},{"type":"pattern","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeIdentifier"},{"value":{"kind":"identifier("item")","text":"item"},"name":"identifier"},{"value":{"text":"nil"},"name":"unexpectedAfterIdentifier"}],"range":{"endRow":17,"startColumn":19,"startRow":17,"endColumn":23},"id":201,"parent":199,"text":"IdentifierPattern"},{"type":"other","structure":[],"parent":201,"token":{"kind":"identifier("item")","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"range":{"startRow":17,"endRow":17,"endColumn":23,"startColumn":19},"id":202,"text":"item"},{"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeEqual"},{"value":{"kind":"equal","text":"="},"name":"equal"},{"value":{"text":"nil"},"name":"unexpectedBetweenEqualAndValue"},{"value":{"text":"SubscriptCallExprSyntax"},"ref":"SubscriptCallExprSyntax","name":"value"},{"value":{"text":"nil"},"name":"unexpectedAfterValue"}],"type":"other","parent":199,"id":203,"text":"InitializerClause","range":{"startColumn":24,"startRow":17,"endColumn":41,"endRow":17}},{"type":"other","structure":[],"parent":203,"token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"equal"},"id":204,"range":{"endRow":17,"endColumn":25,"startColumn":24,"startRow":17},"text":"="},{"structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"name":"calledExpression","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenCalledExpressionAndLeftSquare","value":{"text":"nil"}},{"name":"leftSquare","value":{"text":"[","kind":"leftSquare"}},{"name":"unexpectedBetweenLeftSquareAndArguments","value":{"text":"nil"}},{"name":"arguments","ref":"LabeledExprListSyntax","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenArgumentsAndRightSquare","value":{"text":"nil"}},{"name":"rightSquare","value":{"kind":"rightSquare","text":"]"}},{"name":"unexpectedBetweenRightSquareAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"name":"additionalTrailingClosures","ref":"MultipleTrailingClosureElementListSyntax","value":{"text":"MultipleTrailingClosureElementListSyntax"}},{"name":"unexpectedAfterAdditionalTrailingClosures","value":{"text":"nil"}}],"type":"expr","parent":203,"id":205,"text":"SubscriptCallExpr","range":{"endRow":17,"endColumn":41,"startColumn":26,"startRow":17}},{"range":{"endColumn":35,"endRow":17,"startColumn":26,"startRow":17},"id":206,"parent":205,"text":"DeclReferenceExpr","structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"inventory","kind":"identifier("inventory")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr"},{"type":"other","structure":[],"parent":206,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"identifier("inventory")"},"range":{"endColumn":35,"endRow":17,"startRow":17,"startColumn":26},"id":207,"text":"inventory"},{"type":"other","structure":[],"parent":205,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"leftSquare"},"range":{"endColumn":36,"endRow":17,"startRow":17,"startColumn":35},"id":208,"text":"["},{"range":{"endColumn":40,"endRow":17,"startRow":17,"startColumn":36},"id":209,"parent":205,"text":"LabeledExprList","structure":[{"value":{"text":"LabeledExprSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}],"type":"collection"},{"range":{"endRow":17,"startRow":17,"startColumn":36,"endColumn":40},"id":210,"parent":209,"text":"LabeledExpr","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"text":"nil"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"text":"nil"},"name":"colon"},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"type":"other"},{"text":"DeclReferenceExpr","id":211,"range":{"startColumn":36,"startRow":17,"endColumn":40,"endRow":17},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"name","kind":"identifier("name")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}],"type":"expr","parent":210},{"text":"name","parent":211,"range":{"startRow":17,"startColumn":36,"endRow":17,"endColumn":40},"token":{"trailingTrivia":"","kind":"identifier("name")","leadingTrivia":""},"id":212,"type":"other","structure":[]},{"text":"]","parent":205,"range":{"startRow":17,"startColumn":40,"endRow":17,"endColumn":41},"token":{"trailingTrivia":"␣<\/span>","kind":"rightSquare","leadingTrivia":""},"id":213,"type":"other","structure":[]},{"text":"MultipleTrailingClosureElementList","id":214,"range":{"startRow":17,"startColumn":42,"endRow":17,"endColumn":42},"structure":[{"value":{"text":"MultipleTrailingClosureElementSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"type":"collection","parent":205},{"text":"else","parent":195,"range":{"startRow":17,"startColumn":42,"endColumn":46,"endRow":17},"token":{"leadingTrivia":"","kind":"keyword(SwiftSyntax.Keyword.else)","trailingTrivia":"␣<\/span>"},"id":215,"type":"other","structure":[]},{"range":{"endRow":19,"endColumn":10,"startRow":17,"startColumn":47},"type":"other","structure":[{"name":"unexpectedBeforeLeftBrace","value":{"text":"nil"}},{"name":"leftBrace","value":{"kind":"leftBrace","text":"{"}},{"name":"unexpectedBetweenLeftBraceAndStatements","value":{"text":"nil"}},{"name":"statements","ref":"CodeBlockItemListSyntax","value":{"text":"CodeBlockItemListSyntax"}},{"name":"unexpectedBetweenStatementsAndRightBrace","value":{"text":"nil"}},{"name":"rightBrace","value":{"kind":"rightBrace","text":"}"}},{"name":"unexpectedAfterRightBrace","value":{"text":"nil"}}],"text":"CodeBlock","id":216,"parent":195},{"text":"{","parent":216,"range":{"startColumn":47,"startRow":17,"endColumn":48,"endRow":17},"token":{"kind":"leftBrace","trailingTrivia":"","leadingTrivia":""},"id":217,"type":"other","structure":[]},{"range":{"startColumn":13,"startRow":18,"endColumn":55,"endRow":18},"type":"collection","structure":[{"value":{"text":"CodeBlockItemSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}],"text":"CodeBlockItemList","id":218,"parent":216},{"range":{"startColumn":13,"endRow":18,"endColumn":55,"startRow":18},"type":"other","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeItem"},{"ref":"ThrowStmtSyntax","value":{"text":"ThrowStmtSyntax"},"name":"item"},{"value":{"text":"nil"},"name":"unexpectedBetweenItemAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}],"text":"CodeBlockItem","id":219,"parent":218},{"range":{"endRow":18,"endColumn":55,"startRow":18,"startColumn":13},"type":"other","structure":[{"name":"unexpectedBeforeThrowKeyword","value":{"text":"nil"}},{"name":"throwKeyword","value":{"text":"throw","kind":"keyword(SwiftSyntax.Keyword.throw)"}},{"name":"unexpectedBetweenThrowKeywordAndExpression","value":{"text":"nil"}},{"name":"expression","ref":"MemberAccessExprSyntax","value":{"text":"MemberAccessExprSyntax"}},{"name":"unexpectedAfterExpression","value":{"text":"nil"}}],"text":"ThrowStmt","id":220,"parent":219},{"text":"throw","parent":220,"range":{"startColumn":13,"startRow":18,"endColumn":18,"endRow":18},"token":{"leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.throw)"},"id":221,"type":"other","structure":[]},{"id":222,"parent":220,"type":"expr","text":"MemberAccessExpr","range":{"startColumn":19,"startRow":18,"endColumn":55,"endRow":18},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBase"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"base","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseAndPeriod"},{"value":{"text":".","kind":"period"},"name":"period"},{"value":{"text":"nil"},"name":"unexpectedBetweenPeriodAndDeclName"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"declName","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedAfterDeclName"}]},{"id":223,"parent":222,"type":"expr","text":"DeclReferenceExpr","range":{"endRow":18,"startColumn":19,"endColumn":38,"startRow":18},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"kind":"identifier("VendingMachineError")","text":"VendingMachineError"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"text":"VendingMachineError","parent":223,"range":{"startRow":18,"endRow":18,"endColumn":38,"startColumn":19},"token":{"leadingTrivia":"","trailingTrivia":"","kind":"identifier("VendingMachineError")"},"id":224,"type":"other","structure":[]},{"text":".","parent":222,"range":{"startRow":18,"endRow":18,"endColumn":39,"startColumn":38},"token":{"leadingTrivia":"","trailingTrivia":"","kind":"period"},"id":225,"type":"other","structure":[]},{"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"invalidSelection","kind":"identifier("invalidSelection")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"text":"DeclReferenceExpr","range":{"startRow":18,"endRow":18,"endColumn":55,"startColumn":39},"type":"expr","parent":222,"id":226},{"text":"invalidSelection","parent":226,"range":{"endRow":18,"startColumn":39,"endColumn":55,"startRow":18},"token":{"leadingTrivia":"","kind":"identifier("invalidSelection")","trailingTrivia":""},"id":227,"type":"other","structure":[]},{"text":"}","parent":216,"range":{"endRow":19,"startColumn":9,"endColumn":10,"startRow":19},"token":{"leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","kind":"rightBrace","trailingTrivia":""},"id":228,"type":"other","structure":[]},{"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","value":{"text":"GuardStmtSyntax"},"ref":"GuardStmtSyntax"},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"text":"CodeBlockItem","range":{"endRow":24,"startColumn":9,"endColumn":10,"startRow":22},"type":"other","parent":193,"id":229},{"text":"GuardStmt","structure":[{"name":"unexpectedBeforeGuardKeyword","value":{"text":"nil"}},{"name":"guardKeyword","value":{"text":"guard","kind":"keyword(SwiftSyntax.Keyword.guard)"}},{"name":"unexpectedBetweenGuardKeywordAndConditions","value":{"text":"nil"}},{"name":"conditions","value":{"text":"ConditionElementListSyntax"},"ref":"ConditionElementListSyntax"},{"name":"unexpectedBetweenConditionsAndElseKeyword","value":{"text":"nil"}},{"name":"elseKeyword","value":{"text":"else","kind":"keyword(SwiftSyntax.Keyword.else)"}},{"name":"unexpectedBetweenElseKeywordAndBody","value":{"text":"nil"}},{"name":"body","value":{"text":"CodeBlockSyntax"},"ref":"CodeBlockSyntax"},{"name":"unexpectedAfterBody","value":{"text":"nil"}}],"type":"other","parent":229,"id":230,"range":{"startRow":22,"endColumn":10,"startColumn":9,"endRow":24}},{"text":"guard","parent":230,"range":{"startColumn":9,"endRow":22,"startRow":22,"endColumn":14},"token":{"kind":"keyword(SwiftSyntax.Keyword.guard)","trailingTrivia":"␣<\/span>","leadingTrivia":"↲<\/span>↲<\/span>↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"},"id":231,"type":"other","structure":[]},{"text":"ConditionElementList","structure":[{"value":{"text":"ConditionElementSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}],"type":"collection","parent":230,"id":232,"range":{"startColumn":15,"endRow":22,"startRow":22,"endColumn":29}},{"text":"ConditionElement","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCondition"},{"ref":"InfixOperatorExprSyntax","value":{"text":"InfixOperatorExprSyntax"},"name":"condition"},{"value":{"text":"nil"},"name":"unexpectedBetweenConditionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other","parent":232,"id":233,"range":{"endColumn":29,"startColumn":15,"startRow":22,"endRow":22}},{"text":"InfixOperatorExpr","parent":233,"range":{"endColumn":29,"endRow":22,"startRow":22,"startColumn":15},"structure":[{"name":"unexpectedBeforeLeftOperand","value":{"text":"nil"}},{"name":"leftOperand","value":{"text":"MemberAccessExprSyntax"},"ref":"MemberAccessExprSyntax"},{"name":"unexpectedBetweenLeftOperandAndOperator","value":{"text":"nil"}},{"name":"operator","value":{"text":"BinaryOperatorExprSyntax"},"ref":"BinaryOperatorExprSyntax"},{"name":"unexpectedBetweenOperatorAndRightOperand","value":{"text":"nil"}},{"name":"rightOperand","value":{"text":"IntegerLiteralExprSyntax"},"ref":"IntegerLiteralExprSyntax"},{"name":"unexpectedAfterRightOperand","value":{"text":"nil"}}],"type":"expr","id":234},{"text":"MemberAccessExpr","parent":234,"range":{"startColumn":15,"endRow":22,"endColumn":25,"startRow":22},"structure":[{"name":"unexpectedBeforeBase","value":{"text":"nil"}},{"name":"base","value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax"},{"name":"unexpectedBetweenBaseAndPeriod","value":{"text":"nil"}},{"name":"period","value":{"kind":"period","text":"."}},{"name":"unexpectedBetweenPeriodAndDeclName","value":{"text":"nil"}},{"name":"declName","value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax"},{"name":"unexpectedAfterDeclName","value":{"text":"nil"}}],"type":"expr","id":235},{"parent":235,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("item")","text":"item"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"text":"DeclReferenceExpr","type":"expr","id":236,"range":{"endRow":22,"startColumn":15,"endColumn":19,"startRow":22}},{"text":"item","parent":236,"range":{"startColumn":15,"endRow":22,"startRow":22,"endColumn":19},"token":{"leadingTrivia":"","kind":"identifier("item")","trailingTrivia":""},"id":237,"type":"other","structure":[]},{"text":".","parent":235,"range":{"startColumn":19,"endRow":22,"startRow":22,"endColumn":20},"token":{"leadingTrivia":"","kind":"period","trailingTrivia":""},"id":238,"type":"other","structure":[]},{"parent":235,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("count")","text":"count"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"text":"DeclReferenceExpr","type":"expr","id":239,"range":{"startColumn":20,"endRow":22,"startRow":22,"endColumn":25}},{"text":"count","parent":239,"range":{"startColumn":20,"startRow":22,"endRow":22,"endColumn":25},"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"identifier("count")"},"id":240,"type":"other","structure":[]},{"parent":234,"structure":[{"name":"unexpectedBeforeOperator","value":{"text":"nil"}},{"name":"operator","value":{"kind":"binaryOperator(">")","text":">"}},{"value":{"text":"nil"},"name":"unexpectedAfterOperator"}],"text":"BinaryOperatorExpr","type":"expr","id":241,"range":{"startColumn":26,"startRow":22,"endRow":22,"endColumn":27}},{"text":">","parent":241,"range":{"startColumn":26,"startRow":22,"endColumn":27,"endRow":22},"token":{"trailingTrivia":"␣<\/span>","kind":"binaryOperator(">")","leadingTrivia":""},"id":242,"type":"other","structure":[]},{"text":"IntegerLiteralExpr","id":243,"parent":234,"range":{"startColumn":28,"startRow":22,"endColumn":29,"endRow":22},"structure":[{"name":"unexpectedBeforeLiteral","value":{"text":"nil"}},{"name":"literal","value":{"text":"0","kind":"integerLiteral("0")"}},{"name":"unexpectedAfterLiteral","value":{"text":"nil"}}],"type":"expr"},{"text":"0","parent":243,"range":{"endRow":22,"startRow":22,"endColumn":29,"startColumn":28},"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"integerLiteral("0")"},"id":244,"type":"other","structure":[]},{"text":"else","parent":230,"range":{"endRow":22,"startRow":22,"endColumn":34,"startColumn":30},"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.else)"},"id":245,"type":"other","structure":[]},{"text":"CodeBlock","id":246,"parent":230,"range":{"endRow":24,"startRow":22,"endColumn":10,"startColumn":35},"structure":[{"name":"unexpectedBeforeLeftBrace","value":{"text":"nil"}},{"name":"leftBrace","value":{"text":"{","kind":"leftBrace"}},{"name":"unexpectedBetweenLeftBraceAndStatements","value":{"text":"nil"}},{"ref":"CodeBlockItemListSyntax","name":"statements","value":{"text":"CodeBlockItemListSyntax"}},{"name":"unexpectedBetweenStatementsAndRightBrace","value":{"text":"nil"}},{"name":"rightBrace","value":{"kind":"rightBrace","text":"}"}},{"name":"unexpectedAfterRightBrace","value":{"text":"nil"}}],"type":"other"},{"text":"{","parent":246,"range":{"startColumn":35,"endRow":22,"endColumn":36,"startRow":22},"token":{"kind":"leftBrace","leadingTrivia":"","trailingTrivia":""},"id":247,"type":"other","structure":[]},{"structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"1"}}],"type":"collection","id":248,"parent":246,"text":"CodeBlockItemList","range":{"endColumn":49,"startColumn":13,"endRow":23,"startRow":23}},{"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","ref":"ThrowStmtSyntax","value":{"text":"ThrowStmtSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"type":"other","id":249,"parent":248,"text":"CodeBlockItem","range":{"endRow":23,"endColumn":49,"startColumn":13,"startRow":23}},{"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeThrowKeyword"},{"value":{"kind":"keyword(SwiftSyntax.Keyword.throw)","text":"throw"},"name":"throwKeyword"},{"value":{"text":"nil"},"name":"unexpectedBetweenThrowKeywordAndExpression"},{"value":{"text":"MemberAccessExprSyntax"},"ref":"MemberAccessExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedAfterExpression"}],"type":"other","id":250,"parent":249,"text":"ThrowStmt","range":{"endColumn":49,"startColumn":13,"startRow":23,"endRow":23}},{"text":"throw","parent":250,"range":{"startRow":23,"endColumn":18,"startColumn":13,"endRow":23},"token":{"kind":"keyword(SwiftSyntax.Keyword.throw)","trailingTrivia":"␣<\/span>","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"},"id":251,"type":"other","structure":[]},{"structure":[{"name":"unexpectedBeforeBase","value":{"text":"nil"}},{"name":"base","value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseAndPeriod"},{"value":{"text":".","kind":"period"},"name":"period"},{"value":{"text":"nil"},"name":"unexpectedBetweenPeriodAndDeclName"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"declName"},{"value":{"text":"nil"},"name":"unexpectedAfterDeclName"}],"type":"expr","id":252,"parent":250,"text":"MemberAccessExpr","range":{"startRow":23,"endColumn":49,"startColumn":19,"endRow":23}},{"range":{"startColumn":19,"endRow":23,"endColumn":38,"startRow":23},"parent":252,"text":"DeclReferenceExpr","id":253,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("VendingMachineError")","text":"VendingMachineError"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr"},{"text":"VendingMachineError","parent":253,"range":{"startColumn":19,"startRow":23,"endRow":23,"endColumn":38},"token":{"trailingTrivia":"","leadingTrivia":"","kind":"identifier("VendingMachineError")"},"id":254,"type":"other","structure":[]},{"text":".","parent":252,"range":{"startColumn":38,"startRow":23,"endRow":23,"endColumn":39},"token":{"trailingTrivia":"","leadingTrivia":"","kind":"period"},"id":255,"type":"other","structure":[]},{"range":{"startColumn":39,"startRow":23,"endRow":23,"endColumn":49},"parent":252,"text":"DeclReferenceExpr","id":256,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"outOfStock","kind":"identifier("outOfStock")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr"},{"text":"outOfStock","parent":256,"range":{"endColumn":49,"startColumn":39,"endRow":23,"startRow":23},"token":{"trailingTrivia":"","kind":"identifier("outOfStock")","leadingTrivia":""},"id":257,"type":"other","structure":[]},{"parent":246,"id":258,"type":"other","token":{"trailingTrivia":"","kind":"rightBrace","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"},"structure":[],"range":{"endColumn":10,"startColumn":9,"endRow":24,"startRow":24},"text":"}"},{"range":{"endColumn":10,"startColumn":9,"endRow":29,"startRow":27},"id":259,"text":"CodeBlockItem","parent":193,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","value":{"text":"GuardStmtSyntax"},"ref":"GuardStmtSyntax"},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"type":"other"},{"range":{"endRow":29,"endColumn":10,"startColumn":9,"startRow":27},"id":260,"text":"GuardStmt","parent":259,"structure":[{"name":"unexpectedBeforeGuardKeyword","value":{"text":"nil"}},{"name":"guardKeyword","value":{"text":"guard","kind":"keyword(SwiftSyntax.Keyword.guard)"}},{"name":"unexpectedBetweenGuardKeywordAndConditions","value":{"text":"nil"}},{"name":"conditions","value":{"text":"ConditionElementListSyntax"},"ref":"ConditionElementListSyntax"},{"name":"unexpectedBetweenConditionsAndElseKeyword","value":{"text":"nil"}},{"name":"elseKeyword","value":{"text":"else","kind":"keyword(SwiftSyntax.Keyword.else)"}},{"name":"unexpectedBetweenElseKeywordAndBody","value":{"text":"nil"}},{"name":"body","value":{"text":"CodeBlockSyntax"},"ref":"CodeBlockSyntax"},{"name":"unexpectedAfterBody","value":{"text":"nil"}}],"type":"other"},{"parent":260,"id":261,"type":"other","token":{"kind":"keyword(SwiftSyntax.Keyword.guard)","leadingTrivia":"↲<\/span>↲<\/span>↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"␣<\/span>"},"structure":[],"range":{"startColumn":9,"startRow":27,"endRow":27,"endColumn":14},"text":"guard"},{"parent":260,"type":"collection","id":262,"structure":[{"name":"Element","value":{"text":"ConditionElementSyntax"}},{"name":"Count","value":{"text":"1"}}],"range":{"startColumn":15,"startRow":27,"endRow":27,"endColumn":43},"text":"ConditionElementList"},{"parent":262,"type":"other","id":263,"structure":[{"name":"unexpectedBeforeCondition","value":{"text":"nil"}},{"name":"condition","value":{"text":"InfixOperatorExprSyntax"},"ref":"InfixOperatorExprSyntax"},{"name":"unexpectedBetweenConditionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"range":{"endRow":27,"startRow":27,"startColumn":15,"endColumn":43},"text":"ConditionElement"},{"parent":263,"type":"expr","id":264,"structure":[{"name":"unexpectedBeforeLeftOperand","value":{"text":"nil"}},{"name":"leftOperand","value":{"text":"MemberAccessExprSyntax"},"ref":"MemberAccessExprSyntax"},{"name":"unexpectedBetweenLeftOperandAndOperator","value":{"text":"nil"}},{"name":"operator","value":{"text":"BinaryOperatorExprSyntax"},"ref":"BinaryOperatorExprSyntax"},{"name":"unexpectedBetweenOperatorAndRightOperand","value":{"text":"nil"}},{"name":"rightOperand","value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax"},{"name":"unexpectedAfterRightOperand","value":{"text":"nil"}}],"range":{"startColumn":15,"startRow":27,"endColumn":43,"endRow":27},"text":"InfixOperatorExpr"},{"parent":264,"text":"MemberAccessExpr","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBase"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"base","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseAndPeriod"},{"value":{"kind":"period","text":"."},"name":"period"},{"value":{"text":"nil"},"name":"unexpectedBetweenPeriodAndDeclName"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"declName","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedAfterDeclName"}],"type":"expr","range":{"startRow":27,"endColumn":25,"endRow":27,"startColumn":15},"id":265},{"parent":265,"text":"DeclReferenceExpr","structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"item","kind":"identifier("item")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr","range":{"startColumn":15,"endRow":27,"endColumn":19,"startRow":27},"id":266},{"parent":266,"id":267,"type":"other","token":{"kind":"identifier("item")","leadingTrivia":"","trailingTrivia":""},"structure":[],"range":{"startColumn":15,"startRow":27,"endColumn":19,"endRow":27},"text":"item"},{"parent":265,"id":268,"type":"other","token":{"kind":"period","leadingTrivia":"","trailingTrivia":""},"structure":[],"range":{"startRow":27,"endRow":27,"startColumn":19,"endColumn":20},"text":"."},{"parent":265,"text":"DeclReferenceExpr","id":269,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"kind":"identifier("price")","text":"price"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}],"type":"expr","range":{"endColumn":25,"startRow":27,"endRow":27,"startColumn":20}},{"parent":269,"id":270,"type":"other","token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"identifier("price")"},"structure":[],"range":{"startColumn":20,"endColumn":25,"startRow":27,"endRow":27},"text":"price"},{"parent":264,"text":"BinaryOperatorExpr","id":271,"structure":[{"name":"unexpectedBeforeOperator","value":{"text":"nil"}},{"name":"operator","value":{"text":"<=","kind":"binaryOperator("<=")"}},{"name":"unexpectedAfterOperator","value":{"text":"nil"}}],"type":"expr","range":{"startColumn":26,"endColumn":28,"startRow":27,"endRow":27}},{"parent":271,"id":272,"type":"other","token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"binaryOperator("<=")"},"structure":[],"range":{"startRow":27,"endRow":27,"startColumn":26,"endColumn":28},"text":"<="},{"parent":264,"text":"DeclReferenceExpr","id":273,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"kind":"identifier("coinsDeposited")","text":"coinsDeposited"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}],"type":"expr","range":{"startRow":27,"endRow":27,"startColumn":29,"endColumn":43}},{"parent":273,"id":274,"type":"other","token":{"trailingTrivia":"␣<\/span>","kind":"identifier("coinsDeposited")","leadingTrivia":""},"structure":[],"range":{"startRow":27,"startColumn":29,"endRow":27,"endColumn":43},"text":"coinsDeposited"},{"parent":260,"id":275,"type":"other","token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"keyword(SwiftSyntax.Keyword.else)"},"structure":[],"range":{"startColumn":44,"startRow":27,"endRow":27,"endColumn":48},"text":"else"},{"text":"CodeBlock","range":{"startColumn":49,"startRow":27,"endRow":29,"endColumn":10},"parent":260,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftBrace"},{"value":{"text":"{","kind":"leftBrace"},"name":"leftBrace"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftBraceAndStatements"},{"value":{"text":"CodeBlockItemListSyntax"},"name":"statements","ref":"CodeBlockItemListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenStatementsAndRightBrace"},{"value":{"kind":"rightBrace","text":"}"},"name":"rightBrace"},{"value":{"text":"nil"},"name":"unexpectedAfterRightBrace"}],"type":"other","id":276},{"parent":276,"id":277,"type":"other","token":{"kind":"leftBrace","trailingTrivia":"","leadingTrivia":""},"structure":[],"range":{"startColumn":49,"endColumn":50,"startRow":27,"endRow":27},"text":"{"},{"text":"CodeBlockItemList","range":{"startColumn":13,"endColumn":98,"startRow":28,"endRow":28},"parent":276,"structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"1"}}],"type":"collection","id":278},{"text":"CodeBlockItem","range":{"startColumn":13,"endColumn":98,"endRow":28,"startRow":28},"parent":278,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeItem"},{"ref":"ThrowStmtSyntax","value":{"text":"ThrowStmtSyntax"},"name":"item"},{"value":{"text":"nil"},"name":"unexpectedBetweenItemAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}],"type":"other","id":279},{"range":{"startRow":28,"endRow":28,"endColumn":98,"startColumn":13},"parent":279,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeThrowKeyword"},{"value":{"text":"throw","kind":"keyword(SwiftSyntax.Keyword.throw)"},"name":"throwKeyword"},{"value":{"text":"nil"},"name":"unexpectedBetweenThrowKeywordAndExpression"},{"ref":"FunctionCallExprSyntax","value":{"text":"FunctionCallExprSyntax"},"name":"expression"},{"value":{"text":"nil"},"name":"unexpectedAfterExpression"}],"type":"other","text":"ThrowStmt","id":280},{"parent":280,"id":281,"type":"other","token":{"kind":"keyword(SwiftSyntax.Keyword.throw)","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"␣<\/span>"},"structure":[],"range":{"startRow":28,"endRow":28,"endColumn":18,"startColumn":13},"text":"throw"},{"range":{"startRow":28,"endRow":28,"endColumn":98,"startColumn":19},"parent":280,"structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"name":"calledExpression","ref":"MemberAccessExprSyntax","value":{"text":"MemberAccessExprSyntax"}},{"name":"unexpectedBetweenCalledExpressionAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"text":"(","kind":"leftParen"}},{"name":"unexpectedBetweenLeftParenAndArguments","value":{"text":"nil"}},{"name":"arguments","ref":"LabeledExprListSyntax","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenArgumentsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"kind":"rightParen","text":")"}},{"name":"unexpectedBetweenRightParenAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"name":"additionalTrailingClosures","ref":"MultipleTrailingClosureElementListSyntax","value":{"text":"MultipleTrailingClosureElementListSyntax"}},{"name":"unexpectedAfterAdditionalTrailingClosures","value":{"text":"nil"}}],"type":"expr","text":"FunctionCallExpr","id":282},{"text":"MemberAccessExpr","id":283,"parent":282,"range":{"startColumn":19,"endRow":28,"startRow":28,"endColumn":56},"type":"expr","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBase"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"base","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseAndPeriod"},{"value":{"kind":"period","text":"."},"name":"period"},{"value":{"text":"nil"},"name":"unexpectedBetweenPeriodAndDeclName"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"declName","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedAfterDeclName"}]},{"text":"DeclReferenceExpr","id":284,"parent":283,"range":{"endRow":28,"endColumn":38,"startColumn":19,"startRow":28},"type":"expr","structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"VendingMachineError","kind":"identifier("VendingMachineError")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"parent":284,"id":285,"type":"other","token":{"trailingTrivia":"","kind":"identifier("VendingMachineError")","leadingTrivia":""},"structure":[],"range":{"endColumn":38,"startRow":28,"startColumn":19,"endRow":28},"text":"VendingMachineError"},{"parent":283,"id":286,"type":"other","token":{"trailingTrivia":"","kind":"period","leadingTrivia":""},"structure":[],"range":{"endColumn":39,"startRow":28,"startColumn":38,"endRow":28},"text":"."},{"text":"DeclReferenceExpr","id":287,"parent":283,"range":{"endColumn":56,"startRow":28,"startColumn":39,"endRow":28},"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"insufficientFunds","kind":"identifier("insufficientFunds")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr"},{"parent":287,"id":288,"type":"other","token":{"leadingTrivia":"","trailingTrivia":"","kind":"identifier("insufficientFunds")"},"structure":[],"range":{"startRow":28,"endRow":28,"startColumn":39,"endColumn":56},"text":"insufficientFunds"},{"parent":282,"id":289,"type":"other","token":{"leadingTrivia":"","trailingTrivia":"","kind":"leftParen"},"structure":[],"range":{"startRow":28,"endRow":28,"startColumn":56,"endColumn":57},"text":"("},{"text":"LabeledExprList","id":290,"parent":282,"range":{"startRow":28,"endRow":28,"startColumn":57,"endColumn":97},"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"1"}}],"type":"collection"},{"text":"LabeledExpr","id":291,"parent":290,"range":{"startRow":28,"startColumn":57,"endRow":28,"endColumn":97},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"kind":"identifier("coinsNeeded")","text":"coinsNeeded"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"kind":"colon","text":":"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"InfixOperatorExprSyntax"},"ref":"InfixOperatorExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other"},{"parent":291,"id":292,"type":"other","token":{"trailingTrivia":"","kind":"identifier("coinsNeeded")","leadingTrivia":""},"structure":[],"range":{"startRow":28,"endRow":28,"startColumn":57,"endColumn":68},"text":"coinsNeeded"},{"parent":291,"id":293,"type":"other","token":{"trailingTrivia":"␣<\/span>","kind":"colon","leadingTrivia":""},"structure":[],"range":{"startRow":28,"endRow":28,"startColumn":68,"endColumn":69},"text":":"},{"id":294,"structure":[{"name":"unexpectedBeforeLeftOperand","value":{"text":"nil"}},{"name":"leftOperand","ref":"MemberAccessExprSyntax","value":{"text":"MemberAccessExprSyntax"}},{"name":"unexpectedBetweenLeftOperandAndOperator","value":{"text":"nil"}},{"name":"operator","ref":"BinaryOperatorExprSyntax","value":{"text":"BinaryOperatorExprSyntax"}},{"name":"unexpectedBetweenOperatorAndRightOperand","value":{"text":"nil"}},{"name":"rightOperand","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedAfterRightOperand","value":{"text":"nil"}}],"type":"expr","range":{"startRow":28,"endRow":28,"startColumn":70,"endColumn":97},"parent":291,"text":"InfixOperatorExpr"},{"id":295,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBase"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"base","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseAndPeriod"},{"value":{"kind":"period","text":"."},"name":"period"},{"value":{"text":"nil"},"name":"unexpectedBetweenPeriodAndDeclName"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"declName"},{"value":{"text":"nil"},"name":"unexpectedAfterDeclName"}],"type":"expr","range":{"startRow":28,"endColumn":80,"endRow":28,"startColumn":70},"parent":294,"text":"MemberAccessExpr"},{"parent":295,"id":296,"text":"DeclReferenceExpr","range":{"startColumn":70,"startRow":28,"endRow":28,"endColumn":74},"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"item","kind":"identifier("item")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr"},{"parent":296,"id":297,"type":"other","token":{"leadingTrivia":"","kind":"identifier("item")","trailingTrivia":""},"structure":[],"range":{"startColumn":70,"startRow":28,"endColumn":74,"endRow":28},"text":"item"},{"parent":295,"id":298,"type":"other","token":{"leadingTrivia":"","kind":"period","trailingTrivia":""},"structure":[],"range":{"startColumn":74,"startRow":28,"endColumn":75,"endRow":28},"text":"."},{"parent":295,"id":299,"text":"DeclReferenceExpr","range":{"startColumn":75,"startRow":28,"endColumn":80,"endRow":28},"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"price","kind":"identifier("price")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}],"type":"expr"},{"parent":299,"id":300,"type":"other","token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"identifier("price")"},"structure":[],"range":{"startRow":28,"startColumn":75,"endRow":28,"endColumn":80},"text":"price"},{"type":"expr","id":301,"text":"BinaryOperatorExpr","range":{"startRow":28,"startColumn":81,"endRow":28,"endColumn":82},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeOperator"},{"value":{"kind":"binaryOperator("-")","text":"-"},"name":"operator"},{"value":{"text":"nil"},"name":"unexpectedAfterOperator"}],"parent":294},{"parent":301,"id":302,"type":"other","token":{"leadingTrivia":"","kind":"binaryOperator("-")","trailingTrivia":"␣<\/span>"},"structure":[],"range":{"endColumn":82,"startRow":28,"startColumn":81,"endRow":28},"text":"-"},{"type":"expr","id":303,"text":"DeclReferenceExpr","range":{"endColumn":97,"startRow":28,"startColumn":83,"endRow":28},"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("coinsDeposited")","text":"coinsDeposited"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"parent":294},{"parent":303,"id":304,"type":"other","token":{"kind":"identifier("coinsDeposited")","leadingTrivia":"","trailingTrivia":""},"structure":[],"range":{"endRow":28,"startColumn":83,"endColumn":97,"startRow":28},"text":"coinsDeposited"},{"parent":282,"type":"other","range":{"endRow":28,"startColumn":97,"endColumn":98,"startRow":28},"structure":[],"text":")","id":305,"token":{"kind":"rightParen","leadingTrivia":"","trailingTrivia":""}},{"type":"collection","id":306,"text":"MultipleTrailingClosureElementList","range":{"endRow":28,"startColumn":98,"endColumn":98,"startRow":28},"structure":[{"name":"Element","value":{"text":"MultipleTrailingClosureElementSyntax"}},{"name":"Count","value":{"text":"0"}}],"parent":282},{"parent":276,"type":"other","range":{"endColumn":10,"endRow":29,"startRow":29,"startColumn":9},"structure":[],"text":"}","id":307,"token":{"kind":"rightBrace","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":""}},{"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","ref":"InfixOperatorExprSyntax","value":{"text":"InfixOperatorExprSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"type":"other","parent":193,"text":"CodeBlockItem","range":{"endColumn":37,"endRow":32,"startRow":32,"startColumn":9},"id":308},{"structure":[{"name":"unexpectedBeforeLeftOperand","value":{"text":"nil"}},{"name":"leftOperand","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenLeftOperandAndOperator","value":{"text":"nil"}},{"name":"operator","ref":"BinaryOperatorExprSyntax","value":{"text":"BinaryOperatorExprSyntax"}},{"name":"unexpectedBetweenOperatorAndRightOperand","value":{"text":"nil"}},{"name":"rightOperand","ref":"MemberAccessExprSyntax","value":{"text":"MemberAccessExprSyntax"}},{"name":"unexpectedAfterRightOperand","value":{"text":"nil"}}],"type":"expr","parent":308,"text":"InfixOperatorExpr","range":{"startRow":32,"endRow":32,"startColumn":9,"endColumn":37},"id":309},{"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("coinsDeposited")","text":"coinsDeposited"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr","parent":309,"text":"DeclReferenceExpr","range":{"startRow":32,"startColumn":9,"endRow":32,"endColumn":23},"id":310},{"parent":310,"type":"other","range":{"endRow":32,"endColumn":23,"startRow":32,"startColumn":9},"structure":[],"text":"coinsDeposited","id":311,"token":{"trailingTrivia":"␣<\/span>","kind":"identifier("coinsDeposited")","leadingTrivia":"↲<\/span>↲<\/span>↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"}},{"structure":[{"name":"unexpectedBeforeOperator","value":{"text":"nil"}},{"name":"operator","value":{"text":"-=","kind":"binaryOperator("-=")"}},{"name":"unexpectedAfterOperator","value":{"text":"nil"}}],"type":"expr","id":312,"range":{"endRow":32,"endColumn":26,"startRow":32,"startColumn":24},"parent":309,"text":"BinaryOperatorExpr"},{"parent":312,"type":"other","range":{"endColumn":26,"endRow":32,"startRow":32,"startColumn":24},"structure":[],"text":"-=","id":313,"token":{"kind":"binaryOperator("-=")","leadingTrivia":"","trailingTrivia":"␣<\/span>"}},{"structure":[{"name":"unexpectedBeforeBase","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"base","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenBaseAndPeriod","value":{"text":"nil"}},{"name":"period","value":{"kind":"period","text":"."}},{"name":"unexpectedBetweenPeriodAndDeclName","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"declName","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedAfterDeclName","value":{"text":"nil"}}],"type":"expr","id":314,"range":{"endColumn":37,"endRow":32,"startRow":32,"startColumn":27},"parent":309,"text":"MemberAccessExpr"},{"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"item","kind":"identifier("item")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr","id":315,"range":{"startColumn":27,"endRow":32,"startRow":32,"endColumn":31},"parent":314,"text":"DeclReferenceExpr"},{"parent":315,"type":"other","range":{"endColumn":31,"endRow":32,"startColumn":27,"startRow":32},"structure":[],"text":"item","id":316,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"identifier("item")"}},{"parent":314,"type":"other","range":{"endColumn":32,"endRow":32,"startColumn":31,"startRow":32},"structure":[],"text":".","id":317,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"period"}},{"range":{"endColumn":37,"endRow":32,"startColumn":32,"startRow":32},"id":318,"parent":314,"text":"DeclReferenceExpr","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"price","kind":"identifier("price")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}],"type":"expr"},{"parent":318,"type":"other","range":{"endRow":32,"startRow":32,"startColumn":32,"endColumn":37},"structure":[],"text":"price","id":319,"token":{"leadingTrivia":"","kind":"identifier("price")","trailingTrivia":""}},{"range":{"endRow":35,"startRow":35,"startColumn":9,"endColumn":27},"id":320,"parent":193,"text":"CodeBlockItem","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeItem"},{"ref":"VariableDeclSyntax","value":{"text":"VariableDeclSyntax"},"name":"item"},{"value":{"text":"nil"},"name":"unexpectedBetweenItemAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}],"type":"other"},{"text":"VariableDecl","id":321,"range":{"startRow":35,"startColumn":9,"endColumn":27,"endRow":35},"type":"decl","structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","value":{"text":"AttributeListSyntax"},"ref":"AttributeListSyntax"},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","value":{"text":"DeclModifierListSyntax"},"ref":"DeclModifierListSyntax"},{"name":"unexpectedBetweenModifiersAndBindingSpecifier","value":{"text":"nil"}},{"name":"bindingSpecifier","value":{"text":"var","kind":"keyword(SwiftSyntax.Keyword.var)"}},{"name":"unexpectedBetweenBindingSpecifierAndBindings","value":{"text":"nil"}},{"name":"bindings","value":{"text":"PatternBindingListSyntax"},"ref":"PatternBindingListSyntax"},{"name":"unexpectedAfterBindings","value":{"text":"nil"}}],"parent":320},{"text":"AttributeList","id":322,"range":{"endRow":32,"startRow":32,"endColumn":37,"startColumn":37},"type":"collection","structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"parent":321},{"text":"DeclModifierList","id":323,"range":{"startRow":32,"startColumn":37,"endRow":32,"endColumn":37},"type":"collection","structure":[{"value":{"text":"DeclModifierSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"parent":321},{"parent":321,"type":"other","range":{"startColumn":9,"endColumn":12,"endRow":35,"startRow":35},"structure":[],"text":"var","id":324,"token":{"leadingTrivia":"↲<\/span>↲<\/span>↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.var)"}},{"parent":321,"range":{"startColumn":13,"endColumn":27,"endRow":35,"startRow":35},"structure":[{"value":{"text":"PatternBindingSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}],"text":"PatternBindingList","type":"collection","id":325},{"parent":325,"range":{"startRow":35,"startColumn":13,"endRow":35,"endColumn":27},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforePattern"},{"ref":"IdentifierPatternSyntax","value":{"text":"IdentifierPatternSyntax"},"name":"pattern"},{"value":{"text":"nil"},"name":"unexpectedBetweenPatternAndTypeAnnotation"},{"value":{"text":"nil"},"name":"typeAnnotation"},{"value":{"text":"nil"},"name":"unexpectedBetweenTypeAnnotationAndInitializer"},{"ref":"InitializerClauseSyntax","value":{"text":"InitializerClauseSyntax"},"name":"initializer"},{"value":{"text":"nil"},"name":"unexpectedBetweenInitializerAndAccessorBlock"},{"value":{"text":"nil"},"name":"accessorBlock"},{"value":{"text":"nil"},"name":"unexpectedBetweenAccessorBlockAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"text":"PatternBinding","type":"other","id":326},{"parent":326,"range":{"startRow":35,"endRow":35,"startColumn":13,"endColumn":20},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeIdentifier"},{"name":"identifier","value":{"kind":"identifier("newItem")","text":"newItem"}},{"name":"unexpectedAfterIdentifier","value":{"text":"nil"}}],"text":"IdentifierPattern","type":"pattern","id":327},{"parent":327,"type":"other","range":{"startColumn":13,"endRow":35,"endColumn":20,"startRow":35},"structure":[],"text":"newItem","id":328,"token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"identifier("newItem")"}},{"type":"other","text":"InitializerClause","parent":326,"range":{"startColumn":21,"endRow":35,"endColumn":27,"startRow":35},"id":329,"structure":[{"name":"unexpectedBeforeEqual","value":{"text":"nil"}},{"name":"equal","value":{"kind":"equal","text":"="}},{"name":"unexpectedBetweenEqualAndValue","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"value","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedAfterValue","value":{"text":"nil"}}]},{"parent":329,"type":"other","range":{"startRow":35,"endRow":35,"endColumn":22,"startColumn":21},"structure":[],"text":"=","id":330,"token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"equal"}},{"type":"expr","text":"DeclReferenceExpr","parent":329,"range":{"startRow":35,"endRow":35,"endColumn":27,"startColumn":23},"id":331,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"item","kind":"identifier("item")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"parent":331,"type":"other","range":{"endColumn":27,"endRow":35,"startColumn":23,"startRow":35},"structure":[],"text":"item","id":332,"token":{"kind":"identifier("item")","leadingTrivia":"","trailingTrivia":""}},{"parent":193,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeItem"},{"value":{"text":"InfixOperatorExprSyntax"},"name":"item","ref":"InfixOperatorExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenItemAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}],"type":"other","text":"CodeBlockItem","range":{"startColumn":9,"startRow":36,"endColumn":27,"endRow":36},"id":333},{"parent":333,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftOperand"},{"value":{"text":"MemberAccessExprSyntax"},"ref":"MemberAccessExprSyntax","name":"leftOperand"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftOperandAndOperator"},{"value":{"text":"BinaryOperatorExprSyntax"},"ref":"BinaryOperatorExprSyntax","name":"operator"},{"value":{"text":"nil"},"name":"unexpectedBetweenOperatorAndRightOperand"},{"value":{"text":"IntegerLiteralExprSyntax"},"ref":"IntegerLiteralExprSyntax","name":"rightOperand"},{"value":{"text":"nil"},"name":"unexpectedAfterRightOperand"}],"type":"expr","text":"InfixOperatorExpr","range":{"startRow":36,"endRow":36,"endColumn":27,"startColumn":9},"id":334},{"parent":334,"structure":[{"name":"unexpectedBeforeBase","value":{"text":"nil"}},{"name":"base","value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax"},{"name":"unexpectedBetweenBaseAndPeriod","value":{"text":"nil"}},{"name":"period","value":{"kind":"period","text":"."}},{"name":"unexpectedBetweenPeriodAndDeclName","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"declName","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedAfterDeclName","value":{"text":"nil"}}],"type":"expr","text":"MemberAccessExpr","range":{"startRow":36,"endColumn":22,"endRow":36,"startColumn":9},"id":335},{"type":"expr","parent":335,"id":336,"text":"DeclReferenceExpr","range":{"endRow":36,"startRow":36,"startColumn":9,"endColumn":16},"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"newItem","kind":"identifier("newItem")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"parent":336,"type":"other","range":{"startColumn":9,"endRow":36,"startRow":36,"endColumn":16},"structure":[],"text":"newItem","id":337,"token":{"leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"","kind":"identifier("newItem")"}},{"parent":335,"type":"other","range":{"startColumn":16,"endRow":36,"startRow":36,"endColumn":17},"structure":[],"text":".","id":338,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"period"}},{"type":"expr","parent":335,"id":339,"text":"DeclReferenceExpr","range":{"startColumn":17,"endRow":36,"startRow":36,"endColumn":22},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"count","kind":"identifier("count")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"parent":339,"type":"other","range":{"endColumn":22,"startColumn":17,"startRow":36,"endRow":36},"structure":[],"text":"count","id":340,"token":{"kind":"identifier("count")","leadingTrivia":"","trailingTrivia":"␣<\/span>"}},{"structure":[{"name":"unexpectedBeforeOperator","value":{"text":"nil"}},{"name":"operator","value":{"text":"-=","kind":"binaryOperator("-=")"}},{"name":"unexpectedAfterOperator","value":{"text":"nil"}}],"type":"expr","id":341,"parent":334,"text":"BinaryOperatorExpr","range":{"startRow":36,"endRow":36,"startColumn":23,"endColumn":25}},{"parent":341,"type":"other","range":{"endRow":36,"startRow":36,"startColumn":23,"endColumn":25},"structure":[],"text":"-=","id":342,"token":{"kind":"binaryOperator("-=")","trailingTrivia":"␣<\/span>","leadingTrivia":""}},{"structure":[{"name":"unexpectedBeforeLiteral","value":{"text":"nil"}},{"name":"literal","value":{"kind":"integerLiteral("1")","text":"1"}},{"name":"unexpectedAfterLiteral","value":{"text":"nil"}}],"type":"expr","id":343,"parent":334,"text":"IntegerLiteralExpr","range":{"endRow":36,"startRow":36,"startColumn":26,"endColumn":27}},{"parent":343,"type":"other","range":{"startColumn":26,"startRow":36,"endColumn":27,"endRow":36},"structure":[],"text":"1","id":344,"token":{"trailingTrivia":"","kind":"integerLiteral("1")","leadingTrivia":""}},{"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","value":{"text":"InfixOperatorExprSyntax"},"ref":"InfixOperatorExprSyntax"},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}],"type":"other","id":345,"parent":193,"text":"CodeBlockItem","range":{"startColumn":9,"startRow":37,"endColumn":34,"endRow":37}},{"structure":[{"name":"unexpectedBeforeLeftOperand","value":{"text":"nil"}},{"name":"leftOperand","value":{"text":"SubscriptCallExprSyntax"},"ref":"SubscriptCallExprSyntax"},{"name":"unexpectedBetweenLeftOperandAndOperator","value":{"text":"nil"}},{"name":"operator","value":{"text":"AssignmentExprSyntax"},"ref":"AssignmentExprSyntax"},{"name":"unexpectedBetweenOperatorAndRightOperand","value":{"text":"nil"}},{"name":"rightOperand","value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax"},{"name":"unexpectedAfterRightOperand","value":{"text":"nil"}}],"type":"expr","id":346,"parent":345,"text":"InfixOperatorExpr","range":{"startRow":37,"startColumn":9,"endRow":37,"endColumn":34}},{"id":347,"text":"SubscriptCallExpr","type":"expr","range":{"startColumn":9,"endRow":37,"endColumn":24,"startRow":37},"structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"name":"calledExpression","value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax"},{"name":"unexpectedBetweenCalledExpressionAndLeftSquare","value":{"text":"nil"}},{"name":"leftSquare","value":{"kind":"leftSquare","text":"["}},{"name":"unexpectedBetweenLeftSquareAndArguments","value":{"text":"nil"}},{"name":"arguments","value":{"text":"LabeledExprListSyntax"},"ref":"LabeledExprListSyntax"},{"name":"unexpectedBetweenArgumentsAndRightSquare","value":{"text":"nil"}},{"name":"rightSquare","value":{"kind":"rightSquare","text":"]"}},{"name":"unexpectedBetweenRightSquareAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"value":{"text":"MultipleTrailingClosureElementListSyntax"},"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures"},{"value":{"text":"nil"},"name":"unexpectedAfterAdditionalTrailingClosures"}],"parent":346},{"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"inventory","kind":"identifier("inventory")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"type":"expr","parent":347,"id":348,"text":"DeclReferenceExpr","range":{"startColumn":9,"endRow":37,"endColumn":18,"startRow":37}},{"parent":348,"type":"other","range":{"endRow":37,"startRow":37,"startColumn":9,"endColumn":18},"structure":[],"text":"inventory","id":349,"token":{"kind":"identifier("inventory")","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":""}},{"parent":347,"type":"other","range":{"endRow":37,"startRow":37,"startColumn":18,"endColumn":19},"structure":[],"text":"[","id":350,"token":{"kind":"leftSquare","leadingTrivia":"","trailingTrivia":""}},{"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"1"}}],"type":"collection","parent":347,"id":351,"text":"LabeledExprList","range":{"endRow":37,"startRow":37,"startColumn":19,"endColumn":23}},{"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"expression","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"type":"other","parent":351,"id":352,"text":"LabeledExpr","range":{"startRow":37,"endRow":37,"startColumn":19,"endColumn":23}},{"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("name")","text":"name"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"id":353,"type":"expr","parent":352,"range":{"startColumn":19,"startRow":37,"endRow":37,"endColumn":23},"text":"DeclReferenceExpr"},{"parent":353,"type":"other","range":{"startRow":37,"endRow":37,"startColumn":19,"endColumn":23},"structure":[],"text":"name","id":354,"token":{"trailingTrivia":"","kind":"identifier("name")","leadingTrivia":""}},{"parent":347,"type":"other","range":{"startRow":37,"endRow":37,"startColumn":23,"endColumn":24},"structure":[],"text":"]","id":355,"token":{"trailingTrivia":"␣<\/span>","kind":"rightSquare","leadingTrivia":""}},{"structure":[{"name":"Element","value":{"text":"MultipleTrailingClosureElementSyntax"}},{"name":"Count","value":{"text":"0"}}],"id":356,"type":"collection","parent":347,"range":{"startRow":37,"endRow":37,"startColumn":25,"endColumn":25},"text":"MultipleTrailingClosureElementList"},{"structure":[{"name":"unexpectedBeforeEqual","value":{"text":"nil"}},{"value":{"text":"=","kind":"equal"},"name":"equal"},{"value":{"text":"nil"},"name":"unexpectedAfterEqual"}],"id":357,"type":"expr","parent":346,"range":{"endColumn":26,"startRow":37,"startColumn":25,"endRow":37},"text":"AssignmentExpr"},{"parent":357,"type":"other","range":{"startColumn":25,"endRow":37,"endColumn":26,"startRow":37},"structure":[],"text":"=","id":358,"token":{"kind":"equal","leadingTrivia":"","trailingTrivia":"␣<\/span>"}},{"id":359,"text":"DeclReferenceExpr","range":{"startColumn":27,"endRow":37,"endColumn":34,"startRow":37},"type":"expr","parent":346,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"newItem","kind":"identifier("newItem")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"text":"newItem","range":{"endRow":37,"endColumn":34,"startRow":37,"startColumn":27},"parent":359,"token":{"kind":"identifier("newItem")","leadingTrivia":"","trailingTrivia":""},"type":"other","structure":[],"id":360},{"id":361,"text":"CodeBlockItem","range":{"endRow":40,"endColumn":36,"startRow":40,"startColumn":9},"type":"other","parent":193,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","ref":"FunctionCallExprSyntax","value":{"text":"FunctionCallExprSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"id":362,"text":"FunctionCallExpr","range":{"endRow":40,"startColumn":9,"startRow":40,"endColumn":36},"type":"expr","parent":361,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCalledExpression"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"calledExpression","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenCalledExpressionAndLeftParen"},{"value":{"text":"(","kind":"leftParen"},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndArguments"},{"value":{"text":"LabeledExprListSyntax"},"name":"arguments","ref":"LabeledExprListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenArgumentsAndRightParen"},{"value":{"kind":"rightParen","text":")"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenRightParenAndTrailingClosure"},{"value":{"text":"nil"},"name":"trailingClosure"},{"value":{"text":"nil"},"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures"},{"value":{"text":"MultipleTrailingClosureElementListSyntax"},"name":"additionalTrailingClosures","ref":"MultipleTrailingClosureElementListSyntax"},{"value":{"text":"nil"},"name":"unexpectedAfterAdditionalTrailingClosures"}]},{"id":363,"text":"DeclReferenceExpr","parent":362,"range":{"endColumn":14,"endRow":40,"startColumn":9,"startRow":40},"type":"expr","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"kind":"identifier("print")","text":"print"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"text":"print","parent":363,"range":{"startColumn":9,"startRow":40,"endRow":40,"endColumn":14},"token":{"kind":"identifier("print")","leadingTrivia":"↲<\/span>↲<\/span>↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":""},"type":"other","structure":[],"id":364},{"text":"(","parent":362,"range":{"startColumn":14,"startRow":40,"endRow":40,"endColumn":15},"token":{"kind":"leftParen","leadingTrivia":"","trailingTrivia":""},"type":"other","structure":[],"id":365},{"text":"LabeledExprList","structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"1"}}],"id":366,"parent":362,"range":{"startColumn":15,"startRow":40,"endRow":40,"endColumn":35},"type":"collection"},{"text":"LabeledExpr","structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","value":{"text":"StringLiteralExprSyntax"},"ref":"StringLiteralExprSyntax"},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}],"id":367,"parent":366,"range":{"startColumn":15,"endColumn":35,"endRow":40,"startRow":40},"type":"other"},{"text":"StringLiteralExpr","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeOpeningPounds"},{"value":{"text":"nil"},"name":"openingPounds"},{"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote","value":{"text":"nil"}},{"name":"openingQuote","value":{"text":""","kind":"stringQuote"}},{"name":"unexpectedBetweenOpeningQuoteAndSegments","value":{"text":"nil"}},{"name":"segments","ref":"StringLiteralSegmentListSyntax","value":{"text":"StringLiteralSegmentListSyntax"}},{"name":"unexpectedBetweenSegmentsAndClosingQuote","value":{"text":"nil"}},{"name":"closingQuote","value":{"text":""","kind":"stringQuote"}},{"name":"unexpectedBetweenClosingQuoteAndClosingPounds","value":{"text":"nil"}},{"name":"closingPounds","value":{"text":"nil"}},{"name":"unexpectedAfterClosingPounds","value":{"text":"nil"}}],"id":368,"parent":367,"range":{"endColumn":35,"startRow":40,"startColumn":15,"endRow":40},"type":"expr"},{"parent":368,"text":""","range":{"startRow":40,"endColumn":16,"startColumn":15,"endRow":40},"token":{"leadingTrivia":"","trailingTrivia":"","kind":"stringQuote"},"type":"other","structure":[],"id":369},{"id":370,"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"3"}}],"type":"collection","parent":368,"text":"StringLiteralSegmentList","range":{"startRow":40,"endColumn":34,"startColumn":16,"endRow":40}},{"id":371,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeContent"},{"value":{"kind":"stringSegment("Dispensing ")","text":"Dispensing "},"name":"content"},{"value":{"text":"nil"},"name":"unexpectedAfterContent"}],"type":"other","parent":370,"text":"StringSegment","range":{"startColumn":16,"endRow":40,"endColumn":27,"startRow":40}},{"parent":371,"text":"Dispensing␣<\/span>","range":{"endColumn":27,"startRow":40,"startColumn":16,"endRow":40},"token":{"trailingTrivia":"","leadingTrivia":"","kind":"stringSegment("Dispensing ")"},"type":"other","structure":[],"id":372},{"text":"ExpressionSegment","id":373,"range":{"startRow":40,"startColumn":27,"endRow":40,"endColumn":34},"structure":[{"name":"unexpectedBeforeBackslash","value":{"text":"nil"}},{"name":"backslash","value":{"text":"\\","kind":"backslash"}},{"name":"unexpectedBetweenBackslashAndPounds","value":{"text":"nil"}},{"name":"pounds","value":{"text":"nil"}},{"name":"unexpectedBetweenPoundsAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"kind":"leftParen","text":"("}},{"name":"unexpectedBetweenLeftParenAndExpressions","value":{"text":"nil"}},{"name":"expressions","ref":"LabeledExprListSyntax","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenExpressionsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"kind":"rightParen","text":")"}},{"name":"unexpectedAfterRightParen","value":{"text":"nil"}}],"parent":370,"type":"other"},{"text":"\\","range":{"startRow":40,"startColumn":27,"endColumn":28,"endRow":40},"parent":373,"token":{"kind":"backslash","leadingTrivia":"","trailingTrivia":""},"type":"other","structure":[],"id":374},{"text":"(","range":{"startRow":40,"startColumn":28,"endColumn":29,"endRow":40},"parent":373,"token":{"kind":"leftParen","leadingTrivia":"","trailingTrivia":""},"type":"other","structure":[],"id":375},{"text":"LabeledExprList","id":376,"range":{"startRow":40,"startColumn":29,"endColumn":33,"endRow":40},"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"1"}}],"parent":373,"type":"collection"},{"text":"LabeledExpr","id":377,"range":{"startRow":40,"endColumn":33,"startColumn":29,"endRow":40},"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"text":"nil"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"text":"nil"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}],"parent":376,"type":"other"},{"type":"expr","id":378,"parent":377,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("name")","text":"name"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}],"text":"DeclReferenceExpr","range":{"startColumn":29,"endRow":40,"startRow":40,"endColumn":33}},{"parent":378,"text":"name","range":{"startRow":40,"endRow":40,"endColumn":33,"startColumn":29},"token":{"kind":"identifier("name")","leadingTrivia":"","trailingTrivia":""},"type":"other","structure":[],"id":379},{"parent":373,"text":")","range":{"startRow":40,"endRow":40,"endColumn":34,"startColumn":33},"token":{"kind":"rightParen","leadingTrivia":"","trailingTrivia":""},"type":"other","structure":[],"id":380},{"parent":370,"structure":[{"name":"unexpectedBeforeContent","value":{"text":"nil"}},{"name":"content","value":{"text":"","kind":"stringSegment("")"}},{"name":"unexpectedAfterContent","value":{"text":"nil"}}],"type":"other","id":381,"range":{"endRow":40,"endColumn":34,"startRow":40,"startColumn":34},"text":"StringSegment"},{"parent":381,"range":{"startRow":40,"endRow":40,"endColumn":34,"startColumn":34},"text":"","token":{"leadingTrivia":"","kind":"stringSegment("")","trailingTrivia":""},"type":"other","structure":[],"id":382},{"parent":368,"range":{"startRow":40,"endRow":40,"endColumn":35,"startColumn":34},"text":""","token":{"leadingTrivia":"","kind":"stringQuote","trailingTrivia":""},"type":"other","structure":[],"id":383},{"parent":362,"range":{"startRow":40,"endRow":40,"endColumn":36,"startColumn":35},"text":")","token":{"leadingTrivia":"","kind":"rightParen","trailingTrivia":""},"type":"other","structure":[],"id":384},{"parent":362,"structure":[{"value":{"text":"MultipleTrailingClosureElementSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}],"type":"collection","id":385,"range":{"startRow":40,"endRow":40,"endColumn":36,"startColumn":36},"text":"MultipleTrailingClosureElementList"},{"parent":191,"range":{"startRow":41,"endColumn":6,"startColumn":5,"endRow":41},"text":"}","token":{"kind":"rightBrace","trailingTrivia":"","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"},"type":"other","structure":[],"id":386},{"parent":58,"range":{"startRow":42,"endColumn":2,"startColumn":1,"endRow":42},"text":"}","token":{"kind":"rightBrace","trailingTrivia":"","leadingTrivia":"↲<\/span>"},"type":"other","structure":[],"id":387},{"parent":0,"range":{"startRow":42,"endColumn":2,"startColumn":2,"endRow":42},"text":"","token":{"kind":"endOfFile","trailingTrivia":"","leadingTrivia":""},"type":"other","structure":[],"id":388}] diff --git a/Examples/Completed/errors_async/code.swift b/Examples/Completed/errors_async/code.swift new file mode 100644 index 0000000..7a081a7 --- /dev/null +++ b/Examples/Completed/errors_async/code.swift @@ -0,0 +1,23 @@ + +var vendingMachine = VendingMachine() +vendingMachine.coinsDeposited = 8 +do { + try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine) + print("Success! Yum.") +} catch VendingMachineError.invalidSelection { + print("Invalid Selection.") +} catch VendingMachineError.outOfStock { + print("Out of Stock.") +} catch VendingMachineError.insufficientFunds(let coinsNeeded) { + print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.") +} catch { + print("Unexpected error: \(error).") +} + +func summarize(_ ratings: [Int]) throws(StatisticsError) { + guard !ratings.isEmpty else { throw .noRatings } +} + +async let data = fetchUserData(id: 1) +async let posts = fetchUserPosts(id: 1) +let (fetchedData, fetchedPosts) = try await (data, posts) \ No newline at end of file diff --git a/Examples/Completed/errors_async/dsl.swift b/Examples/Completed/errors_async/dsl.swift new file mode 100644 index 0000000..aad5087 --- /dev/null +++ b/Examples/Completed/errors_async/dsl.swift @@ -0,0 +1,74 @@ +Variable(.var, name: "vendingMachine", equals: Init("VendingMachine")) +Assignment("vendingMachine.coinsDeposited", Literal.integer(8)) +Do { + Call("buyFavoriteSnack") { + ParameterExp(name: "person", value: Literal.string("Alice")) + ParameterExp(name: "vendingMachine", value: Literal.ref("vendingMachine")) + }.throwing() + Call("print") { + ParameterExp(unlabeled: Literal.string("Success! Yum.")) + } +} catch: { + Catch(EnumCase("invalidSelection")) { + Call("print") { + ParameterExp(unlabeled: Literal.string("Invalid Selection.")) + } + } + Catch(EnumCase("outOfStock")) { + Call("print") { + ParameterExp(unlabeled: Literal.string("Out of Stock.")) + } + } + Catch( + EnumCase("insufficientFunds").associatedValue( + "coinsNeeded", type: "Int") + ) { + Call("print") { + ParameterExp( + unlabeled: Literal.string( + "Insufficient funds. Please insert an additional \\(coinsNeeded) coins.")) + } + } + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Unexpected error: \\(error).")) + } + } +} + +Function("summarize") { + Parameter(name: "ratings", type: "[Int]") +} _: { + Guard{ + VariableExp("ratings").property("isEmpty").not() + } else: { + Throw(EnumCase("noRatings")) + } +}.throws("StatisticsError") + +Do { + Variable(.let, name: "data") { + Call("fetchUserData") { + ParameterExp(name: "id", value: Literal.integer(1)) + } + }.async() + Variable(.let, name: "posts") { + Call("fetchUserPosts") { + ParameterExp(name: "id", value: Literal.integer(1)) + } + }.async() + TupleAssignment(["fetchedData", "fetchedPosts"], equals: Tuple { + VariableExp("data") + VariableExp("posts") + }).async().throwing() +} catch: { + Catch(EnumCase("fetchError")) { + // Example catch for async/await + } +} + + + + + + diff --git a/Examples/Completed/errors_async/syntax.json b/Examples/Completed/errors_async/syntax.json new file mode 100644 index 0000000..617a398 --- /dev/null +++ b/Examples/Completed/errors_async/syntax.json @@ -0,0 +1 @@ +[{"range":{"startRow":2,"endColumn":58,"startColumn":1,"endRow":23},"type":"other","id":0,"text":"SourceFile","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeShebang"},{"value":{"text":"nil"},"name":"shebang"},{"value":{"text":"nil"},"name":"unexpectedBetweenShebangAndStatements"},{"value":{"text":"CodeBlockItemListSyntax"},"name":"statements","ref":"CodeBlockItemListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenStatementsAndEndOfFileToken"},{"value":{"text":"","kind":"endOfFile"},"name":"endOfFileToken"},{"value":{"text":"nil"},"name":"unexpectedAfterEndOfFileToken"}]},{"range":{"startColumn":1,"endColumn":58,"startRow":2,"endRow":23},"type":"collection","id":1,"parent":0,"text":"CodeBlockItemList","structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"7"}}]},{"range":{"startColumn":1,"endColumn":38,"startRow":2,"endRow":2},"type":"other","id":2,"parent":1,"text":"CodeBlockItem","structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeItem"},{"value":{"text":"VariableDeclSyntax"},"name":"item","ref":"VariableDeclSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenItemAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}]},{"range":{"startColumn":1,"endColumn":38,"startRow":2,"endRow":2},"type":"decl","id":3,"parent":2,"text":"VariableDecl","structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","value":{"text":"AttributeListSyntax"},"ref":"AttributeListSyntax"},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","value":{"text":"DeclModifierListSyntax"},"ref":"DeclModifierListSyntax"},{"name":"unexpectedBetweenModifiersAndBindingSpecifier","value":{"text":"nil"}},{"name":"bindingSpecifier","value":{"kind":"keyword(SwiftSyntax.Keyword.var)","text":"var"}},{"name":"unexpectedBetweenBindingSpecifierAndBindings","value":{"text":"nil"}},{"name":"bindings","value":{"text":"PatternBindingListSyntax"},"ref":"PatternBindingListSyntax"},{"name":"unexpectedAfterBindings","value":{"text":"nil"}}]},{"range":{"startColumn":1,"endColumn":1,"startRow":1,"endRow":1},"type":"collection","id":4,"parent":3,"text":"AttributeList","structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"0"}}]},{"range":{"startColumn":1,"endColumn":1,"startRow":1,"endRow":1},"type":"collection","id":5,"parent":3,"text":"DeclModifierList","structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"range":{"startColumn":1,"endColumn":4,"startRow":2,"endRow":2},"token":{"leadingTrivia":"↲<\/span>","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.var)"},"type":"other","structure":[],"id":6,"text":"var","parent":3},{"range":{"endRow":2,"startRow":2,"startColumn":5,"endColumn":38},"id":7,"text":"PatternBindingList","type":"collection","parent":3,"structure":[{"name":"Element","value":{"text":"PatternBindingSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"endColumn":38,"startColumn":5,"endRow":2,"startRow":2},"id":8,"text":"PatternBinding","type":"other","parent":7,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforePattern"},{"value":{"text":"IdentifierPatternSyntax"},"ref":"IdentifierPatternSyntax","name":"pattern"},{"value":{"text":"nil"},"name":"unexpectedBetweenPatternAndTypeAnnotation"},{"value":{"text":"nil"},"name":"typeAnnotation"},{"value":{"text":"nil"},"name":"unexpectedBetweenTypeAnnotationAndInitializer"},{"value":{"text":"InitializerClauseSyntax"},"ref":"InitializerClauseSyntax","name":"initializer"},{"value":{"text":"nil"},"name":"unexpectedBetweenInitializerAndAccessorBlock"},{"value":{"text":"nil"},"name":"accessorBlock"},{"value":{"text":"nil"},"name":"unexpectedBetweenAccessorBlockAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"endRow":2,"startRow":2,"endColumn":19,"startColumn":5},"id":9,"text":"IdentifierPattern","type":"pattern","parent":8,"structure":[{"name":"unexpectedBeforeIdentifier","value":{"text":"nil"}},{"name":"identifier","value":{"text":"vendingMachine","kind":"identifier("vendingMachine")"}},{"name":"unexpectedAfterIdentifier","value":{"text":"nil"}}]},{"text":"vendingMachine","parent":9,"structure":[],"type":"other","id":10,"range":{"startColumn":5,"startRow":2,"endRow":2,"endColumn":19},"token":{"kind":"identifier("vendingMachine")","trailingTrivia":"␣<\/span>","leadingTrivia":""}},{"range":{"startColumn":20,"startRow":2,"endRow":2,"endColumn":38},"id":11,"text":"InitializerClause","type":"other","parent":8,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeEqual"},{"value":{"text":"=","kind":"equal"},"name":"equal"},{"value":{"text":"nil"},"name":"unexpectedBetweenEqualAndValue"},{"value":{"text":"FunctionCallExprSyntax"},"ref":"FunctionCallExprSyntax","name":"value"},{"value":{"text":"nil"},"name":"unexpectedAfterValue"}]},{"structure":[],"parent":11,"range":{"startColumn":20,"endRow":2,"startRow":2,"endColumn":21},"type":"other","token":{"kind":"equal","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"text":"=","id":12},{"range":{"startColumn":22,"endRow":2,"startRow":2,"endColumn":38},"id":13,"text":"FunctionCallExpr","type":"expr","parent":11,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCalledExpression"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"calledExpression"},{"value":{"text":"nil"},"name":"unexpectedBetweenCalledExpressionAndLeftParen"},{"value":{"text":"(","kind":"leftParen"},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndArguments"},{"value":{"text":"LabeledExprListSyntax"},"ref":"LabeledExprListSyntax","name":"arguments"},{"value":{"text":"nil"},"name":"unexpectedBetweenArgumentsAndRightParen"},{"value":{"kind":"rightParen","text":")"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenRightParenAndTrailingClosure"},{"value":{"text":"nil"},"name":"trailingClosure"},{"value":{"text":"nil"},"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures"},{"value":{"text":"MultipleTrailingClosureElementListSyntax"},"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures"},{"value":{"text":"nil"},"name":"unexpectedAfterAdditionalTrailingClosures"}]},{"range":{"endColumn":36,"startColumn":22,"endRow":2,"startRow":2},"id":14,"text":"DeclReferenceExpr","type":"expr","parent":13,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"kind":"identifier("VendingMachine")","text":"VendingMachine"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"text":"VendingMachine","id":15,"structure":[],"range":{"startRow":2,"endRow":2,"startColumn":22,"endColumn":36},"parent":14,"type":"other","token":{"leadingTrivia":"","kind":"identifier("VendingMachine")","trailingTrivia":""}},{"id":16,"text":"(","structure":[],"type":"other","token":{"leadingTrivia":"","kind":"leftParen","trailingTrivia":""},"range":{"startRow":2,"endRow":2,"startColumn":36,"endColumn":37},"parent":13},{"range":{"startRow":2,"endRow":2,"startColumn":37,"endColumn":37},"id":17,"text":"LabeledExprList","type":"collection","parent":13,"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"id":18,"structure":[],"range":{"endRow":2,"startRow":2,"endColumn":38,"startColumn":37},"text":")","type":"other","token":{"kind":"rightParen","leadingTrivia":"","trailingTrivia":""},"parent":13},{"range":{"endRow":2,"startRow":2,"endColumn":38,"startColumn":38},"id":19,"text":"MultipleTrailingClosureElementList","type":"collection","parent":13,"structure":[{"name":"Element","value":{"text":"MultipleTrailingClosureElementSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"range":{"startRow":3,"endRow":3,"startColumn":1,"endColumn":34},"id":20,"text":"CodeBlockItem","type":"other","parent":1,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","ref":"InfixOperatorExprSyntax","value":{"text":"InfixOperatorExprSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"startRow":3,"startColumn":1,"endRow":3,"endColumn":34},"id":21,"text":"InfixOperatorExpr","type":"expr","parent":20,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftOperand"},{"ref":"MemberAccessExprSyntax","value":{"text":"MemberAccessExprSyntax"},"name":"leftOperand"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftOperandAndOperator"},{"ref":"AssignmentExprSyntax","value":{"text":"AssignmentExprSyntax"},"name":"operator"},{"value":{"text":"nil"},"name":"unexpectedBetweenOperatorAndRightOperand"},{"ref":"IntegerLiteralExprSyntax","value":{"text":"IntegerLiteralExprSyntax"},"name":"rightOperand"},{"value":{"text":"nil"},"name":"unexpectedAfterRightOperand"}]},{"range":{"endColumn":30,"startRow":3,"startColumn":1,"endRow":3},"id":22,"text":"MemberAccessExpr","type":"expr","parent":21,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBase"},{"ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"},"name":"base"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseAndPeriod"},{"value":{"text":".","kind":"period"},"name":"period"},{"value":{"text":"nil"},"name":"unexpectedBetweenPeriodAndDeclName"},{"ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"},"name":"declName"},{"value":{"text":"nil"},"name":"unexpectedAfterDeclName"}]},{"range":{"startRow":3,"startColumn":1,"endRow":3,"endColumn":15},"id":23,"text":"DeclReferenceExpr","type":"expr","parent":22,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"vendingMachine","kind":"identifier("vendingMachine")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"id":24,"text":"vendingMachine","structure":[],"parent":23,"range":{"endColumn":15,"startRow":3,"startColumn":1,"endRow":3},"type":"other","token":{"leadingTrivia":"↲<\/span>","kind":"identifier("vendingMachine")","trailingTrivia":""}},{"parent":22,"text":".","id":25,"token":{"leadingTrivia":"","kind":"period","trailingTrivia":""},"structure":[],"type":"other","range":{"endColumn":16,"startRow":3,"startColumn":15,"endRow":3}},{"range":{"endColumn":30,"startRow":3,"startColumn":16,"endRow":3},"id":26,"text":"DeclReferenceExpr","type":"expr","parent":22,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"coinsDeposited","kind":"identifier("coinsDeposited")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"type":"other","range":{"startRow":3,"startColumn":16,"endRow":3,"endColumn":30},"structure":[],"id":27,"text":"coinsDeposited","token":{"kind":"identifier("coinsDeposited")","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"parent":26},{"range":{"startRow":3,"startColumn":31,"endRow":3,"endColumn":32},"id":28,"text":"AssignmentExpr","type":"expr","parent":21,"structure":[{"name":"unexpectedBeforeEqual","value":{"text":"nil"}},{"name":"equal","value":{"kind":"equal","text":"="}},{"name":"unexpectedAfterEqual","value":{"text":"nil"}}]},{"id":29,"text":"=","structure":[],"parent":28,"range":{"startColumn":31,"endRow":3,"startRow":3,"endColumn":32},"type":"other","token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"equal"}},{"range":{"startColumn":33,"endRow":3,"startRow":3,"endColumn":34},"id":30,"text":"IntegerLiteralExpr","type":"expr","parent":21,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLiteral"},{"value":{"text":"8","kind":"integerLiteral("8")"},"name":"literal"},{"value":{"text":"nil"},"name":"unexpectedAfterLiteral"}]},{"range":{"startRow":3,"endColumn":34,"endRow":3,"startColumn":33},"id":31,"text":"8","type":"other","parent":30,"structure":[],"token":{"trailingTrivia":"","kind":"integerLiteral("8")","leadingTrivia":""}},{"range":{"startRow":4,"endColumn":2,"endRow":15,"startColumn":1},"id":32,"text":"CodeBlockItem","type":"other","parent":1,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","ref":"DoStmtSyntax","value":{"text":"DoStmtSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"endColumn":2,"endRow":15,"startColumn":1,"startRow":4},"id":33,"text":"DoStmt","type":"other","parent":32,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeDoKeyword"},{"value":{"text":"do","kind":"keyword(SwiftSyntax.Keyword.do)"},"name":"doKeyword"},{"value":{"text":"nil"},"name":"unexpectedBetweenDoKeywordAndThrowsClause"},{"value":{"text":"nil"},"name":"throwsClause"},{"value":{"text":"nil"},"name":"unexpectedBetweenThrowsClauseAndBody"},{"value":{"text":"CodeBlockSyntax"},"ref":"CodeBlockSyntax","name":"body"},{"value":{"text":"nil"},"name":"unexpectedBetweenBodyAndCatchClauses"},{"value":{"text":"CatchClauseListSyntax"},"ref":"CatchClauseListSyntax","name":"catchClauses"},{"value":{"text":"nil"},"name":"unexpectedAfterCatchClauses"}]},{"structure":[],"id":34,"type":"other","range":{"startRow":4,"endRow":4,"endColumn":3,"startColumn":1},"parent":33,"token":{"leadingTrivia":"↲<\/span>","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.do)"},"text":"do"},{"range":{"startRow":4,"endRow":7,"endColumn":2,"startColumn":4},"id":35,"text":"CodeBlock","type":"other","parent":33,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftBrace"},{"value":{"kind":"leftBrace","text":"{"},"name":"leftBrace"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftBraceAndStatements"},{"value":{"text":"CodeBlockItemListSyntax"},"name":"statements","ref":"CodeBlockItemListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenStatementsAndRightBrace"},{"value":{"kind":"rightBrace","text":"}"},"name":"rightBrace"},{"value":{"text":"nil"},"name":"unexpectedAfterRightBrace"}]},{"range":{"endRow":4,"startRow":4,"startColumn":4,"endColumn":5},"text":"{","parent":35,"token":{"leadingTrivia":"","kind":"leftBrace","trailingTrivia":""},"id":36,"structure":[],"type":"other"},{"range":{"endRow":6,"startRow":5,"startColumn":5,"endColumn":27},"id":37,"text":"CodeBlockItemList","type":"collection","parent":35,"structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"2"}}]},{"range":{"startColumn":5,"endRow":5,"endColumn":74,"startRow":5},"id":38,"text":"CodeBlockItem","type":"other","parent":37,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","value":{"text":"TryExprSyntax"},"ref":"TryExprSyntax"},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"startColumn":5,"endRow":5,"startRow":5,"endColumn":74},"id":39,"text":"TryExpr","type":"expr","parent":38,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeTryKeyword"},{"value":{"text":"try","kind":"keyword(SwiftSyntax.Keyword.try)"},"name":"tryKeyword"},{"value":{"text":"nil"},"name":"unexpectedBetweenTryKeywordAndQuestionOrExclamationMark"},{"value":{"text":"nil"},"name":"questionOrExclamationMark"},{"value":{"text":"nil"},"name":"unexpectedBetweenQuestionOrExclamationMarkAndExpression"},{"value":{"text":"FunctionCallExprSyntax"},"ref":"FunctionCallExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedAfterExpression"}]},{"id":40,"parent":39,"type":"other","structure":[],"token":{"trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.try)","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"},"text":"try","range":{"endRow":5,"startColumn":5,"startRow":5,"endColumn":8}},{"range":{"endRow":5,"startColumn":9,"startRow":5,"endColumn":74},"id":41,"text":"FunctionCallExpr","type":"expr","parent":39,"structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"calledExpression","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenCalledExpressionAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"kind":"leftParen","text":"("}},{"name":"unexpectedBetweenLeftParenAndArguments","value":{"text":"nil"}},{"ref":"LabeledExprListSyntax","name":"arguments","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenArgumentsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"kind":"rightParen","text":")"}},{"name":"unexpectedBetweenRightParenAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures","value":{"text":"MultipleTrailingClosureElementListSyntax"}},{"name":"unexpectedAfterAdditionalTrailingClosures","value":{"text":"nil"}}]},{"range":{"endRow":5,"endColumn":25,"startRow":5,"startColumn":9},"id":42,"text":"DeclReferenceExpr","type":"expr","parent":41,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"buyFavoriteSnack","kind":"identifier("buyFavoriteSnack")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"structure":[],"type":"other","text":"buyFavoriteSnack","range":{"startRow":5,"startColumn":9,"endRow":5,"endColumn":25},"id":43,"parent":42,"token":{"trailingTrivia":"","kind":"identifier("buyFavoriteSnack")","leadingTrivia":""}},{"type":"other","structure":[],"parent":41,"id":44,"range":{"startRow":5,"startColumn":25,"endRow":5,"endColumn":26},"token":{"trailingTrivia":"","kind":"leftParen","leadingTrivia":""},"text":"("},{"range":{"startRow":5,"startColumn":26,"endRow":5,"endColumn":73},"id":45,"text":"LabeledExprList","type":"collection","parent":41,"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"2"}}]},{"range":{"startColumn":26,"endRow":5,"endColumn":42,"startRow":5},"id":46,"text":"LabeledExpr","type":"other","parent":45,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"text":"person","kind":"identifier("person")"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"text":":","kind":"colon"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"StringLiteralExprSyntax"},"name":"expression","ref":"StringLiteralExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"kind":"comma","text":","},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"token":{"trailingTrivia":"","kind":"identifier("person")","leadingTrivia":""},"range":{"endRow":5,"startColumn":26,"startRow":5,"endColumn":32},"type":"other","text":"person","parent":46,"id":47,"structure":[]},{"type":"other","token":{"trailingTrivia":"␣<\/span>","kind":"colon","leadingTrivia":""},"structure":[],"text":":","id":48,"range":{"endRow":5,"startColumn":32,"startRow":5,"endColumn":33},"parent":46},{"range":{"endRow":5,"startColumn":34,"startRow":5,"endColumn":41},"id":49,"text":"StringLiteralExpr","type":"expr","parent":46,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeOpeningPounds"},{"value":{"text":"nil"},"name":"openingPounds"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote"},{"value":{"kind":"stringQuote","text":"""},"name":"openingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningQuoteAndSegments"},{"value":{"text":"StringLiteralSegmentListSyntax"},"ref":"StringLiteralSegmentListSyntax","name":"segments"},{"value":{"text":"nil"},"name":"unexpectedBetweenSegmentsAndClosingQuote"},{"value":{"kind":"stringQuote","text":"""},"name":"closingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenClosingQuoteAndClosingPounds"},{"value":{"text":"nil"},"name":"closingPounds"},{"value":{"text":"nil"},"name":"unexpectedAfterClosingPounds"}]},{"text":""","type":"other","structure":[],"parent":49,"token":{"trailingTrivia":"","kind":"stringQuote","leadingTrivia":""},"range":{"startRow":5,"startColumn":34,"endRow":5,"endColumn":35},"id":50},{"range":{"startRow":5,"startColumn":35,"endRow":5,"endColumn":40},"id":51,"text":"StringLiteralSegmentList","type":"collection","parent":49,"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"endColumn":40,"startRow":5,"startColumn":35,"endRow":5},"id":52,"text":"StringSegment","type":"other","parent":51,"structure":[{"name":"unexpectedBeforeContent","value":{"text":"nil"}},{"name":"content","value":{"text":"Alice","kind":"stringSegment("Alice")"}},{"name":"unexpectedAfterContent","value":{"text":"nil"}}]},{"id":53,"text":"Alice","token":{"kind":"stringSegment("Alice")","leadingTrivia":"","trailingTrivia":""},"parent":52,"structure":[],"range":{"endRow":5,"endColumn":40,"startRow":5,"startColumn":35},"type":"other"},{"range":{"endRow":5,"endColumn":41,"startRow":5,"startColumn":40},"token":{"kind":"stringQuote","leadingTrivia":"","trailingTrivia":""},"structure":[],"id":54,"text":""","parent":49,"type":"other"},{"structure":[],"type":"other","text":",","token":{"kind":"comma","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"parent":46,"range":{"endRow":5,"endColumn":42,"startRow":5,"startColumn":41},"id":55},{"range":{"endRow":5,"endColumn":73,"startRow":5,"startColumn":43},"id":56,"text":"LabeledExpr","type":"other","parent":45,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"kind":"identifier("vendingMachine")","text":"vendingMachine"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"kind":"colon","text":":"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"structure":[],"parent":56,"type":"other","token":{"kind":"identifier("vendingMachine")","trailingTrivia":"","leadingTrivia":""},"range":{"startColumn":43,"endRow":5,"startRow":5,"endColumn":57},"id":57,"text":"vendingMachine"},{"parent":56,"id":58,"text":":","token":{"kind":"colon","trailingTrivia":"␣<\/span>","leadingTrivia":""},"structure":[],"range":{"startColumn":57,"endRow":5,"startRow":5,"endColumn":58},"type":"other"},{"range":{"startColumn":59,"endRow":5,"startRow":5,"endColumn":73},"id":59,"text":"DeclReferenceExpr","type":"expr","parent":56,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"vendingMachine","kind":"identifier("vendingMachine")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"parent":59,"structure":[],"range":{"endRow":5,"endColumn":73,"startColumn":59,"startRow":5},"id":60,"text":"vendingMachine","token":{"kind":"identifier("vendingMachine")","leadingTrivia":"","trailingTrivia":""},"type":"other"},{"type":"other","id":61,"range":{"endRow":5,"endColumn":74,"startColumn":73,"startRow":5},"parent":41,"token":{"kind":"rightParen","leadingTrivia":"","trailingTrivia":""},"text":")","structure":[]},{"range":{"endRow":5,"endColumn":74,"startColumn":74,"startRow":5},"id":62,"text":"MultipleTrailingClosureElementList","type":"collection","parent":41,"structure":[{"name":"Element","value":{"text":"MultipleTrailingClosureElementSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"range":{"startRow":6,"endRow":6,"endColumn":27,"startColumn":5},"id":63,"text":"CodeBlockItem","type":"other","parent":37,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"ref":"FunctionCallExprSyntax","name":"item","value":{"text":"FunctionCallExprSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"endColumn":27,"startRow":6,"startColumn":5,"endRow":6},"id":64,"text":"FunctionCallExpr","type":"expr","parent":63,"structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"calledExpression","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenCalledExpressionAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"text":"(","kind":"leftParen"}},{"name":"unexpectedBetweenLeftParenAndArguments","value":{"text":"nil"}},{"ref":"LabeledExprListSyntax","name":"arguments","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenArgumentsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"kind":"rightParen","text":")"}},{"name":"unexpectedBetweenRightParenAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures","value":{"text":"MultipleTrailingClosureElementListSyntax"}},{"name":"unexpectedAfterAdditionalTrailingClosures","value":{"text":"nil"}}]},{"range":{"startRow":6,"startColumn":5,"endRow":6,"endColumn":10},"id":65,"text":"DeclReferenceExpr","type":"expr","parent":64,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"kind":"identifier("print")","text":"print"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"parent":65,"structure":[],"text":"print","id":66,"type":"other","token":{"trailingTrivia":"","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","kind":"identifier("print")"},"range":{"startColumn":5,"endRow":6,"startRow":6,"endColumn":10}},{"text":"(","token":{"trailingTrivia":"","leadingTrivia":"","kind":"leftParen"},"structure":[],"range":{"startColumn":10,"endRow":6,"startRow":6,"endColumn":11},"id":67,"type":"other","parent":64},{"range":{"startColumn":11,"endRow":6,"startRow":6,"endColumn":26},"id":68,"text":"LabeledExprList","type":"collection","parent":64,"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"startRow":6,"endRow":6,"startColumn":11,"endColumn":26},"id":69,"text":"LabeledExpr","type":"other","parent":68,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"text":"nil"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"text":"nil"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"StringLiteralExprSyntax"},"ref":"StringLiteralExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"endColumn":26,"startRow":6,"startColumn":11,"endRow":6},"id":70,"text":"StringLiteralExpr","type":"expr","parent":69,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeOpeningPounds"},{"value":{"text":"nil"},"name":"openingPounds"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote"},{"value":{"kind":"stringQuote","text":"""},"name":"openingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningQuoteAndSegments"},{"ref":"StringLiteralSegmentListSyntax","value":{"text":"StringLiteralSegmentListSyntax"},"name":"segments"},{"value":{"text":"nil"},"name":"unexpectedBetweenSegmentsAndClosingQuote"},{"value":{"kind":"stringQuote","text":"""},"name":"closingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenClosingQuoteAndClosingPounds"},{"value":{"text":"nil"},"name":"closingPounds"},{"value":{"text":"nil"},"name":"unexpectedAfterClosingPounds"}]},{"structure":[],"range":{"endColumn":12,"startColumn":11,"startRow":6,"endRow":6},"token":{"leadingTrivia":"","trailingTrivia":"","kind":"stringQuote"},"id":71,"parent":70,"text":""","type":"other"},{"range":{"endColumn":25,"startColumn":12,"startRow":6,"endRow":6},"id":72,"text":"StringLiteralSegmentList","type":"collection","parent":70,"structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"endRow":6,"endColumn":25,"startColumn":12,"startRow":6},"id":73,"text":"StringSegment","type":"other","parent":72,"structure":[{"name":"unexpectedBeforeContent","value":{"text":"nil"}},{"name":"content","value":{"text":"Success! Yum.","kind":"stringSegment("Success! Yum.")"}},{"name":"unexpectedAfterContent","value":{"text":"nil"}}]},{"type":"other","parent":73,"structure":[],"text":"Success!␣<\/span>Yum.","token":{"kind":"stringSegment("Success! Yum.")","trailingTrivia":"","leadingTrivia":""},"range":{"startRow":6,"endColumn":25,"startColumn":12,"endRow":6},"id":74},{"type":"other","text":""","structure":[],"token":{"kind":"stringQuote","trailingTrivia":"","leadingTrivia":""},"parent":70,"range":{"startRow":6,"endColumn":26,"startColumn":25,"endRow":6},"id":75},{"type":"other","id":76,"range":{"startRow":6,"endColumn":27,"startColumn":26,"endRow":6},"parent":64,"token":{"kind":"rightParen","trailingTrivia":"","leadingTrivia":""},"structure":[],"text":")"},{"range":{"startRow":6,"endColumn":27,"startColumn":27,"endRow":6},"id":77,"text":"MultipleTrailingClosureElementList","type":"collection","parent":64,"structure":[{"name":"Element","value":{"text":"MultipleTrailingClosureElementSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"structure":[],"token":{"leadingTrivia":"↲<\/span>","trailingTrivia":"␣<\/span>","kind":"rightBrace"},"text":"}","range":{"endColumn":2,"endRow":7,"startRow":7,"startColumn":1},"parent":35,"id":78,"type":"other"},{"range":{"endColumn":2,"endRow":15,"startRow":7,"startColumn":3},"id":79,"text":"CatchClauseList","type":"collection","parent":33,"structure":[{"value":{"text":"CatchClauseSyntax"},"name":"Element"},{"value":{"text":"4"},"name":"Count"}]},{"range":{"endColumn":2,"startRow":7,"startColumn":3,"endRow":9},"id":80,"text":"CatchClause","type":"other","parent":79,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCatchKeyword"},{"value":{"kind":"keyword(SwiftSyntax.Keyword.catch)","text":"catch"},"name":"catchKeyword"},{"value":{"text":"nil"},"name":"unexpectedBetweenCatchKeywordAndCatchItems"},{"value":{"text":"CatchItemListSyntax"},"name":"catchItems","ref":"CatchItemListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenCatchItemsAndBody"},{"value":{"text":"CodeBlockSyntax"},"name":"body","ref":"CodeBlockSyntax"},{"value":{"text":"nil"},"name":"unexpectedAfterBody"}]},{"id":81,"token":{"trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.catch)","leadingTrivia":""},"range":{"endRow":7,"startRow":7,"startColumn":3,"endColumn":8},"type":"other","text":"catch","parent":80,"structure":[]},{"range":{"endRow":7,"startRow":7,"startColumn":9,"endColumn":45},"id":82,"text":"CatchItemList","type":"collection","parent":80,"structure":[{"value":{"text":"CatchItemSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"endColumn":45,"startColumn":9,"startRow":7,"endRow":7},"id":83,"text":"CatchItem","type":"other","parent":82,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforePattern"},{"ref":"ExpressionPatternSyntax","value":{"text":"ExpressionPatternSyntax"},"name":"pattern"},{"value":{"text":"nil"},"name":"unexpectedBetweenPatternAndWhereClause"},{"value":{"text":"nil"},"name":"whereClause"},{"value":{"text":"nil"},"name":"unexpectedBetweenWhereClauseAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"startRow":7,"startColumn":9,"endRow":7,"endColumn":45},"id":84,"text":"ExpressionPattern","type":"pattern","parent":83,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeExpression"},{"value":{"text":"MemberAccessExprSyntax"},"name":"expression","ref":"MemberAccessExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedAfterExpression"}]},{"range":{"startRow":7,"startColumn":9,"endRow":7,"endColumn":45},"id":85,"text":"MemberAccessExpr","type":"expr","parent":84,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBase"},{"ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"},"name":"base"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseAndPeriod"},{"value":{"text":".","kind":"period"},"name":"period"},{"value":{"text":"nil"},"name":"unexpectedBetweenPeriodAndDeclName"},{"ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"},"name":"declName"},{"value":{"text":"nil"},"name":"unexpectedAfterDeclName"}]},{"range":{"startColumn":9,"endRow":7,"startRow":7,"endColumn":28},"id":86,"text":"DeclReferenceExpr","type":"expr","parent":85,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"VendingMachineError","kind":"identifier("VendingMachineError")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"token":{"kind":"identifier("VendingMachineError")","trailingTrivia":"","leadingTrivia":""},"text":"VendingMachineError","type":"other","range":{"endRow":7,"startColumn":9,"endColumn":28,"startRow":7},"id":87,"parent":86,"structure":[]},{"range":{"endRow":7,"startColumn":28,"endColumn":29,"startRow":7},"token":{"kind":"period","trailingTrivia":"","leadingTrivia":""},"text":".","structure":[],"parent":85,"type":"other","id":88},{"range":{"endRow":7,"startColumn":29,"endColumn":45,"startRow":7},"id":89,"text":"DeclReferenceExpr","type":"expr","parent":85,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"invalidSelection","kind":"identifier("invalidSelection")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"text":"invalidSelection","structure":[],"range":{"startColumn":29,"endRow":7,"startRow":7,"endColumn":45},"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"identifier("invalidSelection")"},"type":"other","parent":89,"id":90},{"range":{"startColumn":46,"endRow":9,"startRow":7,"endColumn":2},"id":91,"text":"CodeBlock","type":"other","parent":80,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftBrace"},{"value":{"text":"{","kind":"leftBrace"},"name":"leftBrace"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftBraceAndStatements"},{"value":{"text":"CodeBlockItemListSyntax"},"name":"statements","ref":"CodeBlockItemListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenStatementsAndRightBrace"},{"value":{"kind":"rightBrace","text":"}"},"name":"rightBrace"},{"value":{"text":"nil"},"name":"unexpectedAfterRightBrace"}]},{"id":92,"token":{"leadingTrivia":"","kind":"leftBrace","trailingTrivia":""},"type":"other","range":{"endColumn":47,"startColumn":46,"endRow":7,"startRow":7},"parent":91,"structure":[],"text":"{"},{"range":{"endColumn":32,"startColumn":5,"endRow":8,"startRow":8},"id":93,"text":"CodeBlockItemList","type":"collection","parent":91,"structure":[{"value":{"text":"CodeBlockItemSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"endColumn":32,"endRow":8,"startRow":8,"startColumn":5},"id":94,"text":"CodeBlockItem","type":"other","parent":93,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","ref":"FunctionCallExprSyntax","value":{"text":"FunctionCallExprSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"startColumn":5,"endColumn":32,"startRow":8,"endRow":8},"id":95,"text":"FunctionCallExpr","type":"expr","parent":94,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCalledExpression"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"calledExpression","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenCalledExpressionAndLeftParen"},{"value":{"text":"(","kind":"leftParen"},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndArguments"},{"value":{"text":"LabeledExprListSyntax"},"name":"arguments","ref":"LabeledExprListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenArgumentsAndRightParen"},{"value":{"text":")","kind":"rightParen"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenRightParenAndTrailingClosure"},{"value":{"text":"nil"},"name":"trailingClosure"},{"value":{"text":"nil"},"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures"},{"value":{"text":"MultipleTrailingClosureElementListSyntax"},"name":"additionalTrailingClosures","ref":"MultipleTrailingClosureElementListSyntax"},{"value":{"text":"nil"},"name":"unexpectedAfterAdditionalTrailingClosures"}]},{"range":{"startColumn":5,"startRow":8,"endRow":8,"endColumn":10},"id":96,"text":"DeclReferenceExpr","type":"expr","parent":95,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"print","kind":"identifier("print")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"text":"print","parent":96,"token":{"leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":"","kind":"identifier("print")"},"id":97,"range":{"endColumn":10,"startRow":8,"startColumn":5,"endRow":8},"structure":[],"type":"other"},{"text":"(","type":"other","range":{"endColumn":11,"startRow":8,"startColumn":10,"endRow":8},"parent":95,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"leftParen"},"id":98,"structure":[]},{"range":{"endColumn":31,"startRow":8,"startColumn":11,"endRow":8},"id":99,"text":"LabeledExprList","type":"collection","parent":95,"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"startColumn":11,"startRow":8,"endColumn":31,"endRow":8},"id":100,"text":"LabeledExpr","type":"other","parent":99,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","value":{"text":"StringLiteralExprSyntax"},"ref":"StringLiteralExprSyntax"},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"endColumn":31,"endRow":8,"startColumn":11,"startRow":8},"id":101,"text":"StringLiteralExpr","type":"expr","parent":100,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeOpeningPounds"},{"value":{"text":"nil"},"name":"openingPounds"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote"},{"value":{"text":""","kind":"stringQuote"},"name":"openingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningQuoteAndSegments"},{"value":{"text":"StringLiteralSegmentListSyntax"},"ref":"StringLiteralSegmentListSyntax","name":"segments"},{"value":{"text":"nil"},"name":"unexpectedBetweenSegmentsAndClosingQuote"},{"value":{"text":""","kind":"stringQuote"},"name":"closingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenClosingQuoteAndClosingPounds"},{"value":{"text":"nil"},"name":"closingPounds"},{"value":{"text":"nil"},"name":"unexpectedAfterClosingPounds"}]},{"token":{"leadingTrivia":"","trailingTrivia":"","kind":"stringQuote"},"structure":[],"parent":101,"range":{"startRow":8,"startColumn":11,"endRow":8,"endColumn":12},"id":102,"text":""","type":"other"},{"range":{"startRow":8,"startColumn":12,"endRow":8,"endColumn":30},"id":103,"text":"StringLiteralSegmentList","type":"collection","parent":101,"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"startRow":8,"endRow":8,"startColumn":12,"endColumn":30},"id":104,"text":"StringSegment","type":"other","parent":103,"structure":[{"name":"unexpectedBeforeContent","value":{"text":"nil"}},{"name":"content","value":{"kind":"stringSegment("Invalid Selection.")","text":"Invalid Selection."}},{"name":"unexpectedAfterContent","value":{"text":"nil"}}]},{"text":"Invalid␣<\/span>Selection.","range":{"startColumn":12,"endRow":8,"startRow":8,"endColumn":30},"type":"other","structure":[],"token":{"leadingTrivia":"","trailingTrivia":"","kind":"stringSegment("Invalid Selection.")"},"id":105,"parent":104},{"range":{"startColumn":30,"endRow":8,"startRow":8,"endColumn":31},"id":106,"parent":101,"structure":[],"text":""","type":"other","token":{"leadingTrivia":"","trailingTrivia":"","kind":"stringQuote"}},{"structure":[],"token":{"leadingTrivia":"","trailingTrivia":"","kind":"rightParen"},"range":{"startColumn":31,"endRow":8,"startRow":8,"endColumn":32},"id":107,"text":")","type":"other","parent":95},{"range":{"startColumn":32,"endRow":8,"startRow":8,"endColumn":32},"id":108,"text":"MultipleTrailingClosureElementList","type":"collection","parent":95,"structure":[{"value":{"text":"MultipleTrailingClosureElementSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"id":109,"range":{"endRow":9,"endColumn":2,"startColumn":1,"startRow":9},"type":"other","parent":91,"token":{"trailingTrivia":"␣<\/span>","kind":"rightBrace","leadingTrivia":"↲<\/span>"},"structure":[],"text":"}"},{"range":{"endRow":11,"endColumn":2,"startColumn":3,"startRow":9},"id":110,"text":"CatchClause","type":"other","parent":79,"structure":[{"name":"unexpectedBeforeCatchKeyword","value":{"text":"nil"}},{"name":"catchKeyword","value":{"text":"catch","kind":"keyword(SwiftSyntax.Keyword.catch)"}},{"name":"unexpectedBetweenCatchKeywordAndCatchItems","value":{"text":"nil"}},{"name":"catchItems","ref":"CatchItemListSyntax","value":{"text":"CatchItemListSyntax"}},{"name":"unexpectedBetweenCatchItemsAndBody","value":{"text":"nil"}},{"name":"body","ref":"CodeBlockSyntax","value":{"text":"CodeBlockSyntax"}},{"name":"unexpectedAfterBody","value":{"text":"nil"}}]},{"type":"other","parent":110,"structure":[],"range":{"startColumn":3,"startRow":9,"endColumn":8,"endRow":9},"id":111,"token":{"kind":"keyword(SwiftSyntax.Keyword.catch)","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"text":"catch"},{"range":{"startColumn":9,"startRow":9,"endColumn":39,"endRow":9},"id":112,"text":"CatchItemList","type":"collection","parent":110,"structure":[{"name":"Element","value":{"text":"CatchItemSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"startColumn":9,"endColumn":39,"startRow":9,"endRow":9},"id":113,"text":"CatchItem","type":"other","parent":112,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforePattern"},{"value":{"text":"ExpressionPatternSyntax"},"name":"pattern","ref":"ExpressionPatternSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenPatternAndWhereClause"},{"value":{"text":"nil"},"name":"whereClause"},{"value":{"text":"nil"},"name":"unexpectedBetweenWhereClauseAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"startRow":9,"startColumn":9,"endRow":9,"endColumn":39},"id":114,"text":"ExpressionPattern","type":"pattern","parent":113,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeExpression"},{"value":{"text":"MemberAccessExprSyntax"},"name":"expression","ref":"MemberAccessExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedAfterExpression"}]},{"range":{"endColumn":39,"startColumn":9,"startRow":9,"endRow":9},"id":115,"text":"MemberAccessExpr","type":"expr","parent":114,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBase"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"base"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseAndPeriod"},{"value":{"kind":"period","text":"."},"name":"period"},{"value":{"text":"nil"},"name":"unexpectedBetweenPeriodAndDeclName"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"declName"},{"value":{"text":"nil"},"name":"unexpectedAfterDeclName"}]},{"range":{"startRow":9,"startColumn":9,"endColumn":28,"endRow":9},"id":116,"text":"DeclReferenceExpr","type":"expr","parent":115,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"VendingMachineError","kind":"identifier("VendingMachineError")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"text":"VendingMachineError","id":117,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"identifier("VendingMachineError")"},"parent":116,"type":"other","range":{"endRow":9,"endColumn":28,"startColumn":9,"startRow":9},"structure":[]},{"id":118,"structure":[],"range":{"endRow":9,"endColumn":29,"startColumn":28,"startRow":9},"text":".","parent":115,"type":"other","token":{"trailingTrivia":"","leadingTrivia":"","kind":"period"}},{"range":{"endRow":9,"endColumn":39,"startColumn":29,"startRow":9},"id":119,"text":"DeclReferenceExpr","type":"expr","parent":115,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"outOfStock","kind":"identifier("outOfStock")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"text":"outOfStock","range":{"startRow":9,"endColumn":39,"endRow":9,"startColumn":29},"parent":119,"id":120,"token":{"trailingTrivia":"␣<\/span>","kind":"identifier("outOfStock")","leadingTrivia":""},"structure":[],"type":"other"},{"range":{"startRow":9,"endColumn":2,"endRow":11,"startColumn":40},"id":121,"text":"CodeBlock","type":"other","parent":110,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftBrace"},{"value":{"kind":"leftBrace","text":"{"},"name":"leftBrace"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftBraceAndStatements"},{"value":{"text":"CodeBlockItemListSyntax"},"name":"statements","ref":"CodeBlockItemListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenStatementsAndRightBrace"},{"value":{"kind":"rightBrace","text":"}"},"name":"rightBrace"},{"value":{"text":"nil"},"name":"unexpectedAfterRightBrace"}]},{"parent":121,"type":"other","token":{"kind":"leftBrace","leadingTrivia":"","trailingTrivia":""},"structure":[],"range":{"startColumn":40,"endRow":9,"startRow":9,"endColumn":41},"id":122,"text":"{"},{"range":{"startColumn":5,"endRow":10,"startRow":10,"endColumn":27},"id":123,"text":"CodeBlockItemList","type":"collection","parent":121,"structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"startRow":10,"startColumn":5,"endRow":10,"endColumn":27},"id":124,"text":"CodeBlockItem","type":"other","parent":123,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","value":{"text":"FunctionCallExprSyntax"},"ref":"FunctionCallExprSyntax"},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"endColumn":27,"startRow":10,"endRow":10,"startColumn":5},"id":125,"text":"FunctionCallExpr","type":"expr","parent":124,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCalledExpression"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"calledExpression"},{"value":{"text":"nil"},"name":"unexpectedBetweenCalledExpressionAndLeftParen"},{"value":{"text":"(","kind":"leftParen"},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndArguments"},{"value":{"text":"LabeledExprListSyntax"},"ref":"LabeledExprListSyntax","name":"arguments"},{"value":{"text":"nil"},"name":"unexpectedBetweenArgumentsAndRightParen"},{"value":{"kind":"rightParen","text":")"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenRightParenAndTrailingClosure"},{"value":{"text":"nil"},"name":"trailingClosure"},{"value":{"text":"nil"},"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures"},{"value":{"text":"MultipleTrailingClosureElementListSyntax"},"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures"},{"value":{"text":"nil"},"name":"unexpectedAfterAdditionalTrailingClosures"}]},{"range":{"startColumn":5,"endRow":10,"endColumn":10,"startRow":10},"id":126,"text":"DeclReferenceExpr","type":"expr","parent":125,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"print","kind":"identifier("print")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"type":"other","text":"print","parent":126,"id":127,"token":{"trailingTrivia":"","kind":"identifier("print")","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"},"structure":[],"range":{"startRow":10,"endColumn":10,"startColumn":5,"endRow":10}},{"text":"(","parent":125,"type":"other","token":{"trailingTrivia":"","kind":"leftParen","leadingTrivia":""},"range":{"startRow":10,"endColumn":11,"startColumn":10,"endRow":10},"id":128,"structure":[]},{"range":{"startRow":10,"endColumn":26,"startColumn":11,"endRow":10},"id":129,"text":"LabeledExprList","type":"collection","parent":125,"structure":[{"value":{"text":"LabeledExprSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"startColumn":11,"endRow":10,"startRow":10,"endColumn":26},"id":130,"text":"LabeledExpr","type":"other","parent":129,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"ref":"StringLiteralExprSyntax","name":"expression","value":{"text":"StringLiteralExprSyntax"}},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"endRow":10,"startRow":10,"endColumn":26,"startColumn":11},"id":131,"text":"StringLiteralExpr","type":"expr","parent":130,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeOpeningPounds"},{"value":{"text":"nil"},"name":"openingPounds"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote"},{"value":{"kind":"stringQuote","text":"""},"name":"openingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningQuoteAndSegments"},{"value":{"text":"StringLiteralSegmentListSyntax"},"name":"segments","ref":"StringLiteralSegmentListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenSegmentsAndClosingQuote"},{"value":{"kind":"stringQuote","text":"""},"name":"closingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenClosingQuoteAndClosingPounds"},{"value":{"text":"nil"},"name":"closingPounds"},{"value":{"text":"nil"},"name":"unexpectedAfterClosingPounds"}]},{"range":{"startColumn":11,"endColumn":12,"endRow":10,"startRow":10},"id":132,"text":""","token":{"leadingTrivia":"","kind":"stringQuote","trailingTrivia":""},"parent":131,"type":"other","structure":[]},{"range":{"startColumn":12,"endColumn":25,"endRow":10,"startRow":10},"id":133,"text":"StringLiteralSegmentList","type":"collection","parent":131,"structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"startColumn":12,"endRow":10,"startRow":10,"endColumn":25},"id":134,"text":"StringSegment","type":"other","parent":133,"structure":[{"name":"unexpectedBeforeContent","value":{"text":"nil"}},{"name":"content","value":{"text":"Out of Stock.","kind":"stringSegment("Out of Stock.")"}},{"name":"unexpectedAfterContent","value":{"text":"nil"}}]},{"parent":134,"id":135,"structure":[],"token":{"trailingTrivia":"","leadingTrivia":"","kind":"stringSegment("Out of Stock.")"},"range":{"endRow":10,"startRow":10,"endColumn":25,"startColumn":12},"text":"Out␣<\/span>of␣<\/span>Stock.","type":"other"},{"text":""","id":136,"range":{"endRow":10,"startRow":10,"endColumn":26,"startColumn":25},"type":"other","structure":[],"token":{"trailingTrivia":"","leadingTrivia":"","kind":"stringQuote"},"parent":131},{"structure":[],"token":{"trailingTrivia":"","leadingTrivia":"","kind":"rightParen"},"range":{"endRow":10,"startRow":10,"endColumn":27,"startColumn":26},"id":137,"text":")","type":"other","parent":125},{"range":{"endRow":10,"startRow":10,"endColumn":27,"startColumn":27},"id":138,"text":"MultipleTrailingClosureElementList","type":"collection","parent":125,"structure":[{"name":"Element","value":{"text":"MultipleTrailingClosureElementSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"text":"}","id":139,"parent":121,"structure":[],"token":{"leadingTrivia":"↲<\/span>","trailingTrivia":"␣<\/span>","kind":"rightBrace"},"type":"other","range":{"endRow":11,"startRow":11,"startColumn":1,"endColumn":2}},{"range":{"endRow":13,"startRow":11,"startColumn":3,"endColumn":2},"id":140,"text":"CatchClause","type":"other","parent":79,"structure":[{"name":"unexpectedBeforeCatchKeyword","value":{"text":"nil"}},{"name":"catchKeyword","value":{"text":"catch","kind":"keyword(SwiftSyntax.Keyword.catch)"}},{"name":"unexpectedBetweenCatchKeywordAndCatchItems","value":{"text":"nil"}},{"name":"catchItems","value":{"text":"CatchItemListSyntax"},"ref":"CatchItemListSyntax"},{"name":"unexpectedBetweenCatchItemsAndBody","value":{"text":"nil"}},{"name":"body","value":{"text":"CodeBlockSyntax"},"ref":"CodeBlockSyntax"},{"name":"unexpectedAfterBody","value":{"text":"nil"}}]},{"parent":140,"type":"other","text":"catch","structure":[],"range":{"endColumn":8,"endRow":11,"startColumn":3,"startRow":11},"id":141,"token":{"kind":"keyword(SwiftSyntax.Keyword.catch)","trailingTrivia":"␣<\/span>","leadingTrivia":""}},{"range":{"endColumn":63,"endRow":11,"startColumn":9,"startRow":11},"id":142,"text":"CatchItemList","type":"collection","parent":140,"structure":[{"value":{"text":"CatchItemSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"endRow":11,"startColumn":9,"endColumn":63,"startRow":11},"id":143,"text":"CatchItem","type":"other","parent":142,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforePattern"},{"ref":"ExpressionPatternSyntax","value":{"text":"ExpressionPatternSyntax"},"name":"pattern"},{"value":{"text":"nil"},"name":"unexpectedBetweenPatternAndWhereClause"},{"value":{"text":"nil"},"name":"whereClause"},{"value":{"text":"nil"},"name":"unexpectedBetweenWhereClauseAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"startColumn":9,"startRow":11,"endRow":11,"endColumn":63},"id":144,"text":"ExpressionPattern","type":"pattern","parent":143,"structure":[{"name":"unexpectedBeforeExpression","value":{"text":"nil"}},{"name":"expression","ref":"FunctionCallExprSyntax","value":{"text":"FunctionCallExprSyntax"}},{"name":"unexpectedAfterExpression","value":{"text":"nil"}}]},{"range":{"startColumn":9,"endRow":11,"endColumn":63,"startRow":11},"id":145,"text":"FunctionCallExpr","type":"expr","parent":144,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCalledExpression"},{"value":{"text":"MemberAccessExprSyntax"},"ref":"MemberAccessExprSyntax","name":"calledExpression"},{"value":{"text":"nil"},"name":"unexpectedBetweenCalledExpressionAndLeftParen"},{"value":{"kind":"leftParen","text":"("},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndArguments"},{"value":{"text":"LabeledExprListSyntax"},"ref":"LabeledExprListSyntax","name":"arguments"},{"value":{"text":"nil"},"name":"unexpectedBetweenArgumentsAndRightParen"},{"value":{"kind":"rightParen","text":")"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenRightParenAndTrailingClosure"},{"value":{"text":"nil"},"name":"trailingClosure"},{"value":{"text":"nil"},"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures"},{"value":{"text":"MultipleTrailingClosureElementListSyntax"},"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures"},{"value":{"text":"nil"},"name":"unexpectedAfterAdditionalTrailingClosures"}]},{"range":{"startRow":11,"endRow":11,"endColumn":46,"startColumn":9},"id":146,"text":"MemberAccessExpr","type":"expr","parent":145,"structure":[{"name":"unexpectedBeforeBase","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"base","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenBaseAndPeriod","value":{"text":"nil"}},{"name":"period","value":{"kind":"period","text":"."}},{"name":"unexpectedBetweenPeriodAndDeclName","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"declName","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedAfterDeclName","value":{"text":"nil"}}]},{"range":{"startRow":11,"startColumn":9,"endColumn":28,"endRow":11},"id":147,"text":"DeclReferenceExpr","type":"expr","parent":146,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"VendingMachineError","kind":"identifier("VendingMachineError")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"text":"VendingMachineError","structure":[],"parent":147,"id":148,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"identifier("VendingMachineError")"},"range":{"endColumn":28,"startRow":11,"startColumn":9,"endRow":11},"type":"other"},{"structure":[],"id":149,"text":".","range":{"endColumn":29,"startRow":11,"startColumn":28,"endRow":11},"type":"other","parent":146,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"period"}},{"range":{"endColumn":46,"startRow":11,"startColumn":29,"endRow":11},"id":150,"text":"DeclReferenceExpr","type":"expr","parent":146,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"kind":"identifier("insufficientFunds")","text":"insufficientFunds"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"token":{"trailingTrivia":"","kind":"identifier("insufficientFunds")","leadingTrivia":""},"parent":150,"type":"other","structure":[],"id":151,"range":{"startColumn":29,"endRow":11,"endColumn":46,"startRow":11},"text":"insufficientFunds"},{"parent":145,"id":152,"text":"(","structure":[],"token":{"trailingTrivia":"","kind":"leftParen","leadingTrivia":""},"range":{"startColumn":46,"endRow":11,"endColumn":47,"startRow":11},"type":"other"},{"range":{"startColumn":47,"endRow":11,"endColumn":62,"startRow":11},"id":153,"text":"LabeledExprList","type":"collection","parent":145,"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"startRow":11,"endRow":11,"startColumn":47,"endColumn":62},"id":154,"text":"LabeledExpr","type":"other","parent":153,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","value":{"text":"PatternExprSyntax"},"ref":"PatternExprSyntax"},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"startRow":11,"startColumn":47,"endRow":11,"endColumn":62},"id":155,"text":"PatternExpr","type":"expr","parent":154,"structure":[{"name":"unexpectedBeforePattern","value":{"text":"nil"}},{"ref":"ValueBindingPatternSyntax","name":"pattern","value":{"text":"ValueBindingPatternSyntax"}},{"name":"unexpectedAfterPattern","value":{"text":"nil"}}]},{"range":{"endRow":11,"startRow":11,"startColumn":47,"endColumn":62},"id":156,"text":"ValueBindingPattern","type":"pattern","parent":155,"structure":[{"name":"unexpectedBeforeBindingSpecifier","value":{"text":"nil"}},{"name":"bindingSpecifier","value":{"text":"let","kind":"keyword(SwiftSyntax.Keyword.let)"}},{"name":"unexpectedBetweenBindingSpecifierAndPattern","value":{"text":"nil"}},{"ref":"IdentifierPatternSyntax","name":"pattern","value":{"text":"IdentifierPatternSyntax"}},{"name":"unexpectedAfterPattern","value":{"text":"nil"}}]},{"id":157,"type":"other","parent":156,"range":{"endColumn":50,"endRow":11,"startColumn":47,"startRow":11},"text":"let","token":{"trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.let)","leadingTrivia":""},"structure":[]},{"range":{"endColumn":62,"endRow":11,"startColumn":51,"startRow":11},"id":158,"text":"IdentifierPattern","type":"pattern","parent":156,"structure":[{"name":"unexpectedBeforeIdentifier","value":{"text":"nil"}},{"name":"identifier","value":{"text":"coinsNeeded","kind":"identifier("coinsNeeded")"}},{"name":"unexpectedAfterIdentifier","value":{"text":"nil"}}]},{"id":159,"text":"coinsNeeded","parent":158,"range":{"endColumn":62,"startRow":11,"endRow":11,"startColumn":51},"structure":[],"token":{"kind":"identifier("coinsNeeded")","leadingTrivia":"","trailingTrivia":""},"type":"other"},{"parent":145,"range":{"endColumn":63,"startRow":11,"endRow":11,"startColumn":62},"text":")","id":160,"type":"other","structure":[],"token":{"kind":"rightParen","leadingTrivia":"","trailingTrivia":"␣<\/span>"}},{"range":{"endColumn":64,"startRow":11,"endRow":11,"startColumn":64},"id":161,"text":"MultipleTrailingClosureElementList","type":"collection","parent":145,"structure":[{"value":{"text":"MultipleTrailingClosureElementSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"range":{"endColumn":2,"startColumn":64,"startRow":11,"endRow":13},"id":162,"text":"CodeBlock","type":"other","parent":140,"structure":[{"name":"unexpectedBeforeLeftBrace","value":{"text":"nil"}},{"name":"leftBrace","value":{"text":"{","kind":"leftBrace"}},{"name":"unexpectedBetweenLeftBraceAndStatements","value":{"text":"nil"}},{"name":"statements","value":{"text":"CodeBlockItemListSyntax"},"ref":"CodeBlockItemListSyntax"},{"name":"unexpectedBetweenStatementsAndRightBrace","value":{"text":"nil"}},{"name":"rightBrace","value":{"text":"}","kind":"rightBrace"}},{"name":"unexpectedAfterRightBrace","value":{"text":"nil"}}]},{"id":163,"type":"other","structure":[],"text":"{","range":{"endRow":11,"startRow":11,"startColumn":64,"endColumn":65},"parent":162,"token":{"kind":"leftBrace","leadingTrivia":"","trailingTrivia":""}},{"range":{"endRow":12,"startRow":12,"startColumn":5,"endColumn":83},"id":164,"text":"CodeBlockItemList","type":"collection","parent":162,"structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"startRow":12,"endColumn":83,"endRow":12,"startColumn":5},"id":165,"text":"CodeBlockItem","type":"other","parent":164,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"ref":"FunctionCallExprSyntax","name":"item","value":{"text":"FunctionCallExprSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"endColumn":83,"endRow":12,"startRow":12,"startColumn":5},"id":166,"text":"FunctionCallExpr","type":"expr","parent":165,"structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"name":"calledExpression","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenCalledExpressionAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"text":"(","kind":"leftParen"}},{"name":"unexpectedBetweenLeftParenAndArguments","value":{"text":"nil"}},{"name":"arguments","ref":"LabeledExprListSyntax","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenArgumentsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"text":")","kind":"rightParen"}},{"name":"unexpectedBetweenRightParenAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"name":"additionalTrailingClosures","ref":"MultipleTrailingClosureElementListSyntax","value":{"text":"MultipleTrailingClosureElementListSyntax"}},{"name":"unexpectedAfterAdditionalTrailingClosures","value":{"text":"nil"}}]},{"range":{"endRow":12,"endColumn":10,"startColumn":5,"startRow":12},"id":167,"text":"DeclReferenceExpr","type":"expr","parent":166,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"print","kind":"identifier("print")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"token":{"kind":"identifier("print")","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>","trailingTrivia":""},"type":"other","text":"print","parent":167,"id":168,"range":{"endColumn":10,"startColumn":5,"endRow":12,"startRow":12},"structure":[]},{"type":"other","parent":166,"text":"(","range":{"endColumn":11,"startColumn":10,"endRow":12,"startRow":12},"id":169,"structure":[],"token":{"kind":"leftParen","leadingTrivia":"","trailingTrivia":""}},{"range":{"endColumn":82,"startColumn":11,"endRow":12,"startRow":12},"id":170,"text":"LabeledExprList","type":"collection","parent":166,"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"endColumn":82,"endRow":12,"startRow":12,"startColumn":11},"id":171,"text":"LabeledExpr","type":"other","parent":170,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"text":"nil"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"text":"nil"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"StringLiteralExprSyntax"},"ref":"StringLiteralExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"endColumn":82,"startColumn":11,"startRow":12,"endRow":12},"id":172,"text":"StringLiteralExpr","type":"expr","parent":171,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeOpeningPounds"},{"value":{"text":"nil"},"name":"openingPounds"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote"},{"value":{"kind":"stringQuote","text":"""},"name":"openingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenOpeningQuoteAndSegments"},{"value":{"text":"StringLiteralSegmentListSyntax"},"name":"segments","ref":"StringLiteralSegmentListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenSegmentsAndClosingQuote"},{"value":{"text":""","kind":"stringQuote"},"name":"closingQuote"},{"value":{"text":"nil"},"name":"unexpectedBetweenClosingQuoteAndClosingPounds"},{"value":{"text":"nil"},"name":"closingPounds"},{"value":{"text":"nil"},"name":"unexpectedAfterClosingPounds"}]},{"range":{"startRow":12,"endColumn":12,"startColumn":11,"endRow":12},"type":"other","text":""","structure":[],"token":{"trailingTrivia":"","kind":"stringQuote","leadingTrivia":""},"id":173,"parent":172},{"range":{"startRow":12,"endColumn":81,"startColumn":12,"endRow":12},"id":174,"text":"StringLiteralSegmentList","type":"collection","parent":172,"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"3"}}]},{"range":{"endRow":12,"startRow":12,"startColumn":12,"endColumn":60},"id":175,"text":"StringSegment","type":"other","parent":174,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeContent"},{"value":{"kind":"stringSegment("Insufficient funds. Please insert an additional ")","text":"Insufficient funds. Please insert an additional "},"name":"content"},{"value":{"text":"nil"},"name":"unexpectedAfterContent"}]},{"token":{"trailingTrivia":"","kind":"stringSegment("Insufficient funds. Please insert an additional ")","leadingTrivia":""},"structure":[],"text":"Insufficient␣<\/span>funds.␣<\/span>Please␣<\/span>insert␣<\/span>an␣<\/span>additional␣<\/span>","type":"other","id":176,"range":{"endRow":12,"endColumn":60,"startRow":12,"startColumn":12},"parent":175},{"range":{"endRow":12,"endColumn":74,"startRow":12,"startColumn":60},"id":177,"text":"ExpressionSegment","type":"other","parent":174,"structure":[{"name":"unexpectedBeforeBackslash","value":{"text":"nil"}},{"name":"backslash","value":{"text":"\\","kind":"backslash"}},{"name":"unexpectedBetweenBackslashAndPounds","value":{"text":"nil"}},{"name":"pounds","value":{"text":"nil"}},{"name":"unexpectedBetweenPoundsAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"kind":"leftParen","text":"("}},{"name":"unexpectedBetweenLeftParenAndExpressions","value":{"text":"nil"}},{"name":"expressions","value":{"text":"LabeledExprListSyntax"},"ref":"LabeledExprListSyntax"},{"name":"unexpectedBetweenExpressionsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"kind":"rightParen","text":")"}},{"name":"unexpectedAfterRightParen","value":{"text":"nil"}}]},{"text":"\\","type":"other","token":{"trailingTrivia":"","leadingTrivia":"","kind":"backslash"},"structure":[],"id":178,"range":{"startColumn":60,"endRow":12,"endColumn":61,"startRow":12},"parent":177},{"range":{"startColumn":61,"endRow":12,"endColumn":62,"startRow":12},"parent":177,"type":"other","structure":[],"text":"(","id":179,"token":{"trailingTrivia":"","leadingTrivia":"","kind":"leftParen"}},{"range":{"startColumn":62,"endRow":12,"endColumn":73,"startRow":12},"id":180,"text":"LabeledExprList","type":"collection","parent":177,"structure":[{"value":{"text":"LabeledExprSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"startRow":12,"endRow":12,"endColumn":73,"startColumn":62},"id":181,"text":"LabeledExpr","type":"other","parent":180,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"ref":"DeclReferenceExprSyntax","name":"expression","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"startRow":12,"endColumn":73,"startColumn":62,"endRow":12},"id":182,"text":"DeclReferenceExpr","type":"expr","parent":181,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"coinsNeeded","kind":"identifier("coinsNeeded")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"id":183,"parent":182,"text":"coinsNeeded","range":{"startColumn":62,"endRow":12,"endColumn":73,"startRow":12},"token":{"trailingTrivia":"","kind":"identifier("coinsNeeded")","leadingTrivia":""},"type":"other","structure":[]},{"id":184,"token":{"trailingTrivia":"","kind":"rightParen","leadingTrivia":""},"text":")","range":{"startColumn":73,"endRow":12,"endColumn":74,"startRow":12},"parent":177,"structure":[],"type":"other"},{"range":{"startColumn":74,"endRow":12,"endColumn":81,"startRow":12},"id":185,"text":"StringSegment","type":"other","parent":174,"structure":[{"name":"unexpectedBeforeContent","value":{"text":"nil"}},{"name":"content","value":{"kind":"stringSegment(" coins.")","text":" coins."}},{"name":"unexpectedAfterContent","value":{"text":"nil"}}]},{"parent":185,"id":186,"type":"other","range":{"endRow":12,"endColumn":81,"startColumn":74,"startRow":12},"text":"␣<\/span>coins.","structure":[],"token":{"kind":"stringSegment(" coins.")","leadingTrivia":"","trailingTrivia":""}},{"text":""","id":187,"token":{"kind":"stringQuote","leadingTrivia":"","trailingTrivia":""},"type":"other","range":{"endRow":12,"endColumn":82,"startColumn":81,"startRow":12},"structure":[],"parent":172},{"type":"other","parent":166,"structure":[],"token":{"kind":"rightParen","leadingTrivia":"","trailingTrivia":""},"text":")","range":{"endRow":12,"endColumn":83,"startColumn":82,"startRow":12},"id":188},{"range":{"endRow":12,"endColumn":83,"startColumn":83,"startRow":12},"id":189,"text":"MultipleTrailingClosureElementList","type":"collection","parent":166,"structure":[{"value":{"text":"MultipleTrailingClosureElementSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"parent":162,"structure":[],"id":190,"text":"}","type":"other","range":{"startColumn":1,"endRow":13,"startRow":13,"endColumn":2},"token":{"leadingTrivia":"↲<\/span>","kind":"rightBrace","trailingTrivia":"␣<\/span>"}},{"range":{"startColumn":3,"endRow":15,"startRow":13,"endColumn":2},"id":191,"text":"CatchClause","type":"other","parent":79,"structure":[{"name":"unexpectedBeforeCatchKeyword","value":{"text":"nil"}},{"name":"catchKeyword","value":{"text":"catch","kind":"keyword(SwiftSyntax.Keyword.catch)"}},{"name":"unexpectedBetweenCatchKeywordAndCatchItems","value":{"text":"nil"}},{"ref":"CatchItemListSyntax","name":"catchItems","value":{"text":"CatchItemListSyntax"}},{"name":"unexpectedBetweenCatchItemsAndBody","value":{"text":"nil"}},{"ref":"CodeBlockSyntax","name":"body","value":{"text":"CodeBlockSyntax"}},{"name":"unexpectedAfterBody","value":{"text":"nil"}}]},{"id":192,"token":{"kind":"keyword(SwiftSyntax.Keyword.catch)","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"range":{"endColumn":8,"startColumn":3,"endRow":13,"startRow":13},"structure":[],"type":"other","text":"catch","parent":191},{"range":{"endColumn":9,"startColumn":9,"endRow":13,"startRow":13},"id":193,"text":"CatchItemList","type":"collection","parent":191,"structure":[{"value":{"text":"CatchItemSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"range":{"startRow":13,"endRow":15,"startColumn":9,"endColumn":2},"id":194,"text":"CodeBlock","type":"other","parent":191,"structure":[{"name":"unexpectedBeforeLeftBrace","value":{"text":"nil"}},{"name":"leftBrace","value":{"text":"{","kind":"leftBrace"}},{"name":"unexpectedBetweenLeftBraceAndStatements","value":{"text":"nil"}},{"name":"statements","value":{"text":"CodeBlockItemListSyntax"},"ref":"CodeBlockItemListSyntax"},{"name":"unexpectedBetweenStatementsAndRightBrace","value":{"text":"nil"}},{"name":"rightBrace","value":{"kind":"rightBrace","text":"}"}},{"name":"unexpectedAfterRightBrace","value":{"text":"nil"}}]},{"token":{"kind":"leftBrace","leadingTrivia":"","trailingTrivia":""},"id":195,"type":"other","structure":[],"range":{"startColumn":9,"endRow":13,"startRow":13,"endColumn":10},"text":"{","parent":194},{"range":{"startColumn":5,"endRow":14,"startRow":14,"endColumn":41},"id":196,"text":"CodeBlockItemList","type":"collection","parent":194,"structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"startRow":14,"startColumn":5,"endRow":14,"endColumn":41},"id":197,"text":"CodeBlockItem","type":"other","parent":196,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"ref":"FunctionCallExprSyntax","name":"item","value":{"text":"FunctionCallExprSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"endColumn":41,"startColumn":5,"endRow":14,"startRow":14},"id":198,"text":"FunctionCallExpr","type":"expr","parent":197,"structure":[{"name":"unexpectedBeforeCalledExpression","value":{"text":"nil"}},{"name":"calledExpression","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenCalledExpressionAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"kind":"leftParen","text":"("}},{"name":"unexpectedBetweenLeftParenAndArguments","value":{"text":"nil"}},{"name":"arguments","ref":"LabeledExprListSyntax","value":{"text":"LabeledExprListSyntax"}},{"name":"unexpectedBetweenArgumentsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"text":")","kind":"rightParen"}},{"name":"unexpectedBetweenRightParenAndTrailingClosure","value":{"text":"nil"}},{"name":"trailingClosure","value":{"text":"nil"}},{"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures","value":{"text":"nil"}},{"name":"additionalTrailingClosures","ref":"MultipleTrailingClosureElementListSyntax","value":{"text":"MultipleTrailingClosureElementListSyntax"}},{"name":"unexpectedAfterAdditionalTrailingClosures","value":{"text":"nil"}}]},{"range":{"startRow":14,"startColumn":5,"endRow":14,"endColumn":10},"id":199,"text":"DeclReferenceExpr","type":"expr","parent":198,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"print","kind":"identifier("print")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"parent":199,"id":200,"token":{"trailingTrivia":"","kind":"identifier("print")","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"},"structure":[],"range":{"endColumn":10,"startRow":14,"startColumn":5,"endRow":14},"text":"print","type":"other"},{"parent":198,"text":"(","structure":[],"range":{"endColumn":11,"startRow":14,"startColumn":10,"endRow":14},"type":"other","id":201,"token":{"trailingTrivia":"","kind":"leftParen","leadingTrivia":""}},{"range":{"endColumn":40,"startRow":14,"startColumn":11,"endRow":14},"id":202,"text":"LabeledExprList","type":"collection","parent":198,"structure":[{"value":{"text":"LabeledExprSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"startRow":14,"endRow":14,"endColumn":40,"startColumn":11},"id":203,"text":"LabeledExpr","type":"other","parent":202,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"ref":"StringLiteralExprSyntax","name":"expression","value":{"text":"StringLiteralExprSyntax"}},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"startRow":14,"endColumn":40,"endRow":14,"startColumn":11},"id":204,"text":"StringLiteralExpr","type":"expr","parent":203,"structure":[{"name":"unexpectedBeforeOpeningPounds","value":{"text":"nil"}},{"name":"openingPounds","value":{"text":"nil"}},{"name":"unexpectedBetweenOpeningPoundsAndOpeningQuote","value":{"text":"nil"}},{"name":"openingQuote","value":{"text":""","kind":"stringQuote"}},{"name":"unexpectedBetweenOpeningQuoteAndSegments","value":{"text":"nil"}},{"ref":"StringLiteralSegmentListSyntax","name":"segments","value":{"text":"StringLiteralSegmentListSyntax"}},{"name":"unexpectedBetweenSegmentsAndClosingQuote","value":{"text":"nil"}},{"name":"closingQuote","value":{"kind":"stringQuote","text":"""}},{"name":"unexpectedBetweenClosingQuoteAndClosingPounds","value":{"text":"nil"}},{"name":"closingPounds","value":{"text":"nil"}},{"name":"unexpectedAfterClosingPounds","value":{"text":"nil"}}]},{"id":205,"token":{"kind":"stringQuote","leadingTrivia":"","trailingTrivia":""},"range":{"endRow":14,"startRow":14,"startColumn":11,"endColumn":12},"text":""","structure":[],"type":"other","parent":204},{"range":{"endRow":14,"startRow":14,"startColumn":12,"endColumn":39},"id":206,"text":"StringLiteralSegmentList","type":"collection","parent":204,"structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"3"},"name":"Count"}]},{"range":{"endRow":14,"endColumn":30,"startRow":14,"startColumn":12},"id":207,"text":"StringSegment","type":"other","parent":206,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeContent"},{"value":{"kind":"stringSegment("Unexpected error: ")","text":"Unexpected error: "},"name":"content"},{"value":{"text":"nil"},"name":"unexpectedAfterContent"}]},{"type":"other","text":"Unexpected␣<\/span>error:␣<\/span>","id":208,"parent":207,"structure":[],"range":{"endRow":14,"startColumn":12,"endColumn":30,"startRow":14},"token":{"leadingTrivia":"","kind":"stringSegment("Unexpected error: ")","trailingTrivia":""}},{"range":{"endRow":14,"startColumn":30,"endColumn":38,"startRow":14},"id":209,"text":"ExpressionSegment","type":"other","parent":206,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBackslash"},{"value":{"text":"\\","kind":"backslash"},"name":"backslash"},{"value":{"text":"nil"},"name":"unexpectedBetweenBackslashAndPounds"},{"value":{"text":"nil"},"name":"pounds"},{"value":{"text":"nil"},"name":"unexpectedBetweenPoundsAndLeftParen"},{"value":{"text":"(","kind":"leftParen"},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndExpressions"},{"ref":"LabeledExprListSyntax","value":{"text":"LabeledExprListSyntax"},"name":"expressions"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionsAndRightParen"},{"value":{"text":")","kind":"rightParen"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedAfterRightParen"}]},{"parent":209,"type":"other","structure":[],"range":{"endColumn":31,"startRow":14,"startColumn":30,"endRow":14},"token":{"kind":"backslash","trailingTrivia":"","leadingTrivia":""},"text":"\\","id":210},{"structure":[],"token":{"kind":"leftParen","trailingTrivia":"","leadingTrivia":""},"id":211,"type":"other","range":{"endColumn":32,"startRow":14,"startColumn":31,"endRow":14},"parent":209,"text":"("},{"range":{"endColumn":37,"startRow":14,"startColumn":32,"endRow":14},"id":212,"text":"LabeledExprList","type":"collection","parent":209,"structure":[{"name":"Element","value":{"text":"LabeledExprSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"endRow":14,"startColumn":32,"startRow":14,"endColumn":37},"id":213,"text":"LabeledExpr","type":"other","parent":212,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"text":"nil"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"text":"nil"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"endRow":14,"startColumn":32,"startRow":14,"endColumn":37},"id":214,"text":"DeclReferenceExpr","type":"expr","parent":213,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("error")","text":"error"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"token":{"kind":"identifier("error")","trailingTrivia":"","leadingTrivia":""},"structure":[],"range":{"endRow":14,"startColumn":32,"endColumn":37,"startRow":14},"text":"error","parent":214,"type":"other","id":215},{"range":{"endRow":14,"startColumn":37,"endColumn":38,"startRow":14},"parent":209,"id":216,"text":")","structure":[],"type":"other","token":{"kind":"rightParen","trailingTrivia":"","leadingTrivia":""}},{"range":{"endRow":14,"startColumn":38,"endColumn":39,"startRow":14},"id":217,"text":"StringSegment","type":"other","parent":206,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeContent"},{"value":{"text":".","kind":"stringSegment(".")"},"name":"content"},{"value":{"text":"nil"},"name":"unexpectedAfterContent"}]},{"token":{"trailingTrivia":"","kind":"stringSegment(".")","leadingTrivia":""},"range":{"startRow":14,"startColumn":38,"endRow":14,"endColumn":39},"parent":217,"structure":[],"type":"other","id":218,"text":"."},{"text":""","token":{"trailingTrivia":"","kind":"stringQuote","leadingTrivia":""},"type":"other","structure":[],"parent":204,"range":{"startRow":14,"startColumn":39,"endRow":14,"endColumn":40},"id":219},{"id":220,"token":{"trailingTrivia":"","kind":"rightParen","leadingTrivia":""},"range":{"startRow":14,"startColumn":40,"endRow":14,"endColumn":41},"type":"other","parent":198,"text":")","structure":[]},{"range":{"startRow":14,"startColumn":41,"endRow":14,"endColumn":41},"id":221,"text":"MultipleTrailingClosureElementList","type":"collection","parent":198,"structure":[{"value":{"text":"MultipleTrailingClosureElementSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"range":{"startRow":15,"endColumn":2,"endRow":15,"startColumn":1},"text":"}","structure":[],"type":"other","token":{"leadingTrivia":"↲<\/span>","kind":"rightBrace","trailingTrivia":""},"id":222,"parent":194},{"range":{"startRow":17,"endColumn":2,"endRow":19,"startColumn":1},"id":223,"text":"CodeBlockItem","type":"other","parent":1,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","ref":"FunctionDeclSyntax","value":{"text":"FunctionDeclSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"endColumn":2,"startRow":17,"startColumn":1,"endRow":19},"id":224,"text":"FunctionDecl","type":"decl","parent":223,"structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"ref":"AttributeListSyntax","name":"attributes","value":{"text":"AttributeListSyntax"}},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"ref":"DeclModifierListSyntax","name":"modifiers","value":{"text":"DeclModifierListSyntax"}},{"name":"unexpectedBetweenModifiersAndFuncKeyword","value":{"text":"nil"}},{"name":"funcKeyword","value":{"text":"func","kind":"keyword(SwiftSyntax.Keyword.func)"}},{"name":"unexpectedBetweenFuncKeywordAndName","value":{"text":"nil"}},{"name":"name","value":{"kind":"identifier("summarize")","text":"summarize"}},{"name":"unexpectedBetweenNameAndGenericParameterClause","value":{"text":"nil"}},{"name":"genericParameterClause","value":{"text":"nil"}},{"name":"unexpectedBetweenGenericParameterClauseAndSignature","value":{"text":"nil"}},{"ref":"FunctionSignatureSyntax","name":"signature","value":{"text":"FunctionSignatureSyntax"}},{"name":"unexpectedBetweenSignatureAndGenericWhereClause","value":{"text":"nil"}},{"name":"genericWhereClause","value":{"text":"nil"}},{"name":"unexpectedBetweenGenericWhereClauseAndBody","value":{"text":"nil"}},{"ref":"CodeBlockSyntax","name":"body","value":{"text":"CodeBlockSyntax"}},{"name":"unexpectedAfterBody","value":{"text":"nil"}}]},{"range":{"startRow":15,"startColumn":2,"endColumn":2,"endRow":15},"id":225,"text":"AttributeList","type":"collection","parent":224,"structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"range":{"startRow":15,"startColumn":2,"endColumn":2,"endRow":15},"id":226,"text":"DeclModifierList","type":"collection","parent":224,"structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"token":{"leadingTrivia":"↲<\/span>↲<\/span>","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.func)"},"range":{"endColumn":5,"startColumn":1,"endRow":17,"startRow":17},"text":"func","type":"other","parent":224,"structure":[],"id":227},{"parent":224,"structure":[],"token":{"leadingTrivia":"","trailingTrivia":"","kind":"identifier("summarize")"},"id":228,"text":"summarize","type":"other","range":{"endColumn":15,"startColumn":6,"endRow":17,"startRow":17}},{"range":{"endColumn":57,"startColumn":15,"endRow":17,"startRow":17},"id":229,"text":"FunctionSignature","type":"other","parent":224,"structure":[{"name":"unexpectedBeforeParameterClause","value":{"text":"nil"}},{"ref":"FunctionParameterClauseSyntax","name":"parameterClause","value":{"text":"FunctionParameterClauseSyntax"}},{"name":"unexpectedBetweenParameterClauseAndEffectSpecifiers","value":{"text":"nil"}},{"ref":"FunctionEffectSpecifiersSyntax","name":"effectSpecifiers","value":{"text":"FunctionEffectSpecifiersSyntax"}},{"name":"unexpectedBetweenEffectSpecifiersAndReturnClause","value":{"text":"nil"}},{"name":"returnClause","value":{"text":"nil"}},{"name":"unexpectedAfterReturnClause","value":{"text":"nil"}}]},{"range":{"startColumn":15,"endRow":17,"startRow":17,"endColumn":33},"id":230,"text":"FunctionParameterClause","type":"other","parent":229,"structure":[{"name":"unexpectedBeforeLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"kind":"leftParen","text":"("}},{"name":"unexpectedBetweenLeftParenAndParameters","value":{"text":"nil"}},{"ref":"FunctionParameterListSyntax","name":"parameters","value":{"text":"FunctionParameterListSyntax"}},{"name":"unexpectedBetweenParametersAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"text":")","kind":"rightParen"}},{"name":"unexpectedAfterRightParen","value":{"text":"nil"}}]},{"structure":[],"type":"other","id":231,"text":"(","token":{"trailingTrivia":"","leadingTrivia":"","kind":"leftParen"},"range":{"endColumn":16,"startRow":17,"startColumn":15,"endRow":17},"parent":230},{"range":{"endColumn":32,"startRow":17,"startColumn":16,"endRow":17},"id":232,"text":"FunctionParameterList","type":"collection","parent":230,"structure":[{"name":"Element","value":{"text":"FunctionParameterSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"endColumn":32,"startColumn":16,"startRow":17,"endRow":17},"id":233,"text":"FunctionParameter","type":"other","parent":232,"structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","ref":"AttributeListSyntax","value":{"text":"AttributeListSyntax"}},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","ref":"DeclModifierListSyntax","value":{"text":"DeclModifierListSyntax"}},{"name":"unexpectedBetweenModifiersAndFirstName","value":{"text":"nil"}},{"name":"firstName","value":{"kind":"wildcard","text":"_"}},{"name":"unexpectedBetweenFirstNameAndSecondName","value":{"text":"nil"}},{"name":"secondName","value":{"text":"ratings","kind":"identifier("ratings")"}},{"name":"unexpectedBetweenSecondNameAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":":","kind":"colon"}},{"name":"unexpectedBetweenColonAndType","value":{"text":"nil"}},{"name":"type","ref":"ArrayTypeSyntax","value":{"text":"ArrayTypeSyntax"}},{"name":"unexpectedBetweenTypeAndEllipsis","value":{"text":"nil"}},{"name":"ellipsis","value":{"text":"nil"}},{"name":"unexpectedBetweenEllipsisAndDefaultValue","value":{"text":"nil"}},{"name":"defaultValue","value":{"text":"nil"}},{"name":"unexpectedBetweenDefaultValueAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"startRow":17,"endRow":17,"endColumn":16,"startColumn":16},"id":234,"text":"AttributeList","type":"collection","parent":233,"structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"range":{"startColumn":16,"endColumn":16,"endRow":17,"startRow":17},"id":235,"text":"DeclModifierList","type":"collection","parent":233,"structure":[{"value":{"text":"DeclModifierSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"structure":[],"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"wildcard"},"type":"other","range":{"startRow":17,"startColumn":16,"endRow":17,"endColumn":17},"parent":233,"text":"_","id":236},{"id":237,"parent":233,"structure":[],"token":{"leadingTrivia":"","trailingTrivia":"","kind":"identifier("ratings")"},"text":"ratings","range":{"startRow":17,"startColumn":18,"endRow":17,"endColumn":25},"type":"other"},{"parent":233,"structure":[],"id":238,"text":":","range":{"startRow":17,"startColumn":25,"endRow":17,"endColumn":26},"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"colon"},"type":"other"},{"range":{"startRow":17,"startColumn":27,"endRow":17,"endColumn":32},"id":239,"text":"ArrayType","type":"type","parent":233,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftSquare"},{"value":{"kind":"leftSquare","text":"["},"name":"leftSquare"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftSquareAndElement"},{"value":{"text":"IdentifierTypeSyntax"},"ref":"IdentifierTypeSyntax","name":"element"},{"value":{"text":"nil"},"name":"unexpectedBetweenElementAndRightSquare"},{"value":{"text":"]","kind":"rightSquare"},"name":"rightSquare"},{"value":{"text":"nil"},"name":"unexpectedAfterRightSquare"}]},{"id":240,"type":"other","structure":[],"range":{"startRow":17,"endRow":17,"endColumn":28,"startColumn":27},"text":"[","parent":239,"token":{"leadingTrivia":"","trailingTrivia":"","kind":"leftSquare"}},{"range":{"startRow":17,"endRow":17,"endColumn":31,"startColumn":28},"id":241,"text":"IdentifierType","type":"type","parent":239,"structure":[{"name":"unexpectedBeforeName","value":{"text":"nil"}},{"name":"name","value":{"text":"Int","kind":"identifier("Int")"}},{"name":"unexpectedBetweenNameAndGenericArgumentClause","value":{"text":"nil"}},{"name":"genericArgumentClause","value":{"text":"nil"}},{"name":"unexpectedAfterGenericArgumentClause","value":{"text":"nil"}}]},{"text":"Int","type":"other","parent":241,"token":{"kind":"identifier("Int")","trailingTrivia":"","leadingTrivia":""},"id":242,"range":{"endRow":17,"startRow":17,"endColumn":31,"startColumn":28},"structure":[]},{"range":{"endRow":17,"startRow":17,"endColumn":32,"startColumn":31},"parent":239,"token":{"kind":"rightSquare","trailingTrivia":"","leadingTrivia":""},"structure":[],"id":243,"text":"]","type":"other"},{"id":244,"structure":[],"token":{"kind":"rightParen","trailingTrivia":"␣<\/span>","leadingTrivia":""},"text":")","type":"other","range":{"endRow":17,"startRow":17,"endColumn":33,"startColumn":32},"parent":230},{"range":{"endRow":17,"startRow":17,"endColumn":57,"startColumn":34},"id":245,"text":"FunctionEffectSpecifiers","type":"other","parent":229,"structure":[{"name":"unexpectedBeforeAsyncSpecifier","value":{"text":"nil"}},{"name":"asyncSpecifier","value":{"text":"nil"}},{"name":"unexpectedBetweenAsyncSpecifierAndThrowsClause","value":{"text":"nil"}},{"name":"throwsClause","value":{"text":"ThrowsClauseSyntax"},"ref":"ThrowsClauseSyntax"},{"name":"unexpectedAfterThrowsClause","value":{"text":"nil"}}]},{"range":{"startRow":17,"endRow":17,"endColumn":57,"startColumn":34},"id":246,"text":"ThrowsClause","type":"other","parent":245,"structure":[{"name":"unexpectedBeforeThrowsSpecifier","value":{"text":"nil"}},{"name":"throwsSpecifier","value":{"text":"throws","kind":"keyword(SwiftSyntax.Keyword.throws)"}},{"name":"unexpectedBetweenThrowsSpecifierAndLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"text":"(","kind":"leftParen"}},{"name":"unexpectedBetweenLeftParenAndType","value":{"text":"nil"}},{"ref":"IdentifierTypeSyntax","name":"type","value":{"text":"IdentifierTypeSyntax"}},{"name":"unexpectedBetweenTypeAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"kind":"rightParen","text":")"}},{"name":"unexpectedAfterRightParen","value":{"text":"nil"}}]},{"range":{"endColumn":40,"startColumn":34,"startRow":17,"endRow":17},"parent":246,"token":{"kind":"keyword(SwiftSyntax.Keyword.throws)","leadingTrivia":"","trailingTrivia":""},"text":"throws","type":"other","id":247,"structure":[]},{"id":248,"range":{"endColumn":41,"startColumn":40,"startRow":17,"endRow":17},"parent":246,"token":{"kind":"leftParen","leadingTrivia":"","trailingTrivia":""},"structure":[],"text":"(","type":"other"},{"range":{"endColumn":56,"startColumn":41,"startRow":17,"endRow":17},"id":249,"text":"IdentifierType","type":"type","parent":246,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeName"},{"value":{"text":"StatisticsError","kind":"identifier("StatisticsError")"},"name":"name"},{"value":{"text":"nil"},"name":"unexpectedBetweenNameAndGenericArgumentClause"},{"value":{"text":"nil"},"name":"genericArgumentClause"},{"value":{"text":"nil"},"name":"unexpectedAfterGenericArgumentClause"}]},{"type":"other","range":{"startColumn":41,"endColumn":56,"endRow":17,"startRow":17},"id":250,"parent":249,"token":{"kind":"identifier("StatisticsError")","leadingTrivia":"","trailingTrivia":""},"structure":[],"text":"StatisticsError"},{"type":"other","range":{"startColumn":56,"endColumn":57,"endRow":17,"startRow":17},"parent":246,"token":{"kind":"rightParen","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"structure":[],"id":251,"text":")"},{"range":{"startColumn":58,"endColumn":2,"endRow":19,"startRow":17},"id":252,"text":"CodeBlock","type":"other","parent":224,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftBrace"},{"value":{"text":"{","kind":"leftBrace"},"name":"leftBrace"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftBraceAndStatements"},{"value":{"text":"CodeBlockItemListSyntax"},"ref":"CodeBlockItemListSyntax","name":"statements"},{"value":{"text":"nil"},"name":"unexpectedBetweenStatementsAndRightBrace"},{"value":{"kind":"rightBrace","text":"}"},"name":"rightBrace"},{"value":{"text":"nil"},"name":"unexpectedAfterRightBrace"}]},{"id":253,"parent":252,"token":{"kind":"leftBrace","leadingTrivia":"","trailingTrivia":""},"range":{"endRow":17,"endColumn":59,"startRow":17,"startColumn":58},"text":"{","structure":[],"type":"other"},{"range":{"endRow":18,"endColumn":53,"startRow":18,"startColumn":5},"id":254,"text":"CodeBlockItemList","type":"collection","parent":252,"structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"endRow":18,"startRow":18,"endColumn":53,"startColumn":5},"id":255,"text":"CodeBlockItem","type":"other","parent":254,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeItem"},{"value":{"text":"GuardStmtSyntax"},"ref":"GuardStmtSyntax","name":"item"},{"value":{"text":"nil"},"name":"unexpectedBetweenItemAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}]},{"range":{"endColumn":53,"endRow":18,"startRow":18,"startColumn":5},"id":256,"text":"GuardStmt","type":"other","parent":255,"structure":[{"name":"unexpectedBeforeGuardKeyword","value":{"text":"nil"}},{"name":"guardKeyword","value":{"text":"guard","kind":"keyword(SwiftSyntax.Keyword.guard)"}},{"name":"unexpectedBetweenGuardKeywordAndConditions","value":{"text":"nil"}},{"ref":"ConditionElementListSyntax","name":"conditions","value":{"text":"ConditionElementListSyntax"}},{"name":"unexpectedBetweenConditionsAndElseKeyword","value":{"text":"nil"}},{"name":"elseKeyword","value":{"text":"else","kind":"keyword(SwiftSyntax.Keyword.else)"}},{"name":"unexpectedBetweenElseKeywordAndBody","value":{"text":"nil"}},{"ref":"CodeBlockSyntax","name":"body","value":{"text":"CodeBlockSyntax"}},{"name":"unexpectedAfterBody","value":{"text":"nil"}}]},{"range":{"startRow":18,"endColumn":10,"endRow":18,"startColumn":5},"parent":256,"id":257,"structure":[],"text":"guard","token":{"trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.guard)","leadingTrivia":"↲<\/span>␣<\/span>␣<\/span>␣<\/span>␣<\/span>"},"type":"other"},{"range":{"startRow":18,"endColumn":27,"endRow":18,"startColumn":11},"id":258,"text":"ConditionElementList","type":"collection","parent":256,"structure":[{"name":"Element","value":{"text":"ConditionElementSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"startColumn":11,"endColumn":27,"startRow":18,"endRow":18},"id":259,"text":"ConditionElement","type":"other","parent":258,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCondition"},{"value":{"text":"PrefixOperatorExprSyntax"},"ref":"PrefixOperatorExprSyntax","name":"condition"},{"value":{"text":"nil"},"name":"unexpectedBetweenConditionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"endRow":18,"startRow":18,"startColumn":11,"endColumn":27},"id":260,"text":"PrefixOperatorExpr","type":"expr","parent":259,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeOperator"},{"value":{"kind":"prefixOperator("!")","text":"!"},"name":"operator"},{"value":{"text":"nil"},"name":"unexpectedBetweenOperatorAndExpression"},{"value":{"text":"MemberAccessExprSyntax"},"ref":"MemberAccessExprSyntax","name":"expression"},{"value":{"text":"nil"},"name":"unexpectedAfterExpression"}]},{"token":{"trailingTrivia":"","leadingTrivia":"","kind":"prefixOperator("!")"},"type":"other","range":{"startRow":18,"endRow":18,"startColumn":11,"endColumn":12},"text":"!","id":261,"structure":[],"parent":260},{"range":{"startRow":18,"endRow":18,"startColumn":12,"endColumn":27},"id":262,"text":"MemberAccessExpr","type":"expr","parent":260,"structure":[{"name":"unexpectedBeforeBase","value":{"text":"nil"}},{"name":"base","value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax"},{"name":"unexpectedBetweenBaseAndPeriod","value":{"text":"nil"}},{"name":"period","value":{"text":".","kind":"period"}},{"name":"unexpectedBetweenPeriodAndDeclName","value":{"text":"nil"}},{"name":"declName","value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax"},{"name":"unexpectedAfterDeclName","value":{"text":"nil"}}]},{"range":{"startRow":18,"endRow":18,"startColumn":12,"endColumn":19},"id":263,"text":"DeclReferenceExpr","type":"expr","parent":262,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("ratings")","text":"ratings"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"type":"other","parent":263,"token":{"kind":"identifier("ratings")","trailingTrivia":"","leadingTrivia":""},"text":"ratings","range":{"startRow":18,"endColumn":19,"startColumn":12,"endRow":18},"id":264,"structure":[]},{"type":"other","id":265,"text":".","parent":262,"token":{"kind":"period","trailingTrivia":"","leadingTrivia":""},"structure":[],"range":{"startRow":18,"endColumn":20,"startColumn":19,"endRow":18}},{"range":{"startRow":18,"endColumn":27,"startColumn":20,"endRow":18},"id":266,"text":"DeclReferenceExpr","type":"expr","parent":262,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"text":"isEmpty","kind":"identifier("isEmpty")"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"text":"isEmpty","parent":266,"token":{"kind":"identifier("isEmpty")","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"range":{"startRow":18,"endRow":18,"startColumn":20,"endColumn":27},"type":"other","structure":[],"id":267},{"range":{"startRow":18,"endRow":18,"startColumn":28,"endColumn":32},"parent":256,"type":"other","structure":[],"id":268,"text":"else","token":{"kind":"keyword(SwiftSyntax.Keyword.else)","leadingTrivia":"","trailingTrivia":"␣<\/span>"}},{"range":{"startRow":18,"endRow":18,"startColumn":33,"endColumn":53},"id":269,"text":"CodeBlock","type":"other","parent":256,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftBrace"},{"value":{"kind":"leftBrace","text":"{"},"name":"leftBrace"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftBraceAndStatements"},{"value":{"text":"CodeBlockItemListSyntax"},"ref":"CodeBlockItemListSyntax","name":"statements"},{"value":{"text":"nil"},"name":"unexpectedBetweenStatementsAndRightBrace"},{"value":{"kind":"rightBrace","text":"}"},"name":"rightBrace"},{"value":{"text":"nil"},"name":"unexpectedAfterRightBrace"}]},{"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"leftBrace"},"id":270,"type":"other","structure":[],"parent":269,"range":{"startColumn":33,"endColumn":34,"endRow":18,"startRow":18},"text":"{"},{"range":{"startColumn":35,"endColumn":51,"endRow":18,"startRow":18},"id":271,"text":"CodeBlockItemList","type":"collection","parent":269,"structure":[{"name":"Element","value":{"text":"CodeBlockItemSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"endRow":18,"endColumn":51,"startColumn":35,"startRow":18},"id":272,"text":"CodeBlockItem","type":"other","parent":271,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeItem"},{"value":{"text":"ThrowStmtSyntax"},"name":"item","ref":"ThrowStmtSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenItemAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}]},{"range":{"endRow":18,"startColumn":35,"endColumn":51,"startRow":18},"id":273,"text":"ThrowStmt","type":"other","parent":272,"structure":[{"name":"unexpectedBeforeThrowKeyword","value":{"text":"nil"}},{"name":"throwKeyword","value":{"text":"throw","kind":"keyword(SwiftSyntax.Keyword.throw)"}},{"name":"unexpectedBetweenThrowKeywordAndExpression","value":{"text":"nil"}},{"name":"expression","value":{"text":"MemberAccessExprSyntax"},"ref":"MemberAccessExprSyntax"},{"name":"unexpectedAfterExpression","value":{"text":"nil"}}]},{"token":{"trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.throw)","leadingTrivia":""},"type":"other","text":"throw","parent":273,"range":{"startRow":18,"startColumn":35,"endColumn":40,"endRow":18},"structure":[],"id":274},{"range":{"startRow":18,"startColumn":41,"endColumn":51,"endRow":18},"id":275,"text":"MemberAccessExpr","type":"expr","parent":273,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBase"},{"value":{"text":"nil"},"name":"base"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseAndPeriod"},{"value":{"kind":"period","text":"."},"name":"period"},{"value":{"text":"nil"},"name":"unexpectedBetweenPeriodAndDeclName"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"declName"},{"value":{"text":"nil"},"name":"unexpectedAfterDeclName"}]},{"token":{"trailingTrivia":"","kind":"period","leadingTrivia":""},"range":{"startColumn":41,"endColumn":42,"endRow":18,"startRow":18},"text":".","type":"other","structure":[],"id":276,"parent":275},{"range":{"startColumn":42,"endColumn":51,"endRow":18,"startRow":18},"id":277,"text":"DeclReferenceExpr","type":"expr","parent":275,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("noRatings")","text":"noRatings"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"range":{"startColumn":42,"endRow":18,"startRow":18,"endColumn":51},"text":"noRatings","token":{"kind":"identifier("noRatings")","trailingTrivia":"␣<\/span>","leadingTrivia":""},"structure":[],"type":"other","parent":277,"id":278},{"structure":[],"text":"}","range":{"startColumn":52,"endRow":18,"startRow":18,"endColumn":53},"id":279,"token":{"kind":"rightBrace","trailingTrivia":"","leadingTrivia":""},"parent":269,"type":"other"},{"structure":[],"range":{"startColumn":1,"endRow":19,"startRow":19,"endColumn":2},"id":280,"text":"}","type":"other","token":{"kind":"rightBrace","trailingTrivia":"","leadingTrivia":"↲<\/span>"},"parent":252},{"range":{"startColumn":1,"endRow":21,"startRow":21,"endColumn":38},"id":281,"text":"CodeBlockItem","type":"other","parent":1,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeItem"},{"ref":"VariableDeclSyntax","value":{"text":"VariableDeclSyntax"},"name":"item"},{"value":{"text":"nil"},"name":"unexpectedBetweenItemAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}]},{"range":{"startColumn":1,"endColumn":38,"endRow":21,"startRow":21},"id":282,"text":"VariableDecl","type":"decl","parent":281,"structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","value":{"text":"AttributeListSyntax"},"ref":"AttributeListSyntax"},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","value":{"text":"DeclModifierListSyntax"},"ref":"DeclModifierListSyntax"},{"name":"unexpectedBetweenModifiersAndBindingSpecifier","value":{"text":"nil"}},{"name":"bindingSpecifier","value":{"text":"let","kind":"keyword(SwiftSyntax.Keyword.let)"}},{"name":"unexpectedBetweenBindingSpecifierAndBindings","value":{"text":"nil"}},{"name":"bindings","value":{"text":"PatternBindingListSyntax"},"ref":"PatternBindingListSyntax"},{"name":"unexpectedAfterBindings","value":{"text":"nil"}}]},{"range":{"endRow":19,"endColumn":2,"startRow":19,"startColumn":2},"id":283,"text":"AttributeList","type":"collection","parent":282,"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"0"}}]},{"range":{"endColumn":6,"endRow":21,"startRow":21,"startColumn":1},"id":284,"text":"DeclModifierList","type":"collection","parent":282,"structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"endRow":21,"startRow":21,"startColumn":1,"endColumn":6},"id":285,"text":"DeclModifier","type":"other","parent":284,"structure":[{"name":"unexpectedBeforeName","value":{"text":"nil"}},{"name":"name","value":{"kind":"keyword(SwiftSyntax.Keyword.async)","text":"async"}},{"name":"unexpectedBetweenNameAndDetail","value":{"text":"nil"}},{"name":"detail","value":{"text":"nil"}},{"name":"unexpectedAfterDetail","value":{"text":"nil"}}]},{"range":{"startRow":21,"endColumn":6,"startColumn":1,"endRow":21},"parent":285,"id":286,"type":"other","text":"async","structure":[],"token":{"trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.async)","leadingTrivia":"↲<\/span>↲<\/span>"}},{"range":{"startRow":21,"endColumn":10,"startColumn":7,"endRow":21},"parent":282,"text":"let","id":287,"type":"other","structure":[],"token":{"trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.let)","leadingTrivia":""}},{"range":{"startRow":21,"endColumn":38,"startColumn":11,"endRow":21},"id":288,"text":"PatternBindingList","type":"collection","parent":282,"structure":[{"value":{"text":"PatternBindingSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"endRow":21,"startColumn":11,"endColumn":38,"startRow":21},"id":289,"text":"PatternBinding","type":"other","parent":288,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforePattern"},{"value":{"text":"IdentifierPatternSyntax"},"ref":"IdentifierPatternSyntax","name":"pattern"},{"value":{"text":"nil"},"name":"unexpectedBetweenPatternAndTypeAnnotation"},{"value":{"text":"nil"},"name":"typeAnnotation"},{"value":{"text":"nil"},"name":"unexpectedBetweenTypeAnnotationAndInitializer"},{"value":{"text":"InitializerClauseSyntax"},"ref":"InitializerClauseSyntax","name":"initializer"},{"value":{"text":"nil"},"name":"unexpectedBetweenInitializerAndAccessorBlock"},{"value":{"text":"nil"},"name":"accessorBlock"},{"value":{"text":"nil"},"name":"unexpectedBetweenAccessorBlockAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"startRow":21,"startColumn":11,"endRow":21,"endColumn":15},"id":290,"text":"IdentifierPattern","type":"pattern","parent":289,"structure":[{"name":"unexpectedBeforeIdentifier","value":{"text":"nil"}},{"name":"identifier","value":{"kind":"identifier("data")","text":"data"}},{"name":"unexpectedAfterIdentifier","value":{"text":"nil"}}]},{"type":"other","structure":[],"range":{"startRow":21,"endRow":21,"startColumn":11,"endColumn":15},"token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"identifier("data")"},"text":"data","id":291,"parent":290},{"range":{"startRow":21,"endRow":21,"startColumn":16,"endColumn":38},"id":292,"text":"InitializerClause","type":"other","parent":289,"structure":[{"name":"unexpectedBeforeEqual","value":{"text":"nil"}},{"name":"equal","value":{"text":"=","kind":"equal"}},{"name":"unexpectedBetweenEqualAndValue","value":{"text":"nil"}},{"ref":"FunctionCallExprSyntax","name":"value","value":{"text":"FunctionCallExprSyntax"}},{"name":"unexpectedAfterValue","value":{"text":"nil"}}]},{"id":293,"text":"=","range":{"startColumn":16,"endRow":21,"endColumn":17,"startRow":21},"parent":292,"structure":[],"token":{"leadingTrivia":"","kind":"equal","trailingTrivia":"␣<\/span>"},"type":"other"},{"range":{"startColumn":18,"endRow":21,"endColumn":38,"startRow":21},"id":294,"text":"FunctionCallExpr","type":"expr","parent":292,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCalledExpression"},{"value":{"text":"DeclReferenceExprSyntax"},"name":"calledExpression","ref":"DeclReferenceExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenCalledExpressionAndLeftParen"},{"value":{"text":"(","kind":"leftParen"},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndArguments"},{"value":{"text":"LabeledExprListSyntax"},"name":"arguments","ref":"LabeledExprListSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenArgumentsAndRightParen"},{"value":{"text":")","kind":"rightParen"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenRightParenAndTrailingClosure"},{"value":{"text":"nil"},"name":"trailingClosure"},{"value":{"text":"nil"},"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures"},{"value":{"text":"MultipleTrailingClosureElementListSyntax"},"name":"additionalTrailingClosures","ref":"MultipleTrailingClosureElementListSyntax"},{"value":{"text":"nil"},"name":"unexpectedAfterAdditionalTrailingClosures"}]},{"range":{"endColumn":31,"startRow":21,"startColumn":18,"endRow":21},"id":295,"text":"DeclReferenceExpr","type":"expr","parent":294,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"kind":"identifier("fetchUserData")","text":"fetchUserData"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"text":"fetchUserData","range":{"endColumn":31,"endRow":21,"startColumn":18,"startRow":21},"structure":[],"id":296,"type":"other","parent":295,"token":{"trailingTrivia":"","kind":"identifier("fetchUserData")","leadingTrivia":""}},{"type":"other","parent":294,"structure":[],"token":{"trailingTrivia":"","kind":"leftParen","leadingTrivia":""},"range":{"endColumn":32,"endRow":21,"startColumn":31,"startRow":21},"id":297,"text":"("},{"range":{"endColumn":37,"endRow":21,"startColumn":32,"startRow":21},"id":298,"text":"LabeledExprList","type":"collection","parent":294,"structure":[{"value":{"text":"LabeledExprSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"endColumn":37,"endRow":21,"startRow":21,"startColumn":32},"id":299,"text":"LabeledExpr","type":"other","parent":298,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"id","kind":"identifier("id")"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"kind":"colon","text":":"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","value":{"text":"IntegerLiteralExprSyntax"},"ref":"IntegerLiteralExprSyntax"},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"parent":299,"text":"id","type":"other","range":{"startRow":21,"startColumn":32,"endColumn":34,"endRow":21},"token":{"trailingTrivia":"","leadingTrivia":"","kind":"identifier("id")"},"structure":[],"id":300},{"range":{"startRow":21,"startColumn":34,"endColumn":35,"endRow":21},"structure":[],"type":"other","parent":299,"text":":","token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"colon"},"id":301},{"range":{"startRow":21,"startColumn":36,"endColumn":37,"endRow":21},"id":302,"text":"IntegerLiteralExpr","type":"expr","parent":299,"structure":[{"name":"unexpectedBeforeLiteral","value":{"text":"nil"}},{"name":"literal","value":{"text":"1","kind":"integerLiteral("1")"}},{"name":"unexpectedAfterLiteral","value":{"text":"nil"}}]},{"type":"other","token":{"trailingTrivia":"","kind":"integerLiteral("1")","leadingTrivia":""},"id":303,"structure":[],"parent":302,"text":"1","range":{"endRow":21,"startRow":21,"endColumn":37,"startColumn":36}},{"range":{"endRow":21,"startRow":21,"endColumn":38,"startColumn":37},"token":{"trailingTrivia":"","kind":"rightParen","leadingTrivia":""},"text":")","type":"other","structure":[],"id":304,"parent":294},{"range":{"endRow":21,"startRow":21,"endColumn":38,"startColumn":38},"id":305,"text":"MultipleTrailingClosureElementList","type":"collection","parent":294,"structure":[{"value":{"text":"MultipleTrailingClosureElementSyntax"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"range":{"startRow":22,"endRow":22,"endColumn":40,"startColumn":1},"id":306,"text":"CodeBlockItem","type":"other","parent":1,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeItem"},{"ref":"VariableDeclSyntax","value":{"text":"VariableDeclSyntax"},"name":"item"},{"value":{"text":"nil"},"name":"unexpectedBetweenItemAndSemicolon"},{"value":{"text":"nil"},"name":"semicolon"},{"value":{"text":"nil"},"name":"unexpectedAfterSemicolon"}]},{"range":{"endRow":22,"endColumn":40,"startColumn":1,"startRow":22},"id":307,"text":"VariableDecl","type":"decl","parent":306,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeAttributes"},{"ref":"AttributeListSyntax","value":{"text":"AttributeListSyntax"},"name":"attributes"},{"value":{"text":"nil"},"name":"unexpectedBetweenAttributesAndModifiers"},{"ref":"DeclModifierListSyntax","value":{"text":"DeclModifierListSyntax"},"name":"modifiers"},{"value":{"text":"nil"},"name":"unexpectedBetweenModifiersAndBindingSpecifier"},{"value":{"kind":"keyword(SwiftSyntax.Keyword.let)","text":"let"},"name":"bindingSpecifier"},{"value":{"text":"nil"},"name":"unexpectedBetweenBindingSpecifierAndBindings"},{"ref":"PatternBindingListSyntax","value":{"text":"PatternBindingListSyntax"},"name":"bindings"},{"value":{"text":"nil"},"name":"unexpectedAfterBindings"}]},{"range":{"startRow":21,"startColumn":38,"endRow":21,"endColumn":38},"id":308,"text":"AttributeList","type":"collection","parent":307,"structure":[{"value":{"text":"Element"},"name":"Element"},{"value":{"text":"0"},"name":"Count"}]},{"range":{"startColumn":1,"startRow":22,"endRow":22,"endColumn":6},"id":309,"text":"DeclModifierList","type":"collection","parent":307,"structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"1"}}]},{"range":{"endColumn":6,"startRow":22,"startColumn":1,"endRow":22},"id":310,"text":"DeclModifier","type":"other","parent":309,"structure":[{"name":"unexpectedBeforeName","value":{"text":"nil"}},{"name":"name","value":{"text":"async","kind":"keyword(SwiftSyntax.Keyword.async)"}},{"name":"unexpectedBetweenNameAndDetail","value":{"text":"nil"}},{"name":"detail","value":{"text":"nil"}},{"name":"unexpectedAfterDetail","value":{"text":"nil"}}]},{"type":"other","range":{"startRow":22,"endColumn":6,"endRow":22,"startColumn":1},"parent":310,"token":{"leadingTrivia":"↲<\/span>","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.async)"},"structure":[],"text":"async","id":311},{"text":"let","structure":[],"token":{"leadingTrivia":"","trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.let)"},"type":"other","id":312,"parent":307,"range":{"startRow":22,"endColumn":10,"endRow":22,"startColumn":7}},{"range":{"startRow":22,"endColumn":40,"endRow":22,"startColumn":11},"id":313,"text":"PatternBindingList","type":"collection","parent":307,"structure":[{"value":{"text":"PatternBindingSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"endColumn":40,"startRow":22,"startColumn":11,"endRow":22},"id":314,"text":"PatternBinding","type":"other","parent":313,"structure":[{"name":"unexpectedBeforePattern","value":{"text":"nil"}},{"name":"pattern","value":{"text":"IdentifierPatternSyntax"},"ref":"IdentifierPatternSyntax"},{"name":"unexpectedBetweenPatternAndTypeAnnotation","value":{"text":"nil"}},{"name":"typeAnnotation","value":{"text":"nil"}},{"name":"unexpectedBetweenTypeAnnotationAndInitializer","value":{"text":"nil"}},{"name":"initializer","value":{"text":"InitializerClauseSyntax"},"ref":"InitializerClauseSyntax"},{"name":"unexpectedBetweenInitializerAndAccessorBlock","value":{"text":"nil"}},{"name":"accessorBlock","value":{"text":"nil"}},{"name":"unexpectedBetweenAccessorBlockAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"startRow":22,"startColumn":11,"endRow":22,"endColumn":16},"id":315,"text":"IdentifierPattern","type":"pattern","parent":314,"structure":[{"name":"unexpectedBeforeIdentifier","value":{"text":"nil"}},{"name":"identifier","value":{"text":"posts","kind":"identifier("posts")"}},{"name":"unexpectedAfterIdentifier","value":{"text":"nil"}}]},{"text":"posts","token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"identifier("posts")"},"parent":315,"range":{"endRow":22,"startRow":22,"startColumn":11,"endColumn":16},"type":"other","id":316,"structure":[]},{"range":{"endRow":22,"startRow":22,"startColumn":17,"endColumn":40},"id":317,"text":"InitializerClause","type":"other","parent":314,"structure":[{"name":"unexpectedBeforeEqual","value":{"text":"nil"}},{"name":"equal","value":{"kind":"equal","text":"="}},{"name":"unexpectedBetweenEqualAndValue","value":{"text":"nil"}},{"name":"value","ref":"FunctionCallExprSyntax","value":{"text":"FunctionCallExprSyntax"}},{"name":"unexpectedAfterValue","value":{"text":"nil"}}]},{"parent":317,"structure":[],"token":{"trailingTrivia":"␣<\/span>","kind":"equal","leadingTrivia":""},"id":318,"type":"other","text":"=","range":{"endColumn":18,"startRow":22,"startColumn":17,"endRow":22}},{"range":{"endColumn":40,"startRow":22,"startColumn":19,"endRow":22},"id":319,"text":"FunctionCallExpr","type":"expr","parent":317,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeCalledExpression"},{"value":{"text":"DeclReferenceExprSyntax"},"ref":"DeclReferenceExprSyntax","name":"calledExpression"},{"value":{"text":"nil"},"name":"unexpectedBetweenCalledExpressionAndLeftParen"},{"value":{"text":"(","kind":"leftParen"},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndArguments"},{"value":{"text":"LabeledExprListSyntax"},"ref":"LabeledExprListSyntax","name":"arguments"},{"value":{"text":"nil"},"name":"unexpectedBetweenArgumentsAndRightParen"},{"value":{"kind":"rightParen","text":")"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenRightParenAndTrailingClosure"},{"value":{"text":"nil"},"name":"trailingClosure"},{"value":{"text":"nil"},"name":"unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures"},{"value":{"text":"MultipleTrailingClosureElementListSyntax"},"ref":"MultipleTrailingClosureElementListSyntax","name":"additionalTrailingClosures"},{"value":{"text":"nil"},"name":"unexpectedAfterAdditionalTrailingClosures"}]},{"range":{"startRow":22,"endRow":22,"startColumn":19,"endColumn":33},"id":320,"text":"DeclReferenceExpr","type":"expr","parent":319,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"text":"fetchUserPosts","kind":"identifier("fetchUserPosts")"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"structure":[],"text":"fetchUserPosts","range":{"endRow":22,"endColumn":33,"startRow":22,"startColumn":19},"token":{"leadingTrivia":"","trailingTrivia":"","kind":"identifier("fetchUserPosts")"},"type":"other","id":321,"parent":320},{"structure":[],"parent":319,"text":"(","range":{"endRow":22,"endColumn":34,"startRow":22,"startColumn":33},"token":{"leadingTrivia":"","trailingTrivia":"","kind":"leftParen"},"id":322,"type":"other"},{"range":{"endRow":22,"endColumn":39,"startRow":22,"startColumn":34},"id":323,"text":"LabeledExprList","type":"collection","parent":319,"structure":[{"value":{"text":"LabeledExprSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"startRow":22,"startColumn":34,"endColumn":39,"endRow":22},"id":324,"text":"LabeledExpr","type":"other","parent":323,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLabel"},{"value":{"kind":"identifier("id")","text":"id"},"name":"label"},{"value":{"text":"nil"},"name":"unexpectedBetweenLabelAndColon"},{"value":{"kind":"colon","text":":"},"name":"colon"},{"value":{"text":"nil"},"name":"unexpectedBetweenColonAndExpression"},{"value":{"text":"IntegerLiteralExprSyntax"},"name":"expression","ref":"IntegerLiteralExprSyntax"},{"value":{"text":"nil"},"name":"unexpectedBetweenExpressionAndTrailingComma"},{"value":{"text":"nil"},"name":"trailingComma"},{"value":{"text":"nil"},"name":"unexpectedAfterTrailingComma"}]},{"range":{"startColumn":34,"startRow":22,"endRow":22,"endColumn":36},"id":325,"token":{"kind":"identifier("id")","leadingTrivia":"","trailingTrivia":""},"type":"other","text":"id","parent":324,"structure":[]},{"range":{"startColumn":36,"startRow":22,"endRow":22,"endColumn":37},"token":{"kind":"colon","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"parent":324,"id":326,"text":":","type":"other","structure":[]},{"range":{"startColumn":38,"startRow":22,"endRow":22,"endColumn":39},"id":327,"text":"IntegerLiteralExpr","type":"expr","parent":324,"structure":[{"name":"unexpectedBeforeLiteral","value":{"text":"nil"}},{"name":"literal","value":{"text":"1","kind":"integerLiteral("1")"}},{"name":"unexpectedAfterLiteral","value":{"text":"nil"}}]},{"text":"1","id":328,"token":{"leadingTrivia":"","kind":"integerLiteral("1")","trailingTrivia":""},"range":{"startColumn":38,"startRow":22,"endColumn":39,"endRow":22},"type":"other","parent":327,"structure":[]},{"parent":319,"type":"other","token":{"leadingTrivia":"","kind":"rightParen","trailingTrivia":""},"text":")","id":329,"structure":[],"range":{"startColumn":39,"startRow":22,"endColumn":40,"endRow":22}},{"range":{"startColumn":40,"startRow":22,"endColumn":40,"endRow":22},"id":330,"text":"MultipleTrailingClosureElementList","type":"collection","parent":319,"structure":[{"name":"Element","value":{"text":"MultipleTrailingClosureElementSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"range":{"endRow":23,"endColumn":58,"startColumn":1,"startRow":23},"id":331,"text":"CodeBlockItem","type":"other","parent":1,"structure":[{"name":"unexpectedBeforeItem","value":{"text":"nil"}},{"name":"item","ref":"VariableDeclSyntax","value":{"text":"VariableDeclSyntax"}},{"name":"unexpectedBetweenItemAndSemicolon","value":{"text":"nil"}},{"name":"semicolon","value":{"text":"nil"}},{"name":"unexpectedAfterSemicolon","value":{"text":"nil"}}]},{"range":{"startColumn":1,"endColumn":58,"startRow":23,"endRow":23},"id":332,"text":"VariableDecl","type":"decl","parent":331,"structure":[{"name":"unexpectedBeforeAttributes","value":{"text":"nil"}},{"name":"attributes","value":{"text":"AttributeListSyntax"},"ref":"AttributeListSyntax"},{"name":"unexpectedBetweenAttributesAndModifiers","value":{"text":"nil"}},{"name":"modifiers","value":{"text":"DeclModifierListSyntax"},"ref":"DeclModifierListSyntax"},{"name":"unexpectedBetweenModifiersAndBindingSpecifier","value":{"text":"nil"}},{"name":"bindingSpecifier","value":{"kind":"keyword(SwiftSyntax.Keyword.let)","text":"let"}},{"name":"unexpectedBetweenBindingSpecifierAndBindings","value":{"text":"nil"}},{"name":"bindings","value":{"text":"PatternBindingListSyntax"},"ref":"PatternBindingListSyntax"},{"name":"unexpectedAfterBindings","value":{"text":"nil"}}]},{"range":{"startRow":22,"endRow":22,"endColumn":40,"startColumn":40},"id":333,"text":"AttributeList","type":"collection","parent":332,"structure":[{"name":"Element","value":{"text":"Element"}},{"name":"Count","value":{"text":"0"}}]},{"range":{"startColumn":40,"startRow":22,"endRow":22,"endColumn":40},"id":334,"text":"DeclModifierList","type":"collection","parent":332,"structure":[{"name":"Element","value":{"text":"DeclModifierSyntax"}},{"name":"Count","value":{"text":"0"}}]},{"parent":332,"structure":[],"range":{"startColumn":1,"endRow":23,"startRow":23,"endColumn":4},"text":"let","id":335,"token":{"trailingTrivia":"␣<\/span>","kind":"keyword(SwiftSyntax.Keyword.let)","leadingTrivia":"↲<\/span>"},"type":"other"},{"range":{"startColumn":5,"endRow":23,"startRow":23,"endColumn":58},"id":336,"text":"PatternBindingList","type":"collection","parent":332,"structure":[{"value":{"text":"PatternBindingSyntax"},"name":"Element"},{"value":{"text":"1"},"name":"Count"}]},{"range":{"endColumn":58,"startRow":23,"startColumn":5,"endRow":23},"id":337,"text":"PatternBinding","type":"other","parent":336,"structure":[{"name":"unexpectedBeforePattern","value":{"text":"nil"}},{"ref":"TuplePatternSyntax","name":"pattern","value":{"text":"TuplePatternSyntax"}},{"name":"unexpectedBetweenPatternAndTypeAnnotation","value":{"text":"nil"}},{"name":"typeAnnotation","value":{"text":"nil"}},{"name":"unexpectedBetweenTypeAnnotationAndInitializer","value":{"text":"nil"}},{"ref":"InitializerClauseSyntax","name":"initializer","value":{"text":"InitializerClauseSyntax"}},{"name":"unexpectedBetweenInitializerAndAccessorBlock","value":{"text":"nil"}},{"name":"accessorBlock","value":{"text":"nil"}},{"name":"unexpectedBetweenAccessorBlockAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"endRow":23,"startRow":23,"startColumn":5,"endColumn":32},"id":338,"text":"TuplePattern","type":"pattern","parent":337,"structure":[{"name":"unexpectedBeforeLeftParen","value":{"text":"nil"}},{"name":"leftParen","value":{"kind":"leftParen","text":"("}},{"name":"unexpectedBetweenLeftParenAndElements","value":{"text":"nil"}},{"name":"elements","value":{"text":"TuplePatternElementListSyntax"},"ref":"TuplePatternElementListSyntax"},{"name":"unexpectedBetweenElementsAndRightParen","value":{"text":"nil"}},{"name":"rightParen","value":{"kind":"rightParen","text":")"}},{"name":"unexpectedAfterRightParen","value":{"text":"nil"}}]},{"parent":338,"type":"other","text":"(","token":{"kind":"leftParen","leadingTrivia":"","trailingTrivia":""},"range":{"startRow":23,"startColumn":5,"endRow":23,"endColumn":6},"structure":[],"id":339},{"range":{"startRow":23,"startColumn":6,"endRow":23,"endColumn":31},"id":340,"text":"TuplePatternElementList","type":"collection","parent":338,"structure":[{"value":{"text":"TuplePatternElementSyntax"},"name":"Element"},{"value":{"text":"2"},"name":"Count"}]},{"range":{"endRow":23,"startColumn":6,"endColumn":18,"startRow":23},"id":341,"text":"TuplePatternElement","type":"other","parent":340,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndPattern","value":{"text":"nil"}},{"name":"pattern","ref":"IdentifierPatternSyntax","value":{"text":"IdentifierPatternSyntax"}},{"name":"unexpectedBetweenPatternAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":",","kind":"comma"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"endColumn":17,"startRow":23,"endRow":23,"startColumn":6},"id":342,"text":"IdentifierPattern","type":"pattern","parent":341,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeIdentifier"},{"value":{"text":"fetchedData","kind":"identifier("fetchedData")"},"name":"identifier"},{"value":{"text":"nil"},"name":"unexpectedAfterIdentifier"}]},{"range":{"startColumn":6,"startRow":23,"endColumn":17,"endRow":23},"parent":342,"id":343,"structure":[],"text":"fetchedData","type":"other","token":{"kind":"identifier("fetchedData")","leadingTrivia":"","trailingTrivia":""}},{"range":{"startColumn":17,"startRow":23,"endColumn":18,"endRow":23},"parent":341,"type":"other","text":",","structure":[],"token":{"kind":"comma","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"id":344},{"range":{"startColumn":19,"startRow":23,"endColumn":31,"endRow":23},"id":345,"text":"TuplePatternElement","type":"other","parent":340,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndPattern","value":{"text":"nil"}},{"ref":"IdentifierPatternSyntax","name":"pattern","value":{"text":"IdentifierPatternSyntax"}},{"name":"unexpectedBetweenPatternAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"startRow":23,"endColumn":31,"startColumn":19,"endRow":23},"id":346,"text":"IdentifierPattern","type":"pattern","parent":345,"structure":[{"name":"unexpectedBeforeIdentifier","value":{"text":"nil"}},{"name":"identifier","value":{"text":"fetchedPosts","kind":"identifier("fetchedPosts")"}},{"name":"unexpectedAfterIdentifier","value":{"text":"nil"}}]},{"text":"fetchedPosts","id":347,"type":"other","range":{"endColumn":31,"startRow":23,"endRow":23,"startColumn":19},"structure":[],"token":{"trailingTrivia":"","kind":"identifier("fetchedPosts")","leadingTrivia":""},"parent":346},{"token":{"trailingTrivia":"␣<\/span>","kind":"rightParen","leadingTrivia":""},"structure":[],"type":"other","text":")","id":348,"parent":338,"range":{"endColumn":32,"startRow":23,"endRow":23,"startColumn":31}},{"range":{"endColumn":58,"startRow":23,"endRow":23,"startColumn":33},"id":349,"text":"InitializerClause","type":"other","parent":337,"structure":[{"name":"unexpectedBeforeEqual","value":{"text":"nil"}},{"name":"equal","value":{"kind":"equal","text":"="}},{"name":"unexpectedBetweenEqualAndValue","value":{"text":"nil"}},{"ref":"TryExprSyntax","name":"value","value":{"text":"TryExprSyntax"}},{"name":"unexpectedAfterValue","value":{"text":"nil"}}]},{"id":350,"text":"=","token":{"trailingTrivia":"␣<\/span>","kind":"equal","leadingTrivia":""},"structure":[],"range":{"startColumn":33,"startRow":23,"endRow":23,"endColumn":34},"type":"other","parent":349},{"range":{"startColumn":35,"startRow":23,"endRow":23,"endColumn":58},"id":351,"text":"TryExpr","type":"expr","parent":349,"structure":[{"name":"unexpectedBeforeTryKeyword","value":{"text":"nil"}},{"name":"tryKeyword","value":{"kind":"keyword(SwiftSyntax.Keyword.try)","text":"try"}},{"name":"unexpectedBetweenTryKeywordAndQuestionOrExclamationMark","value":{"text":"nil"}},{"name":"questionOrExclamationMark","value":{"text":"nil"}},{"name":"unexpectedBetweenQuestionOrExclamationMarkAndExpression","value":{"text":"nil"}},{"name":"expression","ref":"AwaitExprSyntax","value":{"text":"AwaitExprSyntax"}},{"name":"unexpectedAfterExpression","value":{"text":"nil"}}]},{"type":"other","id":352,"token":{"kind":"keyword(SwiftSyntax.Keyword.try)","leadingTrivia":"","trailingTrivia":"␣<\/span>"},"range":{"endColumn":38,"startColumn":35,"endRow":23,"startRow":23},"parent":351,"text":"try","structure":[]},{"range":{"endColumn":58,"startColumn":39,"endRow":23,"startRow":23},"id":353,"text":"AwaitExpr","type":"expr","parent":351,"structure":[{"name":"unexpectedBeforeAwaitKeyword","value":{"text":"nil"}},{"name":"awaitKeyword","value":{"text":"await","kind":"keyword(SwiftSyntax.Keyword.await)"}},{"name":"unexpectedBetweenAwaitKeywordAndExpression","value":{"text":"nil"}},{"ref":"TupleExprSyntax","name":"expression","value":{"text":"TupleExprSyntax"}},{"name":"unexpectedAfterExpression","value":{"text":"nil"}}]},{"structure":[],"id":354,"text":"await","token":{"trailingTrivia":"␣<\/span>","leadingTrivia":"","kind":"keyword(SwiftSyntax.Keyword.await)"},"parent":353,"range":{"startColumn":39,"endColumn":44,"startRow":23,"endRow":23},"type":"other"},{"range":{"startColumn":45,"endColumn":58,"startRow":23,"endRow":23},"id":355,"text":"TupleExpr","type":"expr","parent":353,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeLeftParen"},{"value":{"text":"(","kind":"leftParen"},"name":"leftParen"},{"value":{"text":"nil"},"name":"unexpectedBetweenLeftParenAndElements"},{"ref":"LabeledExprListSyntax","value":{"text":"LabeledExprListSyntax"},"name":"elements"},{"value":{"text":"nil"},"name":"unexpectedBetweenElementsAndRightParen"},{"value":{"kind":"rightParen","text":")"},"name":"rightParen"},{"value":{"text":"nil"},"name":"unexpectedAfterRightParen"}]},{"parent":355,"range":{"endRow":23,"startColumn":45,"endColumn":46,"startRow":23},"type":"other","structure":[],"token":{"trailingTrivia":"","leadingTrivia":"","kind":"leftParen"},"id":356,"text":"("},{"range":{"endRow":23,"startColumn":46,"endColumn":57,"startRow":23},"id":357,"text":"LabeledExprList","type":"collection","parent":355,"structure":[{"value":{"text":"LabeledExprSyntax"},"name":"Element"},{"value":{"text":"2"},"name":"Count"}]},{"range":{"endRow":23,"startRow":23,"endColumn":51,"startColumn":46},"id":358,"text":"LabeledExpr","type":"other","parent":357,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":",","kind":"comma"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"startColumn":46,"endRow":23,"startRow":23,"endColumn":50},"id":359,"text":"DeclReferenceExpr","type":"expr","parent":358,"structure":[{"value":{"text":"nil"},"name":"unexpectedBeforeBaseName"},{"value":{"kind":"identifier("data")","text":"data"},"name":"baseName"},{"value":{"text":"nil"},"name":"unexpectedBetweenBaseNameAndArgumentNames"},{"value":{"text":"nil"},"name":"argumentNames"},{"value":{"text":"nil"},"name":"unexpectedAfterArgumentNames"}]},{"type":"other","text":"data","token":{"leadingTrivia":"","kind":"identifier("data")","trailingTrivia":""},"structure":[],"range":{"startColumn":46,"startRow":23,"endRow":23,"endColumn":50},"parent":359,"id":360},{"token":{"leadingTrivia":"","kind":"comma","trailingTrivia":"␣<\/span>"},"id":361,"text":",","type":"other","structure":[],"parent":358,"range":{"startColumn":50,"startRow":23,"endRow":23,"endColumn":51}},{"range":{"startColumn":52,"startRow":23,"endRow":23,"endColumn":57},"id":362,"text":"LabeledExpr","type":"other","parent":357,"structure":[{"name":"unexpectedBeforeLabel","value":{"text":"nil"}},{"name":"label","value":{"text":"nil"}},{"name":"unexpectedBetweenLabelAndColon","value":{"text":"nil"}},{"name":"colon","value":{"text":"nil"}},{"name":"unexpectedBetweenColonAndExpression","value":{"text":"nil"}},{"name":"expression","ref":"DeclReferenceExprSyntax","value":{"text":"DeclReferenceExprSyntax"}},{"name":"unexpectedBetweenExpressionAndTrailingComma","value":{"text":"nil"}},{"name":"trailingComma","value":{"text":"nil"}},{"name":"unexpectedAfterTrailingComma","value":{"text":"nil"}}]},{"range":{"startColumn":52,"endRow":23,"endColumn":57,"startRow":23},"id":363,"text":"DeclReferenceExpr","type":"expr","parent":362,"structure":[{"name":"unexpectedBeforeBaseName","value":{"text":"nil"}},{"name":"baseName","value":{"kind":"identifier("posts")","text":"posts"}},{"name":"unexpectedBetweenBaseNameAndArgumentNames","value":{"text":"nil"}},{"name":"argumentNames","value":{"text":"nil"}},{"name":"unexpectedAfterArgumentNames","value":{"text":"nil"}}]},{"structure":[],"token":{"leadingTrivia":"","kind":"identifier("posts")","trailingTrivia":""},"id":364,"range":{"endColumn":57,"endRow":23,"startRow":23,"startColumn":52},"text":"posts","type":"other","parent":363},{"range":{"endColumn":58,"endRow":23,"startRow":23,"startColumn":57},"type":"other","parent":355,"id":365,"structure":[],"token":{"leadingTrivia":"","kind":"rightParen","trailingTrivia":""},"text":")"},{"token":{"leadingTrivia":"","kind":"endOfFile","trailingTrivia":""},"text":"","id":366,"type":"other","parent":0,"range":{"endColumn":58,"endRow":23,"startRow":23,"startColumn":58},"structure":[]}] diff --git a/Examples/Remaining/concurrency/code.swift b/Examples/Remaining/concurrency/code.swift deleted file mode 100644 index 21be8c3..0000000 --- a/Examples/Remaining/concurrency/code.swift +++ /dev/null @@ -1,87 +0,0 @@ -import Foundation - -// MARK: - Async Functions -func fetchUserData(id: Int) async throws -> String { - // Simulate network delay - try await Task.sleep(nanoseconds: 1_000_000_000) // 1 second - return "User data for ID: \(id)" -} - -func fetchUserPosts(id: Int) async throws -> [String] { - // Simulate network delay - try await Task.sleep(nanoseconds: 2_000_000_000) // 2 seconds - return ["Post 1", "Post 2", "Post 3"] -} - -// MARK: - Async Sequence -struct Countdown: AsyncSequence { - let start: Int - - struct AsyncIterator: AsyncIteratorProtocol { - var count: Int - - mutating func next() async -> Int? { - guard !isEmpty else { return nil } - try? await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds - let current = count - count -= 1 - return current - } - } - - func makeAsyncIterator() -> AsyncIterator { - AsyncIterator(count: start) - } -} - -// MARK: - Task Groups -func fetchMultipleUsers(ids: [Int]) async throws -> [String] { - try await withThrowingTaskGroup(of: String.self) { group in - for id in ids { - group.addTask { - try await fetchUserData(id: id) - } - } - - var results: [String] = [] - for try await result in group { - results.append(result) - } - return results - } -} - -// MARK: - Usage Example -@main -struct ConcurrencyExample { - static func main() async { - do { - // Demonstrate basic async/await - print("Fetching user data...") - let userData = try await fetchUserData(id: 1) - print(userData) - - // Demonstrate concurrent tasks - print("\nFetching user data and posts concurrently...") - async let data = fetchUserData(id: 1) - async let posts = fetchUserPosts(id: 1) - let (fetchedData, fetchedPosts) = try await (data, posts) - print("Data: \(fetchedData)") - print("Posts: \(fetchedPosts)") - - // Demonstrate async sequence - print("\nStarting countdown:") - for await number in Countdown(start: 3) { - print(number) - } - print("Liftoff!") - - // Demonstrate task groups - print("\nFetching multiple users:") - let users = try await fetchMultipleUsers(ids: [1, 2, 3]) - print(users) - } catch { - print("Error: \(error)") - } - } -} diff --git a/Examples/Remaining/result_builders/code.swift b/Examples/Remaining/result_builders/code.swift new file mode 100644 index 0000000..148b74e --- /dev/null +++ b/Examples/Remaining/result_builders/code.swift @@ -0,0 +1,58 @@ + +var vendingMachine = VendingMachine() +vendingMachine.coinsDeposited = 8 +do { + try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine) + print("Success! Yum.") +} catch VendingMachineError.invalidSelection { + print("Invalid Selection.") +} catch VendingMachineError.outOfStock { + print("Out of Stock.") +} catch VendingMachineError.insufficientFunds(let coinsNeeded) { + print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.") +} catch { + print("Unexpected error: \(error).") +} + +func summarize(_ ratings: [Int]) throws(StatisticsError) { + guard !ratings.isEmpty else { throw .noRatings } +} + +// MARK: - Task Groups +func fetchMultipleUsers(ids: [Int]) async throws -> [String] { + try await withThrowingTaskGroup(of: String.self) { group in + for id in ids { + group.addTask { + try await fetchUserData(id: id) + } + } + + var results: [String] = [] + for try await result in group { + results.append(result) + } + return results + } +} + +// Demonstrate concurrent tasks +print("\nFetching user data and posts concurrently...") +async let data = fetchUserData(id: 1) +async let posts = fetchUserPosts(id: 1) +let (fetchedData, fetchedPosts) = try await (data, posts) +print("Data: \(fetchedData)") +print("Posts: \(fetchedPosts)") + + +Task { + _ = try await fetchUserData(id: 1) +} + +Task { @MainActor [unowned self] in + _ = try await fetchUserData(id: 1) +} + + +func nonThrowingFunction() throws(Never) { + +} \ No newline at end of file diff --git a/Line.swift b/Line.swift index 29be4c6..41374c1 100644 --- a/Line.swift +++ b/Line.swift @@ -5,7 +5,8 @@ // Created by Leo Dion on 6/16/25. // -/// Represents a single comment line that can be attached to a syntax node when using `.comment { ... }` in the DSL. +/// Represents a single comment line that can be attached to a syntax node when using +/// `.comment { ... }` in the DSL. public struct Line { public enum Kind { /// Regular line comment that starts with `//`. diff --git a/Sources/SyntaxKit/Assignment.swift b/Sources/SyntaxKit/Assignment.swift index a6502da..b3e26ac 100644 --- a/Sources/SyntaxKit/Assignment.swift +++ b/Sources/SyntaxKit/Assignment.swift @@ -71,7 +71,8 @@ public struct Assignment: CodeBlock { elements: ExprListSyntax([ left, ExprSyntax( - AssignmentExprSyntax(equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space))), + AssignmentExprSyntax(equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space)) + ), right, ]) ) diff --git a/Sources/SyntaxKit/Call.swift b/Sources/SyntaxKit/Call.swift index 05bdc09..f3df787 100644 --- a/Sources/SyntaxKit/Call.swift +++ b/Sources/SyntaxKit/Call.swift @@ -33,6 +33,8 @@ import SwiftSyntax public struct Call: CodeBlock { private let functionName: String private let parameters: [ParameterExp] + private var isThrowing: Bool = false + private var isAsync: Bool = false /// Creates a global function call expression. /// - Parameter functionName: The name of the function to call. @@ -50,6 +52,22 @@ public struct Call: CodeBlock { self.parameters = params() } + /// Marks this function call as throwing. + /// - Returns: A copy of the call marked as throwing. + public func throwing() -> Self { + var copy = self + copy.isThrowing = true + return copy + } + + /// Marks this function call as async. + /// - Returns: A copy of the call marked as async. + public func async() -> Self { + var copy = self + copy.isAsync = true + return copy + } + public var syntax: SyntaxProtocol { let function = TokenSyntax.identifier(functionName) let args = LabeledExprListSyntax( @@ -73,12 +91,29 @@ public struct Call: CodeBlock { } }) - return ExprSyntax( - FunctionCallExprSyntax( - calledExpression: ExprSyntax(DeclReferenceExprSyntax(baseName: function)), - leftParen: .leftParenToken(), - arguments: args, - rightParen: .rightParenToken() - )) + let functionCall = FunctionCallExprSyntax( + calledExpression: ExprSyntax(DeclReferenceExprSyntax(baseName: function)), + leftParen: .leftParenToken(), + arguments: args, + rightParen: .rightParenToken() + ) + + if isThrowing { + return ExprSyntax( + TryExprSyntax( + tryKeyword: .keyword(.try, trailingTrivia: .space), + expression: functionCall + ) + ) + } else if isAsync { + return ExprSyntax( + AwaitExprSyntax( + awaitKeyword: .keyword(.await, trailingTrivia: .space), + expression: functionCall + ) + ) + } else { + return ExprSyntax(functionCall) + } } } diff --git a/Sources/SyntaxKit/Case.swift b/Sources/SyntaxKit/Case.swift index 18c8e59..14951df 100644 --- a/Sources/SyntaxKit/Case.swift +++ b/Sources/SyntaxKit/Case.swift @@ -29,10 +29,13 @@ import SwiftSyntax -/// A `case` in a `switch` statement with tuple-style patterns. +/// A `case` in a `switch` statement with tuple-style patterns, or an enum case declaration. public struct Case: CodeBlock { private let patterns: [PatternConvertible] private let body: [CodeBlock] + private let isEnumCase: Bool + private let enumCaseName: String? + private var associatedValue: (name: String, type: String)? /// Creates a `case` for a `switch` statement. /// - Parameters: @@ -42,6 +45,30 @@ public struct Case: CodeBlock { { self.patterns = patterns self.body = content() + self.isEnumCase = false + self.enumCaseName = nil + self.associatedValue = nil + } + + /// Creates an enum case declaration. + /// - Parameter name: The name of the enum case. + public init(_ name: String) { + self.patterns = [] + self.body = [] + self.isEnumCase = true + self.enumCaseName = name + self.associatedValue = nil + } + + /// Sets the associated value for the enum case. + /// - Parameters: + /// - name: The name of the associated value. + /// - type: The type of the associated value. + /// - Returns: A copy of the case with the associated value set. + public func associatedValue(_ name: String, type: String) -> Self { + var copy = self + copy.associatedValue = (name: name, type: type) + return copy } public var switchCaseSyntax: SwitchCaseSyntax { @@ -77,5 +104,47 @@ public struct Case: CodeBlock { ) } - public var syntax: SyntaxProtocol { switchCaseSyntax } + public var syntax: SyntaxProtocol { + if isEnumCase { + // Handle enum case declaration + let caseKeyword = TokenSyntax.keyword(.case, trailingTrivia: .space) + let identifier = TokenSyntax.identifier(enumCaseName ?? "", trailingTrivia: .space) + + var parameterClause: EnumCaseParameterClauseSyntax? + if let associated = associatedValue { + let parameter = EnumCaseParameterSyntax( + firstName: nil, + secondName: .identifier(associated.name), + colon: .colonToken(leadingTrivia: .space, trailingTrivia: .space), + type: TypeSyntax(IdentifierTypeSyntax(name: .identifier(associated.type))) + ) + parameterClause = EnumCaseParameterClauseSyntax( + leftParen: .leftParenToken(), + parameters: EnumCaseParameterListSyntax([parameter]), + rightParen: .rightParenToken() + ) + } + + return EnumCaseDeclSyntax( + caseKeyword: caseKeyword, + elements: EnumCaseElementListSyntax([ + EnumCaseElementSyntax( + leadingTrivia: .space, + _: nil, + name: associatedValue != nil ? TokenSyntax.identifier(enumCaseName ?? "") : identifier, + _: nil, + parameterClause: parameterClause, + _: nil, + rawValue: nil, + _: nil, + trailingComma: nil, + trailingTrivia: .newline + ) + ]) + ) + } else { + // Handle switch case + return switchCaseSyntax + } + } } diff --git a/Sources/SyntaxKit/Catch.swift b/Sources/SyntaxKit/Catch.swift new file mode 100644 index 0000000..a4db19a --- /dev/null +++ b/Sources/SyntaxKit/Catch.swift @@ -0,0 +1,198 @@ +// +// Catch.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import Foundation +import SwiftSyntax + +/// A Swift `catch` clause for error handling. +public struct Catch: CodeBlock { + private let pattern: CodeBlock? + private let body: [CodeBlock] + + /// Creates a `catch` clause with a pattern. + /// - Parameters: + /// - pattern: The pattern to match for this catch clause. + /// - content: A ``CodeBlockBuilder`` that provides the body of the catch clause. + public init( + _ pattern: CodeBlock, + @CodeBlockBuilderResult _ content: () -> [CodeBlock] + ) { + self.pattern = pattern + self.body = content() + } + + /// Creates a `catch` clause without a pattern (catches all errors). + /// - Parameter content: A ``CodeBlockBuilder`` that provides the body of the catch clause. + public init(@CodeBlockBuilderResult _ content: () -> [CodeBlock]) { + self.pattern = nil + self.body = content() + } + + /// Creates a `catch` clause for a specific enum case. + /// - Parameters: + /// - enumCase: The enum case to catch. + /// - content: A ``CodeBlockBuilder`` that provides the body of the catch clause. + public static func `catch`( + _ enumCase: EnumCase, + @CodeBlockBuilderResult _ content: () -> [CodeBlock] + ) -> Catch { + Catch(enumCase, content) + } + + public var catchClauseSyntax: CatchClauseSyntax { + // Build catch items (patterns) + var catchItems: CatchItemListSyntax? + if let pattern = pattern { + var patternSyntax: PatternSyntax + + if let enumCase = pattern as? EnumCase { + if !enumCase.caseAssociatedValues.isEmpty { + let baseName = enumCase.caseName + let baseParts = baseName.split(separator: ".") + let (typeName, caseName) = + baseParts.count == 2 ? (String(baseParts[0]), String(baseParts[1])) : ("", baseName) + // Build the pattern: .caseName(let a, let b) + let memberAccess = MemberAccessExprSyntax( + base: typeName.isEmpty + ? nil : ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(typeName))), + dot: .periodToken(), + name: .identifier(caseName) + ) + let patternWithTuple = PatternSyntax( + ValueBindingPatternSyntax( + bindingSpecifier: .keyword(.case, trailingTrivia: .space), + pattern: PatternSyntax( + ExpressionPatternSyntax( + expression: ExprSyntax(memberAccess) + ) + ) + ) + ) + // Actually, Swift's catch pattern for associated values is: .caseName(let a, let b) + // So we want: ExpressionPatternSyntax(MemberAccessExprSyntax + tuplePattern) + let tuplePattern = TuplePatternSyntax( + leftParen: .leftParenToken(), + elements: TuplePatternElementListSyntax( + enumCase.caseAssociatedValues.enumerated().map { index, associated in + TuplePatternElementSyntax( + pattern: PatternSyntax( + ValueBindingPatternSyntax( + bindingSpecifier: .keyword(.let, trailingTrivia: .space), + pattern: PatternSyntax( + IdentifierPatternSyntax(identifier: .identifier(associated.name)) + ) + ) + ), + trailingComma: index < enumCase.caseAssociatedValues.count - 1 + ? .commaToken(trailingTrivia: .space) : nil + ) + } + ), + rightParen: .rightParenToken() + ) + let patternSyntaxExpr = ExprSyntax( + FunctionCallExprSyntax( + calledExpression: ExprSyntax(memberAccess), + leftParen: .leftParenToken(), + arguments: LabeledExprListSyntax( + enumCase.caseAssociatedValues.enumerated().map { index, associated in + LabeledExprSyntax( + label: nil, + colon: nil, + expression: ExprSyntax( + PatternExprSyntax( + pattern: PatternSyntax( + ValueBindingPatternSyntax( + bindingSpecifier: .keyword(.let, trailingTrivia: .space), + pattern: PatternSyntax( + IdentifierPatternSyntax(identifier: .identifier(associated.name)) + ) + ) + ) + ) + ), + trailingComma: index < enumCase.caseAssociatedValues.count - 1 + ? .commaToken(trailingTrivia: .space) : nil + ) + } + ), + rightParen: .rightParenToken() + ) + ) + patternSyntax = PatternSyntax(ExpressionPatternSyntax(expression: patternSyntaxExpr)) + } else { + let enumCaseExpr = enumCase.asExpressionSyntax + patternSyntax = PatternSyntax(ExpressionPatternSyntax(expression: enumCaseExpr)) + } + } else { + // Handle other patterns + patternSyntax = PatternSyntax( + ExpressionPatternSyntax( + expression: ExprSyntax( + fromProtocol: pattern.syntax.as(ExprSyntax.self) + ?? DeclReferenceExprSyntax(baseName: .identifier("")) + ) + ) + ) + } + + catchItems = CatchItemListSyntax([ + CatchItemSyntax(pattern: patternSyntax) + ]) + } + + // Build catch body + let catchBody = CodeBlockSyntax( + leftBrace: .leftBraceToken(leadingTrivia: .space, trailingTrivia: .newline), + statements: CodeBlockItemListSyntax( + body.compactMap { + var item: CodeBlockItemSyntax? + if let decl = $0.syntax.as(DeclSyntax.self) { + item = CodeBlockItemSyntax(item: .decl(decl)) + } else if let expr = $0.syntax.as(ExprSyntax.self) { + item = CodeBlockItemSyntax(item: .expr(expr)) + } else if let stmt = $0.syntax.as(StmtSyntax.self) { + item = CodeBlockItemSyntax(item: .stmt(stmt)) + } + return item?.with(\.trailingTrivia, .newline) + }), + rightBrace: .rightBraceToken(leadingTrivia: .newline, trailingTrivia: .space) + ) + + return CatchClauseSyntax( + catchKeyword: .keyword(.catch, trailingTrivia: .space), + catchItems: catchItems ?? CatchItemListSyntax([]), + body: catchBody + ) + } + + public var syntax: SyntaxProtocol { + catchClauseSyntax + } +} diff --git a/Sources/SyntaxKit/CatchBuilder.swift b/Sources/SyntaxKit/CatchBuilder.swift new file mode 100644 index 0000000..6991d2a --- /dev/null +++ b/Sources/SyntaxKit/CatchBuilder.swift @@ -0,0 +1,62 @@ +// +// CatchBuilder.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import SwiftSyntax + +/// A result builder for creating catch clauses in a do-catch statement. +@resultBuilder +public struct CatchBuilder { + public static func buildBlock(_ components: CatchClauseSyntax...) -> CatchClauseListSyntax { + CatchClauseListSyntax(components) + } + + public static func buildExpression(_ expression: CatchClauseSyntax) -> CatchClauseSyntax { + expression + } + + public static func buildExpression(_ expression: Catch) -> CatchClauseSyntax { + expression.catchClauseSyntax + } + + public static func buildOptional(_ component: CatchClauseSyntax?) -> CatchClauseSyntax? { + component + } + + public static func buildEither(first component: CatchClauseSyntax) -> CatchClauseSyntax { + component + } + + public static func buildEither(second component: CatchClauseSyntax) -> CatchClauseSyntax { + component + } + + public static func buildArray(_ components: [CatchClauseSyntax]) -> CatchClauseListSyntax { + CatchClauseListSyntax(components) + } +} diff --git a/Sources/SyntaxKit/CodeBlock+Generate.swift b/Sources/SyntaxKit/CodeBlock+Generate.swift index 9acbb9e..ecde6e4 100644 --- a/Sources/SyntaxKit/CodeBlock+Generate.swift +++ b/Sources/SyntaxKit/CodeBlock+Generate.swift @@ -37,6 +37,9 @@ extension CodeBlock { let statements: CodeBlockItemListSyntax if let list = self.syntax.as(CodeBlockItemListSyntax.self) { statements = list + } else if let codeBlock = self.syntax.as(CodeBlockSyntax.self) { + // Handle CodeBlockSyntax by extracting its statements + statements = codeBlock.statements } else { let item: CodeBlockItemSyntax.Item if let decl = self.syntax.as(DeclSyntax.self) { @@ -62,7 +65,8 @@ extension CodeBlock { item = .expr(ExprSyntax(switchExpr)) } else { fatalError( - "Unsupported syntax type at top level: \(type(of: self.syntax)) generating from \(self)") + "Unsupported syntax type at top level: \(type(of: self.syntax)) (\(self.syntax)) generating from \(self)" + ) } statements = CodeBlockItemListSyntax([ CodeBlockItemSyntax(item: item, trailingTrivia: .newline) diff --git a/Sources/SyntaxKit/Default.swift b/Sources/SyntaxKit/Default.swift index ff38a43..9ccb5b3 100644 --- a/Sources/SyntaxKit/Default.swift +++ b/Sources/SyntaxKit/Default.swift @@ -50,7 +50,8 @@ public struct Default: CodeBlock { item = CodeBlockItemSyntax(item: .stmt(stmt)) } return item?.with(\.trailingTrivia, .newline) - }) + } + ) let label = SwitchDefaultLabelSyntax( defaultKeyword: .keyword(.default), colon: .colonToken(trailingTrivia: .newline) diff --git a/Sources/SyntaxKit/DictionaryExpr.swift b/Sources/SyntaxKit/DictionaryExpr.swift new file mode 100644 index 0000000..5ff079c --- /dev/null +++ b/Sources/SyntaxKit/DictionaryExpr.swift @@ -0,0 +1,89 @@ +// +// DictionaryExpr.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import SwiftSyntax + +/// A dictionary expression that can contain both Literal types and CodeBlock types. +public struct DictionaryExpr: CodeBlock, LiteralValue { + private let elements: [(DictionaryValue, DictionaryValue)] + + /// Creates a dictionary expression with the given key-value pairs. + /// - Parameter elements: The dictionary key-value pairs. + public init(_ elements: [(DictionaryValue, DictionaryValue)]) { + self.elements = elements + } + + /// The Swift type name for this dictionary. + public var typeName: String { + if elements.isEmpty { + return "[Any: Any]" + } + return "[String: Any]" + } + + /// Renders this dictionary as a Swift literal string. + public var literalString: String { + let elementStrings = elements.map { _, _ in + let keyString: String + let valueString: String + + // For now, we'll use a simple representation + // In a real implementation, we'd need to convert DictionaryValue to string + keyString = "key" + valueString = "value" + + return "\(keyString): \(valueString)" + } + return "[\(elementStrings.joined(separator: ", "))]" + } + + public var syntax: SyntaxProtocol { + if elements.isEmpty { + // Empty dictionary should generate [:] + return DictionaryExprSyntax( + leftSquare: .leftSquareToken(), + content: .colon(.colonToken(leadingTrivia: .init(), trailingTrivia: .init())), + rightSquare: .rightSquareToken() + ) + } else { + let dictionaryElements = DictionaryElementListSyntax( + elements.enumerated().map { index, keyValue in + let (key, value) = keyValue + return DictionaryElementSyntax( + keyExpression: key.exprSyntax, + colon: .colonToken(), + valueExpression: value.exprSyntax, + trailingComma: index < elements.count - 1 ? .commaToken(trailingTrivia: .space) : nil + ) + } + ) + return DictionaryExprSyntax(content: .elements(dictionaryElements)) + } + } +} diff --git a/Sources/SyntaxKit/DictionaryLiteral.swift b/Sources/SyntaxKit/DictionaryLiteral.swift index 17200ef..c2d7de7 100644 --- a/Sources/SyntaxKit/DictionaryLiteral.swift +++ b/Sources/SyntaxKit/DictionaryLiteral.swift @@ -29,7 +29,7 @@ import Foundation -/// A dictionary value that can be used as a literal. +/// A dictionary literal value that can be used as a literal. public struct DictionaryLiteral: LiteralValue { let elements: [(Literal, Literal)] diff --git a/Sources/SyntaxKit/DictionaryValue.swift b/Sources/SyntaxKit/DictionaryValue.swift new file mode 100644 index 0000000..b8bb8e2 --- /dev/null +++ b/Sources/SyntaxKit/DictionaryValue.swift @@ -0,0 +1,72 @@ +// +// DictionaryValue.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import SwiftSyntax + +/// A protocol for types that can be used as dictionary keys or values. +/// This includes both Literal types and CodeBlock types that can be converted to expressions. +public protocol DictionaryValue { + /// The expression syntax representation of this dictionary value. + var exprSyntax: ExprSyntax { get } +} + +// MARK: - Literal Conformance + +extension Literal: DictionaryValue { + // Literal already has exprSyntax from ExprCodeBlock protocol +} + +// MARK: - CodeBlock Conformance + +extension CodeBlock where Self: DictionaryValue { + /// Converts this code block to an expression syntax. + /// If the code block is already an expression, returns it directly. + /// If it's a token, wraps it in a declaration reference expression. + /// Otherwise, throws a fatal error. + public var exprSyntax: ExprSyntax { + if let expr = self.syntax.as(ExprSyntax.self) { + return expr + } + + if let token = self.syntax.as(TokenSyntax.self) { + return ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(token.text))) + } + + fatalError("CodeBlock of type \(type(of: self.syntax)) cannot be represented as ExprSyntax") + } +} + +// MARK: - Specific CodeBlock Types + +extension Call: DictionaryValue {} +extension Init: DictionaryValue {} +extension VariableExp: DictionaryValue {} +extension PropertyAccessExp: DictionaryValue {} +extension FunctionCallExp: DictionaryValue {} +extension Infix: DictionaryValue {} diff --git a/Sources/SyntaxKit/Do.swift b/Sources/SyntaxKit/Do.swift new file mode 100644 index 0000000..d9279db --- /dev/null +++ b/Sources/SyntaxKit/Do.swift @@ -0,0 +1,78 @@ +// +// Do.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import Foundation +import SwiftSyntax + +/// A Swift `do` statement for error handling. +public struct Do: CodeBlock { + private let body: [CodeBlock] + private let catchClauses: CatchClauseListSyntax + + /// Creates a `do-catch` statement. + /// - Parameters: + /// - body: A ``CodeBlockBuilder`` that provides the body of the do block. + /// - catchClauses: A ``CatchBuilder`` that provides the catch clauses. + public init( + @CodeBlockBuilderResult _ body: () -> [CodeBlock], + @CatchBuilder catch catchClauses: () -> CatchClauseListSyntax + ) { + self.body = body() + self.catchClauses = catchClauses() + } + + public var syntax: SyntaxProtocol { + // Build the do body + let doBody = CodeBlockSyntax( + leftBrace: .leftBraceToken(leadingTrivia: .space, trailingTrivia: .newline), + statements: CodeBlockItemListSyntax( + body.compactMap { + var item: CodeBlockItemSyntax? + if let decl = $0.syntax.as(DeclSyntax.self) { + item = CodeBlockItemSyntax(item: .decl(decl)) + } else if let expr = $0.syntax.as(ExprSyntax.self) { + item = CodeBlockItemSyntax(item: .expr(expr)) + } else if let stmt = $0.syntax.as(StmtSyntax.self) { + item = CodeBlockItemSyntax(item: .stmt(stmt)) + } + return item?.with(\.trailingTrivia, .newline) + } + ), + rightBrace: .rightBraceToken(leadingTrivia: .newline, trailingTrivia: .space) + ) + + return StmtSyntax( + DoStmtSyntax( + doKeyword: .keyword(.do, trailingTrivia: .space), + body: doBody, + catchClauses: catchClauses + ) + ) + } +} diff --git a/Sources/SyntaxKit/EnumCase+Syntax.swift b/Sources/SyntaxKit/EnumCase+Syntax.swift new file mode 100644 index 0000000..d122bf8 --- /dev/null +++ b/Sources/SyntaxKit/EnumCase+Syntax.swift @@ -0,0 +1,133 @@ +// +// EnumCase+Syntax.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import SwiftSyntax + +extension EnumCase { + /// Returns the appropriate syntax based on context. + /// When used in expressions (throw, return, if bodies), returns expression syntax. + /// When used in declarations (enum cases), returns declaration syntax. + public var syntax: SyntaxProtocol { + // Check if we're in an expression context by looking at the call stack + // For now, we'll use a heuristic: if this is being used in a context that expects expressions, + // we'll return the expression syntax. Otherwise, we'll return the declaration syntax. + + // Since we can't easily determine context from here, we'll provide both options + // and let the calling code choose. For now, we'll default to declaration syntax + // and let specific contexts (like Throw) handle the conversion. + + let caseKeyword = TokenSyntax.keyword(.case, trailingTrivia: .space) + let identifier = TokenSyntax.identifier(name, trailingTrivia: .space) + + var parameterClause: EnumCaseParameterClauseSyntax? + if !associatedValues.isEmpty { + let parameters = EnumCaseParameterListSyntax( + associatedValues.map { associated in + EnumCaseParameterSyntax( + firstName: .identifier(associated.name), + secondName: .identifier(associated.name), + colon: .colonToken(leadingTrivia: .space, trailingTrivia: .space), + type: TypeSyntax(IdentifierTypeSyntax(name: .identifier(associated.type))) + ) + } + ) + parameterClause = EnumCaseParameterClauseSyntax( + leftParen: .leftParenToken(), + parameters: parameters, + rightParen: .rightParenToken() + ) + } + + var initializer: InitializerClauseSyntax? + if let literal = literalValue { + switch literal { + case .string(let value): + initializer = InitializerClauseSyntax( + equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), + value: StringLiteralExprSyntax( + openingQuote: .stringQuoteToken(), + segments: StringLiteralSegmentListSyntax([ + .stringSegment(StringSegmentSyntax(content: .stringSegment(value))) + ]), + closingQuote: .stringQuoteToken() + ) + ) + case .float(let value): + initializer = InitializerClauseSyntax( + equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), + value: FloatLiteralExprSyntax(literal: .floatLiteral(String(value))) + ) + case .integer(let value): + initializer = InitializerClauseSyntax( + equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), + value: IntegerLiteralExprSyntax(digits: .integerLiteral(String(value))) + ) + case .nil: + initializer = InitializerClauseSyntax( + equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), + value: NilLiteralExprSyntax(nilKeyword: .keyword(.nil)) + ) + case .boolean(let value): + initializer = InitializerClauseSyntax( + equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), + value: BooleanLiteralExprSyntax(literal: value ? .keyword(.true) : .keyword(.false)) + ) + case .ref(let value): + initializer = InitializerClauseSyntax( + equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), + value: DeclReferenceExprSyntax(baseName: .identifier(value)) + ) + case .tuple: + fatalError("Tuple is not supported as a raw value for enum cases.") + case .array: + fatalError("Array is not supported as a raw value for enum cases.") + case .dictionary: + fatalError("Dictionary is not supported as a raw value for enum cases.") + } + } + + return EnumCaseDeclSyntax( + caseKeyword: caseKeyword, + elements: EnumCaseElementListSyntax([ + EnumCaseElementSyntax( + leadingTrivia: .space, + _: nil, + name: identifier, + _: nil, + parameterClause: parameterClause, + _: nil, + rawValue: initializer, + _: nil, + trailingComma: nil, + trailingTrivia: .newline + ) + ]) + ) + } +} diff --git a/Sources/SyntaxKit/EnumCase.swift b/Sources/SyntaxKit/EnumCase.swift index 61c09ee..9a17724 100644 --- a/Sources/SyntaxKit/EnumCase.swift +++ b/Sources/SyntaxKit/EnumCase.swift @@ -31,8 +31,15 @@ import SwiftSyntax /// A Swift `case` declaration inside an `enum`. public struct EnumCase: CodeBlock { - private let name: String - private var literalValue: Literal? + internal let name: String + internal var literalValue: Literal? + internal var associatedValues: [(name: String, type: String)] = [] + + /// The name of the enum case. + public var caseName: String { name } + + /// The associated values for the enum case, if any. + public var caseAssociatedValues: [(name: String, type: String)] { associatedValues } /// Creates a `case` declaration. /// - Parameter name: The name of the case. @@ -41,6 +48,17 @@ public struct EnumCase: CodeBlock { self.literalValue = nil } + /// Sets the associated value for the case. + /// - Parameters: + /// - name: The name of the associated value. + /// - type: The type of the associated value. + /// - Returns: A copy of the case with the associated value set. + public func associatedValue(_ name: String, type: String) -> Self { + var copy = self + copy.associatedValues.append((name: name, type: type)) + return copy + } + /// Sets the raw value of the case to a Literal. /// - Parameter value: The literal value. /// - Returns: A copy of the case with the raw value set. @@ -71,74 +89,50 @@ public struct EnumCase: CodeBlock { self.equals(.float(value)) } - public var syntax: SyntaxProtocol { - let caseKeyword = TokenSyntax.keyword(.case, trailingTrivia: .space) - let identifier = TokenSyntax.identifier(name, trailingTrivia: .space) - - var initializer: InitializerClauseSyntax? - if let literal = literalValue { - switch literal { - case .string(let value): - initializer = InitializerClauseSyntax( - equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), - value: StringLiteralExprSyntax( - openingQuote: .stringQuoteToken(), - segments: StringLiteralSegmentListSyntax([ - .stringSegment(StringSegmentSyntax(content: .stringSegment(value))) - ]), - closingQuote: .stringQuoteToken() - ) - ) - case .float(let value): - initializer = InitializerClauseSyntax( - equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), - value: FloatLiteralExprSyntax(literal: .floatLiteral(String(value))) - ) - case .integer(let value): - initializer = InitializerClauseSyntax( - equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), - value: IntegerLiteralExprSyntax(digits: .integerLiteral(String(value))) - ) - case .nil: - initializer = InitializerClauseSyntax( - equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), - value: NilLiteralExprSyntax(nilKeyword: .keyword(.nil)) - ) - case .boolean(let value): - initializer = InitializerClauseSyntax( - equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), - value: BooleanLiteralExprSyntax(literal: value ? .keyword(.true) : .keyword(.false)) - ) - case .ref(let value): - initializer = InitializerClauseSyntax( - equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), - value: DeclReferenceExprSyntax(baseName: .identifier(value)) - ) - case .tuple: - fatalError("Tuple is not supported as a raw value for enum cases.") - case .array: - fatalError("Array is not supported as a raw value for enum cases.") - case .dictionary: - fatalError("Dictionary is not supported as a raw value for enum cases.") - } + /// Returns a SwiftSyntax expression for this enum case (for use in throw/return/etc). + public var asExpressionSyntax: ExprSyntax { + let parts = name.split(separator: ".", maxSplits: 1) + let base: ExprSyntax? = + parts.count == 2 + ? ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(String(parts[0])))) + : nil + let caseName = parts.count == 2 ? String(parts[1]) : name + let memberAccess = MemberAccessExprSyntax( + base: base, + dot: .periodToken(), + name: .identifier(caseName) + ) + if !associatedValues.isEmpty { + let tuple = TupleExprSyntax( + leftParen: .leftParenToken(), + elements: TupleExprElementListSyntax( + associatedValues.map { associated in + TupleExprElementSyntax( + label: nil, + colon: nil, + expression: ExprSyntax( + DeclReferenceExprSyntax(baseName: .identifier(associated.name))), + trailingComma: nil + ) + } + ), + rightParen: .rightParenToken() + ) + return ExprSyntax( + FunctionCallExprSyntax( + calledExpression: ExprSyntax(memberAccess), + leftParen: tuple.leftParen, + arguments: tuple.elements, + rightParen: tuple.rightParen + )) + } else { + return ExprSyntax(memberAccess) } + } - return EnumCaseDeclSyntax( - caseKeyword: caseKeyword, - elements: EnumCaseElementListSyntax([ - EnumCaseElementSyntax( - leadingTrivia: .space, - _: nil, - name: identifier, - _: nil, - parameterClause: nil, - _: nil, - rawValue: initializer, - _: nil, - trailingComma: nil, - trailingTrivia: .newline - ) - ]) - ) + /// Returns the expression syntax for this enum case. + /// This is the preferred method when using EnumCase in expression contexts. + public var exprSyntax: ExprSyntax { + asExpressionSyntax } } diff --git a/Sources/SyntaxKit/Function+EffectSpecifiers.swift b/Sources/SyntaxKit/Function+EffectSpecifiers.swift new file mode 100644 index 0000000..f985770 --- /dev/null +++ b/Sources/SyntaxKit/Function+EffectSpecifiers.swift @@ -0,0 +1,88 @@ +// +// Function+EffectSpecifiers.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import SwiftSyntax + +extension Function { + /// Builds the effect specifiers (async / throws) for the function. + internal func buildEffectSpecifiers() -> FunctionEffectSpecifiersSyntax? { + switch effect { + case .none: + return nil + case .throws(let isRethrows, let errorType): + let throwsSpecifier = buildThrowsSpecifier(isRethrows: isRethrows) + if let errorType = errorType { + return FunctionEffectSpecifiersSyntax( + asyncSpecifier: nil, + throwsClause: buildThrowsClause(throwsSpecifier: throwsSpecifier, errorType: errorType) + ) + } else { + return FunctionEffectSpecifiersSyntax( + asyncSpecifier: nil, + throwsSpecifier: throwsSpecifier + ) + } + case .async: + return FunctionEffectSpecifiersSyntax( + asyncSpecifier: .keyword(.async, leadingTrivia: .space, trailingTrivia: .space), + throwsSpecifier: nil + ) + case .asyncThrows(let isRethrows, let errorType): + let throwsSpecifier = buildThrowsSpecifier(isRethrows: isRethrows) + if let errorType = errorType { + return FunctionEffectSpecifiersSyntax( + asyncSpecifier: .keyword(.async, leadingTrivia: .space, trailingTrivia: .space), + throwsClause: buildThrowsClause(throwsSpecifier: throwsSpecifier, errorType: errorType) + ) + } else { + return FunctionEffectSpecifiersSyntax( + asyncSpecifier: .keyword(.async, leadingTrivia: .space, trailingTrivia: .space), + throwsSpecifier: throwsSpecifier + ) + } + } + } + + /// Builds the throws specifier token. + private func buildThrowsSpecifier(isRethrows: Bool) -> TokenSyntax { + .keyword(isRethrows ? .rethrows : .throws, leadingTrivia: .space) + } + + /// Builds the throws clause with error type. + private func buildThrowsClause(throwsSpecifier: TokenSyntax, errorType: String) + -> ThrowsClauseSyntax + { + ThrowsClauseSyntax( + throwsSpecifier: throwsSpecifier, + leftParen: .leftParenToken(), + type: IdentifierTypeSyntax(name: .identifier(errorType)), + rightParen: .rightParenToken() + ) + } +} diff --git a/Sources/SyntaxKit/Function+Effects.swift b/Sources/SyntaxKit/Function+Effects.swift new file mode 100644 index 0000000..ff6766c --- /dev/null +++ b/Sources/SyntaxKit/Function+Effects.swift @@ -0,0 +1,91 @@ +// +// Function+Effects.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import SwiftSyntax + +extension Function { + /// Function effect specifiers (async/throws combinations) + internal enum Effect { + case none + /// synchronous effect specifier: throws or rethrows + case `throws`(isRethrows: Bool, errorType: String?) + case async + /// combined async and throws/rethrows + case asyncThrows(isRethrows: Bool, errorType: String?) + } + + /// Marks the function as `throws` or `rethrows`. + /// - Parameter rethrows: Pass `true` to emit `rethrows` instead of `throws`. + public func `throws`(isRethrows: Bool = false) -> Self { + var copy = self + switch effect { + case .async: + copy.effect = .asyncThrows(isRethrows: isRethrows, errorType: nil) + default: + copy.effect = .throws(isRethrows: isRethrows, errorType: nil) + } + return copy + } + + /// Marks the function as `throws` with a specific error type. + /// - Parameter errorType: The error type to specify in the throws clause. + public func `throws`(_ errorType: String) -> Self { + var copy = self + switch effect { + case .async: + copy.effect = .asyncThrows(isRethrows: false, errorType: errorType) + default: + copy.effect = .throws(isRethrows: false, errorType: errorType) + } + return copy + } + + /// Marks the function as `async`. + public func async() -> Self { + var copy = self + copy.effect = .async + return copy + } + + /// Marks the function as `async throws` or `async rethrows`. + /// - Parameter rethrows: Pass `true` to emit `async rethrows`. + public func asyncThrows(isRethrows: Bool = false) -> Self { + var copy = self + copy.effect = .asyncThrows(isRethrows: isRethrows, errorType: nil) + return copy + } + + /// Marks the function as `async throws` with a specific error type. + /// - Parameter errorType: The error type to specify in the throws clause. + public func asyncThrows(_ errorType: String) -> Self { + var copy = self + copy.effect = .asyncThrows(isRethrows: false, errorType: errorType) + return copy + } +} diff --git a/Sources/SyntaxKit/Function+Modifiers.swift b/Sources/SyntaxKit/Function+Modifiers.swift new file mode 100644 index 0000000..cb1a734 --- /dev/null +++ b/Sources/SyntaxKit/Function+Modifiers.swift @@ -0,0 +1,59 @@ +// +// Function+Modifiers.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import SwiftSyntax + +extension Function { + /// Marks the function as `static`. + /// - Returns: A copy of the function marked as `static`. + public func `static`() -> Self { + var copy = self + copy.isStatic = true + return copy + } + + /// Marks the function as `mutating`. + /// - Returns: A copy of the function marked as `mutating`. + public func mutating() -> Self { + var copy = self + copy.isMutating = true + return copy + } + + /// Adds an attribute to the function declaration. + /// - Parameters: + /// - attribute: The attribute name (without the @ symbol). + /// - arguments: The arguments for the attribute, if any. + /// - Returns: A copy of the function with the attribute added. + public func attribute(_ attribute: String, arguments: [String] = []) -> Self { + var copy = self + copy.attributes.append(AttributeInfo(name: attribute, arguments: arguments)) + return copy + } +} diff --git a/Sources/SyntaxKit/Function+Syntax.swift b/Sources/SyntaxKit/Function+Syntax.swift new file mode 100644 index 0000000..5c03603 --- /dev/null +++ b/Sources/SyntaxKit/Function+Syntax.swift @@ -0,0 +1,195 @@ +// +// Function+Syntax.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import SwiftSyntax + +extension Function { + /// The syntax representation of this function. + public var syntax: SyntaxProtocol { + let funcKeyword = TokenSyntax.keyword(.func, trailingTrivia: .space) + let identifier = TokenSyntax.identifier(name) + + // Build parameter list + let paramList = FunctionParameterListSyntax( + parameters.enumerated().compactMap { index, param in + // Skip empty placeholders (possible in some builder scenarios) + guard !param.name.isEmpty || param.defaultValue != nil else { return nil } + + // Attributes for parameter + let paramAttributes = buildAttributeList(from: param.attributes) + + let firstNameLeading: Trivia = paramAttributes.isEmpty ? [] : .space + + // Determine first & second names + let firstNameToken: TokenSyntax + let secondNameToken: TokenSyntax? + + if param.isUnnamed { + firstNameToken = .wildcardToken(leadingTrivia: firstNameLeading, trailingTrivia: .space) + secondNameToken = .identifier(param.name) + } else if let label = param.label { + firstNameToken = .identifier( + label, leadingTrivia: firstNameLeading, trailingTrivia: .space) + secondNameToken = .identifier(param.name) + } else { + firstNameToken = .identifier( + param.name, leadingTrivia: firstNameLeading, trailingTrivia: .space) + secondNameToken = nil + } + + var paramSyntax = FunctionParameterSyntax( + attributes: paramAttributes, + firstName: firstNameToken, + secondName: secondNameToken, + colon: .colonToken(trailingTrivia: .space), + type: IdentifierTypeSyntax(name: .identifier(param.type)), + defaultValue: param.defaultValue.map { + InitializerClauseSyntax( + equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), + value: ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier($0))) + ) + } + ) + if index < parameters.count - 1 { + paramSyntax = paramSyntax.with(\.trailingComma, .commaToken(trailingTrivia: .space)) + } + return paramSyntax + }) + + // Build return type if specified + var returnClause: ReturnClauseSyntax? + if let returnType = returnType { + returnClause = ReturnClauseSyntax( + arrow: .arrowToken(leadingTrivia: .space, trailingTrivia: .space), + type: IdentifierTypeSyntax(name: .identifier(returnType)) + ) + } + + // Build function body + let bodyBlock = CodeBlockSyntax( + leftBrace: .leftBraceToken(leadingTrivia: .space, trailingTrivia: .newline), + statements: CodeBlockItemListSyntax( + body.compactMap { + var item: CodeBlockItemSyntax? + if let decl = $0.syntax.as(DeclSyntax.self) { + item = CodeBlockItemSyntax(item: .decl(decl)) + } else if let expr = $0.syntax.as(ExprSyntax.self) { + item = CodeBlockItemSyntax(item: .expr(expr)) + } else if let stmt = $0.syntax.as(StmtSyntax.self) { + item = CodeBlockItemSyntax(item: .stmt(stmt)) + } + return item?.with(\.trailingTrivia, .newline) + }), + rightBrace: .rightBraceToken(leadingTrivia: .newline) + ) + + // Build effect specifiers (async / throws) + let effectSpecifiers = buildEffectSpecifiers() + + // Build modifiers + var modifiers: DeclModifierListSyntax = [] + if isStatic { + modifiers = DeclModifierListSyntax([ + DeclModifierSyntax(name: .keyword(.static, trailingTrivia: .space)) + ]) + } + if isMutating { + modifiers = DeclModifierListSyntax( + modifiers + [ + DeclModifierSyntax(name: .keyword(.mutating, trailingTrivia: .space)) + ]) + } + + return FunctionDeclSyntax( + attributes: buildAttributeList(from: attributes), + modifiers: modifiers, + funcKeyword: funcKeyword, + name: identifier, + genericParameterClause: nil, + signature: FunctionSignatureSyntax( + parameterClause: FunctionParameterClauseSyntax( + leftParen: .leftParenToken(), + parameters: paramList, + rightParen: .rightParenToken() + ), + effectSpecifiers: effectSpecifiers, + returnClause: returnClause + ), + genericWhereClause: nil, + body: bodyBlock + ) + } + + private func buildAttributeList(from attributes: [AttributeInfo]) -> AttributeListSyntax { + if attributes.isEmpty { + return AttributeListSyntax([]) + } + + let attributeElements = attributes.map { attributeInfo in + let arguments = attributeInfo.arguments + + var leftParen: TokenSyntax? + var rightParen: TokenSyntax? + var argumentsSyntax: AttributeSyntax.Arguments? + + if !arguments.isEmpty { + leftParen = .leftParenToken() + rightParen = .rightParenToken() + + let argumentList = arguments.map { argument in + DeclReferenceExprSyntax(baseName: .identifier(argument)) + } + + argumentsSyntax = .argumentList( + LabeledExprListSyntax( + argumentList.enumerated().map { index, expr in + var element = LabeledExprSyntax(expression: ExprSyntax(expr)) + if index < argumentList.count - 1 { + element = element.with(\.trailingComma, .commaToken(trailingTrivia: .space)) + } + return element + } + ) + ) + } + + return AttributeListSyntax.Element( + AttributeSyntax( + atSign: .atSignToken(), + attributeName: IdentifierTypeSyntax(name: .identifier(attributeInfo.name)), + leftParen: leftParen, + arguments: argumentsSyntax, + rightParen: rightParen + ) + ) + } + + return AttributeListSyntax(attributeElements) + } +} diff --git a/Sources/SyntaxKit/Function.swift b/Sources/SyntaxKit/Function.swift index 8afa892..655970b 100644 --- a/Sources/SyntaxKit/Function.swift +++ b/Sources/SyntaxKit/Function.swift @@ -31,13 +31,14 @@ import SwiftSyntax /// A Swift `func` declaration. public struct Function: CodeBlock { - private let name: String - private let parameters: [Parameter] - private let returnType: String? - private let body: [CodeBlock] - private var isStatic: Bool = false - private var isMutating: Bool = false - private var attributes: [AttributeInfo] = [] + internal let name: String + internal let parameters: [Parameter] + internal let returnType: String? + internal let body: [CodeBlock] + internal var isStatic: Bool = false + internal var isMutating: Bool = false + internal var effect: Effect = .none + internal var attributes: [AttributeInfo] = [] /// Creates a `func` declaration. /// - Parameters: @@ -71,179 +72,19 @@ public struct Function: CodeBlock { self.body = content() } - /// Marks the function as `static`. - /// - Returns: A copy of the function marked as `static`. - public func `static`() -> Self { - var copy = self - copy.isStatic = true - return copy - } - - /// Marks the function as `mutating`. - /// - Returns: A copy of the function marked as `mutating`. - public func mutating() -> Self { - var copy = self - copy.isMutating = true - return copy - } - - /// Adds an attribute to the function declaration. + /// Creates a `func` declaration with parameters and body using the DSL syntax. /// - Parameters: - /// - attribute: The attribute name (without the @ symbol). - /// - arguments: The arguments for the attribute, if any. - /// - Returns: A copy of the function with the attribute added. - public func attribute(_ attribute: String, arguments: [String] = []) -> Self { - var copy = self - copy.attributes.append(AttributeInfo(name: attribute, arguments: arguments)) - return copy - } - - public var syntax: SyntaxProtocol { - let funcKeyword = TokenSyntax.keyword(.func, trailingTrivia: .space) - let identifier = TokenSyntax.identifier(name) - - // Build parameter list - let paramList: FunctionParameterListSyntax - if parameters.isEmpty { - paramList = FunctionParameterListSyntax([]) - } else { - paramList = FunctionParameterListSyntax( - parameters.enumerated().compactMap { index, param in - guard !param.name.isEmpty, !param.type.isEmpty else { return nil } - - // Build parameter attributes - let paramAttributes = buildAttributeList(from: param.attributes) - - // Determine spacing for firstName based on whether attributes are present - let firstNameLeadingTrivia: Trivia = paramAttributes.isEmpty ? [] : .space - - var paramSyntax = FunctionParameterSyntax( - attributes: paramAttributes, - firstName: param.isUnnamed - ? .wildcardToken(leadingTrivia: firstNameLeadingTrivia, trailingTrivia: .space) - : .identifier(param.name, leadingTrivia: firstNameLeadingTrivia), - secondName: param.isUnnamed ? .identifier(param.name) : nil, - colon: .colonToken(trailingTrivia: .space), - type: IdentifierTypeSyntax(name: .identifier(param.type)), - defaultValue: param.defaultValue.map { - InitializerClauseSyntax( - equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), - value: ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier($0))) - ) - } - ) - if index < parameters.count - 1 { - paramSyntax = paramSyntax.with(\.trailingComma, .commaToken(trailingTrivia: .space)) - } - return paramSyntax - }) - } - - // Build return type if specified - var returnClause: ReturnClauseSyntax? - if let returnType = returnType { - returnClause = ReturnClauseSyntax( - arrow: .arrowToken(leadingTrivia: .space, trailingTrivia: .space), - type: IdentifierTypeSyntax(name: .identifier(returnType)) - ) - } - - // Build function body - let bodyBlock = CodeBlockSyntax( - leftBrace: .leftBraceToken(leadingTrivia: .space, trailingTrivia: .newline), - statements: CodeBlockItemListSyntax( - body.compactMap { - var item: CodeBlockItemSyntax? - if let decl = $0.syntax.as(DeclSyntax.self) { - item = CodeBlockItemSyntax(item: .decl(decl)) - } else if let expr = $0.syntax.as(ExprSyntax.self) { - item = CodeBlockItemSyntax(item: .expr(expr)) - } else if let stmt = $0.syntax.as(StmtSyntax.self) { - item = CodeBlockItemSyntax(item: .stmt(stmt)) - } - return item?.with(\.trailingTrivia, .newline) - }), - rightBrace: .rightBraceToken(leadingTrivia: .newline) - ) - - // Build modifiers - var modifiers: DeclModifierListSyntax = [] - if isStatic { - modifiers = DeclModifierListSyntax([ - DeclModifierSyntax(name: .keyword(.static, trailingTrivia: .space)) - ]) - } - if isMutating { - modifiers = DeclModifierListSyntax( - modifiers + [ - DeclModifierSyntax(name: .keyword(.mutating, trailingTrivia: .space)) - ]) - } - - return FunctionDeclSyntax( - attributes: buildAttributeList(from: attributes), - modifiers: modifiers, - funcKeyword: funcKeyword, - name: identifier, - genericParameterClause: nil, - signature: FunctionSignatureSyntax( - parameterClause: FunctionParameterClauseSyntax( - leftParen: .leftParenToken(), - parameters: paramList, - rightParen: .rightParenToken() - ), - effectSpecifiers: nil, - returnClause: returnClause - ), - genericWhereClause: nil, - body: bodyBlock - ) - } - - private func buildAttributeList(from attributes: [AttributeInfo]) -> AttributeListSyntax { - if attributes.isEmpty { - return AttributeListSyntax([]) - } - - let attributeElements = attributes.map { attributeInfo in - let arguments = attributeInfo.arguments - - var leftParen: TokenSyntax? - var rightParen: TokenSyntax? - var argumentsSyntax: AttributeSyntax.Arguments? - - if !arguments.isEmpty { - leftParen = .leftParenToken() - rightParen = .rightParenToken() - - let argumentList = arguments.map { argument in - DeclReferenceExprSyntax(baseName: .identifier(argument)) - } - - argumentsSyntax = .argumentList( - LabeledExprListSyntax( - argumentList.enumerated().map { index, expr in - var element = LabeledExprSyntax(expression: ExprSyntax(expr)) - if index < argumentList.count - 1 { - element = element.with(\.trailingComma, .commaToken(trailingTrivia: .space)) - } - return element - } - ) - ) - } - - return AttributeListSyntax.Element( - AttributeSyntax( - atSign: .atSignToken(), - attributeName: IdentifierTypeSyntax(name: .identifier(attributeInfo.name)), - leftParen: leftParen, - arguments: argumentsSyntax, - rightParen: rightParen - ) - ) - } - - return AttributeListSyntax(attributeElements) + /// - name: The name of the function. + /// - params: A ``ParameterBuilder`` that provides the parameters of the function. + /// - body: A ``CodeBlockBuilder`` that provides the body of the function. + public init( + _ name: String, + @ParameterBuilderResult _ params: () -> [Parameter], + @CodeBlockBuilderResult _ body: () -> [CodeBlock] + ) { + self.name = name + self.parameters = params() + self.returnType = nil + self.body = body() } } diff --git a/Sources/SyntaxKit/Guard.swift b/Sources/SyntaxKit/Guard.swift index 40f194f..b5e9bf5 100644 --- a/Sources/SyntaxKit/Guard.swift +++ b/Sources/SyntaxKit/Guard.swift @@ -36,7 +36,8 @@ public struct Guard: CodeBlock { /// Creates a `guard` statement. /// - Parameters: - /// - condition: A builder that returns one or more ``CodeBlock`` items representing the guard conditions. + /// - condition: A builder that returns one or more ``CodeBlock`` items representing the guard + /// conditions. /// - elseBody: Builder that produces the statements inside the `else` block. public init( @CodeBlockBuilderResult _ condition: () -> [CodeBlock], @@ -87,7 +88,9 @@ public struct Guard: CodeBlock { condition: .expression( ExprSyntax( fromProtocol: block.syntax.as(ExprSyntax.self) - ?? DeclReferenceExprSyntax(baseName: .identifier("")))) + ?? DeclReferenceExprSyntax(baseName: .identifier("")) + ) + ) ) return appendComma(element) } @@ -107,13 +110,14 @@ public struct Guard: CodeBlock { } // Automatically append a bare `return` if the user didn't provide a terminating statement. - let containsReturn = elseItems.contains { item in + let containsTerminatingStatement = elseItems.contains { item in if case .stmt(let stmt) = item.item { - return stmt.is(ReturnStmtSyntax.self) + return stmt.is(ReturnStmtSyntax.self) || stmt.is(ThrowStmtSyntax.self) + || stmt.is(BreakStmtSyntax.self) || stmt.is(ContinueStmtSyntax.self) } return false } - if !containsReturn { + if !containsTerminatingStatement { let retStmt = ReturnStmtSyntax(returnKeyword: .keyword(.return)) elseItems.append( CodeBlockItemSyntax(item: .stmt(StmtSyntax(retStmt))).with(\.trailingTrivia, .newline) diff --git a/Sources/SyntaxKit/If.swift b/Sources/SyntaxKit/If.swift index 8d8c4e5..b916df7 100644 --- a/Sources/SyntaxKit/If.swift +++ b/Sources/SyntaxKit/If.swift @@ -107,7 +107,10 @@ public struct If: CodeBlock { statements: CodeBlockItemListSyntax( body.compactMap { var item: CodeBlockItemSyntax? - if let decl = $0.syntax.as(DeclSyntax.self) { + if let enumCase = $0 as? EnumCase { + // Handle EnumCase specially - use expression syntax for enum cases in expressions + item = CodeBlockItemSyntax(item: .expr(enumCase.exprSyntax)) + } else if let decl = $0.syntax.as(DeclSyntax.self) { item = CodeBlockItemSyntax(item: .decl(decl)) } else if let expr = $0.syntax.as(ExprSyntax.self) { item = CodeBlockItemSyntax(item: .expr(expr)) @@ -120,7 +123,9 @@ public struct If: CodeBlock { ) // swiftlint:disable:next closure_body_length let elseBlock: IfExprSyntax.ElseBody? = { - guard let elseBlocks = elseBody else { return nil } + guard let elseBlocks = elseBody else { + return nil + } // Build a chained else-if structure if the builder provided If blocks. var current: SyntaxProtocol? @@ -131,7 +136,11 @@ public struct If: CodeBlock { // Leaf `else` – produce a code-block. let stmts = CodeBlockItemListSyntax( thenBlock.body.compactMap { element in - if let decl = element.syntax.as(DeclSyntax.self) { + if let enumCase = element as? EnumCase { + // Handle EnumCase specially - use expression syntax for enum cases in expressions + return CodeBlockItemSyntax(item: .expr(enumCase.exprSyntax)).with( + \.trailingTrivia, .newline) + } else if let decl = element.syntax.as(DeclSyntax.self) { return CodeBlockItemSyntax(item: .decl(decl)).with(\.trailingTrivia, .newline) } else if let expr = element.syntax.as(ExprSyntax.self) { return CodeBlockItemSyntax(item: .expr(expr)).with(\.trailingTrivia, .newline) @@ -169,7 +178,10 @@ public struct If: CodeBlock { default: // Treat any other CodeBlock as part of a final code-block let item: CodeBlockItemSyntax? - if let decl = block.syntax.as(DeclSyntax.self) { + if let enumCase = block as? EnumCase { + // Handle EnumCase specially - use expression syntax for enum cases in expressions + item = CodeBlockItemSyntax(item: .expr(enumCase.exprSyntax)) + } else if let decl = block.syntax.as(DeclSyntax.self) { item = CodeBlockItemSyntax(item: .decl(decl)) } else if let expr = block.syntax.as(ExprSyntax.self) { item = CodeBlockItemSyntax(item: .expr(expr)) diff --git a/Sources/SyntaxKit/Infix.swift b/Sources/SyntaxKit/Infix.swift index ad18e0d..82ce259 100644 --- a/Sources/SyntaxKit/Infix.swift +++ b/Sources/SyntaxKit/Infix.swift @@ -68,3 +68,53 @@ public struct Infix: CodeBlock { ) } } + +// MARK: - Operator Overloads for Infix Expressions + +/// Creates a greater-than comparison expression. +/// - Parameters: +/// - lhs: The left-hand side expression. +/// - rhs: The right-hand side expression. +/// - Returns: An infix expression representing `lhs > rhs`. +public func > (lhs: CodeBlock, rhs: CodeBlock) -> Infix { + Infix(">") { + lhs + rhs + } +} + +/// Creates a less-than comparison expression. +/// - Parameters: +/// - lhs: The left-hand side expression. +/// - rhs: The right-hand side expression. +/// - Returns: An infix expression representing `lhs < rhs`. +public func < (lhs: CodeBlock, rhs: CodeBlock) -> Infix { + Infix("<") { + lhs + rhs + } +} + +/// Creates an equality comparison expression. +/// - Parameters: +/// - lhs: The left-hand side expression. +/// - rhs: The right-hand side expression. +/// - Returns: An infix expression representing `lhs == rhs`. +public func == (lhs: CodeBlock, rhs: CodeBlock) -> Infix { + Infix("==") { + lhs + rhs + } +} + +/// Creates an inequality comparison expression. +/// - Parameters: +/// - lhs: The left-hand side expression. +/// - rhs: The right-hand side expression. +/// - Returns: An infix expression representing `lhs != rhs`. +public func != (lhs: CodeBlock, rhs: CodeBlock) -> Infix { + Infix("!=") { + lhs + rhs + } +} diff --git a/Sources/SyntaxKit/Init.swift b/Sources/SyntaxKit/Init.swift index fb9000e..acf8122 100644 --- a/Sources/SyntaxKit/Init.swift +++ b/Sources/SyntaxKit/Init.swift @@ -30,10 +30,17 @@ import SwiftSyntax /// An initializer expression. -public struct Init: CodeBlock, ExprCodeBlock { +public struct Init: CodeBlock, ExprCodeBlock, LiteralValue { private let type: String private let parameters: [ParameterExp] + /// Creates an initializer expression with no parameters. + /// - Parameter type: The type to initialize. + public init(_ type: String) { + self.type = type + self.parameters = [] + } + /// Creates an initializer expression. /// - Parameters: /// - type: The type to initialize. @@ -66,4 +73,14 @@ public struct Init: CodeBlock, ExprCodeBlock { public var syntax: SyntaxProtocol { exprSyntax } + + // MARK: - LiteralValue Conformance + + public var typeName: String { + type + } + + public var literalString: String { + "\(type)()" + } } diff --git a/Sources/SyntaxKit/Line.swift b/Sources/SyntaxKit/Line.swift index 3017ae6..5127453 100644 --- a/Sources/SyntaxKit/Line.swift +++ b/Sources/SyntaxKit/Line.swift @@ -27,6 +27,27 @@ // OTHER DEALINGS IN THE SOFTWARE. // +/// obtaining a copy of this software and associated documentation +/// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import SwiftSyntax /// Represents a single comment line that can be attached to a syntax node. diff --git a/Sources/SyntaxKit/Literal+ExprCodeBlock.swift b/Sources/SyntaxKit/Literal+ExprCodeBlock.swift index 8e96d14..8b74e74 100644 --- a/Sources/SyntaxKit/Literal+ExprCodeBlock.swift +++ b/Sources/SyntaxKit/Literal+ExprCodeBlock.swift @@ -32,6 +32,7 @@ import SwiftSyntax // MARK: - ExprCodeBlock conformance extension Literal: ExprCodeBlock { + /// The expression syntax representation of this literal. public var exprSyntax: ExprSyntax { switch self { case .string(let value): diff --git a/Sources/SyntaxKit/Parameter.swift b/Sources/SyntaxKit/Parameter.swift index 3046692..a5fa4a7 100644 --- a/Sources/SyntaxKit/Parameter.swift +++ b/Sources/SyntaxKit/Parameter.swift @@ -33,10 +33,20 @@ import SwiftSyntax /// A parameter for a function or initializer. public struct Parameter: CodeBlock { + /// The internal parameter name that is visible inside the function body. internal let name: String + + /// The external argument label (first name) shown at call-sites. + /// If `nil`, the label is identical to the internal name (single-name parameter). + /// If the label is the underscore character "_", the parameter is treated as unnamed. + internal let label: String? + internal let type: String internal let defaultValue: String? - internal let isUnnamed: Bool + + /// Convenience flag – true when the parameter uses the underscore label. + internal var isUnnamed: Bool { label == "_" } + internal var attributes: [AttributeInfo] = [] /// Creates a parameter for a function or initializer. @@ -45,20 +55,15 @@ public struct Parameter: CodeBlock { /// - type: The type of the parameter. /// - defaultValue: The default value of the parameter, if any. /// - isUnnamed: A Boolean value that indicates whether the parameter is unnamed. - public init(name: String, type: String, defaultValue: String? = nil, isUnnamed: Bool = false) { - self.name = name - self.type = type - self.defaultValue = defaultValue - self.isUnnamed = isUnnamed - } + // NOTE: The previous initializer that accepted an `isUnnamed` flag has been replaced. /// Creates an unlabeled parameter for function calls or initializers. /// - Parameter value: The value of the parameter. public init(unlabeled value: String) { self.name = "" + self.label = "_" self.type = "" self.defaultValue = value - self.isUnnamed = true } /// Adds an attribute to the parameter declaration. @@ -73,20 +78,64 @@ public struct Parameter: CodeBlock { } public var syntax: SyntaxProtocol { - // Not used for function signature, but for call sites (Init, etc.) + let callLabel = label ?? name + if let defaultValue = defaultValue { return LabeledExprSyntax( - label: .identifier(name), + label: .identifier(callLabel), colon: .colonToken(), expression: ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(defaultValue))) ) } else { return LabeledExprSyntax( - label: .identifier(name), + label: .identifier(callLabel), colon: .colonToken(), expression: ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(name))) ) } - // Note: If you want to support attributes in parameter syntax, you would need to update the function signature generation in Function.swift to use these attributes. + // Note: If you want to support attributes in parameter syntax, you would need to + // update the function signature generation in Function.swift to use these attributes. + } + + /// Creates a single-name parameter (same label and internal name). + public init(name: String, type: String, defaultValue: String? = nil) { + self.name = name + self.label = nil + self.type = type + self.defaultValue = defaultValue + } + + /// Creates a two-name parameter where the external label differs from the internal name. + /// Example: `Parameter("value", labeled: "forKey", type: "String")` maps to + /// `forKey value: String` in the generated Swift. + public init( + _ internalName: String, + labeled externalLabel: String, + type: String, + defaultValue: String? = nil + ) { + self.name = internalName + self.label = externalLabel + self.type = type + self.defaultValue = defaultValue + } + + /// Creates an unlabeled (anonymous) parameter using the underscore label. + public init(unlabeled internalName: String, type: String, defaultValue: String? = nil) { + self.name = internalName + self.label = "_" + self.type = type + self.defaultValue = defaultValue + } + + /// Deprecated: retains source compatibility with earlier API that used an `isUnnamed` flag. + /// Prefer `Parameter(unlabeled:type:)` or the new labelled initialisers. + @available(*, deprecated, message: "Use Parameter(unlabeled:type:) or Parameter(_:labeled:type:)") + public init(name: String, type: String, defaultValue: String? = nil, isUnnamed: Bool) { + if isUnnamed { + self.init(unlabeled: name, type: type, defaultValue: defaultValue) + } else { + self.init(name: name, type: type, defaultValue: defaultValue) + } } } diff --git a/Sources/SyntaxKit/SwitchCase.swift b/Sources/SyntaxKit/SwitchCase.swift index ff7a3d6..0b579cc 100644 --- a/Sources/SyntaxKit/SwitchCase.swift +++ b/Sources/SyntaxKit/SwitchCase.swift @@ -36,7 +36,8 @@ public struct SwitchCase: CodeBlock { /// Creates a `case` for a `switch` statement. /// - Parameters: - /// - patterns: The patterns to match for the case. Can be `PatternConvertible`, `CodeBlock`, or `SwitchLet` for value binding. + /// - patterns: The patterns to match for the case. Can be `PatternConvertible`, + /// `CodeBlock`, or `SwitchLet` for value binding. /// - content: A ``CodeBlockBuilder`` that provides the body of the case. public init(_ patterns: Any..., @CodeBlockBuilderResult content: () -> [CodeBlock]) { self.patterns = patterns diff --git a/Sources/SyntaxKit/Throw.swift b/Sources/SyntaxKit/Throw.swift new file mode 100644 index 0000000..e85abbb --- /dev/null +++ b/Sources/SyntaxKit/Throw.swift @@ -0,0 +1,57 @@ +// +// Throw.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import Foundation +import SwiftSyntax + +/// A Swift `throw` statement. +public struct Throw: CodeBlock { + private let expr: CodeBlock + + public init(_ expr: CodeBlock) { + self.expr = expr + } + + public var syntax: SyntaxProtocol { + let expression: ExprSyntax + if let enumCase = expr as? EnumCase { + expression = enumCase.asExpressionSyntax + } else { + expression = + expr.syntax.as(ExprSyntax.self) + ?? ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(""))) + } + return StmtSyntax( + ThrowStmtSyntax( + throwKeyword: .keyword(.throw, trailingTrivia: .space), + expression: expression + ) + ) + } +} diff --git a/Sources/SyntaxKit/Tuple.swift b/Sources/SyntaxKit/Tuple.swift index 03bab7f..622673e 100644 --- a/Sources/SyntaxKit/Tuple.swift +++ b/Sources/SyntaxKit/Tuple.swift @@ -31,7 +31,9 @@ import SwiftSyntax /// A tuple expression, e.g. `(a, b, c)`. public struct Tuple: CodeBlock { - private let elements: [CodeBlock] + internal let elements: [CodeBlock] + private var isAsync: Bool = false + private var isThrowing: Bool = false /// Creates a tuple expression comprising the supplied elements. /// - Parameter content: A ``CodeBlockBuilder`` producing the tuple elements **in order**. @@ -53,6 +55,30 @@ public struct Tuple: CodeBlock { TuplePatternCodeBlock(elements: elements) } + /// Marks this tuple as async. + /// - Returns: A copy of the tuple marked as async. + public func async() -> Self { + var copy = self + copy.isAsync = true + return copy + } + + /// Marks this tuple as await. + /// - Returns: A copy of the tuple marked as await. + public func await() -> Self { + var copy = self + copy.isAsync = true + return copy + } + + /// Marks this tuple as throwing. + /// - Returns: A copy of the tuple marked as throwing. + public func throwing() -> Self { + var copy = self + copy.isThrowing = true + return copy + } + public var syntax: SyntaxProtocol { guard !elements.isEmpty else { fatalError("Tuple must contain at least one element.") @@ -60,7 +86,20 @@ public struct Tuple: CodeBlock { let list = TupleExprElementListSyntax( elements.enumerated().map { index, block in - let elementExpr = block.expr + let elementExpr: ExprSyntax + if isAsync { + // For async tuples, generate async let syntax for each element + // This assumes the block is a function call or expression that can be awaited + elementExpr = ExprSyntax( + AwaitExprSyntax( + awaitKeyword: .keyword(.await, trailingTrivia: .space), + expression: block.expr + ) + ) + } else { + elementExpr = block.expr + } + return TupleExprElementSyntax( label: nil, colon: nil, @@ -78,6 +117,15 @@ public struct Tuple: CodeBlock { ) ) - return tupleExpr + if isThrowing { + return ExprSyntax( + TryExprSyntax( + tryKeyword: .keyword(.try, trailingTrivia: .space), + expression: tupleExpr + ) + ) + } else { + return tupleExpr + } } } diff --git a/Sources/SyntaxKit/TupleAssignment+AsyncSet.swift b/Sources/SyntaxKit/TupleAssignment+AsyncSet.swift new file mode 100644 index 0000000..f28bd41 --- /dev/null +++ b/Sources/SyntaxKit/TupleAssignment+AsyncSet.swift @@ -0,0 +1,95 @@ +// +// TupleAssignment+AsyncSet.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import SwiftSyntax + +extension TupleAssignment { + internal enum AsyncSet { + static func tuplePattern(elements: [String]) -> PatternSyntax { + let patternElements = TuplePatternElementListSyntax( + elements.enumerated().map { index, element in + TuplePatternElementSyntax( + label: nil, + colon: nil, + pattern: PatternSyntax(IdentifierPatternSyntax(identifier: .identifier(element))), + trailingComma: index < elements.count - 1 ? .commaToken(trailingTrivia: .space) : nil + ) + } + ) + return PatternSyntax( + TuplePatternSyntax( + leftParen: .leftParenToken(), + elements: patternElements, + rightParen: .rightParenToken() + ) + ) + } + + static func tupleExpr(tuple: Tuple) -> ExprSyntax { + ExprSyntax( + TupleExprSyntax( + leftParen: .leftParenToken(), + elements: LabeledExprListSyntax( + tuple.elements.enumerated().map { index, block in + LabeledExprSyntax( + label: nil, + colon: nil, + expression: block.expr, + trailingComma: index < tuple.elements.count - 1 + ? .commaToken(trailingTrivia: .space) : nil + ) + } + ), + rightParen: .rightParenToken() + ) + ) + } + + static func valueExpr(tupleExpr: ExprSyntax, isThrowing: Bool) -> ExprSyntax { + isThrowing + ? ExprSyntax( + TryExprSyntax( + tryKeyword: .keyword(.try, trailingTrivia: .space), + expression: ExprSyntax( + AwaitExprSyntax( + awaitKeyword: .keyword(.await, trailingTrivia: .space), + expression: tupleExpr + ) + ) + ) + ) + : ExprSyntax( + AwaitExprSyntax( + awaitKeyword: .keyword(.await, trailingTrivia: .space), + expression: tupleExpr + ) + ) + } + } +} diff --git a/Sources/SyntaxKit/TupleAssignment.swift b/Sources/SyntaxKit/TupleAssignment.swift new file mode 100644 index 0000000..10da5e6 --- /dev/null +++ b/Sources/SyntaxKit/TupleAssignment.swift @@ -0,0 +1,207 @@ +// +// TupleAssignment.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import Foundation +import SwiftSyntax + +/// A tuple assignment statement for destructuring multiple values. +public struct TupleAssignment: CodeBlock { + private let elements: [String] + private let value: CodeBlock + private var isAsync: Bool = false + private var isThrowing: Bool = false + private var isAsyncSet: Bool = false + + /// Creates a tuple destructuring declaration. + /// - Parameters: + /// - elements: The names of the variables to destructure into. + /// - value: The expression to destructure. + public init(_ elements: [String], equals value: CodeBlock) { + self.elements = elements + self.value = value + } + + /// Marks this destructuring as async. + /// - Returns: A copy of the destructuring marked as async. + public func async() -> Self { + var copy = self + copy.isAsync = true + return copy + } + + /// Marks this destructuring as throwing. + /// - Returns: A copy of the destructuring marked as throwing. + public func throwing() -> Self { + var copy = self + copy.isThrowing = true + return copy + } + + /// Marks this destructuring as concurrent async (async let set). + /// - Returns: A copy of the destructuring marked as async set. + public func asyncSet() -> Self { + var copy = self + copy.isAsyncSet = true + return copy + } + + /// The syntax representation of this tuple assignment. + public var syntax: SyntaxProtocol { + if isAsyncSet { + return generateAsyncSetSyntax() + } + return generateRegularSyntax() + } + + /// Generates the asyncSet tuple assignment syntax. + private func generateAsyncSetSyntax() -> SyntaxProtocol { + // Generate a single async let tuple destructuring assignment + guard let tuple = value as? Tuple, elements.count == tuple.elements.count else { + fatalError( + "asyncSet requires a Tuple value with the same number of elements as the assignment.") + } + + // Use helpers from AsyncSet + let tuplePattern = AsyncSet.tuplePattern(elements: elements) + let tupleExpr = AsyncSet.tupleExpr(tuple: tuple) + let valueExpr = AsyncSet.valueExpr(tupleExpr: tupleExpr, isThrowing: isThrowing) + + // Build the async let declaration + let asyncLet = CodeBlockItemSyntax( + item: CodeBlockItemSyntax.Item.decl( + DeclSyntax( + VariableDeclSyntax( + modifiers: DeclModifierListSyntax([ + DeclModifierSyntax( + name: .keyword(.async, trailingTrivia: .space) + ) + ]), + bindingSpecifier: .keyword(.let, trailingTrivia: .space), + bindings: PatternBindingListSyntax([ + PatternBindingSyntax( + pattern: tuplePattern, + initializer: InitializerClauseSyntax( + equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), + value: valueExpr + ) + ) + ]) + ) + ) + ) + ) + + return CodeBlockSyntax( + leftBrace: .leftBraceToken(), + statements: CodeBlockItemListSyntax([asyncLet]), + rightBrace: .rightBraceToken() + ) + } + + /// Generates the regular tuple assignment syntax. + private func generateRegularSyntax() -> SyntaxProtocol { + // Build the tuple pattern + let patternElements = TuplePatternElementListSyntax( + elements.enumerated().map { index, element in + TuplePatternElementSyntax( + label: nil, + colon: nil, + pattern: PatternSyntax(IdentifierPatternSyntax(identifier: .identifier(element))), + trailingComma: index < elements.count - 1 ? .commaToken(trailingTrivia: .space) : nil + ) + } + ) + + let tuplePattern = PatternSyntax( + TuplePatternSyntax( + leftParen: .leftParenToken(), + elements: patternElements, + rightParen: .rightParenToken() + ) + ) + + // Build the value expression + let valueExpr = buildValueExpression() + + // Build the variable declaration + return VariableDeclSyntax( + bindingSpecifier: .keyword(.let, trailingTrivia: .space), + bindings: PatternBindingListSyntax([ + PatternBindingSyntax( + pattern: tuplePattern, + initializer: InitializerClauseSyntax( + equal: .equalToken(leadingTrivia: .space, trailingTrivia: .space), + value: valueExpr + ) + ) + ]) + ) + } + + /// Builds the value expression based on async and throwing flags. + private func buildValueExpression() -> ExprSyntax { + let baseExpr = + value.syntax.as(ExprSyntax.self) + ?? ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(""))) + + if isThrowing { + if isAsync { + return ExprSyntax( + TryExprSyntax( + tryKeyword: .keyword(.try, trailingTrivia: .space), + expression: ExprSyntax( + AwaitExprSyntax( + awaitKeyword: .keyword(.await, trailingTrivia: .space), + expression: baseExpr + ) + ) + ) + ) + } else { + return ExprSyntax( + TryExprSyntax( + tryKeyword: .keyword(.try, trailingTrivia: .space), + expression: baseExpr + ) + ) + } + } else { + if isAsync { + return ExprSyntax( + AwaitExprSyntax( + awaitKeyword: .keyword(.await, trailingTrivia: .space), + expression: baseExpr + ) + ) + } else { + return baseExpr + } + } + } +} diff --git a/Sources/SyntaxKit/TupleLiteral.swift b/Sources/SyntaxKit/TupleLiteral.swift index 58b8fc4..ecf3444 100644 --- a/Sources/SyntaxKit/TupleLiteral.swift +++ b/Sources/SyntaxKit/TupleLiteral.swift @@ -29,7 +29,7 @@ import Foundation -/// A tuple value that can be used as a literal. +/// A tuple literal value that can be used as a literal. public struct TupleLiteral: LiteralValue { let elements: [Literal?] diff --git a/Sources/SyntaxKit/Variable+Initializers.swift b/Sources/SyntaxKit/Variable+LiteralInitializers.swift similarity index 60% rename from Sources/SyntaxKit/Variable+Initializers.swift rename to Sources/SyntaxKit/Variable+LiteralInitializers.swift index 0799395..a23ed4e 100644 --- a/Sources/SyntaxKit/Variable+Initializers.swift +++ b/Sources/SyntaxKit/Variable+LiteralInitializers.swift @@ -1,5 +1,5 @@ // -// Variable+Initializers.swift +// Variable+LiteralInitializers.swift // SyntaxKit // // Created by Leo Dion. @@ -29,110 +29,9 @@ import Foundation -// MARK: - Variable Initializers +// MARK: - Variable Literal Initializers extension Variable { - /// Creates a `let` or `var` declaration with an explicit type. - /// - Parameters: - /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. - /// - name: The name of the variable. - /// - type: The type of the variable. - /// - equals: The initial value expression of the variable, if any. - /// - explicitType: Whether the variable has an explicit type. - public init( - _ kind: VariableKind, name: String, type: String, equals defaultValue: CodeBlock? = nil, - explicitType: Bool? = nil - ) { - let finalExplicitType = explicitType ?? (defaultValue == nil) - self.init( - kind: kind, - name: name, - type: type, - defaultValue: defaultValue, - explicitType: finalExplicitType - ) - } - - /// Creates a `let` or `var` declaration with an explicit type and string literal value. - /// - Parameters: - /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. - /// - name: The name of the variable. - /// - type: The type of the variable. - /// - equals: A string literal value. - /// - explicitType: Whether the variable has an explicit type. - public init( - _ kind: VariableKind, name: String, type: String, equals value: String, - explicitType: Bool? = nil - ) { - self.init( - kind: kind, - name: name, - type: type, - defaultValue: Literal.string(value), - explicitType: explicitType ?? true - ) - } - - /// Creates a `let` or `var` declaration with an explicit type and integer literal value. - /// - Parameters: - /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. - /// - name: The name of the variable. - /// - type: The type of the variable. - /// - equals: An integer literal value. - /// - explicitType: Whether the variable has an explicit type. - public init( - _ kind: VariableKind, name: String, type: String, equals value: Int, - explicitType: Bool? = nil - ) { - self.init( - kind: kind, - name: name, - type: type, - defaultValue: Literal.integer(value), - explicitType: explicitType ?? true - ) - } - - /// Creates a `let` or `var` declaration with an explicit type and boolean literal value. - /// - Parameters: - /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. - /// - name: The name of the variable. - /// - type: The type of the variable. - /// - equals: A boolean literal value. - /// - explicitType: Whether the variable has an explicit type. - public init( - _ kind: VariableKind, name: String, type: String, equals value: Bool, - explicitType: Bool? = nil - ) { - self.init( - kind: kind, - name: name, - type: type, - defaultValue: Literal.boolean(value), - explicitType: explicitType ?? true - ) - } - - /// Creates a `let` or `var` declaration with an explicit type and double literal value. - /// - Parameters: - /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. - /// - name: The name of the variable. - /// - type: The type of the variable. - /// - equals: A double literal value. - /// - explicitType: Whether the variable has an explicit type. - public init( - _ kind: VariableKind, name: String, type: String, equals value: Double, - explicitType: Bool? = nil - ) { - self.init( - kind: kind, - name: name, - type: type, - defaultValue: Literal.float(value), - explicitType: explicitType ?? true - ) - } - /// Creates a `let` or `var` declaration with a literal value. /// - Parameters: /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. @@ -154,8 +53,17 @@ extension Variable { defaultValue = Literal.array(array.map { .string($0) }) } else if let dict = value as? [Int: String] { defaultValue = Literal.dictionary(dict.map { (.integer($0.key), .string($0.value)) }) + } else if let dictExpr = value as? DictionaryExpr { + defaultValue = dictExpr + } else if let initExpr = value as? Init { + defaultValue = initExpr + } else if let codeBlock = value as? CodeBlock { + defaultValue = codeBlock } else { - fatalError("Variable: Only Literal types are supported for defaultValue. Got: \(T.self)") + // For any other LiteralValue type that doesn't conform to CodeBlock, + // create a fallback or throw an error + fatalError( + "Variable: Unsupported LiteralValue type that doesn't conform to CodeBlock: \(T.self)") } self.init( diff --git a/Sources/SyntaxKit/Variable+TypedInitializers.swift b/Sources/SyntaxKit/Variable+TypedInitializers.swift new file mode 100644 index 0000000..f5f805b --- /dev/null +++ b/Sources/SyntaxKit/Variable+TypedInitializers.swift @@ -0,0 +1,154 @@ +// +// Variable+TypedInitializers.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import Foundation + +// MARK: - Variable Typed Initializers + +extension Variable { + /// Creates a `let` or `var` declaration with an Init value, inferring the type from the Init. + /// - Parameters: + /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. + /// - name: The name of the variable. + /// - equals: An Init expression. + /// - explicitType: Whether the variable has an explicit type. + public init( + _ kind: VariableKind, name: String, equals defaultValue: Init, + explicitType: Bool? = nil + ) { + self.init( + kind: kind, + name: name, + type: nil, // Will be inferred from Init + defaultValue: defaultValue, + explicitType: explicitType ?? false + ) + } + + /// Creates a `let` or `var` declaration with an explicit type. + /// - Parameters: + /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. + /// - name: The name of the variable. + /// - type: The type of the variable. + /// - equals: The initial value expression of the variable, if any. + /// - explicitType: Whether the variable has an explicit type. + public init( + _ kind: VariableKind, name: String, type: String, equals defaultValue: CodeBlock? = nil, + explicitType: Bool? = nil + ) { + let finalExplicitType = explicitType ?? (defaultValue == nil) + self.init( + kind: kind, + name: name, + type: type, + defaultValue: defaultValue, + explicitType: finalExplicitType + ) + } + + /// Creates a `let` or `var` declaration with an explicit type and string literal value. + /// - Parameters: + /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. + /// - name: The name of the variable. + /// - type: The type of the variable. + /// - equals: A string literal value. + /// - explicitType: Whether the variable has an explicit type. + public init( + _ kind: VariableKind, name: String, type: String, equals value: String, + explicitType: Bool? = nil + ) { + self.init( + kind: kind, + name: name, + type: type, + defaultValue: Literal.string(value), + explicitType: explicitType ?? true + ) + } + + /// Creates a `let` or `var` declaration with an explicit type and integer literal value. + /// - Parameters: + /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. + /// - name: The name of the variable. + /// - type: The type of the variable. + /// - equals: An integer literal value. + /// - explicitType: Whether the variable has an explicit type. + public init( + _ kind: VariableKind, name: String, type: String, equals value: Int, + explicitType: Bool? = nil + ) { + self.init( + kind: kind, + name: name, + type: type, + defaultValue: Literal.integer(value), + explicitType: explicitType ?? true + ) + } + + /// Creates a `let` or `var` declaration with an explicit type and boolean literal value. + /// - Parameters: + /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. + /// - name: The name of the variable. + /// - type: The type of the variable. + /// - equals: A boolean literal value. + /// - explicitType: Whether the variable has an explicit type. + public init( + _ kind: VariableKind, name: String, type: String, equals value: Bool, + explicitType: Bool? = nil + ) { + self.init( + kind: kind, + name: name, + type: type, + defaultValue: Literal.boolean(value), + explicitType: explicitType ?? true + ) + } + + /// Creates a `let` or `var` declaration with an explicit type and double literal value. + /// - Parameters: + /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. + /// - name: The name of the variable. + /// - type: The type of the variable. + /// - equals: A double literal value. + /// - explicitType: Whether the variable has an explicit type. + public init( + _ kind: VariableKind, name: String, type: String, equals value: Double, + explicitType: Bool? = nil + ) { + self.init( + kind: kind, + name: name, + type: type, + defaultValue: Literal.float(value), + explicitType: explicitType ?? true + ) + } +} diff --git a/Sources/SyntaxKit/Variable.swift b/Sources/SyntaxKit/Variable.swift index 310b6c2..7b89b5f 100644 --- a/Sources/SyntaxKit/Variable.swift +++ b/Sources/SyntaxKit/Variable.swift @@ -32,31 +32,41 @@ import SwiftSyntax /// A Swift `let` or `var` declaration with an explicit type. public struct Variable: CodeBlock { - let kind: VariableKind - let name: String - let type: String - let defaultValue: CodeBlock? - var isStatic: Bool = false - var attributes: [AttributeInfo] = [] - var explicitType: Bool = false + private let kind: VariableKind + private let name: String + private let type: String + private let defaultValue: CodeBlock? + private var isStatic: Bool = false + private var isAsync: Bool = false + private var attributes: [AttributeInfo] = [] + private var explicitType: Bool = false /// Internal initializer used by extension initializers to reduce code duplication. /// - Parameters: /// - kind: The kind of variable, either ``VariableKind/let`` or ``VariableKind/var``. /// - name: The name of the variable. - /// - type: The type of the variable. + /// - type: The type of the variable. If nil, will be inferred from defaultValue if it's an Init. /// - defaultValue: The initial value expression of the variable, if any. /// - explicitType: Whether the variable has an explicit type. internal init( kind: VariableKind, name: String, - type: String, + type: String? = nil, defaultValue: CodeBlock? = nil, explicitType: Bool = false ) { self.kind = kind self.name = name - self.type = type + + // If type is provided, use it; otherwise try to infer from defaultValue + if let providedType = type { + self.type = providedType + } else if let initValue = defaultValue as? Init { + self.type = initValue.typeName + } else { + self.type = "" + } + self.defaultValue = defaultValue self.explicitType = explicitType } @@ -69,6 +79,14 @@ public struct Variable: CodeBlock { return copy } + /// Marks the variable as `async`. + /// - Returns: A copy of the variable marked as `async`. + public func async() -> Self { + var copy = self + copy.isAsync = true + return copy + } + /// Adds an attribute to the variable declaration. /// - Parameters: /// - attribute: The attribute name (without the @ symbol). @@ -115,6 +133,13 @@ public struct Variable: CodeBlock { DeclModifierSyntax(name: .keyword(.static, trailingTrivia: .space)) ]) } + if isAsync { + modifiers = DeclModifierListSyntax( + modifiers + [ + DeclModifierSyntax(name: .keyword(.async, trailingTrivia: .space)) + ] + ) + } return VariableDeclSyntax( attributes: buildAttributeList(from: attributes), modifiers: modifiers, @@ -175,4 +200,16 @@ public struct Variable: CodeBlock { return AttributeListSyntax(attributeElements) } + + public enum VariableKind { + case `var` + case `let` + case `static` + case `lazy` + case `weak` + case `unowned` + case `final` + case `override` + case `mutating` + } } diff --git a/Sources/SyntaxKit/VariableDecl.swift b/Sources/SyntaxKit/VariableDecl.swift index 27f1029..3460622 100644 --- a/Sources/SyntaxKit/VariableDecl.swift +++ b/Sources/SyntaxKit/VariableDecl.swift @@ -57,7 +57,8 @@ public struct VariableDecl: CodeBlock { openingQuote: .stringQuoteToken(), segments: StringLiteralSegmentListSyntax([ .stringSegment( - StringSegmentSyntax(content: .stringSegment(String(value.dropFirst().dropLast())))) + StringSegmentSyntax(content: .stringSegment(String(value.dropFirst().dropLast()))) + ) ]), closingQuote: .stringQuoteToken() ) @@ -69,7 +70,8 @@ public struct VariableDecl: CodeBlock { openingQuote: .stringQuoteToken(), segments: StringLiteralSegmentListSyntax([ .stringSegment( - StringSegmentSyntax(content: .stringSegment(value))) + StringSegmentSyntax(content: .stringSegment(value)) + ) ]), closingQuote: .stringQuoteToken() ) diff --git a/Sources/SyntaxKit/VariableExp.swift b/Sources/SyntaxKit/VariableExp.swift index f35234a..6870691 100644 --- a/Sources/SyntaxKit/VariableExp.swift +++ b/Sources/SyntaxKit/VariableExp.swift @@ -42,8 +42,8 @@ public struct VariableExp: CodeBlock, PatternConvertible { /// Accesses a property on the variable. /// - Parameter propertyName: The name of the property to access. /// - Returns: A ``PropertyAccessExp`` that represents the property access. - public func property(_ propertyName: String) -> CodeBlock { - PropertyAccessExp(baseName: name, propertyName: propertyName) + public func property(_ propertyName: String) -> PropertyAccessExp { + PropertyAccessExp(base: self, propertyName: propertyName) } /// Calls a method on the variable. @@ -75,30 +75,79 @@ public struct VariableExp: CodeBlock, PatternConvertible { /// An expression that accesses a property on a base expression. public struct PropertyAccessExp: CodeBlock { - internal let baseName: String + internal let base: CodeBlock internal let propertyName: String /// Creates a property access expression. /// - Parameters: - /// - baseName: The name of the base variable. + /// - base: The base expression. /// - propertyName: The name of the property to access. + public init(base: CodeBlock, propertyName: String) { + self.base = base + self.propertyName = propertyName + } + + /// Convenience initializer for backward compatibility (baseName as String). public init(baseName: String, propertyName: String) { - self.baseName = baseName + self.base = VariableExp(baseName) self.propertyName = propertyName } + /// Accesses a property on the current property access expression (chaining). + /// - Parameter propertyName: The name of the next property to access. + /// - Returns: A new ``PropertyAccessExp`` representing the chained property access. + public func property(_ propertyName: String) -> PropertyAccessExp { + PropertyAccessExp(base: self, propertyName: propertyName) + } + + /// Negates the property access expression. + /// - Returns: A negated property access expression. + public func not() -> CodeBlock { + NegatedPropertyAccessExp(base: self) + } + public var syntax: SyntaxProtocol { - let base = ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(baseName))) + let baseSyntax = + base.syntax.as(ExprSyntax.self) + ?? ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(""))) let property = TokenSyntax.identifier(propertyName) return ExprSyntax( MemberAccessExprSyntax( - base: base, + base: baseSyntax, dot: .periodToken(), name: property )) } } +/// An expression that negates a property access. +public struct NegatedPropertyAccessExp: CodeBlock { + internal let base: CodeBlock + + /// Creates a negated property access expression. + /// - Parameter base: The base property access expression. + public init(base: CodeBlock) { + self.base = base + } + + /// Backward compatibility initializer for (baseName, propertyName). + public init(baseName: String, propertyName: String) { + self.base = PropertyAccessExp(baseName: baseName, propertyName: propertyName) + } + + public var syntax: SyntaxProtocol { + let memberAccess = + base.syntax.as(ExprSyntax.self) + ?? ExprSyntax(DeclReferenceExprSyntax(baseName: .identifier(""))) + return ExprSyntax( + PrefixOperatorExprSyntax( + operator: .prefixOperator("!", leadingTrivia: [], trailingTrivia: []), + expression: memberAccess + ) + ) + } +} + /// An expression that calls a function. public struct FunctionCallExp: CodeBlock { internal let baseName: String diff --git a/Sources/SyntaxKit/parser/TokenVisitor+Helpers.swift b/Sources/SyntaxKit/parser/TokenVisitor+Helpers.swift new file mode 100644 index 0000000..4c20266 --- /dev/null +++ b/Sources/SyntaxKit/parser/TokenVisitor+Helpers.swift @@ -0,0 +1,84 @@ +// +// TokenVisitor+Helpers.swift +// SyntaxKit +// +// Created by Leo Dion. +// Copyright © 2025 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import Foundation +import SwiftSyntax + +extension TokenVisitor { + func processToken(_ token: TokenSyntax) { + var kind = "\(token.tokenKind)" + if let index = kind.firstIndex(of: "(") { + kind = String(kind.prefix(upTo: index)) + } + if kind.hasSuffix("Keyword") { + kind = "keyword" + } + + let sourceRange = token.sourceRange(converter: locationConverter) + let start = sourceRange.start + let end = sourceRange.end + let text = token.presence == .present || showMissingTokens ? token.text : "" + } + + func processTriviaPiece(_ piece: TriviaPiece) -> String { + func wrapWithSpanTag(class className: String, text: String) -> String { + "\(text.escapeHTML().replaceInvisiblesWithHTML())" + } + + var trivia = "" + switch piece { + case .spaces(let count): + trivia += String(repeating: " ", count: count) + case .tabs(let count): + trivia += String(repeating: " ", count: count * 2) + case .verticalTabs, .formfeeds: + break + case .newlines(let count), .carriageReturns(let count), .carriageReturnLineFeeds(let count): + trivia += String(repeating: "
", count: count) + case .lineComment(let text): + trivia += wrapWithSpanTag(class: "lineComment", text: text) + case .blockComment(let text): + trivia += wrapWithSpanTag(class: "blockComment", text: text) + case .docLineComment(let text): + trivia += wrapWithSpanTag(class: "docLineComment", text: text) + case .docBlockComment(let text): + trivia += wrapWithSpanTag(class: "docBlockComment", text: text) + case .unexpectedText(let text): + trivia += wrapWithSpanTag(class: "unexpectedText", text: text) + case .backslashes(let count): + trivia += String(repeating: #"\"#, count: count) + case .pounds(let count): + trivia += String(repeating: "#", count: count) + } + return trivia + } +} diff --git a/Sources/SyntaxKit/parser/TokenVisitor.swift b/Sources/SyntaxKit/parser/TokenVisitor.swift index 4eef1ff..09a8e3d 100644 --- a/Sources/SyntaxKit/parser/TokenVisitor.swift +++ b/Sources/SyntaxKit/parser/TokenVisitor.swift @@ -37,8 +37,8 @@ internal final class TokenVisitor: SyntaxRewriter { private var current: TreeNode! private var index = 0 - private let locationConverter: SourceLocationConverter - private let showMissingTokens: Bool + internal let locationConverter: SourceLocationConverter + internal let showMissingTokens: Bool internal init(locationConverter: SourceLocationConverter, showMissingTokens: Bool) { self.locationConverter = locationConverter @@ -206,55 +206,4 @@ internal final class TokenVisitor: SyntaxRewriter { current = nil } } - - private func processToken(_ token: TokenSyntax) { - var kind = "\(token.tokenKind)" - if let index = kind.firstIndex(of: "(") { - kind = String(kind.prefix(upTo: index)) - } - if kind.hasSuffix("Keyword") { - kind = "keyword" - } - - let sourceRange = token.sourceRange(converter: locationConverter) - let start = sourceRange.start - let end = sourceRange.end - let text = token.presence == .present || showMissingTokens ? token.text : "" - } - - private func processTriviaPiece(_ piece: TriviaPiece) -> String { - func wrapWithSpanTag(class className: String, text: String) -> String { - "\(text.escapeHTML().replaceInvisiblesWithHTML())" - } - - var trivia = "" - switch piece { - case .spaces(let count): - trivia += String(repeating: " ", count: count) - case .tabs(let count): - trivia += String(repeating: " ", count: count * 2) - case .verticalTabs, .formfeeds: - break - case .newlines(let count), .carriageReturns(let count), .carriageReturnLineFeeds(let count): - trivia += String(repeating: "
", count: count) - case .lineComment(let text): - trivia += wrapWithSpanTag(class: "lineComment", text: text) - case .blockComment(let text): - trivia += wrapWithSpanTag(class: "blockComment", text: text) - case .docLineComment(let text): - trivia += wrapWithSpanTag(class: "docLineComment", text: text) - case .docBlockComment(let text): - trivia += wrapWithSpanTag(class: "docBlockComment", text: text) - case .unexpectedText(let text): - trivia += wrapWithSpanTag(class: "unexpectedText", text: text) - case .backslashes(let count): - trivia += String(repeating: #"\"#, count: count) - case .pounds(let count): - trivia += String(repeating: "#", count: count) - } - return trivia - } } diff --git a/Tests/SyntaxKitTests/Integration/CommentTests.swift b/Tests/SyntaxKitTests/Integration/CommentTests.swift index 1cd2e8e..6397f11 100644 --- a/Tests/SyntaxKitTests/Integration/CommentTests.swift +++ b/Tests/SyntaxKitTests/Integration/CommentTests.swift @@ -21,7 +21,9 @@ internal struct CommentTests { Line(.doc, "Represents a playing card in a standard 52-card deck") Line(.doc) Line( - .doc, "A card has a rank (2-10, J, Q, K, A) and a suit (hearts, diamonds, clubs, spades)." + .doc, + "A card has a rank (2-10, J, Q, K, A) and a suit " + + "(hearts, diamonds, clubs, spades)." ) Line(.doc, "Each card can be compared to other cards based on its rank.") } @@ -102,7 +104,8 @@ internal struct CommentTests { #expect(!generated.isEmpty) // // #expect(generated.contains("MARK: - Models"), "MARK line should be present in generated code") - // #expect(generated.contains("Foo struct docs"), "Doc comment line should be present in generated code") + // #expect(generated.contains("Foo struct docs"), + // "Doc comment line should be present in generated code") // // Ensure the struct declaration itself is still correct // #expect(generated.contains("struct Foo")) // #expect(generated.contains("bar"), "Variable declaration should be present") diff --git a/Tests/SyntaxKitTests/Integration/ConcurrencyExampleTests.swift b/Tests/SyntaxKitTests/Integration/ConcurrencyExampleTests.swift new file mode 100644 index 0000000..9aac57b --- /dev/null +++ b/Tests/SyntaxKitTests/Integration/ConcurrencyExampleTests.swift @@ -0,0 +1,157 @@ +import Foundation +import Testing + +@testable import SyntaxKit + +@Suite internal struct ConcurrencyExampleTests { + @Test("Concurrency vending machine DSL generates expected Swift code") + internal func testConcurrencyVendingMachineExample() throws { + // Build DSL equivalent of Examples/Remaining/concurrency/dsl.swift + // Note: This test includes the Item struct that's referenced but not defined in the original DSL + + let program = Group { + // Item struct (needed for the vending machine) + Struct("Item") { + Variable(.let, name: "price", type: "Int").withExplicitType() + Variable(.var, name: "count", type: "Int").withExplicitType() + } + + // VendingMachineError enum + Enum("VendingMachineError") { + Case("invalidSelection") + Case("insufficientFunds").associatedValue("coinsNeeded", type: "Int") + Case("outOfStock") + } + .inherits("Error") + + // VendingMachine class + Class("VendingMachine") { + Variable( + .var, name: "inventory", + equals: DictionaryExpr([ + ( + Literal.string("Candy Bar"), + Init("Item") { + ParameterExp(name: "price", value: Literal.integer(12)) + ParameterExp(name: "count", value: Literal.integer(7)) + } + ), + ( + Literal.string("Chips"), + Init("Item") { + ParameterExp(name: "price", value: Literal.integer(10)) + ParameterExp(name: "count", value: Literal.integer(4)) + } + ), + ( + Literal.string("Pretzels"), + Init("Item") { + ParameterExp(name: "price", value: Literal.integer(7)) + ParameterExp(name: "count", value: Literal.integer(11)) + } + ), + ]) + ) + Variable(.var, name: "coinsDeposited", equals: 0) + + Function("vend") { + Parameter("name", labeled: "itemNamed", type: "String") + } _: { + Guard { + Let("item", "inventory[name]") + } else: { + Throw(VariableExp("VendingMachineError.invalidSelection")) + } + Guard { + Infix(">") { + VariableExp("item").property("count") + Literal.integer(0) + } + } else: { + Throw(VariableExp("VendingMachineError.outOfStock")) + } + Guard { + Infix("<=") { + VariableExp("item").property("price") + VariableExp("coinsDeposited") + } + } else: { + Throw( + Call("VendingMachineError.insufficientFunds") { + ParameterExp( + name: "coinsNeeded", + value: Infix("-") { + VariableExp("item").property("price") + VariableExp("coinsDeposited") + } + ) + } + ) + } + Infix("-=") { + VariableExp("coinsDeposited") + VariableExp("item").property("price") + } + Variable(.var, name: "newItem", equals: Literal.ref("item")) + Infix("-=") { + VariableExp("newItem").property("count") + Literal.integer(1) + } + Assignment("inventory[name]", .ref("newItem")) + Call("print") { + ParameterExp(unlabeled: "\"Dispensing \\(name)\"") + } + } + .throws() + } + } + + // Expected Swift code from Examples/Remaining/concurrency/code.swift + let expectedCode = """ + struct Item { + let price: Int + var count: Int + } + + enum VendingMachineError: Error { + case invalidSelection + case insufficientFunds(coinsNeeded: Int) + case outOfStock + } + + class VendingMachine { + var inventory = ["Candy Bar": Item(price: 12, count: 7), + "Chips": Item(price: 10, count: 4), + "Pretzels": Item(price: 7, count: 11)] + var coinsDeposited = 0 + + func vend(itemNamed name: String) throws { + guard let item = inventory[name] else { + throw VendingMachineError.invalidSelection + } + + guard item.count > 0 else { + throw VendingMachineError.outOfStock + } + + guard item.price <= coinsDeposited else { + throw VendingMachineError.insufficientFunds(coinsNeeded: item.price - coinsDeposited) + } + + coinsDeposited -= item.price + + var newItem = item + newItem.count -= 1 + inventory[name] = newItem + + print("Dispensing \\(name)") + } + } + """ + + // Generate code from DSL + let generated = program.generateCode().normalize() + let expected = expectedCode.normalize() + #expect(generated == expected) + } +} diff --git a/Tests/SyntaxKitTests/Integration/ConditionalsExampleTests.swift b/Tests/SyntaxKitTests/Integration/ConditionalsExampleTests.swift index 585c458..821c215 100644 --- a/Tests/SyntaxKitTests/Integration/ConditionalsExampleTests.swift +++ b/Tests/SyntaxKitTests/Integration/ConditionalsExampleTests.swift @@ -200,13 +200,15 @@ import Testing SwitchCase(Tuple.pattern([(-2...2), (-2...2)])) { Call("print") { ParameterExp( - name: "", value: "\"(\\(somePoint.0), \\(somePoint.1)) is inside the box\"") + name: "", value: "\"(\\(somePoint.0), \\(somePoint.1)) is inside the box\"" + ) } } Default { Call("print") { ParameterExp( - name: "", value: "\"(\\(somePoint.0), \\(somePoint.1)) is outside of the box\"") + name: "", value: "\"(\\(somePoint.0), \\(somePoint.1)) is outside of the box\"" + ) } } } @@ -220,17 +222,23 @@ import Testing Switch("anotherPoint") { SwitchCase(Tuple.pattern([Pattern.let("x"), 0])) { Call("print") { - ParameterExp(name: "", value: "\"on the x-axis with an x value of \\(x)\"") + ParameterExp( + name: "", value: "\"on the x-axis with an x value of \\(x)\"" + ) } } SwitchCase(Tuple.pattern([0, Pattern.let("y")])) { Call("print") { - ParameterExp(name: "", value: "\"on the y-axis with a y value of \\(y)\"") + ParameterExp( + name: "", value: "\"on the y-axis with a y value of \\(y)\"" + ) } } SwitchCase(Tuple.pattern([Pattern.let("x"), Pattern.let("y")])) { Call("print") { - ParameterExp(name: "", value: "\"somewhere else at (\\(x), \\(y))\"") + ParameterExp( + name: "", value: "\"somewhere else at (\\(x), \\(y))\"" + ) } } } @@ -269,7 +277,8 @@ import Testing value: Infix("+") { VariableExp("finalSquare") Literal.integer(1) - }) + } + ) } } diff --git a/Tests/SyntaxKitTests/Integration/ForLoopsExampleTests.swift b/Tests/SyntaxKitTests/Integration/ForLoopsExampleTests.swift index ef823bb..3c8aabb 100644 --- a/Tests/SyntaxKitTests/Integration/ForLoopsExampleTests.swift +++ b/Tests/SyntaxKitTests/Integration/ForLoopsExampleTests.swift @@ -11,9 +11,12 @@ import Testing let program = Group { // MARK: - Basic For-in Loop Variable( - .let, name: "names", + .let, + name: "names", equals: Literal.array([ - Literal.string("Alice"), Literal.string("Bob"), Literal.string("Charlie"), + Literal.string("Alice"), + Literal.string("Bob"), + Literal.string("Charlie"), ]) ) .comment { @@ -22,12 +25,14 @@ import Testing } For( - VariableExp("name"), in: VariableExp("names"), + VariableExp("name"), + in: VariableExp("names"), then: { Call("print") { ParameterExp(unlabeled: "\"Hello, \\(name)!\"") } - }) + } + ) // MARK: - For-in with Enumerated Call("print") { @@ -38,13 +43,17 @@ import Testing Line("For-in loop with enumerated() to get index and value") } For( - Tuple.patternCodeBlock([VariableExp("index"), VariableExp("name")]), + Tuple.patternCodeBlock([ + VariableExp("index"), + VariableExp("name"), + ]), in: VariableExp("names").call("enumerated"), then: { Call("print") { ParameterExp(unlabeled: "\"Index: \\(index), Name: \\(name)\"") } - }) + } + ) // MARK: - For-in with Where Clause Call("print") { @@ -55,15 +64,25 @@ import Testing Line("For-in loop with where clause") } Variable( - .let, name: "numbers", + .let, + name: "numbers", equals: Literal.array([ - Literal.integer(1), Literal.integer(2), Literal.integer(3), Literal.integer(4), - Literal.integer(5), Literal.integer(6), Literal.integer(7), Literal.integer(8), - Literal.integer(9), Literal.integer(10), - ])) + Literal.integer(1), + Literal.integer(2), + Literal.integer(3), + Literal.integer(4), + Literal.integer(5), + Literal.integer(6), + Literal.integer(7), + Literal.integer(8), + Literal.integer(9), + Literal.integer(10), + ]) + ) For( - VariableExp("number"), in: VariableExp("numbers"), + VariableExp("number"), + in: VariableExp("numbers"), where: { Infix("==") { Infix("%") { @@ -89,21 +108,27 @@ import Testing Line("For-in loop over dictionary") } Variable( - .let, name: "scores", + .let, + name: "scores", equals: Literal.dictionary([ (Literal.string("Alice"), Literal.integer(95)), (Literal.string("Bob"), Literal.integer(87)), (Literal.string("Charlie"), Literal.integer(92)), - ])) + ]) + ) For( - Tuple.patternCodeBlock([VariableExp("name"), VariableExp("score")]), + Tuple.patternCodeBlock([ + VariableExp("name"), + VariableExp("score"), + ]), in: VariableExp("scores"), then: { Call("print") { ParameterExp(unlabeled: "\"\\(name): \\(score)\"") } - }) + } + ) } // Generate Swift from DSL diff --git a/Tests/SyntaxKitTests/Unit/AttributeTests.swift b/Tests/SyntaxKitTests/Unit/AttributeTests.swift index 3c70141..e71f4ee 100644 --- a/Tests/SyntaxKitTests/Unit/AttributeTests.swift +++ b/Tests/SyntaxKitTests/Unit/AttributeTests.swift @@ -176,7 +176,7 @@ import Testing let generated = function.syntax.description #expect(generated.contains("@escaping")) - #expect(generated.contains("data: Data")) + #expect(generated.contains("data : Data")) #expect(generated.contains("func process")) } @@ -193,7 +193,7 @@ import Testing #expect(generated.contains("@available")) #expect(generated.contains("iOS")) #expect(generated.contains("17.0")) - #expect(generated.contains("input: String")) + #expect(generated.contains("input : String")) #expect(generated.contains("func validate")) } } diff --git a/Tests/SyntaxKitTests/Unit/CatchBasicTests.swift b/Tests/SyntaxKitTests/Unit/CatchBasicTests.swift new file mode 100644 index 0000000..dcaad97 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/CatchBasicTests.swift @@ -0,0 +1,157 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct CatchBasicTests { + // MARK: - Basic Catch Tests + + @Test("Basic catch without pattern generates correct syntax") + internal func testBasicCatchWithoutPattern() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("An error occurred")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try someFunction(param: "test") + } catch { print(\"An error occurred\") } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with enum case pattern generates correct syntax") + internal func testCatchWithEnumCasePattern() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("connectionFailed")) { + Call("print") { + ParameterExp(unlabeled: Literal.string("Connection failed")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try someFunction(param: "test") + } catch .connectionFailed { print(\"Connection failed\") } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with enum case and associated value generates correct syntax") + internal func testCatchWithEnumCaseAndAssociatedValue() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("invalidInput").associatedValue("fieldName", type: "String")) { + Call("print") { + ParameterExp( + unlabeled: Literal.string("Invalid input for field: \\(fieldName)") + ) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try someFunction(param: "test") + } catch .invalidInput(let fieldName) { print(\"Invalid input for field: \\(fieldName)\") } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + // MARK: - Catch with Different Pattern Types + + @Test("Catch with multiple enum cases generates correct syntax") + internal func testCatchWithMultipleEnumCases() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("timeout")) { + Call("print") { + ParameterExp(unlabeled: Literal.string("Request timed out")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try someFunction(param: "test") + } catch .timeout { print(\"Request timed out\") } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with error binding generates correct syntax") + internal func testCatchWithErrorBinding() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch { + Call("logError") { + ParameterExp(name: "error", value: VariableExp("error")) + } + Call("print") { + ParameterExp( + unlabeled: Literal.string("Error: \\(error)") + ) + } + } + } + + let generated = doCatch.generateCode() + let expected = + "do { try someFunction(param: \"test\") } catch { logError(error: error) print(\"Error: \\(error)\") }" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with specific error type generates correct syntax") + internal func testCatchWithSpecificErrorType() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("CustomError")) { + Call("handleCustomError") { + ParameterExp(name: "error", value: VariableExp("error")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try someFunction(param: "test") + } catch .CustomError { handleCustomError(error: error) } + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/CatchComplexTests.swift b/Tests/SyntaxKitTests/Unit/CatchComplexTests.swift new file mode 100644 index 0000000..5fbb362 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/CatchComplexTests.swift @@ -0,0 +1,110 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct CatchComplexTests { + // MARK: - Complex Catch Patterns + + @Test("Catch with multiple associated values generates correct syntax") + internal func testCatchWithMultipleAssociatedValues() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch( + EnumCase("requestFailed") + .associatedValue("statusCode", type: "Int") + .associatedValue("message", type: "String") + ) { + Call("logAPIError") { + ParameterExp(name: "statusCode", value: VariableExp("statusCode")) + ParameterExp(name: "message", value: VariableExp("message")) + } + } + } + + let generated = doCatch.generateCode() + let expected = + "do { try someFunction(param: \"test\") } catch .requestFailed(let statusCode, let message) { " + + "logAPIError(statusCode: statusCode, message: message) }" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with where clause generates correct syntax") + internal func testCatchWithWhereClause() throws { + // Note: This would require additional DSL support for where clauses + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("connectionFailed")) { + Call("retryConnection") { + ParameterExp(name: "maxAttempts", value: Literal.integer(3)) + } + } + } + + let generated = doCatch.generateCode() + let expected = + "do { try someFunction(param: \"test\") } catch .connectionFailed { retryConnection(maxAttempts: 3) }" + + #expect(generated.normalize() == expected.normalize()) + } + + // MARK: - Catch with Complex Body + + @Test("Catch with multiple statements generates correct syntax") + internal func testCatchWithMultipleStatements() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("invalidEmail")) { + Call("logValidationError") { + ParameterExp(name: "field", value: Literal.string("email")) + } + Variable(.let, name: "errorMessage", equals: Literal.string("Invalid email format")) + Call("showError") { + ParameterExp(name: "message", value: VariableExp("errorMessage")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { try someFunction(param: "test") } catch .invalidEmail { logValidationError(field: "email") let errorMessage = "Invalid email format" showError(message: errorMessage) } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with nested control flow generates correct syntax") + internal func testCatchWithNestedControlFlow() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("connectionFailed")) { + Variable(.let, name: "retryCount", equals: Literal.integer(0)) + Call("attemptConnection") { + ParameterExp(name: "attempt", value: VariableExp("retryCount")) + } + Call("incrementRetryCount") { + ParameterExp(name: "current", value: VariableExp("retryCount")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { try someFunction(param: "test") } catch .connectionFailed { let retryCount = 0 attemptConnection(attempt: retryCount) incrementRetryCount(current: retryCount) } + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/CatchEdgeCaseTests.swift b/Tests/SyntaxKitTests/Unit/CatchEdgeCaseTests.swift new file mode 100644 index 0000000..861f339 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/CatchEdgeCaseTests.swift @@ -0,0 +1,113 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct CatchEdgeCaseTests { + // MARK: - Edge Cases + + @Test("Catch with empty body generates correct syntax") + internal func testCatchWithEmptyBody() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("ignored")) { + // Empty body + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try someFunction(param: "test") + } catch .ignored { } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with single statement generates correct syntax") + internal func testCatchWithSingleStatement() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("connectionFailed")) { + Call("retry") { + ParameterExp(name: "maxAttempts", value: Literal.integer(1)) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try someFunction(param: "test") + } catch .connectionFailed { retry(maxAttempts: 1) } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with function call and variable assignment generates correct syntax") + internal func testCatchWithFunctionCallAndVariableAssignment() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("invalidInput")) { + Variable(.let, name: "errorMessage", equals: Literal.string("Invalid input")) + Call("logError") { + ParameterExp(name: "message", value: VariableExp("errorMessage")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try someFunction(param: "test") + } catch .invalidInput { + let errorMessage = "Invalid input" + logError(message: errorMessage) + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with conditional logic generates correct syntax") + internal func testCatchWithConditionalLogic() throws { + let doCatch = Do { + Call("someFunction") { + ParameterExp(name: "param", value: Literal.string("test")) + }.throwing() + } catch: { + Catch(EnumCase("connectionFailed")) { + Variable(.let, name: "retryCount", equals: Literal.integer(0)) + Call("checkRetryCount") { + ParameterExp(name: "count", value: VariableExp("retryCount")) + } + Call("showError") { + ParameterExp(name: "message", value: Literal.string("Max retries exceeded")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try someFunction(param: "test") + } catch .connectionFailed { + let retryCount = 0 + checkRetryCount(count: retryCount) + showError(message: "Max retries exceeded") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/CatchIntegrationTests.swift b/Tests/SyntaxKitTests/Unit/CatchIntegrationTests.swift new file mode 100644 index 0000000..0fd1c4e --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/CatchIntegrationTests.swift @@ -0,0 +1,124 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct CatchIntegrationTests { + // MARK: - Integration Tests + + @Test("Catch in do-catch statement generates correct syntax") + internal func testCatchInDoCatchStatement() throws { + let doCatch = Do { + Call("fetchData") { + ParameterExp(name: "id", value: Literal.integer(123)) + }.throwing() + } catch: { + Catch(EnumCase("connectionFailed")) { + Call("print") { + ParameterExp(unlabeled: Literal.string("Connection failed")) + } + } + Catch(EnumCase("invalidId")) { + Call("print") { + ParameterExp(unlabeled: Literal.string("Invalid ID")) + } + } + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Unexpected error: \\(error)")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try fetchData(id: 123) + } catch .connectionFailed { + print("Connection failed") + } catch .invalidId { + print("Invalid ID") + } catch { + print("Unexpected error: \\(error)") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with async operations generates correct syntax") + internal func testCatchWithAsyncOperations() throws { + let doCatch = Do { + Variable(.let, name: "data") { + Call("fetchData") { + ParameterExp(name: "id", value: Literal.integer(123)) + } + }.async() + } catch: { + Catch(EnumCase("timeout")) { + Variable(.let, name: "fallbackData") { + Call("fetchFallbackData") { + ParameterExp(name: "id", value: Literal.integer(123)) + } + }.async() + } + Catch { + Call("logError") { + ParameterExp(name: "error", value: VariableExp("error")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + async let data = fetchData(id: 123) + } catch .timeout { + async let fallbackData = fetchFallbackData(id: 123) + } catch { + logError(error: error) + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Catch with error recovery generates correct syntax") + internal func testCatchWithErrorRecovery() throws { + let doCatch = Do { + Call("processUserData") { + ParameterExp(name: "user", value: VariableExp("user")) + }.throwing() + } catch: { + Catch( + EnumCase("missingField") + .associatedValue("fieldName", type: "String") + ) { + Call("setDefaultValue") { + ParameterExp(name: "field", value: VariableExp("fieldName")) + } + Call("processUserData") { + ParameterExp(name: "user", value: VariableExp("user")) + }.throwing() + } + Catch { + Call("handleUnexpectedError") { + ParameterExp(name: "error", value: VariableExp("error")) + } + } + } + + let generated = doCatch.generateCode() + let expected = """ + do { + try processUserData(user: user) + } catch .missingField(let fieldName) { + setDefaultValue(field: fieldName) + try processUserData(user: user) + } catch { + handleUnexpectedError(error: error) + } + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/CodeStyleMigrationTests.swift b/Tests/SyntaxKitTests/Unit/CodeStyleMigrationTests.swift index ab867ee..9591a6e 100644 --- a/Tests/SyntaxKitTests/Unit/CodeStyleMigrationTests.swift +++ b/Tests/SyntaxKitTests/Unit/CodeStyleMigrationTests.swift @@ -41,7 +41,8 @@ internal struct CodeStyleMigrationTests { // Verify proper indentation is maintained #expect( generated - == "struct IndentationTest { let property1: String let property2: Int func method(param: String) { let local = \"value\" return local } }" + == "struct IndentationTest { let property1: String let property2: Int " + + "func method(param: String) { let local = \"value\" return local } }" ) } diff --git a/Tests/SyntaxKitTests/Unit/DoBasicTests.swift b/Tests/SyntaxKitTests/Unit/DoBasicTests.swift new file mode 100644 index 0000000..7ca7cf7 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/DoBasicTests.swift @@ -0,0 +1,91 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct DoBasicTests { + // MARK: - Basic Do Tests + + @Test("Basic do statement generates correct syntax") + internal func testBasicDoStatement() throws { + let doStatement = Do { + Call("print") { + ParameterExp(unlabeled: Literal.string("Hello, World!")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Error occurred")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + print("Hello, World!") + } catch { + print("Error occurred") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Do statement with multiple statements generates correct syntax") + internal func testDoStatementWithMultipleStatements() throws { + let doStatement = Do { + Variable(.let, name: "message", equals: Literal.string("Hello")) + Call("print") { + ParameterExp(unlabeled: VariableExp("message")) + } + Call("logMessage") { + ParameterExp(name: "text", value: VariableExp("message")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Error occurred")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + let message = "Hello" + print(message) + logMessage(text: message) + } catch { + print("Error occurred") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Do statement with throwing function generates correct syntax") + internal func testDoStatementWithThrowingFunction() throws { + let doStatement = Do { + Call("fetchData") { + ParameterExp(name: "id", value: Literal.integer(123)) + }.throwing() + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Failed to fetch data")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + try fetchData(id: 123) + } catch { + print("Failed to fetch data") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/DoComplexTests.swift b/Tests/SyntaxKitTests/Unit/DoComplexTests.swift new file mode 100644 index 0000000..955b7e4 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/DoComplexTests.swift @@ -0,0 +1,112 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct DoComplexTests { + // MARK: - Do with Complex Body + + @Test("Do statement with variable declarations generates correct syntax") + internal func testDoStatementWithVariableDeclarations() throws { + let doStatement = Do { + Variable(.let, name: "user", equals: Literal.string("John")) + Variable(.let, name: "age", equals: Literal.integer(30)) + Variable(.let, name: "isActive", equals: Literal.boolean(true)) + Call("processUser") { + ParameterExp(name: "name", value: VariableExp("user")) + ParameterExp(name: "age", value: VariableExp("age")) + ParameterExp(name: "active", value: VariableExp("isActive")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Error processing user")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + let user = "John" + let age = 30 + let isActive = true + processUser(name: user, age: age, active: isActive) + } catch { + print("Error processing user") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Do statement with async operations generates correct syntax") + internal func testDoStatementWithAsyncOperations() throws { + let doStatement = Do { + Variable(.let, name: "data") { + Call("fetchData") { + ParameterExp(name: "id", value: Literal.integer(123)) + } + }.async() + Variable(.let, name: "posts") { + Call("fetchPosts") { + ParameterExp(name: "userId", value: Literal.integer(123)) + } + }.async() + Call("processResults") { + ParameterExp(name: "data", value: VariableExp("data")) + ParameterExp(name: "posts", value: VariableExp("posts")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Error in async operations")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + async let data = fetchData(id: 123) + async let posts = fetchPosts(userId: 123) + processResults(data: data, posts: posts) + } catch { + print("Error in async operations") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Do statement with control flow generates correct syntax") + internal func testDoStatementWithControlFlow() throws { + let doStatement = Do { + Variable(.let, name: "count", equals: Literal.integer(5)) + Call("checkCount") { + ParameterExp(name: "value", value: VariableExp("count")) + } + Call("print") { + ParameterExp(unlabeled: Literal.string("Count processed")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Error in control flow")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + let count = 5 + checkCount(value: count) + print("Count processed") + } catch { + print("Error in control flow") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/DoEdgeCaseTests.swift b/Tests/SyntaxKitTests/Unit/DoEdgeCaseTests.swift new file mode 100644 index 0000000..7bc1147 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/DoEdgeCaseTests.swift @@ -0,0 +1,156 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct DoEdgeCaseTests { + // MARK: - Edge Cases + + @Test("Do statement with empty body generates correct syntax") + internal func testDoStatementWithEmptyBody() throws { + let doStatement = Do { + // Empty body + } catch: { + Catch { + // Empty catch + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + } catch { + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Do statement with single expression generates correct syntax") + internal func testDoStatementWithSingleExpression() throws { + let doStatement = Do { + VariableExp("someVariable") + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Error")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + someVariable + } catch { + print("Error") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Do statement with function call and variable assignment generates correct syntax") + internal func testDoStatementWithFunctionCallAndVariableAssignment() throws { + let doStatement = Do { + Variable(.let, name: "result", equals: Literal.integer(42)) + Call("processResult") { + ParameterExp(name: "value", value: VariableExp("result")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Error processing result")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + let result = 42 + processResult(value: result) + } catch { + print("Error processing result") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Do statement with nested do statement generates correct syntax") + internal func testDoStatementWithNestedDoStatement() throws { + let doStatement = Do { + Call("outerFunction") { + ParameterExp(name: "param", value: Literal.string("outer")) + } + Do { + Call("innerFunction") { + ParameterExp(name: "param", value: Literal.string("inner")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Inner error")) + } + } + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Outer error")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + outerFunction(param: "outer") + do { + innerFunction(param: "inner") + } catch { + print("Inner error") + } + } catch { + print("Outer error") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Do statement with tuple assignment generates correct syntax") + internal func testDoStatementWithTupleAssignment() throws { + let doStatement = Do { + TupleAssignment( + ["x", "y"], + equals: Tuple { + Literal.integer(10) + Literal.integer(20) + } + ) + Call("processCoordinates") { + ParameterExp(name: "x", value: VariableExp("x")) + ParameterExp(name: "y", value: VariableExp("y")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Error processing coordinates")) + } + } + } + + let generated = doStatement.generateCode() + let expected = """ + do { + let (x, y) = (10, 20) + processCoordinates(x: x, y: y) + } catch { + print("Error processing coordinates") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/DoIntegrationTests.swift b/Tests/SyntaxKitTests/Unit/DoIntegrationTests.swift new file mode 100644 index 0000000..d5cb69d --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/DoIntegrationTests.swift @@ -0,0 +1,88 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct DoIntegrationTests { + // MARK: - Integration Tests + + @Test("Do statement in function generates correct syntax") + internal func testDoStatementInFunction() throws { + let function = Function("processData") { + Parameter(name: "input", type: "[Int]") + } _: { + Do { + Call("validateInput") { + ParameterExp(name: "data", value: VariableExp("input")) + }.throwing() + Call("processValidData") { + ParameterExp(name: "data", value: VariableExp("input")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Validation failed")) + } + } + } + } + + let generated = function.generateCode() + let expected = """ + func processData(input: [Int]) { + do { + try validateInput(data: input) + processValidData(data: input) + } catch { + print("Validation failed") + } + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Do statement with async function generates correct syntax") + internal func testDoStatementWithAsyncFunction() throws { + let function = Function("fetchUserData") { + Parameter(name: "userId", type: "Int") + } _: { + Do { + Variable(.let, name: "user") { + Call("fetchUser") { + ParameterExp(name: "id", value: VariableExp("userId")) + } + }.async() + Variable(.let, name: "profile") { + Call("fetchProfile") { + ParameterExp(name: "userId", value: VariableExp("userId")) + } + }.async() + Call("combineUserData") { + ParameterExp(name: "user", value: VariableExp("user")) + ParameterExp(name: "profile", value: VariableExp("profile")) + } + } catch: { + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Failed to fetch user data")) + } + } + } + }.async() + + let generated = function.generateCode() + let expected = """ + func fetchUserData(userId: Int) async { + do { + async let user = fetchUser(id: userId) + async let profile = fetchProfile(userId: userId) + combineUserData(user: user, profile: profile) + } catch { + print("Failed to fetch user data") + } + } + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/EdgeCaseTests.swift b/Tests/SyntaxKitTests/Unit/EdgeCaseTests.swift index 55c7c96..c4a5720 100644 --- a/Tests/SyntaxKitTests/Unit/EdgeCaseTests.swift +++ b/Tests/SyntaxKitTests/Unit/EdgeCaseTests.swift @@ -32,257 +32,4 @@ internal struct EdgeCaseTests { // This test documents the expected behavior #expect(true) // Placeholder - fatal errors can't be easily tested } - - // MARK: - Switch and Case Tests - - @Test("Switch with multiple patterns generates correct syntax") - internal func testSwitchWithMultiplePatterns() throws { - let switchStmt = Switch("value") { - SwitchCase("1") { - Return { VariableExp("one") } - } - SwitchCase("2") { - Return { VariableExp("two") } - } - } - - let generated = switchStmt.generateCode() - #expect(generated.contains("switch value")) - #expect(generated.contains("case 1:")) - #expect(generated.contains("case 2:")) - } - - @Test("SwitchCase with multiple patterns generates correct syntax") - internal func testSwitchCaseWithMultiplePatterns() throws { - let switchCase = SwitchCase("1", "2", "3") { - Return { VariableExp("number") } - } - - let generated = switchCase.generateCode() - #expect(generated.contains("case 1, 2, 3:")) - } - - // MARK: - Complex Expression Tests - - @Test("Infix with complex expressions generates correct syntax") - internal func testInfixWithComplexExpressions() throws { - let infix = Infix("*") { - Parenthesized { - Infix("+") { - VariableExp("a") - VariableExp("b") - } - } - Parenthesized { - Infix("-") { - VariableExp("c") - VariableExp("d") - } - } - } - - let generated = infix.generateCode() - #expect(generated.contains("(a + b) * (c - d)")) - } - - @Test("Return with VariableExp generates correct syntax") - internal func testReturnWithVariableExp() throws { - let returnStmt = Return { - VariableExp("result") - } - - let generated = returnStmt.generateCode() - #expect(generated.contains("return result")) - } - - @Test("Return with complex expression generates correct syntax") - internal func testReturnWithComplexExpression() throws { - let returnStmt = Return { - Infix("+") { - VariableExp("a") - VariableExp("b") - } - } - - let generated = returnStmt.generateCode() - #expect(generated.contains("return a + b")) - } - - // MARK: - CodeBlock Expression Tests - - @Test("CodeBlock expr with TokenSyntax wraps in DeclReferenceExpr") - internal func testCodeBlockExprWithTokenSyntax() throws { - let variableExp = VariableExp("x") - let expr = variableExp.expr - - let generated = expr.description - #expect(generated.contains("x")) - } - - // MARK: - Code Generation Edge Cases - - @Test("CodeBlock generateCode with CodeBlockItemListSyntax") - internal func testCodeBlockGenerateCodeWithItemList() throws { - let group = Group { - Variable(.let, name: "x", type: "Int", equals: 1).withExplicitType() - Variable(.let, name: "y", type: "Int", equals: 2).withExplicitType() - } - - let generated = group.generateCode() - #expect(generated.contains("let x : Int = 1")) - #expect(generated.contains("let y : Int = 2")) - } - - @Test("CodeBlock generateCode with single declaration") - internal func testCodeBlockGenerateCodeWithSingleDeclaration() throws { - let variable = Variable(.let, name: "x", type: "Int", equals: 1).withExplicitType() - - let generated = variable.generateCode() - #expect(generated.contains("let x : Int = 1")) - } - - @Test("CodeBlock generateCode with single statement") - internal func testCodeBlockGenerateCodeWithSingleStatement() throws { - let assignment = Assignment("x", Literal.integer(42)) - - let generated = assignment.generateCode() - #expect(generated.contains("x = 42")) - } - - @Test("CodeBlock generateCode with single expression") - internal func testCodeBlockGenerateCodeWithSingleExpression() throws { - let variableExp = VariableExp("x") - - let generated = variableExp.generateCode() - #expect(generated.contains("x")) - } - - // MARK: - Complex Type Tests - - @Test("TypeAlias with complex nested types") - internal func testTypeAliasWithComplexNestedTypes() throws { - let typeAlias = TypeAlias("ComplexType", equals: "Array>>") - - let generated = typeAlias.generateCode() - #expect( - generated.normalize().contains( - "typealias ComplexType = Array>>".normalize())) - } - - @Test("TypeAlias with multiple generic parameters") - internal func testTypeAliasWithMultipleGenericParameters() throws { - let typeAlias = TypeAlias("Result", equals: "Result") - - let generated = typeAlias.generateCode().normalize() - #expect(generated.contains("typealias Result = Result".normalize())) - } - - // MARK: - Function Parameter Tests - - @Test("Function with unnamed parameter generates correct syntax") - internal func testFunctionWithUnnamedParameter() throws { - let function = Function("process") { - Parameter(name: "data", type: "Data", isUnnamed: true) - } _: { - Variable(.let, name: "result", type: "String", equals: "processed") - } - - let generated = function.generateCode() - #expect(generated.contains("func process(_ data: Data)")) - } - - @Test("Function with parameter default value generates correct syntax") - internal func testFunctionWithParameterDefaultValue() throws { - let function = Function("greet") { - Parameter(name: "name", type: "String", defaultValue: "\"World\"") - } _: { - Variable(.let, name: "message", type: "String", equals: "greeting") - } - - let generated = function.generateCode() - #expect(generated.contains("func greet(name: String = \"World\")")) - } - - // MARK: - Enum Case Tests - - @Test("EnumCase with string raw value generates correct syntax") - internal func testEnumCaseWithStringRawValue() throws { - let enumDecl = Enum("Status") { - EnumCase("active").equals(Literal.string("active")) - EnumCase("inactive").equals(Literal.string("inactive")) - } - - let generated = enumDecl.generateCode().normalize() - #expect(generated.contains("case active = \"active\"")) - #expect(generated.contains("case inactive = \"inactive\"")) - } - - @Test("EnumCase with double raw value generates correct syntax") - internal func testEnumCaseWithDoubleRawValue() throws { - let enumDecl = Enum("Precision") { - EnumCase("low").equals(Literal.float(0.1)) - EnumCase("high").equals(Literal.float(0.001)) - } - - let generated = enumDecl.generateCode().normalize() - #expect(generated.contains("case low = 0.1")) - #expect(generated.contains("case high = 0.001")) - } - - // MARK: - Computed Property Tests - - @Test("ComputedProperty with complex return expression") - internal func testComputedPropertyWithComplexReturn() throws { - let computedProperty = ComputedProperty("description", type: "String") { - Return { - VariableExp("name").call("appending") { - ParameterExp(name: "", value: "\" - \" + String(count)") - } - } - } - - let generated = computedProperty.generateCode().normalize() - #expect(generated.contains("var description: String")) - #expect(generated.contains("return name.appending(\" - \" + String(count))")) - } - - // MARK: - Comment Integration Tests - - @Test("ComputedProperty with comments generates correct syntax") - internal func testComputedPropertyWithComments() throws { - let computedProperty = ComputedProperty("formattedName", type: "String") { - Return { - VariableExp("name").property("uppercased") - } - }.comment { - Line(.doc, "Returns the name in uppercase format") - } - - let generated = computedProperty.generateCode() - #expect(generated.contains("/// Returns the name in uppercase format")) - #expect(generated.contains("var formattedName : String")) - } - - // MARK: - Literal Tests - - @Test("Literal with nil generates correct syntax") - internal func testLiteralWithNil() throws { - let literal = Literal.nil - let generated = literal.generateCode() - #expect(generated.contains("nil")) - } - - @Test("Literal with boolean generates correct syntax") - internal func testLiteralWithBoolean() throws { - let literal = Literal.boolean(true) - let generated = literal.generateCode() - #expect(generated.contains("true")) - } - - @Test("Literal with float generates correct syntax") - internal func testLiteralWithFloat() throws { - let literal = Literal.float(3.14159) - let generated = literal.generateCode() - #expect(generated.contains("3.14159")) - } } diff --git a/Tests/SyntaxKitTests/Unit/EdgeCaseTestsExpressions.swift b/Tests/SyntaxKitTests/Unit/EdgeCaseTestsExpressions.swift new file mode 100644 index 0000000..8296755 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/EdgeCaseTestsExpressions.swift @@ -0,0 +1,129 @@ +import Testing + +@testable import SyntaxKit + +internal struct EdgeCaseTestsExpressions { + // MARK: - Switch and Case Tests + + @Test("Switch with multiple patterns generates correct syntax") + internal func testSwitchWithMultiplePatterns() throws { + let switchStmt = Switch("value") { + SwitchCase("1") { + Return { VariableExp("one") } + } + SwitchCase("2") { + Return { VariableExp("two") } + } + } + + let generated = switchStmt.generateCode() + #expect(generated.contains("switch value")) + #expect(generated.contains("case 1:")) + #expect(generated.contains("case 2:")) + } + + @Test("SwitchCase with multiple patterns generates correct syntax") + internal func testSwitchCaseWithMultiplePatterns() throws { + let switchCase = SwitchCase("1", "2", "3") { + Return { VariableExp("number") } + } + + let generated = switchCase.generateCode() + #expect(generated.contains("case 1, 2, 3:")) + } + + // MARK: - Complex Expression Tests + + @Test("Infix with complex expressions generates correct syntax") + internal func testInfixWithComplexExpressions() throws { + let infix = Infix("*") { + Parenthesized { + Infix("+") { + VariableExp("a") + VariableExp("b") + } + } + Parenthesized { + Infix("-") { + VariableExp("c") + VariableExp("d") + } + } + } + + let generated = infix.generateCode() + #expect(generated.contains("(a + b) * (c - d)")) + } + + @Test("Return with VariableExp generates correct syntax") + internal func testReturnWithVariableExp() throws { + let returnStmt = Return { + VariableExp("result") + } + + let generated = returnStmt.generateCode() + #expect(generated.contains("return result")) + } + + @Test("Return with complex expression generates correct syntax") + internal func testReturnWithComplexExpression() throws { + let returnStmt = Return { + Infix("+") { + VariableExp("a") + VariableExp("b") + } + } + + let generated = returnStmt.generateCode() + #expect(generated.contains("return a + b")) + } + + // MARK: - CodeBlock Expression Tests + + @Test("CodeBlock expr with TokenSyntax wraps in DeclReferenceExpr") + internal func testCodeBlockExprWithTokenSyntax() throws { + let variableExp = VariableExp("x") + let expr = variableExp.expr + + let generated = expr.description + #expect(generated.contains("x")) + } + + // MARK: - Code Generation Edge Cases + + @Test("CodeBlock generateCode with CodeBlockItemListSyntax") + internal func testCodeBlockGenerateCodeWithItemList() throws { + let group = Group { + Variable(.let, name: "x", type: "Int", equals: 1).withExplicitType() + Variable(.let, name: "y", type: "Int", equals: 2).withExplicitType() + } + + let generated = group.generateCode() + #expect(generated.contains("let x : Int = 1")) + #expect(generated.contains("let y : Int = 2")) + } + + @Test("CodeBlock generateCode with single declaration") + internal func testCodeBlockGenerateCodeWithSingleDeclaration() throws { + let variable = Variable(.let, name: "x", type: "Int", equals: 1).withExplicitType() + + let generated = variable.generateCode() + #expect(generated.contains("let x : Int = 1")) + } + + @Test("CodeBlock generateCode with single statement") + internal func testCodeBlockGenerateCodeWithSingleStatement() throws { + let assignment = Assignment("x", Literal.integer(42)) + + let generated = assignment.generateCode() + #expect(generated.contains("x = 42")) + } + + @Test("CodeBlock generateCode with single expression") + internal func testCodeBlockGenerateCodeWithSingleExpression() throws { + let variableExp = VariableExp("x") + + let generated = variableExp.generateCode() + #expect(generated.contains("x")) + } +} diff --git a/Tests/SyntaxKitTests/Unit/EdgeCaseTestsTypes.swift b/Tests/SyntaxKitTests/Unit/EdgeCaseTestsTypes.swift new file mode 100644 index 0000000..237aa60 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/EdgeCaseTestsTypes.swift @@ -0,0 +1,136 @@ +import Testing + +@testable import SyntaxKit + +internal struct EdgeCaseTestsTypes { + // MARK: - Complex Type Tests + + @Test("TypeAlias with complex nested types") + internal func testTypeAliasWithComplexNestedTypes() throws { + let typeAlias = TypeAlias("ComplexType", equals: "Array>>") + + let generated = typeAlias.generateCode() + #expect( + generated.normalize().contains( + "typealias ComplexType = Array>>".normalize() + ) + ) + } + + @Test("TypeAlias with multiple generic parameters") + internal func testTypeAliasWithMultipleGenericParameters() throws { + let typeAlias = TypeAlias("Result", equals: "Result") + + let generated = typeAlias.generateCode().normalize() + #expect(generated.contains("typealias Result = Result".normalize())) + } + + // MARK: - Function Parameter Tests + + @Test("Function with unnamed parameter generates correct syntax") + internal func testFunctionWithUnnamedParameter() throws { + let function = Function("process") { + Parameter(name: "data", type: "Data", isUnnamed: true) + } _: { + Variable(.let, name: "result", type: "String", equals: "processed") + } + + let generated = function.generateCode() + #expect(generated.contains("func process(_ data: Data)")) + } + + @Test("Function with parameter default value generates correct syntax") + internal func testFunctionWithParameterDefaultValue() throws { + let function = Function("greet") { + Parameter(name: "name", type: "String", defaultValue: "\"World\"") + } _: { + Variable(.let, name: "message", type: "String", equals: "greeting") + } + + let generated = function.generateCode() + #expect(generated.contains("func greet(name : String = \"World\")")) + } + + // MARK: - Enum Case Tests + + @Test("EnumCase with string raw value generates correct syntax") + internal func testEnumCaseWithStringRawValue() throws { + let enumDecl = Enum("Status") { + EnumCase("active").equals(Literal.string("active")) + EnumCase("inactive").equals(Literal.string("inactive")) + } + + let generated = enumDecl.generateCode().normalize() + #expect(generated.contains("case active = \"active\"")) + #expect(generated.contains("case inactive = \"inactive\"")) + } + + @Test("EnumCase with double raw value generates correct syntax") + internal func testEnumCaseWithDoubleRawValue() throws { + let enumDecl = Enum("Precision") { + EnumCase("low").equals(Literal.float(0.1)) + EnumCase("high").equals(Literal.float(0.001)) + } + + let generated = enumDecl.generateCode().normalize() + #expect(generated.contains("case low = 0.1")) + #expect(generated.contains("case high = 0.001")) + } + + // MARK: - Computed Property Tests + + @Test("ComputedProperty with complex return expression") + internal func testComputedPropertyWithComplexReturn() throws { + let computedProperty = ComputedProperty("description", type: "String") { + Return { + VariableExp("name").call("appending") { + ParameterExp(name: "", value: "\" - \" + String(count)") + } + } + } + + let generated = computedProperty.generateCode().normalize() + #expect(generated.contains("var description: String")) + #expect(generated.contains("return name.appending(\" - \" + String(count))")) + } + + // MARK: - Comment Integration Tests + + @Test("ComputedProperty with comments generates correct syntax") + internal func testComputedPropertyWithComments() throws { + let computedProperty = ComputedProperty("formattedName", type: "String") { + Return { + VariableExp("name").property("uppercased") + } + }.comment { + Line(.doc, "Returns the name in uppercase format") + } + + let generated = computedProperty.generateCode() + #expect(generated.contains("/// Returns the name in uppercase format")) + #expect(generated.contains("var formattedName : String")) + } + + // MARK: - Literal Tests + + @Test("Literal with nil generates correct syntax") + internal func testLiteralWithNil() throws { + let literal = Literal.nil + let generated = literal.generateCode() + #expect(generated.contains("nil")) + } + + @Test("Literal with boolean generates correct syntax") + internal func testLiteralWithBoolean() throws { + let literal = Literal.boolean(true) + let generated = literal.generateCode() + #expect(generated.contains("true")) + } + + @Test("Literal with float generates correct syntax") + internal func testLiteralWithFloat() throws { + let literal = Literal.float(3.14159) + let generated = literal.generateCode() + #expect(generated.contains("3.14159")) + } +} diff --git a/Tests/SyntaxKitTests/Unit/ErrorHandlingTests.swift b/Tests/SyntaxKitTests/Unit/ErrorHandlingTests.swift new file mode 100644 index 0000000..e68a119 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/ErrorHandlingTests.swift @@ -0,0 +1,129 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct ErrorHandlingTests { + @Test("Error handling DSL generates expected Swift code") + internal func testErrorHandlingExample() throws { + let errorHandlingExample = Group { + Variable(.var, name: "vendingMachine", equals: Init("VendingMachine")) + Assignment("vendingMachine.coinsDeposited", Literal.integer(8)) + Do { + Call("buyFavoriteSnack") { + ParameterExp(name: "person", value: Literal.string("Alice")) + ParameterExp(name: "vendingMachine", value: Literal.ref("vendingMachine")) + }.throwing() + Call("print") { + ParameterExp(unlabeled: Literal.string("Success! Yum.")) + } + } catch: { + Catch(EnumCase("invalidSelection")) { + Call("print") { + ParameterExp(unlabeled: Literal.string("Invalid Selection.")) + } + } + Catch(EnumCase("outOfStock")) { + Call("print") { + ParameterExp(unlabeled: Literal.string("Out of Stock.")) + } + } + Catch( + EnumCase("insufficientFunds") + .associatedValue("coinsNeeded", type: "Int") + ) { + Call("print") { + ParameterExp( + unlabeled: Literal.string( + "Insufficient funds. Please insert an additional \\(coinsNeeded) coins." + ) + ) + } + } + Catch { + Call("print") { + ParameterExp(unlabeled: Literal.string("Unexpected error: \\(error).")) + } + } + } + } + + let generated = errorHandlingExample.generateCode() + let expected = """ + var vendingMachine = VendingMachine() + vendingMachine.coinsDeposited = 8 + do { + try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine) + print("Success! Yum.") + } catch .invalidSelection { + print("Invalid Selection.") + } catch .outOfStock { + print("Out of Stock.") + } catch .insufficientFunds(let coinsNeeded) { + print("Insufficient funds. Please insert an additional \\(coinsNeeded) coins.") + } catch { + print("Unexpected error: \\(error).") + } + """ + + #expect( + generated.normalize() == expected.normalize() + ) + + print("Generated code:") + print(generated) + } + + @Test("Function with throws clause and unlabeled parameter generates correct syntax") + internal func testFunctionWithThrowsClauseAndUnlabeledParameter() throws { + let function = Function("summarize") { + Parameter(unlabeled: "ratings", type: "[Int]") + } _: { + Guard { + VariableExp("ratings").property("isEmpty").not() + } else: { + Throw(EnumCase("noRatings")) + } + }.throws("StatisticsError") + + let generated = function.generateCode() + let expected = """ + func summarize(_ ratings: [Int]) throws(StatisticsError) { + guard !ratings.isEmpty else { throw .noRatings } + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Async functionality generates correct syntax") + internal func testAsyncFunctionality() throws { + let asyncCode = Group { + Variable(.let, name: "data") { + Call("fetchUserData") { + ParameterExp(name: "id", value: Literal.integer(1)) + } + }.async() + Variable(.let, name: "posts") { + Call("fetchUserPosts") { + ParameterExp(name: "id", value: Literal.integer(1)) + } + }.async() + TupleAssignment( + ["fetchedData", "fetchedPosts"], + equals: Tuple { + VariableExp("data") + VariableExp("posts") + } + ).async().throwing() + } + + let generated = asyncCode.generateCode() + let expected = """ + async let data = fetchUserData(id: 1) + async let posts = fetchUserPosts(id: 1) + let (fetchedData, fetchedPosts) = try await (data, posts) + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/MainApplicationTests.swift b/Tests/SyntaxKitTests/Unit/MainApplicationTests.swift index d47974f..133d548 100644 --- a/Tests/SyntaxKitTests/Unit/MainApplicationTests.swift +++ b/Tests/SyntaxKitTests/Unit/MainApplicationTests.swift @@ -116,7 +116,10 @@ internal struct MainApplicationTests { internal func testMainApplicationErrorResponseFormat() throws { // Test the error response format that the main application would generate let testError = NSError( - domain: "TestDomain", code: 1, userInfo: [NSLocalizedDescriptionKey: "Test error message"]) + domain: "TestDomain", + code: 1, + userInfo: [NSLocalizedDescriptionKey: "Test error message"] + ) let errorResponse = ["error": testError.localizedDescription] let jsonData = try JSONSerialization.data(withJSONObject: errorResponse) diff --git a/Tests/SyntaxKitTests/Unit/OptionsMacroIntegrationTests.swift b/Tests/SyntaxKitTests/Unit/OptionsMacroIntegrationTests.swift index 3870889..3319c29 100644 --- a/Tests/SyntaxKitTests/Unit/OptionsMacroIntegrationTests.swift +++ b/Tests/SyntaxKitTests/Unit/OptionsMacroIntegrationTests.swift @@ -47,7 +47,9 @@ internal struct OptionsMacroIntegrationTests { #expect( generated.contains( - "extension MockDictionaryEnum: MappedValueRepresentable, MappedValueRepresented")) + "extension MockDictionaryEnum: MappedValueRepresentable, MappedValueRepresented" + ) + ) #expect(generated.contains("typealias MappedType = String")) #expect(generated.contains("static let mappedValues: [Int: String]")) #expect(generated.contains("2: \"a\"")) @@ -172,7 +174,9 @@ internal struct OptionsMacroIntegrationTests { #expect( generated.contains( - "extension EmptyDictEnum: MappedValueRepresentable, MappedValueRepresented")) + "extension EmptyDictEnum: MappedValueRepresentable, MappedValueRepresented" + ) + ) #expect(generated.contains("typealias MappedType = String")) #expect(generated.contains("static let mappedValues: [Int: String] = [: ]")) } @@ -195,38 +199,4 @@ internal struct OptionsMacroIntegrationTests { #expect(generated.contains("\"case-with-dash\"")) #expect(generated.contains("\"caseWithCamelCase\"")) } - - // MARK: - API Validation Tests - - @Test internal func testNewSyntaxKitAPICompleteness() { - // Verify that all the new API components work together correctly - - // Test LiteralValue protocol - let array: [String] = ["a", "b", "c"] - #expect(array.typeName == "[String]") - #expect(array.literalString == "[\"a\", \"b\", \"c\"]") - - let dict: [Int: String] = [1: "a", 2: "b"] - #expect(dict.typeName == "[Int: String]") - #expect(dict.literalString.contains("1: \"a\"")) - #expect(dict.literalString.contains("2: \"b\"")) - - // Test Variable with static support - let staticVar = Variable(.let, name: "test", equals: array).withExplicitType().static() - let staticGenerated = staticVar.generateCode().normalize() - #expect(staticGenerated.contains("static let test: [String] = [\"a\", \"b\", \"c\"]")) - - // Test Extension with inheritance - let ext = Extension("Test") { - // Empty content - }.inherits("Protocol1", "Protocol2") - - let extGenerated = ext.generateCode().normalize() - #expect(extGenerated.contains("extension Test: Protocol1, Protocol2")) - - // Test TypeAlias - let alias = TypeAlias("MyType", equals: "String") - let aliasGenerated = alias.generateCode().normalize() - #expect(aliasGenerated.contains("typealias MyType = String")) - } } diff --git a/Tests/SyntaxKitTests/Unit/OptionsMacroIntegrationTestsAPI.swift b/Tests/SyntaxKitTests/Unit/OptionsMacroIntegrationTestsAPI.swift new file mode 100644 index 0000000..41a4701 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/OptionsMacroIntegrationTestsAPI.swift @@ -0,0 +1,39 @@ +import Testing + +@testable import SyntaxKit + +internal struct OptionsMacroIntegrationTestsAPI { + // MARK: - API Validation Tests + + @Test internal func testNewSyntaxKitAPICompleteness() { + // Verify that all the new API components work together correctly + + // Test LiteralValue protocol + let array: [String] = ["a", "b", "c"] + #expect(array.typeName == "[String]") + #expect(array.literalString == "[\"a\", \"b\", \"c\"]") + + let dict: [Int: String] = [1: "a", 2: "b"] + #expect(dict.typeName == "[Int: String]") + #expect(dict.literalString.contains("1: \"a\"")) + #expect(dict.literalString.contains("2: \"b\"")) + + // Test Variable with static support + let staticVar = Variable(.let, name: "test", equals: array).withExplicitType().static() + let staticGenerated = staticVar.generateCode().normalize() + #expect(staticGenerated.contains("static let test: [String] = [\"a\", \"b\", \"c\"]")) + + // Test Extension with inheritance + let ext = Extension("Test") { + // Empty content + }.inherits("Protocol1", "Protocol2") + + let extGenerated = ext.generateCode().normalize() + #expect(extGenerated.contains("extension Test: Protocol1, Protocol2")) + + // Test TypeAlias + let alias = TypeAlias("MyType", equals: "String") + let aliasGenerated = alias.generateCode().normalize() + #expect(aliasGenerated.contains("typealias MyType = String")) + } +} diff --git a/Tests/SyntaxKitTests/Unit/ThrowBasicTests.swift b/Tests/SyntaxKitTests/Unit/ThrowBasicTests.swift new file mode 100644 index 0000000..e6db237 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/ThrowBasicTests.swift @@ -0,0 +1,92 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct ThrowBasicTests { + // MARK: - Basic Throw Tests + + @Test("Basic throw with enum case generates correct syntax") + internal func testBasicThrowWithEnumCase() throws { + let throwStatement = Throw(EnumCase("connectionFailed")) + + let generated = throwStatement.generateCode() + let expected = "throw .connectionFailed" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with enum case and type generates correct syntax") + internal func testThrowWithEnumCaseAndType() throws { + let throwStatement = Throw(EnumCase("connectionFailed")) + + let generated = throwStatement.generateCode() + let expected = "throw .connectionFailed" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with enum case with associated value generates correct syntax") + internal func testThrowWithEnumCaseWithAssociatedValue() throws { + let throwStatement = Throw( + EnumCase("invalidInput") + .associatedValue("fieldName", type: "String") + ) + + let generated = throwStatement.generateCode() + let expected = "throw .invalidInput(fieldName)" + + #expect(generated.normalize() == expected.normalize()) + } + + // MARK: - Throw with Different Expression Types + + @Test("Throw with string literal generates correct syntax") + internal func testThrowWithStringLiteral() throws { + let throwStatement = Throw(Literal.string("Custom error message")) + + let generated = throwStatement.generateCode() + let expected = "throw \"Custom error message\"" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with integer literal generates correct syntax") + internal func testThrowWithIntegerLiteral() throws { + let throwStatement = Throw(Literal.integer(404)) + + let generated = throwStatement.generateCode() + let expected = "throw 404" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with boolean literal generates correct syntax") + internal func testThrowWithBooleanLiteral() throws { + let throwStatement = Throw(Literal.boolean(true)) + + let generated = throwStatement.generateCode() + let expected = "throw true" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with variable expression generates correct syntax") + internal func testThrowWithVariableExpression() throws { + let throwStatement = Throw(VariableExp("customError")) + + let generated = throwStatement.generateCode() + let expected = "throw customError" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with property access generates correct syntax") + internal func testThrowWithPropertyAccess() throws { + let throwStatement = Throw(VariableExp("user").property("validationError")) + + let generated = throwStatement.generateCode() + let expected = "throw user.validationError" + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/ThrowComplexTests.swift b/Tests/SyntaxKitTests/Unit/ThrowComplexTests.swift new file mode 100644 index 0000000..eb8700c --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/ThrowComplexTests.swift @@ -0,0 +1,131 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct ThrowComplexTests { + // MARK: - Complex Throw Expressions + + @Test("Throw with conditional expression generates correct syntax") + internal func testThrowWithConditionalExpression() throws { + let throwStatement = Throw( + If(VariableExp("isNetworkError")) { + EnumCase("connectionFailed") + } else: { + EnumCase("invalidInput") + } + ) + + let generated = throwStatement.generateCode() + let expected = "throw if isNetworkError { .connectionFailed } else { .invalidInput }" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with tuple expression generates correct syntax") + internal func testThrowWithTupleExpression() throws { + let throwStatement = Throw( + Tuple { + Literal.string("Error occurred") + Literal.integer(500) + } + ) + + let generated = throwStatement.generateCode() + let expected = "throw (\"Error occurred\", 500)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with array literal generates correct syntax") + internal func testThrowWithArrayLiteral() throws { + let throwStatement = Throw( + Literal.array([ + Literal.string("Error 1"), + Literal.string("Error 2"), + ]) + ) + + let generated = throwStatement.generateCode() + let expected = "throw [\"Error 1\", \"Error 2\"]" + + #expect(generated.normalize() == expected.normalize()) + } + + // MARK: - Integration Tests + + @Test("Throw in guard statement generates correct syntax") + internal func testThrowInGuardStatement() throws { + let guardStatement = Guard { + VariableExp("user").property("isValid").not() + } else: { + Throw(EnumCase("invalidUser")) + } + + let generated = guardStatement.generateCode() + let expected = "guard !user.isValid else { throw .invalidUser }" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw in function generates correct syntax") + internal func testThrowInFunction() throws { + let function = Function("validateUser") { + Parameter(name: "user", type: "User") + } _: { + Guard { + VariableExp("user").property("name").property("isEmpty").not() + } else: { + Throw(EnumCase("emptyName")) + } + Guard { + VariableExp("user").property("email").property("isEmpty").not() + } else: { + Throw(EnumCase("emptyEmail")) + } + }.throws("ValidationError") + + let generated = function.generateCode() + let expected = """ + func validateUser(user: User) throws(ValidationError) { + guard !user.name.isEmpty else { throw .emptyName } + guard !user.email.isEmpty else { throw .emptyEmail } + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw in async function generates correct syntax") + internal func testThrowInAsyncFunction() throws { + let function = Function("fetchUser") { + Parameter(name: "id", type: "Int") + } _: { + Guard { + VariableExp("id") > Literal.integer(0) + } else: { + Throw(EnumCase("invalidId")) + } + Variable(.let, name: "user") { + Call("fetchUserFromAPI") { + ParameterExp(name: "userId", value: VariableExp("id")) + } + }.async() + Guard { + VariableExp("user") != Literal.nil + } else: { + Throw(EnumCase("userNotFound")) + } + }.asyncThrows("NetworkError") + + let generated = function.generateCode() + let expected = """ + func fetchUser(id: Int) async throws(NetworkError) { + guard id > 0 else { throw .invalidId } + async let user = fetchUserFromAPI(userId: id) + guard user != nil else { throw .userNotFound } + } + """ + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/ThrowEdgeCaseTests.swift b/Tests/SyntaxKitTests/Unit/ThrowEdgeCaseTests.swift new file mode 100644 index 0000000..c2a3b9b --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/ThrowEdgeCaseTests.swift @@ -0,0 +1,37 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct ThrowEdgeCaseTests { + // MARK: - Edge Cases + + @Test("Throw with nil literal generates correct syntax") + internal func testThrowWithNilLiteral() throws { + let throwStatement = Throw(Literal.nil) + + let generated = throwStatement.generateCode() + let expected = "throw nil" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with float literal generates correct syntax") + internal func testThrowWithFloatLiteral() throws { + let throwStatement = Throw(Literal.float(3.14)) + + let generated = throwStatement.generateCode() + let expected = "throw 3.14" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with reference literal generates correct syntax") + internal func testThrowWithReferenceLiteral() throws { + let throwStatement = Throw(Literal.ref("globalError")) + + let generated = throwStatement.generateCode() + let expected = "throw globalError" + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/ThrowFunctionTests.swift b/Tests/SyntaxKitTests/Unit/ThrowFunctionTests.swift new file mode 100644 index 0000000..7432ff7 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/ThrowFunctionTests.swift @@ -0,0 +1,66 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct ThrowFunctionTests { + // MARK: - Throw with Function Calls + + @Test("Throw with function call generates correct syntax") + internal func testThrowWithFunctionCall() throws { + let throwStatement = Throw( + Call("createError") { + ParameterExp(name: "code", value: Literal.integer(500)) + ParameterExp(name: "message", value: Literal.string("Internal server error")) + } + ) + + let generated = throwStatement.generateCode() + let expected = "throw createError(code: 500, message: \"Internal server error\")" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with async function call generates correct syntax") + internal func testThrowWithAsyncFunctionCall() throws { + let throwStatement = Throw( + Call("fetchError") { + ParameterExp(name: "id", value: Literal.integer(123)) + }.async() + ) + + let generated = throwStatement.generateCode() + let expected = "throw await fetchError(id: 123)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with throwing function call generates correct syntax") + internal func testThrowWithThrowingFunctionCall() throws { + let throwStatement = Throw( + Call("parseError") { + ParameterExp(name: "data", value: VariableExp("jsonData")) + }.throwing() + ) + + let generated = throwStatement.generateCode() + let expected = "throw try parseError(data: jsonData)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throw with custom error type generates correct syntax") + internal func testThrowWithCustomErrorType() throws { + let throwStatement = Throw( + Call("CustomError") { + ParameterExp(name: "code", value: Literal.integer(404)) + ParameterExp(name: "message", value: Literal.string("Not found")) + ParameterExp(name: "details", value: VariableExp("errorDetails")) + } + ) + + let generated = throwStatement.generateCode() + let expected = "throw CustomError(code: 404, message: \"Not found\", details: errorDetails)" + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/TupleAssignmentAsyncTests.swift b/Tests/SyntaxKitTests/Unit/TupleAssignmentAsyncTests.swift new file mode 100644 index 0000000..9578aba --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/TupleAssignmentAsyncTests.swift @@ -0,0 +1,122 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct TupleAssignmentAsyncTests { + // MARK: - Async Tuple Assignment Tests + + @Test("Async tuple assignment generates correct syntax") + internal func testAsyncTupleAssignment() throws { + let tupleAssignment = TupleAssignment( + ["data", "posts"], + equals: Tuple { + VariableExp("fetchData") + VariableExp("fetchPosts") + } + ).async() + + let generated = tupleAssignment.generateCode() + let expected = "let (data, posts) = await (fetchData, fetchPosts)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Async tuple assignment with mixed expressions generates correct syntax") + internal func testAsyncTupleAssignmentWithMixedExpressions() throws { + let tupleAssignment = TupleAssignment( + ["result", "count"], + equals: Tuple { + Call("processData") { + ParameterExp(name: "input", value: Literal.string("test")) + } + Literal.integer(42) + } + ).async() + + let generated = tupleAssignment.generateCode() + let expected = "let (result, count) = await (processData(input: \"test\"), 42)" + + #expect(generated.normalize() == expected.normalize()) + } + + // MARK: - Throwing Tuple Assignment Tests + + @Test("Throwing tuple assignment generates correct syntax") + internal func testThrowingTupleAssignment() throws { + let tupleAssignment = TupleAssignment( + ["data", "posts"], + equals: Tuple { + VariableExp("fetchData") + VariableExp("fetchPosts") + } + ).throwing() + + let generated = tupleAssignment.generateCode() + let expected = "let (data, posts) = try (fetchData, fetchPosts)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Throwing tuple assignment with async calls generates correct syntax") + internal func testThrowingTupleAssignmentWithAsyncCalls() throws { + let tupleAssignment = TupleAssignment( + ["data", "posts"], + equals: Tuple { + Call("fetchUserData") { + ParameterExp(name: "id", value: Literal.integer(1)) + }.async() + Call("fetchUserPosts") { + ParameterExp(name: "id", value: Literal.integer(1)) + }.async() + } + ).throwing() + + let generated = tupleAssignment.generateCode() + let expected = + "let (data, posts) = try (await fetchUserData(id: 1), await fetchUserPosts(id: 1))" + + #expect(generated.normalize() == expected.normalize()) + } + + // MARK: - Async and Throwing Tuple Assignment Tests + + @Test("Async and throwing tuple assignment generates correct syntax") + internal func testAsyncAndThrowingTupleAssignment() throws { + let tupleAssignment = TupleAssignment( + ["data", "posts"], + equals: Tuple { + VariableExp("fetchData") + VariableExp("fetchPosts") + } + ).async().throwing() + + let generated = tupleAssignment.generateCode() + let expected = "let (data, posts) = try await (fetchData, fetchPosts)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Async and throwing tuple assignment with complex expressions generates correct syntax") + internal func testAsyncAndThrowingTupleAssignmentWithComplexExpressions() throws { + let tupleAssignment = TupleAssignment( + ["user", "profile", "settings"], + equals: Tuple { + Call("fetchUser") { + ParameterExp(name: "id", value: Literal.integer(123)) + }.async() + Call("fetchProfile") { + ParameterExp(name: "userId", value: Literal.integer(123)) + }.async() + Call("fetchSettings") { + ParameterExp(name: "userId", value: Literal.integer(123)) + }.async() + } + ).async().throwing() + + let generated = tupleAssignment.generateCode() + let expected = + "let (user, profile, settings) = try await (await fetchUser(id: 123), await fetchProfile(userId: 123), await fetchSettings(userId: 123))" + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/TupleAssignmentBasicTests.swift b/Tests/SyntaxKitTests/Unit/TupleAssignmentBasicTests.swift new file mode 100644 index 0000000..47889a5 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/TupleAssignmentBasicTests.swift @@ -0,0 +1,72 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct TupleAssignmentBasicTests { + // MARK: - Basic Tuple Assignment Tests + + @Test("Basic tuple assignment generates correct syntax") + internal func testBasicTupleAssignment() throws { + let tupleAssignment = TupleAssignment( + ["x", "y"], + equals: Tuple { + Literal.integer(1) + Literal.integer(2) + } + ) + + let generated = tupleAssignment.generateCode() + let expected = "let (x, y) = (1, 2)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Single element tuple assignment generates correct syntax") + internal func testSingleElementTupleAssignment() throws { + let tupleAssignment = TupleAssignment( + ["value"], + equals: Tuple { + Literal.string("test") + } + ) + + let generated = tupleAssignment.generateCode() + let expected = "let (value) = (\"test\")" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Three element tuple assignment generates correct syntax") + internal func testThreeElementTupleAssignment() throws { + let tupleAssignment = TupleAssignment( + ["x", "y", "z"], + equals: Tuple { + Literal.integer(1) + Literal.integer(2) + Literal.integer(3) + } + ) + + let generated = tupleAssignment.generateCode() + let expected = "let (x, y, z) = (1, 2, 3)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Tuple assignment with mixed literal types generates correct syntax") + internal func testTupleAssignmentWithMixedTypes() throws { + let tupleAssignment = TupleAssignment( + ["name", "age", "isActive"], + equals: Tuple { + Literal.string("John") + Literal.integer(30) + Literal.boolean(true) + } + ) + + let generated = tupleAssignment.generateCode() + let expected = "let (name, age, isActive) = (\"John\", 30, true)" + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/TupleAssignmentEdgeCaseTests.swift b/Tests/SyntaxKitTests/Unit/TupleAssignmentEdgeCaseTests.swift new file mode 100644 index 0000000..ced5f47 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/TupleAssignmentEdgeCaseTests.swift @@ -0,0 +1,82 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct TupleAssignmentEdgeCaseTests { + // MARK: - Edge Cases and Error Handling Tests + + @Test("Tuple assignment with empty elements array throws error") + internal func testTupleAssignmentWithEmptyElements() throws { + // This should be handled gracefully by the DSL + let tupleAssignment = TupleAssignment( + [], + equals: Tuple { + Literal.integer(1) + } + ) + + let generated = tupleAssignment.generateCode() + let expected = "let () = (1)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Tuple assignment with variable expressions generates correct syntax") + internal func testTupleAssignmentWithVariableExpressions() throws { + let tupleAssignment = TupleAssignment( + ["firstName", "lastName"], + equals: Tuple { + VariableExp("user.firstName") + VariableExp("user.lastName") + } + ) + + let generated = tupleAssignment.generateCode() + let expected = "let (firstName, lastName) = (user.firstName, user.lastName)" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Tuple assignment with function calls generates correct syntax") + internal func testTupleAssignmentWithFunctionCalls() throws { + let tupleAssignment = TupleAssignment( + ["min", "max"], + equals: Tuple { + Call("findMinimum") { + ParameterExp(name: "array", value: VariableExp("numbers")) + } + Call("findMaximum") { + ParameterExp(name: "array", value: VariableExp("numbers")) + } + } + ) + + let generated = tupleAssignment.generateCode() + let expected = "let (min, max) = (findMinimum(array: numbers), findMaximum(array: numbers))" + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Tuple assignment with nested tuples generates correct syntax") + internal func testTupleAssignmentWithNestedTuples() throws { + let tupleAssignment = TupleAssignment( + ["point", "color"], + equals: Tuple { + Tuple { + Literal.integer(10) + Literal.integer(20) + } + Tuple { + Literal.integer(255) + Literal.integer(0) + Literal.integer(0) + } + } + ) + + let generated = tupleAssignment.generateCode() + let expected = "let (point, color) = ((10, 20), (255, 0, 0))" + + #expect(generated.normalize() == expected.normalize()) + } +} diff --git a/Tests/SyntaxKitTests/Unit/TupleAssignmentIntegrationTests.swift b/Tests/SyntaxKitTests/Unit/TupleAssignmentIntegrationTests.swift new file mode 100644 index 0000000..9e1ee18 --- /dev/null +++ b/Tests/SyntaxKitTests/Unit/TupleAssignmentIntegrationTests.swift @@ -0,0 +1,96 @@ +import Testing + +@testable import SyntaxKit + +@Suite internal struct TupleAssignmentIntegrationTests { + // MARK: - Integration Tests + + @Test("Tuple assignment in a function generates correct syntax") + internal func testTupleAssignmentInFunction() throws { + let function = Function("processData") { + Parameter(name: "input", type: "[Int]") + } _: { + TupleAssignment( + ["sum", "count"], + equals: Tuple { + Call("calculateSum") { + ParameterExp(name: "numbers", value: VariableExp("input")) + } + Call("calculateCount") { + ParameterExp(name: "numbers", value: VariableExp("input")) + } + } + ) + Call("print") { + ParameterExp( + unlabeled: Literal.string("Sum: \\(sum), Count: \\(count)") + ) + } + } + + let generated = function.generateCode() + let expected = """ + func processData(input: [Int]) { + let (sum, count) = (calculateSum(numbers: input), calculateCount(numbers: input)) + print("Sum: \\(sum), Count: \\(count)") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("Async tuple assignment in async function generates correct syntax") + internal func testAsyncTupleAssignmentInAsyncFunction() throws { + let function = Function("fetchUserData") { + Parameter(name: "userId", type: "Int") + } _: { + TupleAssignment( + ["user", "posts"], + equals: Tuple { + Call("fetchUser") { + ParameterExp(name: "id", value: VariableExp("userId")) + }.async() + Call("fetchPosts") { + ParameterExp(name: "userId", value: VariableExp("userId")) + }.async() + } + ).async().throwing() + Call("print") { + ParameterExp( + unlabeled: Literal.string("User: \\(user.name), Posts: \\(posts.count)") + ) + } + }.async().throws("NetworkError") + + let generated = function.generateCode() + let expected = """ + func fetchUserData(userId: Int) async throws(NetworkError) { + let (user, posts) = try await (await fetchUser(id: userId), await fetchPosts(userId: userId)) + print("User: \\(user.name), Posts: \\(posts.count)") + } + """ + + #expect(generated.normalize() == expected.normalize()) + } + + @Test("AsyncSet tuple assignment generates concurrent async let pattern") + internal func testAsyncSetTupleAssignment() throws { + let tupleAssignment = TupleAssignment( + ["data", "posts"], + equals: Tuple { + Call("fetchUserData") { + ParameterExp(name: "id", value: Literal.integer(1)) + } + Call("fetchUserPosts") { + ParameterExp(name: "id", value: Literal.integer(1)) + } + } + ).asyncSet().throwing() + + let generated = tupleAssignment.generateCode() + let expected = """ + async let (data, posts) = try await (fetchUserData(id: 1), fetchUserPosts(id: 1)) + """ + #expect(generated.normalize() == expected.normalize()) + } +}