• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

unpackdev / solgo / 6533479902

16 Oct 2023 12:21PM UTC coverage: 82.617% (-0.5%) from 83.146%
6533479902

Pull #123

github

0x19
Bumping protoc
Pull Request #123: Grouped fixes No.1

407 of 606 new or added lines in 38 files covered. (67.16%)

19 existing lines in 4 files now uncovered.

14125 of 17097 relevant lines covered (82.62%)

0.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.14
/ast/function_call.go
1
package ast
2

3
import (
4
        "encoding/json"
5
        "fmt"
6
        "regexp"
7
        "strings"
8

9
        v3 "github.com/cncf/xds/go/xds/type/v3"
10
        ast_pb "github.com/unpackdev/protos/dist/go/ast"
11
        "github.com/unpackdev/solgo/parser"
12
)
13

14
// FunctionCall represents a function call node in the AST.
15
type FunctionCall struct {
16
        *ASTBuilder
17

18
        Id                    int64              `json:"id"`                               // Unique identifier for the node.
19
        NodeType              ast_pb.NodeType    `json:"node_type"`                        // Type of the node.
20
        Kind                  ast_pb.NodeType    `json:"kind"`                             // Kind of the node.
21
        Src                   SrcNode            `json:"src"`                              // Source location of the node.
22
        ArgumentTypes         []*TypeDescription `json:"argument_types"`                   // Types of the arguments.
23
        Arguments             []Node[NodeType]   `json:"arguments"`                        // Arguments of the function call.
24
        Expression            Node[NodeType]     `json:"expression"`                       // Expression of the function call.
25
        ReferencedDeclaration int64              `json:"referenced_declaration,omitempty"` // Referenced declaration of the function call.
26
        TypeDescription       *TypeDescription   `json:"type_description"`                 // Type description of the function call.
27
}
28

29
// NewFunctionCall creates a new FunctionCall node with a given ASTBuilder.
30
// It initializes the Arguments slice and sets the NodeType and Kind to FUNCTION_CALL.
31
func NewFunctionCall(b *ASTBuilder) *FunctionCall {
1✔
32
        return &FunctionCall{
1✔
33
                ASTBuilder:    b,
1✔
34
                Arguments:     make([]Node[NodeType], 0),
1✔
35
                ArgumentTypes: make([]*TypeDescription, 0),
1✔
36
                NodeType:      ast_pb.NodeType_FUNCTION_CALL,
1✔
37
                Kind:          ast_pb.NodeType_FUNCTION_CALL,
1✔
38
        }
1✔
39
}
1✔
40

41
// SetReferenceDescriptor sets the reference descriptions of the FunctionCall node.
42
func (f *FunctionCall) SetReferenceDescriptor(refId int64, refDesc *TypeDescription) bool {
1✔
43
        f.ReferencedDeclaration = refId
1✔
44
        f.TypeDescription = refDesc
1✔
45
        return false
1✔
46
}
1✔
47

48
// GetId returns the unique identifier of the FunctionCall node.
49
func (f *FunctionCall) GetId() int64 {
1✔
50
        return f.Id
1✔
51
}
1✔
52

53
// GetType returns the type of the FunctionCall node.
54
func (f *FunctionCall) GetType() ast_pb.NodeType {
1✔
55
        return f.NodeType
1✔
56
}
1✔
57

58
// GetSrc returns the source location of the FunctionCall node.
59
func (f *FunctionCall) GetSrc() SrcNode {
1✔
60
        return f.Src
1✔
61
}
1✔
62

63
// GetArguments returns the arguments of the FunctionCall node.
64
func (f *FunctionCall) GetArguments() []Node[NodeType] {
1✔
65
        return f.Arguments
1✔
66
}
1✔
67

68
// GetArgumentTypes returns the types of the arguments of the FunctionCall node.
69
func (f *FunctionCall) GetArgumentTypes() []*TypeDescription {
1✔
70
        return f.ArgumentTypes
1✔
71
}
1✔
72

73
// GetKind returns the kind of the FunctionCall node.
74
func (f *FunctionCall) GetKind() ast_pb.NodeType {
1✔
75
        return f.Kind
1✔
76
}
1✔
77

78
// GetExpression returns the expression of the FunctionCall node.
79
func (f *FunctionCall) GetExpression() Node[NodeType] {
1✔
80
        return f.Expression
1✔
81
}
1✔
82

83
// GetTypeDescription returns the type description of the FunctionCall node.
84
// Currently, it returns nil and needs to be implemented.
85
func (f *FunctionCall) GetTypeDescription() *TypeDescription {
1✔
86
        return f.TypeDescription
1✔
87
}
1✔
88

89
// GetNodes returns a slice of nodes that includes the expression of the FunctionCall node.
90
func (f *FunctionCall) GetNodes() []Node[NodeType] {
1✔
91
        toReturn := []Node[NodeType]{f.Expression}
1✔
92
        toReturn = append(toReturn, f.Arguments...)
1✔
93
        return toReturn
1✔
94
}
1✔
95

96
// GetReferenceDeclaration returns the referenced declaration of the FunctionCall node.
97
func (f *FunctionCall) GetReferenceDeclaration() int64 {
1✔
98
        return f.ReferencedDeclaration
1✔
99
}
1✔
100

101
// RebuildDescriptions rebuilds the type descriptions of the FunctionCall node. It is called after the AST is built.
102
func (f *FunctionCall) RebuildDescriptions() {
1✔
103
        var newArgs []*TypeDescription
1✔
104
        for _, arg := range f.GetArguments() {
2✔
105
                newArgs = append(newArgs, arg.GetTypeDescription())
1✔
106
        }
1✔
107
        f.ArgumentTypes = newArgs
1✔
108
        f.TypeDescription = f.buildTypeDescription()
1✔
109
}
110

111
// UnmarshalJSON unmarshals a given JSON byte array into a FunctionCall node.
112
func (f *FunctionCall) UnmarshalJSON(data []byte) error {
1✔
113
        var tempMap map[string]json.RawMessage
1✔
114
        if err := json.Unmarshal(data, &tempMap); err != nil {
1✔
115
                return err
×
116
        }
×
117

118
        if id, ok := tempMap["id"]; ok {
2✔
119
                if err := json.Unmarshal(id, &f.Id); err != nil {
1✔
120
                        return err
×
121
                }
×
122
        }
123

124
        if nodeType, ok := tempMap["node_type"]; ok {
2✔
125
                if err := json.Unmarshal(nodeType, &f.NodeType); err != nil {
1✔
126
                        return err
×
127
                }
×
128
        }
129

130
        if kind, ok := tempMap["kind"]; ok {
2✔
131
                if err := json.Unmarshal(kind, &f.Kind); err != nil {
1✔
132
                        return err
×
133
                }
×
134
        }
135

136
        if src, ok := tempMap["src"]; ok {
2✔
137
                if err := json.Unmarshal(src, &f.Src); err != nil {
1✔
138
                        return err
×
139
                }
×
140
        }
141

142
        if referencedDeclaration, ok := tempMap["referenced_declaration"]; ok {
1✔
143
                if err := json.Unmarshal(referencedDeclaration, &f.ReferencedDeclaration); err != nil {
×
144
                        return err
×
145
                }
×
146
        }
147

148
        if typeDescription, ok := tempMap["type_description"]; ok {
2✔
149
                if err := json.Unmarshal(typeDescription, &f.TypeDescription); err != nil {
1✔
150
                        return err
×
151
                }
×
152
        }
153

154
        if argTypes, ok := tempMap["argument_types"]; ok {
2✔
155
                if err := json.Unmarshal(argTypes, &f.ArgumentTypes); err != nil {
1✔
156
                        return err
×
157
                }
×
158
        }
159

160
        if arguments, ok := tempMap["arguments"]; ok {
2✔
161
                f.Arguments = make([]Node[NodeType], 0)
1✔
162
                var nodes []json.RawMessage
1✔
163
                if err := json.Unmarshal(arguments, &nodes); err != nil {
1✔
164
                        return err
×
165
                }
×
166

167
                for _, tempNode := range nodes {
2✔
168
                        var tempNodeMap map[string]json.RawMessage
1✔
169
                        if err := json.Unmarshal(tempNode, &tempNodeMap); err != nil {
1✔
170
                                return err
×
171
                        }
×
172

173
                        var tempNodeType ast_pb.NodeType
1✔
174
                        if err := json.Unmarshal(tempNodeMap["node_type"], &tempNodeType); err != nil {
1✔
175
                                return err
×
176
                        }
×
177

178
                        node, err := unmarshalNode(tempNode, tempNodeType)
1✔
179
                        if err != nil {
1✔
180
                                return err
×
181
                        }
×
182
                        f.Arguments = append(f.Arguments, node)
1✔
183
                }
184
        }
185

186
        if expression, ok := tempMap["expression"]; ok {
2✔
187
                if err := json.Unmarshal(expression, &f.Expression); err != nil {
2✔
188
                        var tempNodeMap map[string]json.RawMessage
1✔
189
                        if err := json.Unmarshal(expression, &tempNodeMap); err != nil {
1✔
190
                                return err
×
191
                        }
×
192

193
                        var tempNodeType ast_pb.NodeType
1✔
194
                        if err := json.Unmarshal(tempNodeMap["node_type"], &tempNodeType); err != nil {
1✔
195
                                return err
×
196
                        }
×
197

198
                        node, err := unmarshalNode(expression, tempNodeType)
1✔
199
                        if err != nil {
1✔
200
                                return err
×
201
                        }
×
202
                        f.Expression = node
1✔
203
                }
204
        }
205

206
        return nil
1✔
207
}
208

209
// ToProto returns a protobuf representation of the FunctionCall node.
210
// Currently, it returns an empty Statement and needs to be implemented.
211
func (f *FunctionCall) ToProto() NodeType {
1✔
212
        proto := ast_pb.FunctionCall{
1✔
213
                Id:                    f.GetId(),
1✔
214
                NodeType:              f.GetType(),
1✔
215
                Kind:                  f.GetKind(),
1✔
216
                Src:                   f.Src.ToProto(),
1✔
217
                ReferencedDeclaration: f.GetReferenceDeclaration(),
1✔
218
                TypeDescription:       f.GetTypeDescription().ToProto(),
1✔
219
                ArgumentTypes:         make([]*ast_pb.TypeDescription, 0),
1✔
220
        }
1✔
221

1✔
222
        if f.GetExpression() != nil {
2✔
223
                proto.Expression = f.GetExpression().ToProto().(*v3.TypedStruct)
1✔
224
        }
1✔
225

226
        for _, arg := range f.GetArguments() {
2✔
227
                proto.Arguments = append(proto.Arguments, arg.ToProto().(*v3.TypedStruct))
1✔
228
        }
1✔
229

230
        for _, argType := range f.GetArgumentTypes() {
2✔
231
                if argType == nil {
1✔
UNCOV
232
                        continue
×
233
                }
234

235
                proto.ArgumentTypes = append(proto.ArgumentTypes, argType.ToProto())
1✔
236
        }
237

238
        return NewTypedStruct(&proto, "FunctionCall")
1✔
239
}
240

241
// Parse takes a parser.FunctionCallContext and parses it into a FunctionCall node.
242
// It sets the Id, Src, Arguments, ArgumentTypes, and Expression of the FunctionCall node.
243
// It returns the created FunctionCall node.
244
func (f *FunctionCall) Parse(
245
        unit *SourceUnit[Node[ast_pb.SourceUnit]],
246
        contractNode Node[NodeType],
247
        fnNode Node[NodeType],
248
        bodyNode *BodyNode,
249
        vDeclar *VariableDeclaration,
250
        expNode Node[NodeType],
251
        ctx *parser.FunctionCallContext,
252
) Node[NodeType] {
1✔
253
        f.Id = f.GetNextID()
1✔
254
        f.Src = SrcNode{
1✔
255
                Id:     f.GetNextID(),
1✔
256
                Line:   int64(ctx.GetStart().GetLine()),
1✔
257
                Column: int64(ctx.GetStart().GetColumn()),
1✔
258
                Start:  int64(ctx.GetStart().GetStart()),
1✔
259
                End:    int64(ctx.GetStop().GetStop()),
1✔
260
                Length: int64(ctx.GetStop().GetStop() - ctx.GetStart().GetStart() + 1),
1✔
261
                ParentIndex: func() int64 {
2✔
262
                        if vDeclar != nil {
2✔
263
                                return vDeclar.GetId()
1✔
264
                        }
1✔
265

266
                        if expNode != nil {
2✔
267
                                return expNode.GetId()
1✔
268
                        }
1✔
269

270
                        if bodyNode != nil {
2✔
271
                                return bodyNode.GetId()
1✔
272
                        }
1✔
273

274
                        if fnNode != nil {
×
275
                                return fnNode.GetId()
×
276
                        }
×
277

278
                        return contractNode.GetId()
×
279
                }(),
280
        }
281

282
        expression := NewExpression(f.ASTBuilder)
1✔
283

1✔
284
        if ctx.Expression() != nil {
2✔
285
                f.Expression = expression.Parse(
1✔
286
                        unit, contractNode, fnNode, bodyNode, nil, f, ctx.Expression(),
1✔
287
                )
1✔
288
        }
1✔
289

290
        if ctx.CallArgumentList() != nil {
2✔
291
                for _, expressionCtx := range ctx.CallArgumentList().AllExpression() {
2✔
292
                        expr := expression.Parse(unit, contractNode, fnNode, bodyNode, nil, f, expressionCtx)
1✔
293
                        f.Arguments = append(
1✔
294
                                f.Arguments,
1✔
295
                                expr,
1✔
296
                        )
1✔
297

1✔
298
                        f.ArgumentTypes = append(
1✔
299
                                f.ArgumentTypes,
1✔
300
                                expr.GetTypeDescription(),
1✔
301
                        )
1✔
302
                }
1✔
303
        }
304

305
        f.TypeDescription = f.buildTypeDescription()
1✔
306
        return f
1✔
307
}
308

309
// buildTypeDescription constructs and returns the TypeDescription of the FunctionCall.
310
func (f *FunctionCall) buildTypeDescription() *TypeDescription {
1✔
311
        typeString := "function("
1✔
312
        typeIdentifier := "t_function_"
1✔
313
        typeStrings := make([]string, 0)
1✔
314
        typeIdentifiers := make([]string, 0)
1✔
315

1✔
316
        for _, paramType := range f.GetArgumentTypes() {
2✔
317
                if paramType == nil {
2✔
318
                        typeStrings = append(typeStrings, fmt.Sprintf("unknown_%d", f.GetId()))
1✔
319
                        typeIdentifiers = append(typeIdentifiers, fmt.Sprintf("$_t_unknown_%d", f.GetId()))
1✔
320
                        continue
1✔
321
                } else if strings.Contains(paramType.TypeString, "literal_string") {
2✔
322
                        typeStrings = append(typeStrings, "string memory")
1✔
323
                        typeIdentifiers = append(typeIdentifiers, "_"+paramType.TypeIdentifier)
1✔
324
                        continue
1✔
325
                } else if strings.Contains(paramType.TypeString, "contract") {
2✔
326
                        typeStrings = append(typeStrings, "address")
1✔
327
                        typeIdentifiers = append(typeIdentifiers, "$_t_address")
1✔
328
                        continue
1✔
329
                }
330

331
                typeStrings = append(typeStrings, paramType.TypeString)
1✔
332
                typeIdentifiers = append(typeIdentifiers, "$_"+paramType.TypeIdentifier)
1✔
333
        }
334

335
        typeString += strings.Join(typeStrings, ",") + ")"
1✔
336
        typeIdentifier += strings.Join(typeIdentifiers, "$")
1✔
337

1✔
338
        if !strings.HasSuffix(typeIdentifier, "$") {
2✔
339
                typeIdentifier += "$"
1✔
340
        }
1✔
341

342
        re := regexp.MustCompile(`\${2,}`)
1✔
343
        typeIdentifier = re.ReplaceAllString(typeIdentifier, "$")
1✔
344

1✔
345
        return &TypeDescription{
1✔
346
                TypeString:     typeString,
1✔
347
                TypeIdentifier: typeIdentifier,
1✔
348
        }
1✔
349
}
350

351
// FunctionCallOption represents a function call node in the AST.
352
type FunctionCallOption struct {
353
        *ASTBuilder
354

355
        Id                    int64            `json:"id"`                               // Unique identifier for the node.
356
        NodeType              ast_pb.NodeType  `json:"node_type"`                        // Type of the node.
357
        Kind                  ast_pb.NodeType  `json:"kind"`                             // Kind of the node.
358
        Src                   SrcNode          `json:"src"`                              // Source location of the node.
359
        Expression            Node[NodeType]   `json:"expression"`                       // Expression of the function call.
360
        ReferencedDeclaration int64            `json:"referenced_declaration,omitempty"` // Referenced declaration of the function call.
361
        TypeDescription       *TypeDescription `json:"type_description"`                 // Type description of the function call.
362
}
363

364
// NewFunctionCall creates a new FunctionCallOption node with a given ASTBuilder.
365
// It initializes the Arguments slice and sets the NodeType and Kind to FUNCTION_CALL.
366
func NewFunctionCallOption(b *ASTBuilder) *FunctionCallOption {
1✔
367
        return &FunctionCallOption{
1✔
368
                ASTBuilder: b,
1✔
369
                NodeType:   ast_pb.NodeType_FUNCTION_CALL_OPTION,
1✔
370
                Kind:       ast_pb.NodeType_FUNCTION_CALL_OPTION,
1✔
371
        }
1✔
372
}
1✔
373

374
// SetReferenceDescriptor sets the reference descriptions of the FunctionCallOption node.
375
func (f *FunctionCallOption) SetReferenceDescriptor(refId int64, refDesc *TypeDescription) bool {
1✔
376
        f.ReferencedDeclaration = refId
1✔
377
        f.TypeDescription = refDesc
1✔
378
        return false
1✔
379
}
1✔
380

381
// GetId returns the unique identifier of the FunctionCallOption node.
382
func (f *FunctionCallOption) GetId() int64 {
1✔
383
        return f.Id
1✔
384
}
1✔
385

386
// GetType returns the type of the FunctionCallOption node.
387
func (f *FunctionCallOption) GetType() ast_pb.NodeType {
1✔
388
        return f.NodeType
1✔
389
}
1✔
390

391
// GetSrc returns the source location of the FunctionCallOption node.
392
func (f *FunctionCallOption) GetSrc() SrcNode {
1✔
393
        return f.Src
1✔
394
}
1✔
395

396
// GetKind returns the kind of the FunctionCallOption node.
397
func (f *FunctionCallOption) GetKind() ast_pb.NodeType {
1✔
398
        return f.Kind
1✔
399
}
1✔
400

401
// GetExpression returns the expression of the FunctionCallOption node.
402
func (f *FunctionCallOption) GetExpression() Node[NodeType] {
1✔
403
        return f.Expression
1✔
404
}
1✔
405

406
// GetTypeDescription returns the type description of the FunctionCallOption node.
407
// Currently, it returns nil and needs to be implemented.
408
func (f *FunctionCallOption) GetTypeDescription() *TypeDescription {
1✔
409
        return f.TypeDescription
1✔
410
}
1✔
411

412
// GetNodes returns a slice of nodes that includes the expression of the FunctionCallOption node.
413
func (f *FunctionCallOption) GetNodes() []Node[NodeType] {
1✔
414
        return []Node[NodeType]{f.Expression}
1✔
415
}
1✔
416

417
// GetReferenceDeclaration returns the referenced declaration of the FunctionCallOption node.
418
func (f *FunctionCallOption) GetReferenceDeclaration() int64 {
1✔
419
        return f.ReferencedDeclaration
1✔
420
}
1✔
421

422
// UnmarshalJSON unmarshals a given JSON byte array into a FunctionCallOption node.
423
func (f *FunctionCallOption) UnmarshalJSON(data []byte) error {
1✔
424
        var tempMap map[string]json.RawMessage
1✔
425
        if err := json.Unmarshal(data, &tempMap); err != nil {
1✔
426
                return err
×
427
        }
×
428

429
        if id, ok := tempMap["id"]; ok {
2✔
430
                if err := json.Unmarshal(id, &f.Id); err != nil {
1✔
431
                        return err
×
432
                }
×
433
        }
434

435
        if nodeType, ok := tempMap["node_type"]; ok {
2✔
436
                if err := json.Unmarshal(nodeType, &f.NodeType); err != nil {
1✔
437
                        return err
×
438
                }
×
439
        }
440

441
        if kind, ok := tempMap["kind"]; ok {
2✔
442
                if err := json.Unmarshal(kind, &f.Kind); err != nil {
1✔
443
                        return err
×
444
                }
×
445
        }
446

447
        if src, ok := tempMap["src"]; ok {
2✔
448
                if err := json.Unmarshal(src, &f.Src); err != nil {
1✔
449
                        return err
×
450
                }
×
451
        }
452

453
        if referencedDeclaration, ok := tempMap["referenced_declaration"]; ok {
1✔
454
                if err := json.Unmarshal(referencedDeclaration, &f.ReferencedDeclaration); err != nil {
×
455
                        return err
×
456
                }
×
457
        }
458

459
        if typeDescription, ok := tempMap["type_description"]; ok {
2✔
460
                if err := json.Unmarshal(typeDescription, &f.TypeDescription); err != nil {
1✔
461
                        return err
×
462
                }
×
463
        }
464

465
        if expression, ok := tempMap["expression"]; ok {
2✔
466
                if err := json.Unmarshal(expression, &f.Expression); err != nil {
2✔
467
                        var tempNodeMap map[string]json.RawMessage
1✔
468
                        if err := json.Unmarshal(expression, &tempNodeMap); err != nil {
1✔
469
                                return err
×
470
                        }
×
471

472
                        var tempNodeType ast_pb.NodeType
1✔
473
                        if err := json.Unmarshal(tempNodeMap["node_type"], &tempNodeType); err != nil {
1✔
474
                                return err
×
475
                        }
×
476

477
                        node, err := unmarshalNode(expression, tempNodeType)
1✔
478
                        if err != nil {
1✔
479
                                return err
×
480
                        }
×
481
                        f.Expression = node
1✔
482
                }
483
        }
484

485
        return nil
1✔
486
}
487

488
// ToProto returns a protobuf representation of the FunctionCallOption node.
489
// Currently, it returns an empty Statement and needs to be implemented.
490
func (f *FunctionCallOption) ToProto() NodeType {
1✔
491
        proto := ast_pb.FunctionCallOption{
1✔
492
                Id:                    f.GetId(),
1✔
493
                NodeType:              f.GetType(),
1✔
494
                Kind:                  f.GetKind(),
1✔
495
                Src:                   f.Src.ToProto(),
1✔
496
                ReferencedDeclaration: f.GetReferenceDeclaration(),
1✔
497
                TypeDescription:       f.GetTypeDescription().ToProto(),
1✔
498
        }
1✔
499

1✔
500
        if f.GetExpression() != nil {
2✔
501
                proto.Expression = f.GetExpression().ToProto().(*v3.TypedStruct)
1✔
502
        }
1✔
503

504
        return NewTypedStruct(&proto, "FunctionCallOption")
1✔
505
}
506

507
// Parse takes a parser.FunctionCallOptionsContext and parses it into a FunctionCallOption node.
508
// It sets the Id, Src, Expression, and TypeDescription of the FunctionCallOption node.
509
// It returns the created FunctionCallOption node.
510
func (f *FunctionCallOption) Parse(
511
        unit *SourceUnit[Node[ast_pb.SourceUnit]],
512
        contractNode Node[NodeType],
513
        fnNode Node[NodeType],
514
        bodyNode *BodyNode,
515
        vDeclar *VariableDeclaration,
516
        expNode Node[NodeType],
517
        ctx *parser.FunctionCallOptionsContext,
518
) Node[NodeType] {
1✔
519
        f.Id = f.GetNextID()
1✔
520
        f.Src = SrcNode{
1✔
521
                Id:     f.GetNextID(),
1✔
522
                Line:   int64(ctx.GetStart().GetLine()),
1✔
523
                Column: int64(ctx.GetStart().GetColumn()),
1✔
524
                Start:  int64(ctx.GetStart().GetStart()),
1✔
525
                End:    int64(ctx.GetStop().GetStop()),
1✔
526
                Length: int64(ctx.GetStop().GetStop() - ctx.GetStart().GetStart() + 1),
1✔
527
                ParentIndex: func() int64 {
2✔
528
                        if vDeclar != nil {
1✔
529
                                return vDeclar.GetId()
×
530
                        }
×
531

532
                        if expNode != nil {
2✔
533
                                return expNode.GetId()
1✔
534
                        }
1✔
535

536
                        if bodyNode != nil {
×
537
                                return bodyNode.GetId()
×
538
                        }
×
539

540
                        if fnNode != nil {
×
541
                                return fnNode.GetId()
×
542
                        }
×
543

544
                        return contractNode.GetId()
×
545
                }(),
546
        }
547

548
        expression := NewExpression(f.ASTBuilder)
1✔
549

1✔
550
        if ctx.Expression() != nil {
2✔
551
                f.Expression = expression.Parse(
1✔
552
                        unit, contractNode, fnNode, bodyNode, nil, f, ctx.Expression(),
1✔
553
                )
1✔
554
                f.TypeDescription = f.Expression.GetTypeDescription()
1✔
555
        }
1✔
556

557
        return f
1✔
558
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc