lkml 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +28 -0
- data/.gitignore +57 -0
- data/.rubocop.yml +25 -0
- data/.ruby-version +1 -0
- data/CONTRIBUTING.md +56 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +76 -0
- data/LICENSE.md +1 -2
- data/README.md +81 -7
- data/Rakefile +12 -0
- data/bin/lkml +6 -0
- data/lib/lkml/cli.rb +44 -0
- data/lib/lkml/keys.rb +64 -114
- data/lib/lkml/lexer.rb +45 -68
- data/lib/lkml/parser.rb +296 -191
- data/lib/lkml/simple.rb +244 -238
- data/lib/lkml/tokens.rb +44 -129
- data/lib/lkml/tree.rb +362 -236
- data/lib/lkml/utils.rb +32 -0
- data/lib/lkml/version.rb +1 -1
- data/lib/lkml/visitors.rb +69 -64
- data/lib/lkml.rb +49 -14
- data/lkml.gemspec +35 -0
- data/script/benchmark.rb +36 -0
- data/script/download_lookml.rb +70 -0
- metadata +88 -13
data/lib/lkml/tokens.rb
CHANGED
|
@@ -1,211 +1,126 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Tokens used by the lexer to tokenize LookML.
|
|
4
|
-
|
|
5
3
|
module Lkml
|
|
6
4
|
module Tokens
|
|
7
5
|
class Token
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
TOKEN_ID = "<base token>"
|
|
10
7
|
attr_reader :line_number
|
|
11
8
|
|
|
12
|
-
def
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
# Args:
|
|
16
|
-
# line_number: The corresponding line in the text where this token begins
|
|
9
|
+
def id
|
|
10
|
+
self.class::TOKEN_ID
|
|
11
|
+
end
|
|
17
12
|
|
|
13
|
+
def value
|
|
14
|
+
nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize(line_number)
|
|
18
18
|
@line_number = line_number
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def ==(other)
|
|
22
|
-
|
|
23
|
-
self.class == other.class
|
|
22
|
+
instance_of?(other.class)
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
def
|
|
27
|
-
|
|
28
|
-
#
|
|
29
|
-
# If the token has a `value` attribute, include that in the output.
|
|
30
|
-
|
|
31
|
-
value = defined?(@value) ? @value.strip : ''
|
|
25
|
+
def inspect
|
|
26
|
+
value = respond_to?(:value) ? send(:value).to_s.strip : ""
|
|
32
27
|
value = "#{value[0, 25].rstrip} ... " if value.length > 25
|
|
33
|
-
"#{self.class.name}(#{value})"
|
|
28
|
+
"#{self.class.name.split('::').last}(#{value})"
|
|
34
29
|
end
|
|
30
|
+
alias to_s inspect
|
|
35
31
|
end
|
|
36
32
|
|
|
37
33
|
class ContentToken < Token
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
attr_accessor :value
|
|
34
|
+
attr_accessor :value # literals may be mutated after lex (e.g. hyphen join)
|
|
41
35
|
|
|
42
36
|
def initialize(value, line_number)
|
|
43
|
-
# Initializes a ContentToken with string content.
|
|
44
|
-
#
|
|
45
|
-
# Args:
|
|
46
|
-
# value: A string value for the token's content
|
|
47
|
-
# line_number: The corresponding line in the text where this token begins
|
|
48
|
-
|
|
49
|
-
@value = value
|
|
50
37
|
super(line_number)
|
|
38
|
+
@value = value
|
|
51
39
|
end
|
|
52
40
|
|
|
53
41
|
def ==(other)
|
|
54
|
-
|
|
55
|
-
self.class == other.class && @value == other.value
|
|
42
|
+
instance_of?(other.class) && value == other.value
|
|
56
43
|
end
|
|
57
|
-
end
|
|
58
44
|
|
|
59
|
-
|
|
60
|
-
|
|
45
|
+
def eql?(other)
|
|
46
|
+
self == other
|
|
47
|
+
end
|
|
61
48
|
|
|
62
|
-
def
|
|
63
|
-
|
|
64
|
-
@id = '<stream start>'
|
|
49
|
+
def hash
|
|
50
|
+
[self.class, value].hash
|
|
65
51
|
end
|
|
66
52
|
end
|
|
67
53
|
|
|
68
|
-
class
|
|
69
|
-
|
|
54
|
+
class StreamStartToken < Token
|
|
55
|
+
TOKEN_ID = "<stream start>"
|
|
56
|
+
end
|
|
70
57
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
@id = '<stream end>'
|
|
74
|
-
end
|
|
58
|
+
class StreamEndToken < Token
|
|
59
|
+
TOKEN_ID = "<stream end>"
|
|
75
60
|
end
|
|
76
61
|
|
|
77
62
|
class BlockStartToken < Token
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def initialize(line_number)
|
|
81
|
-
super
|
|
82
|
-
@id = '{'
|
|
83
|
-
end
|
|
63
|
+
TOKEN_ID = "{"
|
|
84
64
|
end
|
|
85
65
|
|
|
86
66
|
class BlockEndToken < Token
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def initialize(line_number)
|
|
90
|
-
super
|
|
91
|
-
@id = '}'
|
|
92
|
-
end
|
|
67
|
+
TOKEN_ID = "}"
|
|
93
68
|
end
|
|
94
69
|
|
|
95
70
|
class ValueToken < Token
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def initialize(line_number)
|
|
99
|
-
super
|
|
100
|
-
@id = ':'
|
|
101
|
-
end
|
|
71
|
+
TOKEN_ID = ":"
|
|
102
72
|
end
|
|
103
73
|
|
|
104
74
|
class ExpressionBlockEndToken < Token
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def initialize(line_number)
|
|
108
|
-
super
|
|
109
|
-
@id = ';;'
|
|
110
|
-
end
|
|
75
|
+
TOKEN_ID = ";;"
|
|
111
76
|
end
|
|
112
77
|
|
|
113
78
|
class CommaToken < Token
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def initialize(line_number)
|
|
117
|
-
super
|
|
118
|
-
@id = ','
|
|
119
|
-
end
|
|
79
|
+
TOKEN_ID = ","
|
|
120
80
|
end
|
|
121
81
|
|
|
122
82
|
class ListStartToken < Token
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def initialize(line_number)
|
|
126
|
-
super
|
|
127
|
-
@id = '['
|
|
128
|
-
end
|
|
83
|
+
TOKEN_ID = "["
|
|
129
84
|
end
|
|
130
85
|
|
|
131
86
|
class ListEndToken < Token
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
def initialize(line_number)
|
|
135
|
-
super
|
|
136
|
-
@id = ']'
|
|
137
|
-
end
|
|
87
|
+
TOKEN_ID = "]"
|
|
138
88
|
end
|
|
139
89
|
|
|
140
90
|
class TriviaToken < ContentToken
|
|
141
|
-
# Represents a comment or whitespace.
|
|
142
91
|
end
|
|
143
92
|
|
|
144
93
|
class WhitespaceToken < TriviaToken
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def initialize(value, line_number)
|
|
148
|
-
super
|
|
149
|
-
@id = '<whitespace>'
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def to_s
|
|
153
|
-
"#{self.class.name}(#{@value.inspect})"
|
|
154
|
-
end
|
|
94
|
+
TOKEN_ID = "<whitespace>"
|
|
155
95
|
end
|
|
156
96
|
|
|
157
97
|
class LinebreakToken < WhitespaceToken
|
|
158
|
-
|
|
98
|
+
TOKEN_ID = "<linebreak>"
|
|
159
99
|
|
|
160
|
-
def
|
|
161
|
-
|
|
162
|
-
@id = '<linebreak>'
|
|
100
|
+
def inspect
|
|
101
|
+
"#{self.class.name.split('::').last}(#{value.inspect})"
|
|
163
102
|
end
|
|
103
|
+
alias to_s inspect
|
|
164
104
|
end
|
|
165
105
|
|
|
166
106
|
class InlineWhitespaceToken < WhitespaceToken
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def initialize(value, line_number)
|
|
170
|
-
super
|
|
171
|
-
@id = '<inline whitespace>'
|
|
172
|
-
end
|
|
107
|
+
TOKEN_ID = "<inline whitespace>"
|
|
173
108
|
end
|
|
174
109
|
|
|
175
110
|
class CommentToken < TriviaToken
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def initialize(value, line_number)
|
|
179
|
-
super
|
|
180
|
-
@id = '<comment>'
|
|
181
|
-
end
|
|
111
|
+
TOKEN_ID = "<comment>"
|
|
182
112
|
end
|
|
183
113
|
|
|
184
114
|
class ExpressionBlockToken < ContentToken
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def initialize(value, line_number)
|
|
188
|
-
super
|
|
189
|
-
@id = '<expression block>'
|
|
190
|
-
end
|
|
115
|
+
TOKEN_ID = "<expression block>"
|
|
191
116
|
end
|
|
192
117
|
|
|
193
118
|
class LiteralToken < ContentToken
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def initialize(value, line_number)
|
|
197
|
-
super
|
|
198
|
-
@id = '<literal>'
|
|
199
|
-
end
|
|
119
|
+
TOKEN_ID = "<literal>"
|
|
200
120
|
end
|
|
201
121
|
|
|
202
122
|
class QuotedLiteralToken < ContentToken
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
def initialize(value, line_number)
|
|
206
|
-
super
|
|
207
|
-
@id = '<quoted literal>'
|
|
208
|
-
end
|
|
123
|
+
TOKEN_ID = "<quoted literal>"
|
|
209
124
|
end
|
|
210
125
|
end
|
|
211
126
|
end
|