@nestia/core 12.0.0-dev.20260601.1 → 12.0.0-dev.20260612.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.
Files changed (116) hide show
  1. package/LICENSE +21 -21
  2. package/MIGRATION.md +169 -169
  3. package/README.md +93 -93
  4. package/lib/adaptors/McpAdaptor.d.ts +75 -0
  5. package/lib/adaptors/McpAdaptor.js +257 -0
  6. package/lib/adaptors/McpAdaptor.js.map +1 -0
  7. package/lib/adaptors/WebSocketAdaptor.js +4 -4
  8. package/lib/adaptors/WebSocketAdaptor.js.map +1 -1
  9. package/lib/decorators/McpRoute.d.ts +69 -0
  10. package/lib/decorators/McpRoute.js +58 -0
  11. package/lib/decorators/McpRoute.js.map +1 -0
  12. package/lib/decorators/TypedParam.js +4 -4
  13. package/lib/decorators/TypedParam.js.map +1 -1
  14. package/lib/decorators/TypedRoute.js +1 -1
  15. package/lib/decorators/TypedRoute.js.map +1 -1
  16. package/lib/decorators/internal/IMcpRouteReflect.d.ts +2 -0
  17. package/lib/decorators/internal/IMcpRouteReflect.js +3 -0
  18. package/lib/decorators/internal/IMcpRouteReflect.js.map +1 -0
  19. package/lib/decorators/internal/get_path_and_querify.js +4 -4
  20. package/lib/decorators/internal/get_path_and_querify.js.map +1 -1
  21. package/lib/decorators/internal/get_path_and_stringify.js +4 -4
  22. package/lib/decorators/internal/get_path_and_stringify.js.map +1 -1
  23. package/lib/decorators/internal/load_controller.js +34 -65
  24. package/lib/decorators/internal/load_controller.js.map +1 -1
  25. package/lib/decorators/internal/validate_request_body.js +4 -4
  26. package/lib/decorators/internal/validate_request_body.js.map +1 -1
  27. package/lib/decorators/internal/validate_request_form_data.js +4 -4
  28. package/lib/decorators/internal/validate_request_form_data.js.map +1 -1
  29. package/lib/decorators/internal/validate_request_headers.js +4 -4
  30. package/lib/decorators/internal/validate_request_headers.js.map +1 -1
  31. package/lib/decorators/internal/validate_request_query.js +4 -4
  32. package/lib/decorators/internal/validate_request_query.js.map +1 -1
  33. package/lib/module.d.ts +2 -0
  34. package/lib/module.js +2 -0
  35. package/lib/module.js.map +1 -1
  36. package/native/cmd/ttsc-nestia/main.go +11 -11
  37. package/native/go.mod +32 -32
  38. package/native/go.sum +54 -54
  39. package/native/plugin/plan.go +102 -102
  40. package/native/transform/ast.go +32 -32
  41. package/native/transform/build.go +380 -444
  42. package/native/transform/cleanup.go +408 -408
  43. package/native/transform/contributor.go +97 -68
  44. package/native/transform/core_querify.go +231 -227
  45. package/native/transform/core_transform.go +1996 -1713
  46. package/native/transform/core_websocket.go +115 -115
  47. package/native/transform/exports.go +13 -13
  48. package/native/transform/mcp_transform.go +414 -0
  49. package/native/transform/node_transform.go +357 -0
  50. package/native/transform/path_rewrite.go +285 -285
  51. package/native/transform/printer.go +244 -244
  52. package/native/transform/rewrite.go +668 -662
  53. package/native/transform/run.go +73 -73
  54. package/native/transform/transform.go +336 -403
  55. package/native/transform/typia_fast.go +352 -326
  56. package/native/transform/typia_replacement.go +24 -24
  57. package/native/transform.cjs +43 -43
  58. package/package.json +15 -8
  59. package/src/adaptors/McpAdaptor.ts +276 -0
  60. package/src/adaptors/WebSocketAdaptor.ts +429 -429
  61. package/src/decorators/DynamicModule.ts +44 -44
  62. package/src/decorators/EncryptedBody.ts +97 -97
  63. package/src/decorators/EncryptedController.ts +40 -40
  64. package/src/decorators/EncryptedModule.ts +98 -98
  65. package/src/decorators/EncryptedRoute.ts +213 -213
  66. package/src/decorators/HumanRoute.ts +21 -21
  67. package/src/decorators/McpRoute.ts +154 -0
  68. package/src/decorators/NoTransformConfigurationError.ts +40 -40
  69. package/src/decorators/PlainBody.ts +76 -76
  70. package/src/decorators/SwaggerCustomizer.ts +97 -97
  71. package/src/decorators/SwaggerExample.ts +180 -180
  72. package/src/decorators/TypedBody.ts +57 -57
  73. package/src/decorators/TypedException.ts +147 -147
  74. package/src/decorators/TypedFormData.ts +187 -187
  75. package/src/decorators/TypedHeaders.ts +66 -66
  76. package/src/decorators/TypedParam.ts +77 -77
  77. package/src/decorators/TypedQuery.ts +234 -234
  78. package/src/decorators/TypedRoute.ts +198 -196
  79. package/src/decorators/WebSocketRoute.ts +242 -242
  80. package/src/decorators/doNotThrowTransformError.ts +5 -5
  81. package/src/decorators/internal/EncryptedConstant.ts +2 -2
  82. package/src/decorators/internal/IMcpRouteReflect.ts +40 -0
  83. package/src/decorators/internal/IWebSocketRouteReflect.ts +23 -23
  84. package/src/decorators/internal/get_path_and_querify.ts +94 -94
  85. package/src/decorators/internal/get_path_and_stringify.ts +110 -110
  86. package/src/decorators/internal/get_text_body.ts +16 -16
  87. package/src/decorators/internal/headers_to_object.ts +11 -11
  88. package/src/decorators/internal/is_request_body_undefined.ts +12 -12
  89. package/src/decorators/internal/load_controller.ts +91 -76
  90. package/src/decorators/internal/route_error.ts +43 -43
  91. package/src/decorators/internal/validate_request_body.ts +64 -64
  92. package/src/decorators/internal/validate_request_form_data.ts +67 -67
  93. package/src/decorators/internal/validate_request_headers.ts +76 -76
  94. package/src/decorators/internal/validate_request_query.ts +83 -83
  95. package/src/index.ts +5 -5
  96. package/src/module.ts +25 -23
  97. package/src/options/IRequestBodyValidator.ts +20 -20
  98. package/src/options/IRequestFormDataProps.ts +27 -27
  99. package/src/options/IRequestHeadersValidator.ts +22 -22
  100. package/src/options/IRequestQueryValidator.ts +20 -20
  101. package/src/options/IResponseBodyQuerifier.ts +25 -25
  102. package/src/options/IResponseBodyStringifier.ts +30 -30
  103. package/src/transform.ts +101 -101
  104. package/src/typings/Creator.ts +3 -3
  105. package/src/typings/get-function-location.d.ts +7 -7
  106. package/src/utils/ArrayUtil.ts +7 -7
  107. package/src/utils/ExceptionManager.ts +115 -115
  108. package/src/utils/Singleton.ts +16 -16
  109. package/src/utils/SourceFinder.ts +54 -54
  110. package/src/utils/VersioningStrategy.ts +27 -27
  111. package/native/transform/cleanup_test.go +0 -76
  112. package/native/transform/commonjs_import_alias_test.go +0 -49
  113. package/native/transform/core_dispatch_test.go +0 -127
  114. package/native/transform/path_rewrite_test.go +0 -243
  115. package/native/transform/rewrite_test.go +0 -118
  116. package/native/transform/rewrite_unique_base_test.go +0 -48
@@ -0,0 +1,357 @@
1
+ package transform
2
+
3
+ import (
4
+ shimast "github.com/microsoft/typescript-go/shim/ast"
5
+ shimprinter "github.com/microsoft/typescript-go/shim/printer"
6
+ "github.com/samchon/nestia/packages/core/native/plugin"
7
+ "github.com/samchon/ttsc/packages/ttsc/driver"
8
+ nativecontext "github.com/samchon/typia/packages/typia/native/core/context"
9
+ )
10
+
11
+ // nestiaCoreNodeTransform builds the @nestia/core AST-integration transformer for
12
+ // one emit run. It mirrors typia's transform.Transform / FileTransformer: per
13
+ // source file it allocates a shared ec-mode ImportProgrammer, rebuilds every
14
+ // nestia-core decorator call with its generated validator argument nodes (whose
15
+ // runtime references resolve to namespace imports tsgo's module-transform
16
+ // aliases), injects those imports, and normalizes the synthetic operator tokens
17
+ // typia's programmers leave nil. A diagnostic is appended for any site whose
18
+ // generation raises a (recovered) transform error, matching the legacy text
19
+ // path's swallow-and-report behavior.
20
+ //
21
+ // addDiagnostic receives one entry per failed site; the build command turns a
22
+ // non-empty diagnostic slice into a non-zero exit.
23
+ func nestiaCoreNodeTransform(
24
+ prog *driver.Program,
25
+ plan plugin.Plan,
26
+ addDiagnostic func(Diagnostic),
27
+ ) driver.PluginTransform {
28
+ if plan.Core == false {
29
+ return func(_ *shimprinter.EmitContext, sf *shimast.SourceFile) *shimast.SourceFile {
30
+ return sf
31
+ }
32
+ }
33
+ options := readNestiaCoreOptions(plan)
34
+ strictReported := false
35
+ return func(ec *shimprinter.EmitContext, sf *shimast.SourceFile) *shimast.SourceFile {
36
+ if sf == nil || sf.IsDeclarationFile {
37
+ return sf
38
+ }
39
+ if nestiaCoreStrictMode(prog) == false && strictReported == false {
40
+ strictReported = true
41
+ addDiagnostic(nestiaCoreGlobalDiagnostic("@nestia/core", "strict mode is required."))
42
+ }
43
+ importer := nativecontext.NewImportProgrammer(nativecontext.ImportProgrammer_IOptions{
44
+ InternalPrefix: "typia_transform_",
45
+ Runtime: "typia",
46
+ })
47
+ importer.SetEmitContext(ec)
48
+ state := newNestiaCoreTransformState(prog, options)
49
+ state.importer = importer
50
+ state.ec = ec
51
+
52
+ replacements := map[*shimast.Node]*shimast.CallExpression{}
53
+ context := newNestiaCoreFileContext(sf)
54
+ sf.ForEachChild(func(node *shimast.Node) bool {
55
+ nestiaCoreCollectNodeReplacements(state, context, node, replacements, addDiagnostic)
56
+ return false
57
+ })
58
+ if len(replacements) == 0 {
59
+ // Nothing rewritten: no imports were injected, so leave the file as-is
60
+ // (the shared typia transform pass handles any typia call sites).
61
+ return sf
62
+ }
63
+
64
+ // Traverse with the emit EmitContext, not a standalone factory: every
65
+ // ancestor node the visitor recreates to hold a rebuilt decorator call
66
+ // gets an `original` link back to its parse-tree node, so tsgo's emit
67
+ // resolver can recover the binder symbol when it marks linked references.
68
+ // A plain factory drops that link, so tsgo's MarkLinkedReferences pass
69
+ // nil-panics (and exported namespaces silently vanish). Mirrors typia's
70
+ // FileTransformer emit-context traversal.
71
+ var visitor *shimast.NodeVisitor
72
+ visitor = ec.NewNodeVisitor(func(node *shimast.Node) *shimast.Node {
73
+ if node == nil {
74
+ return nil
75
+ }
76
+ if node.Kind == shimast.KindCallExpression {
77
+ if updated, ok := replacements[node]; ok {
78
+ // Link the rebuilt decorator call back to its parse-tree node and
79
+ // keep visiting it through the emit EmitContext (like typia's
80
+ // FileTransformer returns visitor.VisitEachChild(next)). Visiting
81
+ // the substituted subtree is what wires the injected validator
82
+ // nodes' parents and original links, so tsgo's emit resolver can
83
+ // recover their binder symbols when it marks linked references —
84
+ // returning the node raw leaves that subtree untracked and the
85
+ // resolver nil-panics.
86
+ ec.SetOriginal(updated.AsNode(), node)
87
+ return visitor.VisitEachChild(updated.AsNode())
88
+ }
89
+ }
90
+ return visitor.VisitEachChild(node)
91
+ })
92
+ visited := visitor.VisitNode(sf.AsNode())
93
+ if visited == nil {
94
+ return sf
95
+ }
96
+ result := visited.AsSourceFile()
97
+ result = nestiaCoreInjectImports(result, importer.ToStatements(), ec)
98
+ // The node path prints through tsgo's printer, which dereferences the
99
+ // conditional ?/: operator tokens typia's programmers leave nil; the
100
+ // legacy text path filled them via normalizeNestiaSyntheticTokens before
101
+ // printing, so do the same here.
102
+ normalizeNestiaSyntheticTokens(result.AsNode())
103
+ return result
104
+ }
105
+ }
106
+
107
+ // nestiaCoreCollectNodeReplacements walks a node looking for nestia-core
108
+ // parameter / method decorator calls. For each, it generates the appended
109
+ // validator argument nodes via the shared ec-importer and records a rebuilt
110
+ // CallExpression keyed by the original decorator call node, for the visitor to
111
+ // substitute.
112
+ func nestiaCoreCollectNodeReplacements(
113
+ state *nestiaCoreTransformState,
114
+ context nestiaCoreFileContext,
115
+ node *shimast.Node,
116
+ replacements map[*shimast.Node]*shimast.CallExpression,
117
+ addDiagnostic func(Diagnostic),
118
+ ) {
119
+ if node == nil {
120
+ return
121
+ }
122
+ switch node.Kind {
123
+ case shimast.KindParameter:
124
+ nestiaCoreCollectParameterReplacements(state, context, node, replacements, addDiagnostic)
125
+ case shimast.KindMethodDeclaration:
126
+ nestiaCoreCollectMethodReplacements(state, context, node, replacements, addDiagnostic)
127
+ }
128
+ node.ForEachChild(func(child *shimast.Node) bool {
129
+ nestiaCoreCollectNodeReplacements(state, context, child, replacements, addDiagnostic)
130
+ return false
131
+ })
132
+ }
133
+
134
+ func nestiaCoreCollectParameterReplacements(
135
+ state *nestiaCoreTransformState,
136
+ context nestiaCoreFileContext,
137
+ node *shimast.Node,
138
+ replacements map[*shimast.Node]*shimast.CallExpression,
139
+ addDiagnostic func(Diagnostic),
140
+ ) {
141
+ decorators := node.Decorators()
142
+ if len(decorators) == 0 {
143
+ return
144
+ }
145
+ type candidate struct {
146
+ call *shimast.CallExpression
147
+ segments []string
148
+ kind string
149
+ }
150
+ candidates := []candidate{}
151
+ for _, decorator := range decorators {
152
+ call, segments, ok := nestiaCoreRawDecoratorCall(decorator)
153
+ if !ok {
154
+ continue
155
+ }
156
+ canonical := nestiaCoreCanonicalSegments(context, segments)
157
+ kind := nestiaCoreParameterKind(canonical)
158
+ if kind == "" || nestiaCoreDecoratorReference(state.prog, context, decorator, segments, canonical) == false {
159
+ continue
160
+ }
161
+ candidates = append(candidates, candidate{call: call, segments: segments, kind: kind})
162
+ }
163
+ if len(candidates) == 0 {
164
+ return
165
+ }
166
+ typ := state.prog.Checker.GetTypeAtLocation(nestiaCoreOriginalNode(state.ec, node))
167
+ for _, candidate := range candidates {
168
+ // Hand typia the real callee node (e.g. `core.TypedBody`) as the modulo,
169
+ // mirroring typia's own transformer (props.Expression.Expression). typia's
170
+ // programmers read its source-span text via GetTextOfNode for the error
171
+ // method label; a synthesized identifier has no source span and nil-panics,
172
+ // so map back to the parse-tree callee when typia rebuilt this decorator.
173
+ modulo := nestiaCoreOriginalNode(state.ec, candidate.call.Expression)
174
+ nodes, ok, err := nestiaCoreParameterArgumentNodes(state.prog, state.importer, state.ec, state.options, candidate.call, modulo, candidate.kind, typ)
175
+ if err != nil {
176
+ addDiagnostic(nestiaCoreDiagnostic(nestiaCoreSiteFor(context.file, candidate.call, candidate.kind, candidate.segments), err.Error()))
177
+ continue
178
+ }
179
+ if !ok {
180
+ continue
181
+ }
182
+ replacements[candidate.call.AsNode()] = nestiaCoreAppendArgumentNodes(candidate.call, nodes, state.ec)
183
+ }
184
+ }
185
+
186
+ func nestiaCoreCollectMethodReplacements(
187
+ state *nestiaCoreTransformState,
188
+ context nestiaCoreFileContext,
189
+ node *shimast.Node,
190
+ replacements map[*shimast.Node]*shimast.CallExpression,
191
+ addDiagnostic func(Diagnostic),
192
+ ) {
193
+ decorators := node.Decorators()
194
+ if len(decorators) == 0 {
195
+ return
196
+ }
197
+ type candidate struct {
198
+ call *shimast.CallExpression
199
+ segments []string
200
+ kind string
201
+ }
202
+ candidates := []candidate{}
203
+ for _, decorator := range decorators {
204
+ call, segments, ok := nestiaCoreRawDecoratorCall(decorator)
205
+ if !ok {
206
+ continue
207
+ }
208
+ canonical := nestiaCoreCanonicalSegments(context, segments)
209
+ if nestiaCoreDecoratorReference(state.prog, context, decorator, segments, canonical) == false {
210
+ continue
211
+ }
212
+ // @WebSocketRoute carries no injected validator (it is not a method kind),
213
+ // but its acceptor/driver parameter shapes are validated here, mirroring the
214
+ // legacy visitNestiaCoreNode path. Validate against the parse-tree method so
215
+ // parameter type text resolves even when typia rebuilt this method.
216
+ if len(canonical) != 0 && canonical[len(canonical)-1] == "WebSocketRoute" {
217
+ for _, diag := range validateNestiaCoreWebSocketRoute(state.prog, context, nestiaCoreOriginalNode(state.ec, node), call, canonical) {
218
+ addDiagnostic(diag)
219
+ }
220
+ }
221
+ kind := nestiaCoreMethodKind(canonical)
222
+ if kind == "" {
223
+ continue
224
+ }
225
+ if kind == "McpRoute" {
226
+ if nestiaCoreMcpRouteAlreadyTransformed(call) {
227
+ continue
228
+ }
229
+ } else if nestiaCoreShouldSkipMethodDecorator(state.prog, call) {
230
+ continue
231
+ }
232
+ candidates = append(candidates, candidate{call: call, segments: segments, kind: kind})
233
+ }
234
+ if len(candidates) == 0 {
235
+ return
236
+ }
237
+ typ := NestiaCoreMethodReturnType(state.prog, nestiaCoreOriginalNode(state.ec, node))
238
+ if typ == nil {
239
+ return
240
+ }
241
+ for _, candidate := range candidates {
242
+ if candidate.kind == "McpRoute" {
243
+ generated, err := nestiaCoreMcpRouteArgumentNode(state.prog, state.importer, state.ec, state.options, context.file, nestiaCoreOriginalNode(state.ec, node), candidate.call, typ)
244
+ if err != nil {
245
+ addDiagnostic(nestiaCoreDiagnostic(nestiaCoreSiteFor(context.file, candidate.call, candidate.kind, candidate.segments), err.Error()))
246
+ continue
247
+ }
248
+ replacements[candidate.call.AsNode()] = nestiaCoreReplaceArgumentNodes(candidate.call, []*shimast.Node{generated}, state.ec)
249
+ continue
250
+ }
251
+ // Real callee node as modulo (see nestiaCoreCollectParameterReplacements).
252
+ modulo := nestiaCoreOriginalNode(state.ec, candidate.call.Expression)
253
+ generated, err := nestiaCoreMethodArgumentNode(state.prog, state.importer, state.ec, state.options, modulo, candidate.kind, typ)
254
+ if err != nil {
255
+ addDiagnostic(nestiaCoreDiagnostic(nestiaCoreSiteFor(context.file, candidate.call, candidate.kind, candidate.segments), err.Error()))
256
+ continue
257
+ }
258
+ replacements[candidate.call.AsNode()] = nestiaCoreAppendArgumentNodes(candidate.call, []*shimast.Node{generated}, state.ec)
259
+ }
260
+ }
261
+
262
+ // nestiaCoreOriginalNode returns the parse-tree node a (possibly synthetic) node
263
+ // was rebuilt from, so checker queries that need binder symbols or types resolve
264
+ // against the original. core runs after typia in the shared emit pass: when typia
265
+ // lowers a `typia.random<T>()` call that sits in a decorator argument or method
266
+ // body, it rebuilds the enclosing method (and its parameters) into synthetic
267
+ // nodes that carry no binder symbol. GetSignatureFromDeclaration /
268
+ // GetTypeAtLocation then nil-panic on them, and GetTextOfNode on a synthetic
269
+ // callee has no source span. ec.MostOriginal walks the original-link chain back
270
+ // to the parse node; it is a no-op for nodes core sees before typia touched them.
271
+ func nestiaCoreOriginalNode(ec *shimprinter.EmitContext, node *shimast.Node) *shimast.Node {
272
+ if ec == nil || node == nil {
273
+ return node
274
+ }
275
+ if original := ec.MostOriginal(node); original != nil {
276
+ return original
277
+ }
278
+ return node
279
+ }
280
+
281
+ // nestiaCoreReplaceArgumentNodes rebuilds a decorator call with the generated
282
+ // nodes replacing every original argument.
283
+ func nestiaCoreReplaceArgumentNodes(call *shimast.CallExpression, replacements []*shimast.Node, ec *shimprinter.EmitContext) *shimast.CallExpression {
284
+ f := nativecontext.EmitFactoryOf(nestiaCoreFactory, ec)
285
+ updated := f.NewCallExpression(
286
+ call.Expression,
287
+ call.QuestionDotToken,
288
+ call.TypeArguments,
289
+ f.NewNodeList(replacements),
290
+ call.AsNode().Flags,
291
+ )
292
+ return updated.AsCallExpression()
293
+ }
294
+
295
+ // nestiaCoreAppendArgumentNodes rebuilds a decorator call with the generated
296
+ // validator nodes appended after its original arguments.
297
+ func nestiaCoreAppendArgumentNodes(call *shimast.CallExpression, appended []*shimast.Node, ec *shimprinter.EmitContext) *shimast.CallExpression {
298
+ f := nativecontext.EmitFactoryOf(nestiaCoreFactory, ec)
299
+ existing := []*shimast.Node{}
300
+ if call.Arguments != nil {
301
+ existing = append(existing, call.Arguments.Nodes...)
302
+ }
303
+ args := make([]*shimast.Node, 0, len(existing)+len(appended))
304
+ args = append(args, existing...)
305
+ args = append(args, appended...)
306
+ updated := f.NewCallExpression(
307
+ call.Expression,
308
+ call.QuestionDotToken,
309
+ call.TypeArguments,
310
+ f.NewNodeList(args),
311
+ call.AsNode().Flags,
312
+ )
313
+ return updated.AsCallExpression()
314
+ }
315
+
316
+ // nestiaCoreInjectImports prepends the importer's namespace-import statements
317
+ // after any leading "use ..." prologue, mirroring typia's
318
+ // fileTransformer_inject_imports.
319
+ func nestiaCoreInjectImports(file *shimast.SourceFile, imports []*shimast.Node, ec *shimprinter.EmitContext) *shimast.SourceFile {
320
+ if file == nil || len(imports) == 0 {
321
+ return file
322
+ }
323
+ f := nativecontext.EmitFactoryOf(nestiaCoreFactory, ec)
324
+ index := 0
325
+ for ; index < len(file.Statements.Nodes); index++ {
326
+ stmt := file.Statements.Nodes[index]
327
+ if stmt == nil || stmt.Kind != shimast.KindExpressionStatement {
328
+ break
329
+ }
330
+ expression := stmt.AsExpressionStatement().Expression
331
+ if expression == nil || expression.Kind != shimast.KindStringLiteral {
332
+ break
333
+ }
334
+ if text := expression.AsStringLiteral().Text; len(text) < 4 || text[:4] != "use " {
335
+ break
336
+ }
337
+ }
338
+ nodes := make([]*shimast.Node, 0, len(file.Statements.Nodes)+len(imports))
339
+ nodes = append(nodes, file.Statements.Nodes[:index]...)
340
+ nodes = append(nodes, imports...)
341
+ nodes = append(nodes, file.Statements.Nodes[index:]...)
342
+ return f.UpdateSourceFile(
343
+ file,
344
+ f.NewNodeList(nodes),
345
+ file.EndOfFileToken,
346
+ ).AsSourceFile()
347
+ }
348
+
349
+ func nestiaCoreSiteFor(file *shimast.SourceFile, call *shimast.CallExpression, kind string, segments []string) nestiaCoreSite {
350
+ return nestiaCoreSite{
351
+ File: file,
352
+ FilePath: file.FileName(),
353
+ Call: call,
354
+ Kind: kind,
355
+ Segments: segments,
356
+ }
357
+ }