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

unpackdev / solgo / 6615392737

23 Oct 2023 03:25PM UTC coverage: 78.656% (-0.3%) from 78.98%
6615392737

push

github

web-flow
Group Fixes No.2 (#132)

* foobar

* Finally works

301 of 509 new or added lines in 42 files covered. (59.14%)

8 existing lines in 5 files now uncovered.

15725 of 19992 relevant lines covered (78.66%)

0.87 hits per line

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

72.1
/ast/function.go
1
package ast
2

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

9
        "github.com/ethereum/go-ethereum/common"
10
        ast_pb "github.com/unpackdev/protos/dist/go/ast"
11
        "github.com/unpackdev/solgo/parser"
12
        "github.com/unpackdev/solgo/utils"
13
)
14

15
// Function represents a Solidity function definition within an abstract syntax tree.
16
type Function struct {
17
        *ASTBuilder // Embedded ASTBuilder for creating the AST.
18

19
        // Core properties of a function node.
20
        Id                    int64                 `json:"id"`
21
        Name                  string                `json:"name"`
22
        NodeType              ast_pb.NodeType       `json:"node_type"`
23
        Kind                  ast_pb.NodeType       `json:"kind"`
24
        Src                   SrcNode               `json:"src"`
25
        NameLocation          SrcNode               `json:"name_location"`
26
        Body                  *BodyNode             `json:"body"`
27
        Implemented           bool                  `json:"implemented"`
28
        Visibility            ast_pb.Visibility     `json:"visibility"`
29
        StateMutability       ast_pb.Mutability     `json:"state_mutability"`
30
        Virtual               bool                  `json:"virtual"`
31
        Modifiers             []*ModifierInvocation `json:"modifiers"`
32
        Overrides             []*OverrideSpecifier  `json:"overrides"`
33
        Parameters            *ParameterList        `json:"parameters"`
34
        ReturnParameters      *ParameterList        `json:"return_parameters"`
35
        SignatureRaw          string                `json:"signature_raw"`
36
        SignatureBytes        []byte                `json:"-"`
37
        Signature             string                `json:"signature"`
38
        Scope                 int64                 `json:"scope"`
39
        ReferencedDeclaration int64                 `json:"referenced_declaration,omitempty"`
40
        TypeDescription       *TypeDescription      `json:"type_description"`
41
}
42

43
// NewFunction creates and initializes a new Function node.
44
func NewFunction(b *ASTBuilder) *Function {
1✔
45
        return &Function{
1✔
46
                ASTBuilder:  b,
1✔
47
                NodeType:    ast_pb.NodeType_FUNCTION_DEFINITION,
1✔
48
                Kind:        ast_pb.NodeType_KIND_FUNCTION,
1✔
49
                Modifiers:   make([]*ModifierInvocation, 0),
1✔
50
                Overrides:   make([]*OverrideSpecifier, 0),
1✔
51
                Implemented: true,
1✔
52
        }
1✔
53
}
1✔
54

55
// SetReferenceDescriptor sets the reference descriptions of the Function node.
56
func (f *Function) SetReferenceDescriptor(refId int64, refDesc *TypeDescription) bool {
1✔
57
        f.ReferencedDeclaration = refId
1✔
58
        f.TypeDescription = refDesc
1✔
59
        return false
1✔
60
}
1✔
61

62
// GetId returns the unique identifier of the Function node.
63
func (f *Function) GetId() int64 {
1✔
64
        return f.Id
1✔
65
}
1✔
66

67
// GetType returns the type of the Function node.
68
func (f *Function) GetType() ast_pb.NodeType {
1✔
69
        return f.NodeType
1✔
70
}
1✔
71

72
// GetSrc returns the source location information of the Function node.
73
func (f *Function) GetSrc() SrcNode {
1✔
74
        return f.Src
1✔
75
}
1✔
76

77
// GetNameLocation returns the source location information of the name of the Function node.
78
func (f *Function) GetNameLocation() SrcNode {
1✔
79
        return f.NameLocation
1✔
80
}
1✔
81

82
// GetParameters returns the list of parameters of the Function node.
83
func (f *Function) GetParameters() *ParameterList {
1✔
84
        return f.Parameters
1✔
85
}
1✔
86

87
// GetReturnParameters returns the list of return parameters of the Function node.
88
func (f *Function) GetReturnParameters() *ParameterList {
1✔
89
        return f.ReturnParameters
1✔
90
}
1✔
91

92
// GetBody returns the body of the Function node.
93
func (f *Function) GetBody() *BodyNode {
1✔
94
        return f.Body
1✔
95
}
1✔
96

97
// GetKind returns the kind of the Function node.
98
func (f *Function) GetKind() ast_pb.NodeType {
1✔
99
        return f.Kind
1✔
100
}
1✔
101

102
// IsImplemented returns true if the Function node is implemented, false otherwise.
103
func (f *Function) IsImplemented() bool {
1✔
104
        return f.Implemented
1✔
105
}
1✔
106

107
// GetModifiers returns the list of modifier invocations applied to the Function node.
108
func (f *Function) GetModifiers() []*ModifierInvocation {
1✔
109
        return f.Modifiers
1✔
110
}
1✔
111

112
// GetOverrides returns the list of override specifiers associated with the Function node.
113
func (f *Function) GetOverrides() []*OverrideSpecifier {
1✔
114
        return f.Overrides
1✔
115
}
1✔
116

117
// GetVisibility returns the visibility of the Function node.
118
func (f *Function) GetVisibility() ast_pb.Visibility {
1✔
119
        return f.Visibility
1✔
120
}
1✔
121

122
// GetStateMutability returns the state mutability of the Function node.
123
func (f *Function) GetStateMutability() ast_pb.Mutability {
1✔
124
        return f.StateMutability
1✔
125
}
1✔
126

127
// IsVirtual returns true if the Function node is declared as virtual, false otherwise.
128
func (f *Function) IsVirtual() bool {
1✔
129
        return f.Virtual
1✔
130
}
1✔
131

132
// GetScope returns the scope of the Function node.
133
func (f *Function) GetScope() int64 {
1✔
134
        return f.Scope
1✔
135
}
1✔
136

137
// GetName returns the name of the Function node.
138
func (f *Function) GetName() string {
1✔
139
        return f.Name
1✔
140
}
1✔
141

142
// GetTypeDescription returns the type description of the Function node.
143
func (f *Function) GetTypeDescription() *TypeDescription {
1✔
144
        return f.TypeDescription
1✔
145
}
1✔
146

147
// ComputeSignature computes the signature of the Function node.
148
func (f *Function) ComputeSignature() {
1✔
149
        params := make([]string, 0)
1✔
150

1✔
151
        if f.GetParameters() != nil {
2✔
152
                for _, param := range f.GetParameters().GetParameters() {
2✔
153
                        params = append(params, param.TypeName.Name)
1✔
154
                }
1✔
155
        }
156
        f.SignatureRaw = strings.Join(
1✔
157
                []string{
1✔
158
                        f.GetName(),
1✔
159
                        "(",
1✔
160
                        strings.Join(params, ", "),
1✔
161
                        ")",
1✔
162
                }, "",
1✔
163
        )
1✔
164
        f.SignatureBytes = utils.Keccak256([]byte(f.SignatureRaw))
1✔
165
        f.Signature = common.Bytes2Hex(f.SignatureBytes[:4])
1✔
166
}
167

168
// GetSignatureRaw returns the raw signature of the Function node.
169
func (f *Function) GetSignatureRaw() string {
1✔
170
        return f.SignatureRaw
1✔
171
}
1✔
172

173
// GetSignatureBytes returns the keccak signature full bytes of the Function node.
174
func (f *Function) GetSignatureBytes() []byte {
1✔
175
        return f.SignatureBytes
1✔
176
}
1✔
177

178
// GetSignature computes the keccak signature of the Function node.
179
func (f *Function) GetSignature() string {
1✔
180
        return f.Signature
1✔
181
}
1✔
182

183
// GetNodes returns a list of child nodes within the Function node.
184
func (f *Function) GetNodes() []Node[NodeType] {
1✔
185
        toReturn := []Node[NodeType]{}
1✔
186
        toReturn = append(toReturn, f.GetBody().GetNodes()...)
1✔
187
        toReturn = append(toReturn, f.GetParameters().GetNodes()...)
1✔
188
        toReturn = append(toReturn, f.GetReturnParameters().GetNodes()...)
1✔
189

1✔
190
        for _, override := range f.GetOverrides() {
2✔
191
                toReturn = append(toReturn, override)
1✔
192
        }
1✔
193

194
        for _, modifier := range f.GetModifiers() {
2✔
195
                toReturn = append(toReturn, modifier)
1✔
196
        }
1✔
197

198
        return toReturn
1✔
199
}
200

201
// GetReferencedDeclaration returns the referenced declaration identifier associated with the Function node.
202
func (f *Function) GetReferencedDeclaration() int64 {
1✔
203
        return f.ReferencedDeclaration
1✔
204
}
1✔
205

206
func (f *Function) UnmarshalJSON(data []byte) error {
1✔
207
        var tempMap map[string]json.RawMessage
1✔
208
        if err := json.Unmarshal(data, &tempMap); err != nil {
1✔
209
                return err
×
210
        }
×
211

212
        if id, ok := tempMap["id"]; ok {
2✔
213
                if err := json.Unmarshal(id, &f.Id); err != nil {
1✔
214
                        return err
×
215
                }
×
216
        }
217

218
        if name, ok := tempMap["name"]; ok {
2✔
219
                if err := json.Unmarshal(name, &f.Name); err != nil {
1✔
220
                        return err
×
221
                }
×
222
        }
223

224
        if nodeType, ok := tempMap["node_type"]; ok {
2✔
225
                if err := json.Unmarshal(nodeType, &f.NodeType); err != nil {
1✔
226
                        return err
×
227
                }
×
228
        }
229

230
        if kind, ok := tempMap["kind"]; ok {
2✔
231
                if err := json.Unmarshal(kind, &f.Kind); err != nil {
1✔
232
                        return err
×
233
                }
×
234
        }
235

236
        if src, ok := tempMap["src"]; ok {
2✔
237
                if err := json.Unmarshal(src, &f.Src); err != nil {
1✔
238
                        return err
×
239
                }
×
240
        }
241

242
        if nameLocation, ok := tempMap["name_location"]; ok {
2✔
243
                if err := json.Unmarshal(nameLocation, &f.NameLocation); err != nil {
1✔
244
                        return err
×
245
                }
×
246
        }
247

248
        if implemented, ok := tempMap["implemented"]; ok {
2✔
249
                if err := json.Unmarshal(implemented, &f.Implemented); err != nil {
1✔
250
                        return err
×
251
                }
×
252
        }
253

254
        if visibility, ok := tempMap["visibility"]; ok {
2✔
255
                if err := json.Unmarshal(visibility, &f.Visibility); err != nil {
1✔
256
                        return err
×
257
                }
×
258
        }
259

260
        if sm, ok := tempMap["state_mutability"]; ok {
2✔
261
                if err := json.Unmarshal(sm, &f.StateMutability); err != nil {
1✔
262
                        return err
×
263
                }
×
264
        }
265

266
        if virtual, ok := tempMap["virtual"]; ok {
2✔
267
                if err := json.Unmarshal(virtual, &f.Virtual); err != nil {
1✔
268
                        return err
×
269
                }
×
270
        }
271

272
        if modifiers, ok := tempMap["modifiers"]; ok {
2✔
273
                if err := json.Unmarshal(modifiers, &f.Modifiers); err != nil {
1✔
274
                        return err
×
275
                }
×
276
        }
277

278
        if overrides, ok := tempMap["overrides"]; ok {
2✔
279
                if err := json.Unmarshal(overrides, &f.Overrides); err != nil {
1✔
280
                        return err
×
281
                }
×
282
        }
283

284
        if params, ok := tempMap["parameters"]; ok {
2✔
285
                if err := json.Unmarshal(params, &f.Parameters); err != nil {
1✔
286
                        return err
×
287
                }
×
288
        }
289

290
        if retParams, ok := tempMap["return_parameters"]; ok {
2✔
291
                if err := json.Unmarshal(retParams, &f.ReturnParameters); err != nil {
1✔
292
                        return err
×
293
                }
×
294
        }
295

296
        if scope, ok := tempMap["scope"]; ok {
2✔
297
                if err := json.Unmarshal(scope, &f.Scope); err != nil {
1✔
298
                        return err
×
299
                }
×
300
        }
301

302
        if refD, ok := tempMap["referenced_declaration"]; ok {
1✔
303
                if err := json.Unmarshal(refD, &f.ReferencedDeclaration); err != nil {
×
304
                        return err
×
305
                }
×
306
        }
307

308
        if td, ok := tempMap["type_description"]; ok {
2✔
309
                if err := json.Unmarshal(td, &f.TypeDescription); err != nil {
1✔
310
                        return err
×
311
                }
×
312
        }
313

314
        if sigRaw, ok := tempMap["signature_raw"]; ok {
2✔
315
                if err := json.Unmarshal(sigRaw, &f.SignatureRaw); err != nil {
1✔
316
                        return err
×
317
                }
×
318
        }
319

320
        if sigBytes, ok := tempMap["signature_bytes"]; ok {
1✔
321
                if err := json.Unmarshal(sigBytes, &f.SignatureBytes); err != nil {
×
322
                        return err
×
323
                }
×
324
        }
325

326
        if sig, ok := tempMap["signature"]; ok {
2✔
327
                if err := json.Unmarshal(sig, &f.Signature); err != nil {
1✔
328
                        return err
×
329
                }
×
330
        }
331

332
        if body, ok := tempMap["body"]; ok {
2✔
333
                if err := json.Unmarshal(body, &f.Body); err != nil {
1✔
334
                        return err
×
335
                }
×
336
        }
337

338
        return nil
1✔
339
}
340

341
// ToProto converts the Function node to its corresponding protobuf representation.
342
func (f *Function) ToProto() NodeType {
1✔
343
        proto := ast_pb.Function{
1✔
344
                Id:                    f.GetId(),
1✔
345
                Name:                  f.GetName(),
1✔
346
                NodeType:              f.GetType(),
1✔
347
                Kind:                  f.GetKind(),
1✔
348
                Src:                   f.GetSrc().ToProto(),
1✔
349
                NameLocation:          f.GetNameLocation().ToProto(),
1✔
350
                ReferencedDeclaration: f.GetReferencedDeclaration(),
1✔
351
                Implemented:           f.IsImplemented(),
1✔
352
                Virtual:               f.IsVirtual(),
1✔
353
                Scope:                 f.GetScope(),
1✔
354
                Visibility:            f.GetVisibility(),
1✔
355
                StateMutability:       f.GetStateMutability(),
1✔
356
                Modifiers:             make([]*ast_pb.ModifierInvocation, 0),
1✔
357
                Overrides:             make([]*ast_pb.OverrideSpecifier, 0),
1✔
358
                Parameters:            f.GetParameters().ToProto(),
1✔
359
                ReturnParameters:      f.GetReturnParameters().ToProto(),
1✔
360
                Body:                  f.GetBody().ToProto().(*ast_pb.Body),
1✔
361
                Signature:             f.GetSignature(),
1✔
362
        }
1✔
363

1✔
364
        if f.GetTypeDescription() != nil {
2✔
365
                proto.TypeDescription = f.GetTypeDescription().ToProto()
1✔
366
        }
1✔
367

368
        for _, modifier := range f.GetModifiers() {
2✔
369
                proto.Modifiers = append(proto.Modifiers, modifier.ToProto().(*ast_pb.ModifierInvocation))
1✔
370
        }
1✔
371

372
        for _, override := range f.GetOverrides() {
2✔
373
                proto.Overrides = append(proto.Overrides, override.ToProto().(*ast_pb.OverrideSpecifier))
1✔
374
        }
1✔
375

376
        return NewTypedStruct(&proto, "Function")
1✔
377
}
378

379
// Parse parses the source code and constructs the Function node.
380
func (f *Function) Parse(
381
        unit *SourceUnit[Node[ast_pb.SourceUnit]],
382
        contractNode Node[NodeType],
383
        bodyCtx parser.IContractBodyElementContext,
384
        ctx *parser.FunctionDefinitionContext,
385
) Node[NodeType] {
1✔
386
        // Initialize basic properties.
1✔
387
        f.Id = f.GetNextID()
1✔
388
        f.Scope = contractNode.GetId()
1✔
389
        if ctx.Identifier() != nil {
2✔
390
                f.Name = ctx.Identifier().GetText()
1✔
391
                f.NameLocation = SrcNode{
1✔
392
                        Line:        int64(ctx.Identifier().GetStart().GetLine()),
1✔
393
                        Column:      int64(ctx.Identifier().GetStart().GetColumn()),
1✔
394
                        Start:       int64(ctx.Identifier().GetStart().GetStart()),
1✔
395
                        End:         int64(ctx.Identifier().GetStop().GetStop()),
1✔
396
                        Length:      int64(ctx.Identifier().GetStop().GetStop() - ctx.Identifier().GetStart().GetStart() + 1),
1✔
397
                        ParentIndex: f.Id,
1✔
398
                }
1✔
399
        }
1✔
400
        f.Implemented = ctx.Block() != nil && !ctx.Block().IsEmpty()
1✔
401
        f.Src = SrcNode{
1✔
402
                Line:        int64(ctx.GetStart().GetLine()),
1✔
403
                Column:      int64(ctx.GetStart().GetColumn()),
1✔
404
                Start:       int64(ctx.GetStart().GetStart()),
1✔
405
                End:         int64(ctx.GetStop().GetStop()),
1✔
406
                Length:      int64(ctx.GetStop().GetStop() - ctx.GetStart().GetStart() + 1),
1✔
407
                ParentIndex: contractNode.GetId(),
1✔
408
        }
1✔
409

1✔
410
        // Set function visibility state.
1✔
411
        f.Visibility = f.getVisibilityFromCtx(ctx)
1✔
412

1✔
413
        // Set function state mutability.
1✔
414
        f.StateMutability = f.getStateMutabilityFromCtx(ctx)
1✔
415

1✔
416
        // Set if function is virtual.
1✔
417
        f.Virtual = f.getVirtualState(ctx)
1✔
418

1✔
419
        // Set function parameters if they exist.
1✔
420
        params := NewParameterList(f.ASTBuilder)
1✔
421
        if len(ctx.AllParameterList()) > 0 {
2✔
422
                params.Parse(unit, f, ctx.AllParameterList()[0])
1✔
423
        } else {
2✔
424
                params.Src = f.Src
1✔
425
                params.Src.ParentIndex = f.Id
1✔
426
        }
1✔
427
        f.Parameters = params
1✔
428

1✔
429
        // Set function modifiers.
1✔
430
        for _, modifierCtx := range ctx.AllModifierInvocation() {
2✔
431
                modifier := NewModifierInvocation(f.ASTBuilder)
1✔
432
                modifier.Parse(unit, contractNode, f, nil, modifierCtx)
1✔
433
                f.Modifiers = append(f.Modifiers, modifier)
1✔
434
        }
1✔
435

436
        // Set function override specifier.
437
        for _, overrideCtx := range ctx.AllOverrideSpecifier() {
2✔
438
                overrideSpecifier := NewOverrideSpecifier(f.ASTBuilder)
1✔
439
                overrideSpecifier.Parse(unit, f, overrideCtx)
1✔
440
                f.Overrides = append(f.Overrides, overrideSpecifier)
1✔
441
        }
1✔
442

443
        // Set function return parameters if they exist.
444
        // @TODO: Consider traversing through body to discover name of the return parameters even
445
        // if they are not defined in (name uint) format.
446
        returnParams := NewParameterList(f.ASTBuilder)
1✔
447
        if ctx.GetReturnParameters() != nil {
2✔
448
                returnParams.Parse(unit, f, ctx.GetReturnParameters())
1✔
449
        } else {
2✔
450
                returnParams.Src = f.Src
1✔
451
                returnParams.Src.ParentIndex = f.Id
1✔
452
        }
1✔
453
        f.ReturnParameters = returnParams
1✔
454

1✔
455
        if ctx.Block() != nil && !ctx.Block().IsEmpty() {
2✔
456
                bodyNode := NewBodyNode(f.ASTBuilder, false)
1✔
457
                bodyNode.ParseBlock(unit, contractNode, f, ctx.Block())
1✔
458
                f.Body = bodyNode
1✔
459

1✔
460
                // In case at any point we discover that the function is not implemented, we set the
1✔
461
                // implemented flag to false.
1✔
462
                if !bodyNode.Implemented {
1✔
463
                        f.Implemented = false
×
464
                }
×
465

466
                if ctx.Block().AllUncheckedBlock() != nil {
2✔
467
                        for _, uncheckedCtx := range ctx.Block().AllUncheckedBlock() {
2✔
468
                                bodyNode := NewBodyNode(f.ASTBuilder, false)
1✔
469
                                bodyNode.ParseUncheckedBlock(unit, contractNode, f, uncheckedCtx)
1✔
470
                                f.Body.Statements = append(f.Body.Statements, bodyNode)
1✔
471

1✔
472
                                // In case at any point we discover that the function is not implemented, we set the
1✔
473
                                // implemented flag to false.
1✔
474
                                if !bodyNode.Implemented {
2✔
475
                                        f.Implemented = false
1✔
476
                                }
1✔
477
                        }
478
                }
479
        } else {
1✔
480
                bodyNode := NewBodyNode(f.ASTBuilder, false)
1✔
481
                bodyNode.Src = f.Src
1✔
482
                bodyNode.Src.ParentIndex = f.Id
1✔
483
                f.Body = bodyNode
1✔
484
        }
1✔
485

486
        f.TypeDescription = f.buildTypeDescription()
1✔
487

1✔
488
        f.ComputeSignature()
1✔
489

1✔
490
        f.currentFunctions = append(f.currentFunctions, f)
1✔
491

1✔
492
        return f
1✔
493
}
494

495
// ParseTypeName parses the source code and constructs the Function node for TypeName.
496
func (f *Function) ParseTypeName(
497
        unit *SourceUnit[Node[ast_pb.SourceUnit]],
498
        parentNodeId int64,
499
        ctx *parser.FunctionTypeNameContext,
500
) Node[NodeType] {
×
501
        // Initialize basic properties.
×
502
        f.Id = f.GetNextID()
×
NEW
503

×
NEW
504
        if unit != nil {
×
NEW
505
                f.Scope = unit.GetId()
×
NEW
506
        }
×
507

508
        f.Src = SrcNode{
×
509
                Line:        int64(ctx.GetStart().GetLine()),
×
510
                Column:      int64(ctx.GetStart().GetColumn()),
×
511
                Start:       int64(ctx.GetStart().GetStart()),
×
512
                End:         int64(ctx.GetStop().GetStop()),
×
513
                Length:      int64(ctx.GetStop().GetStop() - ctx.GetStart().GetStart() + 1),
×
514
                ParentIndex: parentNodeId,
×
515
        }
×
516

×
517
        // Set function visibility state.
×
518
        f.Visibility = f.getVisibilityFromTypeNameCtx(ctx)
×
519

×
520
        // Set function state mutability.
×
521
        f.StateMutability = f.getStateMutabilityFromTypeNameCtx(ctx)
×
522

×
523
        // Set function parameters if they exist.
×
524
        params := NewParameterList(f.ASTBuilder)
×
525
        if len(ctx.AllParameterList()) > 0 {
×
526
                params.Parse(unit, f, ctx.AllParameterList()[0])
×
527
        } else {
×
528
                params.Src = f.Src
×
529
                params.Src.ParentIndex = f.Id
×
530
        }
×
531
        f.Parameters = params
×
532

×
533
        // Set function return parameters if they exist.
×
534
        // @TODO: Consider traversing through body to discover name of the return parameters even
×
535
        // if they are not defined in (name uint) format.
×
536
        returnParams := NewParameterList(f.ASTBuilder)
×
537
        if ctx.GetReturnParameters() != nil {
×
538
                returnParams.Parse(unit, f, ctx.GetReturnParameters())
×
539
        } else {
×
540
                returnParams.Src = f.Src
×
541
                returnParams.Src.ParentIndex = f.Id
×
542
        }
×
543
        f.ReturnParameters = returnParams
×
544

×
545
        bodyNode := NewBodyNode(f.ASTBuilder, false)
×
546
        bodyNode.Src = f.Src
×
547
        bodyNode.Src.ParentIndex = f.Id
×
548
        f.Body = bodyNode
×
549

×
550
        f.TypeDescription = f.buildTypeDescription()
×
551

×
552
        f.ComputeSignature()
×
553

×
554
        f.currentFunctions = append(f.currentFunctions, f)
×
555

×
556
        return f
×
557
}
558

559
// buildTypeDescription constructs the type description of the Function node.
560
func (f *Function) buildTypeDescription() *TypeDescription {
1✔
561
        typeString := "function("
1✔
562
        typeIdentifier := "t_function_"
1✔
563
        typeStrings := make([]string, 0)
1✔
564
        typeIdentifiers := make([]string, 0)
1✔
565

1✔
566
        for _, paramType := range f.GetParameters().GetParameterTypes() {
2✔
567
                if paramType == nil {
2✔
568
                        typeStrings = append(typeStrings, fmt.Sprintf("unknown_%d", f.GetId()))
1✔
569
                        typeIdentifiers = append(typeIdentifiers, fmt.Sprintf("$_t_unknown_%d", f.GetId()))
1✔
570
                        continue
1✔
571
                }
572

573
                typeStrings = append(typeStrings, paramType.TypeString)
1✔
574
                typeIdentifiers = append(typeIdentifiers, "$_"+paramType.TypeIdentifier)
1✔
575
        }
576
        typeString += strings.Join(typeStrings, ",") + ")"
1✔
577
        typeIdentifier += strings.Join(typeIdentifiers, "$")
1✔
578

1✔
579
        if !strings.HasSuffix(typeIdentifier, "$") {
2✔
580
                typeIdentifier += "$"
1✔
581
        }
1✔
582

583
        re := regexp.MustCompile(`\${2,}`)
1✔
584
        typeIdentifier = re.ReplaceAllString(typeIdentifier, "$")
1✔
585

1✔
586
        return &TypeDescription{
1✔
587
                TypeString:     typeString,
1✔
588
                TypeIdentifier: typeIdentifier,
1✔
589
        }
1✔
590
}
591

592
// getVisibilityFromCtx extracts the visibility of the Function node from the parser context.
593
func (f *Function) getVisibilityFromCtx(ctx *parser.FunctionDefinitionContext) ast_pb.Visibility {
1✔
594
        visibilityMap := map[string]ast_pb.Visibility{
1✔
595
                "public":   ast_pb.Visibility_PUBLIC,
1✔
596
                "private":  ast_pb.Visibility_PRIVATE,
1✔
597
                "internal": ast_pb.Visibility_INTERNAL,
1✔
598
                "external": ast_pb.Visibility_EXTERNAL,
1✔
599
        }
1✔
600

1✔
601
        for _, visibility := range ctx.AllVisibility() {
2✔
602
                if v, ok := visibilityMap[visibility.GetText()]; ok {
2✔
603
                        return v
1✔
604
                }
1✔
605
        }
606

607
        return ast_pb.Visibility_INTERNAL
×
608
}
609

610
// getVisibilityFromTypeNameCtx extracts the visibility of the Function node from the parser context.
611
func (f *Function) getVisibilityFromTypeNameCtx(ctx *parser.FunctionTypeNameContext) ast_pb.Visibility {
×
612
        visibilityMap := map[string]ast_pb.Visibility{
×
613
                "public":   ast_pb.Visibility_PUBLIC,
×
614
                "private":  ast_pb.Visibility_PRIVATE,
×
615
                "internal": ast_pb.Visibility_INTERNAL,
×
616
                "external": ast_pb.Visibility_EXTERNAL,
×
617
        }
×
618

×
619
        for _, visibility := range ctx.AllVisibility() {
×
620
                if v, ok := visibilityMap[visibility.GetText()]; ok {
×
621
                        return v
×
622
                }
×
623
        }
624

625
        return ast_pb.Visibility_INTERNAL
×
626
}
627

628
// getStateMutabilityFromCtx extracts the state mutability of the Function node from the parser context.
629
func (f *Function) getStateMutabilityFromCtx(ctx *parser.FunctionDefinitionContext) ast_pb.Mutability {
1✔
630
        mutabilityMap := map[string]ast_pb.Mutability{
1✔
631
                "payable": ast_pb.Mutability_PAYABLE,
1✔
632
                "pure":    ast_pb.Mutability_PURE,
1✔
633
                "view":    ast_pb.Mutability_VIEW,
1✔
634
        }
1✔
635

1✔
636
        for _, stateMutability := range ctx.AllStateMutability() {
2✔
637
                if m, ok := mutabilityMap[stateMutability.GetText()]; ok {
2✔
638
                        return m
1✔
639
                }
1✔
640
        }
641

642
        return ast_pb.Mutability_NONPAYABLE
1✔
643
}
644

645
// getStateMutabilityFromTypeNameCtx extracts the state mutability of the Function node from the parser context.
646
func (f *Function) getStateMutabilityFromTypeNameCtx(ctx *parser.FunctionTypeNameContext) ast_pb.Mutability {
×
647
        mutabilityMap := map[string]ast_pb.Mutability{
×
648
                "payable": ast_pb.Mutability_PAYABLE,
×
649
                "pure":    ast_pb.Mutability_PURE,
×
650
                "view":    ast_pb.Mutability_VIEW,
×
651
        }
×
652

×
653
        for _, stateMutability := range ctx.AllStateMutability() {
×
654
                if m, ok := mutabilityMap[stateMutability.GetText()]; ok {
×
655
                        return m
×
656
                }
×
657
        }
658

659
        return ast_pb.Mutability_NONPAYABLE
×
660
}
661

662
// getVirtualState determines if the Function node is declared as virtual from the parser context.
663
func (f *Function) getVirtualState(ctx *parser.FunctionDefinitionContext) bool {
1✔
664
        for _, virtual := range ctx.AllVirtual() {
2✔
665
                if virtual.GetText() == "virtual" {
2✔
666
                        return true
1✔
667
                }
1✔
668
        }
669

670
        return false
1✔
671
}
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