textbringer-tree-sitter 1.2.0 → 1.2.2
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/CLAUDE.md +8 -0
- data/lib/textbringer/tree_sitter/node_maps/ruby.rb +4 -79
- data/lib/textbringer/tree_sitter/node_maps/sql.rb +14 -21
- data/lib/textbringer/tree_sitter/version.rb +1 -1
- data/lib/textbringer/tree_sitter_adapter.rb +7 -5
- data/samples/Sample.java +289 -0
- data/samples/sample.c +176 -0
- data/samples/sample.cob +174 -0
- data/samples/sample.cr +321 -0
- data/samples/sample.cs +273 -0
- data/samples/sample.ex +307 -0
- data/samples/sample.groovy +258 -0
- data/samples/sample.haml +154 -0
- data/samples/sample.html +168 -0
- data/samples/sample.js +266 -0
- data/samples/sample.json +68 -0
- data/samples/sample.pas +276 -0
- data/samples/sample.php +303 -0
- data/samples/sample.py +290 -0
- data/samples/sample.rb +160 -0
- data/samples/sample.rs +391 -0
- data/samples/sample.sh +142 -0
- data/samples/sample.sql +352 -0
- data/samples/sample.swift +482 -0
- data/samples/sample.tf +150 -0
- data/samples/sample.yaml +182 -0
- metadata +22 -1
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
// Line comment
|
|
2
|
+
/* Block comment */
|
|
3
|
+
/// Doc comment
|
|
4
|
+
/**
|
|
5
|
+
* Multi-line
|
|
6
|
+
* doc comment
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
import SwiftUI
|
|
11
|
+
|
|
12
|
+
// --- Constants & Variables ---
|
|
13
|
+
let pi = 3.14159
|
|
14
|
+
let maxSize = 100
|
|
15
|
+
var counter = 0
|
|
16
|
+
|
|
17
|
+
// --- Enums ---
|
|
18
|
+
enum Color: String, CaseIterable {
|
|
19
|
+
case red = "Red"
|
|
20
|
+
case green = "Green"
|
|
21
|
+
case blue = "Blue"
|
|
22
|
+
|
|
23
|
+
var display: String {
|
|
24
|
+
return rawValue.lowercased()
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
enum Shape {
|
|
29
|
+
case circle(radius: Double)
|
|
30
|
+
case rectangle(width: Double, height: Double)
|
|
31
|
+
indirect case compound(Shape, Shape)
|
|
32
|
+
|
|
33
|
+
var area: Double {
|
|
34
|
+
switch self {
|
|
35
|
+
case .circle(let radius):
|
|
36
|
+
return Double.pi * radius * radius
|
|
37
|
+
case .rectangle(let width, let height):
|
|
38
|
+
return width * height
|
|
39
|
+
case .compound(let a, let b):
|
|
40
|
+
return a.area + b.area
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// --- Protocols ---
|
|
46
|
+
protocol Greeter {
|
|
47
|
+
func greet(name: String) -> String
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
protocol Drawable {
|
|
51
|
+
func draw()
|
|
52
|
+
var description: String { get }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
extension Drawable {
|
|
56
|
+
func draw() {
|
|
57
|
+
print("Drawing \(description)")
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// --- Structs ---
|
|
62
|
+
struct Point: CustomStringConvertible {
|
|
63
|
+
var x: Double
|
|
64
|
+
var y: Double
|
|
65
|
+
|
|
66
|
+
var description: String {
|
|
67
|
+
return "(\(x), \(y))"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func distance(to other: Point) -> Double {
|
|
71
|
+
return sqrt(pow(x - other.x, 2) + pow(y - other.y, 2))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
mutating func translate(dx: Double, dy: Double) {
|
|
75
|
+
x += dx
|
|
76
|
+
y += dy
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// --- Classes ---
|
|
81
|
+
class Animal: CustomStringConvertible {
|
|
82
|
+
let name: String
|
|
83
|
+
var age: Int
|
|
84
|
+
|
|
85
|
+
init(name: String, age: Int = 0) {
|
|
86
|
+
self.name = name
|
|
87
|
+
self.age = age
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
func speak() -> String {
|
|
91
|
+
fatalError("Must override")
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var description: String {
|
|
95
|
+
return "\(name): \(speak())"
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
deinit {
|
|
99
|
+
print("\(name) deallocated")
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
class Dog: Animal, Greeter {
|
|
104
|
+
private(set) var breed: String
|
|
105
|
+
|
|
106
|
+
init(name: String, age: Int, breed: String = "Mixed") {
|
|
107
|
+
self.breed = breed
|
|
108
|
+
super.init(name: name, age: age)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
override func speak() -> String {
|
|
112
|
+
return "Woof!"
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
func greet(name: String) -> String {
|
|
116
|
+
return "Woof! Hello, \(name)!"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// --- Generics ---
|
|
121
|
+
class Container<T> {
|
|
122
|
+
private var items: [T] = []
|
|
123
|
+
|
|
124
|
+
func add(_ item: T) {
|
|
125
|
+
items.append(item)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
func get(_ index: Int) -> T? {
|
|
129
|
+
guard index < items.count else { return nil }
|
|
130
|
+
return items[index]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
var count: Int {
|
|
134
|
+
return items.count
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
func largest<T: Comparable>(_ array: [T]) -> T? {
|
|
139
|
+
guard var result = array.first else { return nil }
|
|
140
|
+
for item in array {
|
|
141
|
+
if item > result {
|
|
142
|
+
result = item
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return result
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// --- Extensions ---
|
|
149
|
+
extension Int {
|
|
150
|
+
var squared: Int {
|
|
151
|
+
return self * self
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
func times(_ closure: () -> Void) {
|
|
155
|
+
for _ in 0..<self {
|
|
156
|
+
closure()
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
extension String {
|
|
162
|
+
subscript(index: Int) -> Character {
|
|
163
|
+
return self[self.index(self.startIndex, offsetBy: index)]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// --- Typealias ---
|
|
168
|
+
typealias StringArray = [String]
|
|
169
|
+
typealias Handler = (String) -> Void
|
|
170
|
+
|
|
171
|
+
// --- Functions ---
|
|
172
|
+
func add(_ a: Int, _ b: Int) -> Int {
|
|
173
|
+
return a + b
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
func greet(name: String, greeting: String = "Hello") -> String {
|
|
177
|
+
return "\(greeting), \(name)!"
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
func divide(_ a: Double, by b: Double) throws -> Double {
|
|
181
|
+
guard b != 0 else {
|
|
182
|
+
throw NSError(domain: "Math", code: 1, userInfo: [NSLocalizedDescriptionKey: "Division by zero"])
|
|
183
|
+
}
|
|
184
|
+
return a / b
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Variadic
|
|
188
|
+
func sum(_ numbers: Int...) -> Int {
|
|
189
|
+
return numbers.reduce(0, +)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Inout
|
|
193
|
+
func swap(_ a: inout Int, _ b: inout Int) {
|
|
194
|
+
let temp = a
|
|
195
|
+
a = b
|
|
196
|
+
b = temp
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// --- Async/Await ---
|
|
200
|
+
func fetchData(from url: String) async throws -> String {
|
|
201
|
+
try await Task.sleep(nanoseconds: 1_000_000)
|
|
202
|
+
return "Data from \(url)"
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// --- Main ---
|
|
206
|
+
func main() {
|
|
207
|
+
// --- Strings ---
|
|
208
|
+
let simple = "Hello, World!"
|
|
209
|
+
let interpolated = "Sum: \(1 + 2)"
|
|
210
|
+
let multiline = """
|
|
211
|
+
This is a multi-line
|
|
212
|
+
string literal with
|
|
213
|
+
"quotes" inside
|
|
214
|
+
"""
|
|
215
|
+
let escaped = "tab\tnewline\nnull\0"
|
|
216
|
+
let raw = #"raw string \n no escape"#
|
|
217
|
+
let rawInterp = #"raw with \#(counter)"#
|
|
218
|
+
|
|
219
|
+
// --- Numbers ---
|
|
220
|
+
let integer = 42
|
|
221
|
+
let float: Float = 3.14
|
|
222
|
+
let double: Double = 2.71828
|
|
223
|
+
let hex = 0xFF
|
|
224
|
+
let octal = 0o77
|
|
225
|
+
let binary = 0b1010
|
|
226
|
+
let separator = 1_000_000
|
|
227
|
+
|
|
228
|
+
// --- Booleans & Nil ---
|
|
229
|
+
let yes: Bool = true
|
|
230
|
+
let no: Bool = false
|
|
231
|
+
var optional: String? = nil
|
|
232
|
+
let forced: String = optional ?? "default"
|
|
233
|
+
|
|
234
|
+
// --- Type annotations ---
|
|
235
|
+
let typed: Int = 42
|
|
236
|
+
let array: [Int] = [1, 2, 3]
|
|
237
|
+
let dict: [String: Int] = ["a": 1, "b": 2]
|
|
238
|
+
let tuple: (Int, String) = (1, "hello")
|
|
239
|
+
let closure: (Int) -> Int = { $0 * 2 }
|
|
240
|
+
|
|
241
|
+
// --- Control flow ---
|
|
242
|
+
if integer > 0 {
|
|
243
|
+
print("positive")
|
|
244
|
+
} else if integer < 0 {
|
|
245
|
+
print("negative")
|
|
246
|
+
} else {
|
|
247
|
+
print("zero")
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Guard
|
|
251
|
+
guard let value = optional else {
|
|
252
|
+
print("nil")
|
|
253
|
+
return
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Switch
|
|
257
|
+
switch integer {
|
|
258
|
+
case 0:
|
|
259
|
+
print("zero")
|
|
260
|
+
case 1...10:
|
|
261
|
+
print("small")
|
|
262
|
+
case let n where n > 100:
|
|
263
|
+
print("big: \(n)")
|
|
264
|
+
default:
|
|
265
|
+
print("other")
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Switch with enum
|
|
269
|
+
let shape = Shape.circle(radius: 5.0)
|
|
270
|
+
switch shape {
|
|
271
|
+
case .circle(let radius):
|
|
272
|
+
print("Circle: \(radius)")
|
|
273
|
+
case .rectangle(let w, let h):
|
|
274
|
+
print("Rect: \(w)x\(h)")
|
|
275
|
+
case .compound:
|
|
276
|
+
print("Compound")
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// --- Loops ---
|
|
280
|
+
for i in 0..<10 {
|
|
281
|
+
if i == 5 { break }
|
|
282
|
+
if i == 3 { continue }
|
|
283
|
+
print(i)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
for item in array {
|
|
287
|
+
print(item)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
for (key, value) in dict {
|
|
291
|
+
print("\(key): \(value)")
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
var j = 10
|
|
295
|
+
while j > 0 {
|
|
296
|
+
j -= 1
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
repeat {
|
|
300
|
+
j += 1
|
|
301
|
+
} while j < 5
|
|
302
|
+
|
|
303
|
+
// Labeled loop
|
|
304
|
+
outer: for i in 0..<3 {
|
|
305
|
+
for k in 0..<3 {
|
|
306
|
+
if k == 1 { continue outer }
|
|
307
|
+
if i == 2 { break outer }
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// --- Operators ---
|
|
312
|
+
let sum = 1 + 2
|
|
313
|
+
let diff = 5 - 3
|
|
314
|
+
let prod = 4 * 2
|
|
315
|
+
let quot = 10 / 3
|
|
316
|
+
let mod = 10 % 3
|
|
317
|
+
let neg = -sum
|
|
318
|
+
let logic = true && false || !true
|
|
319
|
+
let ternary = sum > 0 ? "yes" : "no"
|
|
320
|
+
let nilCoalesce = optional ?? "default"
|
|
321
|
+
|
|
322
|
+
// --- Optionals ---
|
|
323
|
+
var name: String? = "Alice"
|
|
324
|
+
let length = name?.count
|
|
325
|
+
let upper = name?.uppercased()
|
|
326
|
+
let unwrapped = name!
|
|
327
|
+
|
|
328
|
+
if let n = name {
|
|
329
|
+
print("Name: \(n)")
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Optional chaining
|
|
333
|
+
let firstChar = name?.first?.uppercased()
|
|
334
|
+
|
|
335
|
+
// --- Error handling ---
|
|
336
|
+
do {
|
|
337
|
+
let result = try divide(10, by: 3)
|
|
338
|
+
print("Result: \(result)")
|
|
339
|
+
} catch {
|
|
340
|
+
print("Error: \(error)")
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
let tryResult = try? divide(10, by: 0)
|
|
344
|
+
let forceResult = try! divide(10, by: 2)
|
|
345
|
+
|
|
346
|
+
// --- Closures ---
|
|
347
|
+
let double = { (x: Int) -> Int in
|
|
348
|
+
return x * 2
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
let shortClosure: (Int) -> Int = { $0 * 2 }
|
|
352
|
+
|
|
353
|
+
let numbers = [3, 1, 4, 1, 5, 9, 2, 6]
|
|
354
|
+
let sorted = numbers.sorted { $0 < $1 }
|
|
355
|
+
let doubled = numbers.map { $0 * 2 }
|
|
356
|
+
let evens = numbers.filter { $0 % 2 == 0 }
|
|
357
|
+
let total = numbers.reduce(0, +)
|
|
358
|
+
|
|
359
|
+
// Trailing closure
|
|
360
|
+
numbers.forEach { number in
|
|
361
|
+
print(number)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// --- Collections ---
|
|
365
|
+
var mutableArray = [1, 2, 3]
|
|
366
|
+
mutableArray.append(4)
|
|
367
|
+
mutableArray += [5, 6]
|
|
368
|
+
|
|
369
|
+
var mutableDict = ["a": 1, "b": 2]
|
|
370
|
+
mutableDict["c"] = 3
|
|
371
|
+
mutableDict.removeValue(forKey: "a")
|
|
372
|
+
|
|
373
|
+
var mutableSet: Set<Int> = [1, 2, 3]
|
|
374
|
+
mutableSet.insert(4)
|
|
375
|
+
mutableSet.remove(1)
|
|
376
|
+
|
|
377
|
+
// --- Defer ---
|
|
378
|
+
defer {
|
|
379
|
+
print("cleanup")
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// --- Object creation ---
|
|
383
|
+
let dog = Dog(name: "Rex", age: 5, breed: "Labrador")
|
|
384
|
+
print(dog.speak())
|
|
385
|
+
print(dog.greet(name: "World"))
|
|
386
|
+
|
|
387
|
+
// Type checking
|
|
388
|
+
if dog is Animal {
|
|
389
|
+
print("Is an animal")
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if let animal = dog as? Animal {
|
|
393
|
+
print("Cast: \(animal.name)")
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// --- Struct usage ---
|
|
397
|
+
var p1 = Point(x: 1.0, y: 2.0)
|
|
398
|
+
let p2 = Point(x: 4.0, y: 6.0)
|
|
399
|
+
print(p1.distance(to: p2))
|
|
400
|
+
p1.translate(dx: 1.0, dy: 1.0)
|
|
401
|
+
|
|
402
|
+
// --- Async ---
|
|
403
|
+
Task {
|
|
404
|
+
do {
|
|
405
|
+
let data = try await fetchData(from: "https://example.com")
|
|
406
|
+
print(data)
|
|
407
|
+
} catch {
|
|
408
|
+
print("Error: \(error)")
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// --- Self ---
|
|
413
|
+
print(type(of: dog))
|
|
414
|
+
|
|
415
|
+
// --- Subscript ---
|
|
416
|
+
let char = "Hello"[0]
|
|
417
|
+
print(char)
|
|
418
|
+
|
|
419
|
+
// --- Lazy ---
|
|
420
|
+
lazy var expensive = {
|
|
421
|
+
return "computed"
|
|
422
|
+
}()
|
|
423
|
+
|
|
424
|
+
// --- Property observers (in class context) ---
|
|
425
|
+
// willSet, didSet
|
|
426
|
+
|
|
427
|
+
// --- Associated types ---
|
|
428
|
+
// protocol Collection {
|
|
429
|
+
// associatedtype Element
|
|
430
|
+
// }
|
|
431
|
+
|
|
432
|
+
// --- Where clause ---
|
|
433
|
+
func process<T>(_ items: [T]) where T: Comparable, T: Hashable {
|
|
434
|
+
print(items.sorted())
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// --- Operator declaration ---
|
|
438
|
+
// prefix operator +++
|
|
439
|
+
// infix operator **: MultiplicationPrecedence
|
|
440
|
+
// precedencegroup MyPrecedence { ... }
|
|
441
|
+
|
|
442
|
+
print("Done!")
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// --- Computed property ---
|
|
446
|
+
struct Temperature {
|
|
447
|
+
var celsius: Double
|
|
448
|
+
|
|
449
|
+
var fahrenheit: Double {
|
|
450
|
+
get {
|
|
451
|
+
return celsius * 9.0 / 5.0 + 32.0
|
|
452
|
+
}
|
|
453
|
+
set {
|
|
454
|
+
celsius = (newValue - 32.0) * 5.0 / 9.0
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
static let boiling = Temperature(celsius: 100.0)
|
|
459
|
+
static let freezing = Temperature(celsius: 0.0)
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// --- Final class ---
|
|
463
|
+
final class Singleton {
|
|
464
|
+
static let shared = Singleton()
|
|
465
|
+
private init() {}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// --- Property wrapper (SwiftUI style) ---
|
|
469
|
+
@propertyWrapper
|
|
470
|
+
struct Clamped {
|
|
471
|
+
var wrappedValue: Int {
|
|
472
|
+
didSet {
|
|
473
|
+
wrappedValue = min(max(wrappedValue, range.lowerBound), range.upperBound)
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
let range: ClosedRange<Int>
|
|
477
|
+
|
|
478
|
+
init(wrappedValue: Int, _ range: ClosedRange<Int>) {
|
|
479
|
+
self.range = range
|
|
480
|
+
self.wrappedValue = min(max(wrappedValue, range.lowerBound), range.upperBound)
|
|
481
|
+
}
|
|
482
|
+
}
|
data/samples/sample.tf
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Single line comment
|
|
2
|
+
|
|
3
|
+
// Alternative comment style
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
Multi-line
|
|
7
|
+
comment block
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
# --- Variables ---
|
|
11
|
+
variable "instance_type" {
|
|
12
|
+
description = "EC2 instance type"
|
|
13
|
+
type = string
|
|
14
|
+
default = "t3.micro"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
variable "instance_count" {
|
|
18
|
+
description = "Number of instances"
|
|
19
|
+
type = number
|
|
20
|
+
default = 2
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
variable "enable_monitoring" {
|
|
24
|
+
type = bool
|
|
25
|
+
default = true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
variable "tags" {
|
|
29
|
+
type = map(string)
|
|
30
|
+
default = {
|
|
31
|
+
Environment = "development"
|
|
32
|
+
Project = "sample"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
variable "availability_zones" {
|
|
37
|
+
type = list(string)
|
|
38
|
+
default = ["us-east-1a", "us-east-1b"]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# --- Locals ---
|
|
42
|
+
locals {
|
|
43
|
+
common_tags = {
|
|
44
|
+
ManagedBy = "terraform"
|
|
45
|
+
Project = var.tags["Project"]
|
|
46
|
+
}
|
|
47
|
+
name_prefix = "sample-${var.tags["Environment"]}"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# --- Data source ---
|
|
51
|
+
data "aws_ami" "amazon_linux" {
|
|
52
|
+
most_recent = true
|
|
53
|
+
owners = ["amazon"]
|
|
54
|
+
|
|
55
|
+
filter {
|
|
56
|
+
name = "name"
|
|
57
|
+
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# --- Resources ---
|
|
62
|
+
resource "aws_instance" "web" {
|
|
63
|
+
count = var.instance_count
|
|
64
|
+
ami = data.aws_ami.amazon_linux.id
|
|
65
|
+
instance_type = var.instance_type
|
|
66
|
+
|
|
67
|
+
tags = merge(local.common_tags, {
|
|
68
|
+
Name = "${local.name_prefix}-web-${count.index}"
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
monitoring = var.enable_monitoring
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
resource "aws_security_group" "web" {
|
|
75
|
+
name = "${local.name_prefix}-sg"
|
|
76
|
+
description = "Security group for web servers"
|
|
77
|
+
|
|
78
|
+
# Dynamic block with for_each
|
|
79
|
+
dynamic "ingress" {
|
|
80
|
+
for_each = [80, 443]
|
|
81
|
+
content {
|
|
82
|
+
from_port = ingress.value
|
|
83
|
+
to_port = ingress.value
|
|
84
|
+
protocol = "tcp"
|
|
85
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
egress {
|
|
90
|
+
from_port = 0
|
|
91
|
+
to_port = 0
|
|
92
|
+
protocol = "-1"
|
|
93
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# --- For expressions ---
|
|
98
|
+
locals {
|
|
99
|
+
instance_ids = [for instance in aws_instance.web : instance.id]
|
|
100
|
+
|
|
101
|
+
instance_map = {
|
|
102
|
+
for instance in aws_instance.web :
|
|
103
|
+
instance.tags["Name"] => instance.id
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
filtered = [for id in local.instance_ids : id if id != ""]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# --- Conditional ---
|
|
110
|
+
resource "aws_eip" "web" {
|
|
111
|
+
count = var.enable_monitoring ? var.instance_count : 0
|
|
112
|
+
instance = aws_instance.web[count.index].id
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# --- Functions ---
|
|
116
|
+
locals {
|
|
117
|
+
upper_name = upper(local.name_prefix)
|
|
118
|
+
joined = join(",", var.availability_zones)
|
|
119
|
+
encoded = base64encode("Hello, World!")
|
|
120
|
+
timestamp = formatdate("YYYY-MM-DD", timestamp())
|
|
121
|
+
file_content = file("${path.module}/sample.tf")
|
|
122
|
+
length = length(var.availability_zones)
|
|
123
|
+
lookup_val = lookup(var.tags, "Environment", "unknown")
|
|
124
|
+
coalesce_val = coalesce(null, "", "default")
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# --- Outputs ---
|
|
128
|
+
output "instance_ids" {
|
|
129
|
+
description = "IDs of created instances"
|
|
130
|
+
value = aws_instance.web[*].id
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
output "public_ips" {
|
|
134
|
+
description = "Public IPs"
|
|
135
|
+
value = [for instance in aws_instance.web : instance.public_ip]
|
|
136
|
+
sensitive = false
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# --- Numbers ---
|
|
140
|
+
locals {
|
|
141
|
+
integer_val = 42
|
|
142
|
+
float_val = 3.14
|
|
143
|
+
negative = -17
|
|
144
|
+
scientific = 1e10
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# --- Null ---
|
|
148
|
+
locals {
|
|
149
|
+
nothing = null
|
|
150
|
+
}
|