Skip to content

Commit

Permalink
decoder: Implement semantic tokens for TypeDeclaration
Browse files Browse the repository at this point in the history
  • Loading branch information
radeksimko committed Feb 17, 2023
1 parent cc16479 commit c1073ed
Show file tree
Hide file tree
Showing 3 changed files with 526 additions and 8 deletions.
8 changes: 0 additions & 8 deletions decoder/expr_type_declaration.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package decoder

import (
"context"

"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl-lang/schema"
"github.com/hashicorp/hcl/v2"
)
Expand All @@ -16,11 +13,6 @@ type TypeDeclaration struct {
insideObject bool
}

func (td TypeDeclaration) SemanticTokens(ctx context.Context) []lang.SemanticToken {
// TODO
return nil
}

func isSingleArgTypeName(name string) bool {
return name == "list" || name == "set" || name == "map"
}
133 changes: 133 additions & 0 deletions decoder/expr_type_declaration_semtok.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package decoder

import (
"context"

"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl/v2/hclsyntax"
)

func (td TypeDeclaration) SemanticTokens(ctx context.Context) []lang.SemanticToken {
switch eType := td.expr.(type) {
case *hclsyntax.ScopeTraversalExpr:
if len(eType.Traversal) != 1 {
return []lang.SemanticToken{}
}

if isPrimitiveTypeDeclaration(eType.Traversal.RootName()) {
return []lang.SemanticToken{
{
Type: lang.TokenTypePrimitive,
Modifiers: []lang.SemanticTokenModifier{},
Range: eType.Range(),
},
}
}
case *hclsyntax.FunctionCallExpr:
if isSingleArgTypeName(eType.Name) {
tokens := make([]lang.SemanticToken, 0)

tokens = append(tokens, lang.SemanticToken{
Type: lang.TokenTypeCapsule,
Modifiers: []lang.SemanticTokenModifier{},
Range: eType.NameRange,
})

if len(eType.Args) == 0 {
return tokens
}

if len(eType.Args) == 1 {
cons := TypeDeclaration{
expr: eType.Args[0],
pathCtx: td.pathCtx,
}
tokens = append(tokens, cons.SemanticTokens(ctx)...)

return tokens
}

return []lang.SemanticToken{}
}

if eType.Name == "object" {
tokens := make([]lang.SemanticToken, 0)
tokens = append(tokens, lang.SemanticToken{
Type: lang.TokenTypeCapsule,
Modifiers: []lang.SemanticTokenModifier{},
Range: eType.NameRange,
})

if len(eType.Args) != 1 {
return tokens
}

objExpr, ok := eType.Args[0].(*hclsyntax.ObjectConsExpr)
if !ok {
return []lang.SemanticToken{}
}

cons := TypeDeclaration{
expr: objExpr,
pathCtx: td.pathCtx,
insideObject: true,
}

tokens = append(tokens, cons.SemanticTokens(ctx)...)

return tokens
}

if eType.Name == "tuple" {
tokens := make([]lang.SemanticToken, 0)
tokens = append(tokens, lang.SemanticToken{
Type: lang.TokenTypeCapsule,
Modifiers: []lang.SemanticTokenModifier{},
Range: eType.NameRange,
})

if len(eType.Args) != 1 {
return tokens
}

tupleExpr, ok := eType.Args[0].(*hclsyntax.TupleConsExpr)
if !ok {
return []lang.SemanticToken{}
}

for _, expr := range tupleExpr.Exprs {
cons := TypeDeclaration{
expr: expr,
pathCtx: td.pathCtx,
}
tokens = append(tokens, cons.SemanticTokens(ctx)...)
}

return tokens
}
case *hclsyntax.ObjectConsExpr:
if !td.insideObject {
// no tokens in bare object notation w/out object()
return []lang.SemanticToken{}
}

tokens := make([]lang.SemanticToken, 0)

for _, item := range eType.Items {
tokens = append(tokens, lang.SemanticToken{
Type: lang.TokenAttrName,
Modifiers: []lang.SemanticTokenModifier{},
Range: item.KeyExpr.Range(),
})

cons := TypeDeclaration{
expr: item.ValueExpr,
pathCtx: td.pathCtx,
}
tokens = append(tokens, cons.SemanticTokens(ctx)...)
}

return tokens
}
return nil
}
Loading

0 comments on commit c1073ed

Please sign in to comment.