Swift AST written in Swift. Part 7 of ∞

Alexey Demedeckiy
3 min readApr 9, 2017

--

In previous part I have cover struct and class declarations. In this part I will describe another fundamental pillar of Swift language: protocols.

As usually, let’s start from looking on grammar:

Well, it is looks like class and struct a lot. But instead of allow any declaration to be defined inside protocols, it is limited to several strict cases.

Let’s write code for this grammar.

struct ProtocolDeclaration {
let attributes: [Attribute]
let accessLevel: AccessLevelModifier?
let name: Identifier
let typeInheritance: TypeInheritanceClause?
let members: [ProtocolMember]
}
enum ProtocolMember {
case `var`(ProtocolPropertyDeclaration)
case `func`(ProtocolMethodDeclaration)
case `init`(ProtocolInitializerDeclaration)
case `subscript`(ProtocolSubscriptDeclaration)
case `associatedtype`(ProtocolAssociatedTypeDeclaration)
case `typealias`(TypealiasDeclaration)
case compilerStatement(CompilerControlStatement)
}

Property

This is simplified verion of var declaration. It should be really easy to model it using struct:

struct ProtocolPropertyDeclaration {
let attributes: [Attribute]
let modifiers: [DeclarationModifier]
let name: Identifier
let type: TypeAnnotation
let getter: GetterKeywordClause
let setter: SetterKeywordClause?
}

Interesting that this exact declaration is matched part of a regular var declaration. It can be sign of some technical debt in Swift grammar.

Method

struct ProtocolMethodDeclaration {
let attributes: [Attribute]
let modifiers: [DeclarationModifier]
let name: Identifier
let genericParameters: GenericParameterClause?
let parameters: [Parameter]
let throwBehavior: ThrowsModifier?
let result: FunctionResult?
let `where`: GenericWhereClause?
}

One more time. This looks exactly like regular func declaration but without body code block. And In func declaration we have optional body block. Another sign of technical debt in grammar. Looks like long time age protocols consist from regular definitions. And later — special versions of grammar was introduced.

Initializer

struct ProtocolInitializerDeclaration {
let attributes: [Attribute]
let modifiers: [DeclarationModifier]
let optionalModifier: InitializerOptionalKind?
let genericParamters: GenericParameterClause?
let parameters: [Parameter]
let throwBehavior: ThrowsModifier?
let `where`: GenericWhereClause?
}

This part also mirror default init declaration without body. I will cover init in next part, but pattern is the same.

Subscript

struct ProtocolSubscriptDeclaration {
let attributes: [Attribute]
let modifiers: [DeclarationModifier]
let parameters: [Parameter]
let result: FunctionResult
let getter: GetterKeywordClause
let setter: SetterKeywordClause
}

Looks a lot like a function, but without name (it always will be subscript)

Associated type

struct ProtocolAssociatedTypeDeclaration {
let attributes: [Attribute]
let accessModifier: AccessLevelModifier?
let name: Identifier
let typeInheritance: TypeInheritanceClause?
let type: Type?
}

Associated types is a special form of a typealieas declaration where type assignement is an optional thing. But they are using a lot of grammar from original typealias declaration.

Looks like in Swift grammar we can found a lot of repeating and overlapping parts. I believe this is an inevitable entropy that arrives at high speed of development and evolution. In next part I will discover special form of functions in Swift: init, deinit and subscript.

--

--