-
Notifications
You must be signed in to change notification settings - Fork 93
Support elseif/else directive #328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
d108d0f
29813a1
f438d08
8f625f0
5bd510a
49b62cb
c473455
4d0a100
b5e8319
d9bc429
976c215
46a71d6
4835eef
d2b8d09
8a084a4
37babbc
7e6ca03
edec992
f040ca5
0f99d8c
8076b21
cbdf6a8
668097c
74a2589
bd332f8
ee70651
d849dcb
87d1fef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // | ||
| // Copyright (c) 2018. Uber Technologies | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
| // | ||
|
|
||
| /// Represents import content: either a simple import statement or a nested conditional block | ||
| public indirect enum ImportContent { | ||
| case simple(Import) | ||
| case conditional(ConditionalImportBlock) | ||
| } | ||
|
|
||
| /// Represents a conditional import block (#if/#elseif/#else/#endif) | ||
| public struct ConditionalImportBlock { | ||
| /// Represents a single clause in a conditional import block | ||
| public struct Clause { | ||
| public let type: ClauseType | ||
| public let condition: String? // nil for #else | ||
| public var contents: [ImportContent] | ||
|
|
||
| public init(type: ClauseType, condition: String?, contents: [ImportContent]) { | ||
| self.type = type | ||
| self.condition = condition | ||
| self.contents = contents | ||
| } | ||
| } | ||
|
|
||
| public let clauses: [Clause] | ||
| public let offset: Int64 | ||
|
|
||
| public init(clauses: [Clause], offset: Int64) { | ||
| self.clauses = clauses | ||
| self.offset = offset | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,36 +14,69 @@ | |
| // limitations under the License. | ||
| // | ||
|
|
||
| /// Represents the type of a clause in an #if/#elseif/#else block | ||
| public enum ClauseType: Comparable { | ||
| case `if` | ||
| case elseif(order: Int) | ||
| case `else` | ||
|
|
||
| // Comparable implementation: if < elseif(0) < elseif(1) < ... < else | ||
| public static func < (lhs: ClauseType, rhs: ClauseType) -> Bool { | ||
| switch (lhs, rhs) { | ||
| case (.if, .elseif), (.if, .else), (.elseif, .else): | ||
| true | ||
| case (.elseif(let l), .elseif(let r)): | ||
| l < r | ||
| default: | ||
| false | ||
| } | ||
| } | ||
| } | ||
|
|
||
| final class IfMacroModel: Model { | ||
| let name: String | ||
| /// Represents a single clause in a conditional compilation block | ||
| struct Clause { | ||
| let type: ClauseType | ||
| let condition: String? // nil for #else | ||
| let entities: [(String, Model)] | ||
| } | ||
|
Comment on lines
34
to
38
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [self review] Now Because IfMacroModel self is also Model, this recursively stores. |
||
|
|
||
| let clauses: [Clause] | ||
| let offset: Int64 | ||
| let entities: [(String, Model)] | ||
|
|
||
| var modelType: ModelType { | ||
| return .macro | ||
| .macro | ||
| } | ||
|
|
||
| var name: String { | ||
| clauses.first?.condition ?? "" | ||
| } | ||
|
|
||
| var fullName: String { | ||
| return entities.map {$0.0}.joined(separator: "_") | ||
| clauses.flatMap(\.entities).map { $0.0 }.joined(separator: "_") | ||
| } | ||
|
|
||
| init(name: String, | ||
| offset: Int64, | ||
| entities: [(String, Model)]) { | ||
| self.name = name | ||
| self.entities = entities | ||
|
|
||
| /// Creates an IfMacroModel with multiple clauses | ||
| init(clauses: [Clause], offset: Int64) { | ||
| self.clauses = clauses | ||
| self.offset = offset | ||
| } | ||
|
|
||
|
|
||
| /// Initializer for simple #if blocks | ||
| convenience init(name: String, | ||
| offset: Int64, | ||
| entities: [(String, Model)]) { | ||
| let clause = Clause(type: .if, condition: name, entities: entities) | ||
| self.init(clauses: [clause], offset: offset) | ||
| } | ||
|
|
||
| func render( | ||
| context: RenderContext, | ||
| arguments: GenerationArguments | ||
| ) -> String? { | ||
| return applyMacroTemplate( | ||
| name: name, | ||
| applyMacroTemplate( | ||
| context: context, | ||
| arguments: arguments, | ||
| entities: entities | ||
| arguments: arguments | ||
| ) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -150,7 +150,20 @@ struct GenerationArguments { | |
| ) | ||
| } | ||
|
|
||
| public typealias ImportMap = [String: [String: [String]]] | ||
| /// Structured import data parsed from a source file | ||
| public struct ParsedImports { | ||
|
||
| /// Top-level imports without conditional compilation | ||
| public var topLevel: [Import] | ||
| /// Conditional import blocks (#if/#elseif/#else/#endif) | ||
| public var conditional: [ConditionalImportBlock] | ||
|
|
||
| public init(topLevel: [Import] = [], conditional: [ConditionalImportBlock] = []) { | ||
| self.topLevel = topLevel | ||
| self.conditional = conditional | ||
| } | ||
| } | ||
|
|
||
| public typealias ImportMap = [String: ParsedImports] | ||
|
|
||
| /// Metadata for a type being mocked | ||
| public final class Entity { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[self review]
Except for
Import, all nodes withinIfDeclConfigSyntaxare stored inIfMacroModel'sentities.However, import statement is not represented as one of them, rather it is represented as
ImportContent.