From 117d18819424faca2c6a269bc73996c1c0bd60ae Mon Sep 17 00:00:00 2001 From: pavel Date: Thu, 27 Aug 2026 18:05:28 +0200 Subject: [PATCH] Use dot notation for enum variants --- README.md | 6 +- cmd/gotlin-lsp/main.go | 2 +- examples/enums.gt | 8 +- examples/mapping.gt | 8 +- internal/lang/enum_test.go | 33 +++-- internal/lang/generate_go.go | 62 ++++++-- internal/lang/lexer.go | 3 - internal/lang/mapping.go | 4 +- internal/lang/parser.go | 29 +--- internal/lang/result_test.go | 8 +- internal/lang/token.go | 133 +++++++++--------- .../snippets/gotlin.code-snippets | 16 +-- .../syntaxes/gotlin.tmLanguage.json | 4 - 13 files changed, 162 insertions(+), 154 deletions(-) diff --git a/README.md b/README.md index 22ee488..8d6a0b8 100644 --- a/README.md +++ b/README.md @@ -109,9 +109,9 @@ enum PaymentResult { fun describe(result: PaymentResult): String { return match (result) { - PaymentResult::Accepted(id) -> id - PaymentResult::Rejected(reason) -> reason - PaymentResult::Pending -> "pending" + PaymentResult.Accepted(id) -> id + PaymentResult.Rejected(reason) -> reason + PaymentResult.Pending -> "pending" } } ``` diff --git a/cmd/gotlin-lsp/main.go b/cmd/gotlin-lsp/main.go index 0e8d59b..b84b64c 100644 --- a/cmd/gotlin-lsp/main.go +++ b/cmd/gotlin-lsp/main.go @@ -646,7 +646,7 @@ func indexSymbols(text string, program *lang.Program) []symbol { } symbols = append(symbols, symbol{Name: decl.Name, Kind: symbolKindEnum, Detail: "enum " + decl.Name, Range: r}) for _, variant := range decl.Variants { - symbols = append(symbols, symbol{Name: variant.Name, Kind: symbolKindVariable, Detail: decl.Name + "::" + variant.Name, Range: r, Targets: []string{decl.Name}}) + symbols = append(symbols, symbol{Name: variant.Name, Kind: symbolKindVariable, Detail: decl.Name + "." + variant.Name, Range: r, Targets: []string{decl.Name}}) } } diff --git a/examples/enums.gt b/examples/enums.gt index ec69ef7..584d8d8 100644 --- a/examples/enums.gt +++ b/examples/enums.gt @@ -8,13 +8,13 @@ enum PaymentResult { fun describe(result: PaymentResult): String { return match (result) { - PaymentResult::Accepted(id) -> "accepted " + id - PaymentResult::Rejected(reason) -> "rejected " + reason - PaymentResult::Pending -> "pending" + PaymentResult.Accepted(id) -> "accepted " + id + PaymentResult.Rejected(reason) -> "rejected " + reason + PaymentResult.Pending -> "pending" } } fun main() { - val result = PaymentResult::Accepted("payment-1") + val result = PaymentResult.Accepted("payment-1") println(describe(result)) } diff --git a/examples/mapping.gt b/examples/mapping.gt index 3b866d6..7720c17 100644 --- a/examples/mapping.gt +++ b/examples/mapping.gt @@ -29,12 +29,12 @@ data class AccountResponse( ) fun main() { - val entity = AccountEntity("account-1", AddressEntity("Berlin"), listOf("active"), EntityState::Active) + val entity = AccountEntity("account-1", AddressEntity("Berlin"), listOf("active"), EntityState.Active) val response = entity.mapTo() println(response.address.city) match (response.state) { - ResponseState::Active -> { println("active") } - ResponseState::Failed(reason) -> { println(reason) } - ResponseState::Pending -> { println("pending") } + ResponseState.Active -> { println("active") } + ResponseState.Failed(reason) -> { println(reason) } + ResponseState.Pending -> { println("pending") } } } diff --git a/internal/lang/enum_test.go b/internal/lang/enum_test.go index c89e22b..a243308 100644 --- a/internal/lang/enum_test.go +++ b/internal/lang/enum_test.go @@ -12,13 +12,13 @@ enum PaymentResult { Accepted(String), Rejected(String), Pending } fun describe(result: PaymentResult): String { var description = "" match (result) { - PaymentResult::Accepted(id) -> { description = id } - PaymentResult::Rejected(reason) -> { description = reason } - PaymentResult::Pending -> { description = "pending" } + PaymentResult.Accepted(id) -> { description = id } + PaymentResult.Rejected(reason) -> { description = reason } + PaymentResult.Pending -> { description = "pending" } } return description } -fun main() { println(describe(PaymentResult::Accepted("p1"))) } +fun main() { println(describe(PaymentResult.Accepted("p1"))) } `) if err != nil { t.Fatal(err) @@ -37,7 +37,7 @@ fun main() { println(describe(PaymentResult::Accepted("p1"))) } func TestRejectNonExhaustiveEnumMatch(t *testing.T) { prog, err := Parse(`package demo enum Result { Ok, Error(String) } -fun use(result: Result) { match (result) { Result::Ok -> { println("ok") } } }`) +fun use(result: Result) { match (result) { Result.Ok -> { println("ok") } } }`) if err != nil { t.Fatal(err) } @@ -50,7 +50,7 @@ fun use(result: Result) { match (result) { Result::Ok -> { println("ok") } } }`) func TestRejectWrongVariantPayloadCount(t *testing.T) { prog, err := Parse(`package demo enum Outcome { Ok(String) } -fun main() { val result = Outcome::Ok() }`) +fun main() { val result = Outcome.Ok() }`) if err != nil { t.Fatal(err) } @@ -60,10 +60,17 @@ fun main() { val result = Outcome::Ok() }`) } } +func TestRejectDoubleColonEnumSyntax(t *testing.T) { + _, err := Parse(`package demo enum State { Ready } fun main() { println(State::Ready) }`) + if err == nil { + t.Fatal("deprecated double-colon enum syntax parsed") + } +} + func TestPayloadlessEnumUsesExactVariantStrings(t *testing.T) { prog, err := Parse(`package demo enum Status { PendingReservation, Initiated } -fun main() { println(Status::PendingReservation) }`) +fun main() { println(Status.PendingReservation) }`) if err != nil { t.Fatal(err) } @@ -83,8 +90,8 @@ func TestGenerateExhaustiveMatchExpression(t *testing.T) { enum AccountType { BASIC, SAVINGS } fun interestRate(accountType: AccountType): Double { return match (accountType) { - AccountType::BASIC -> 0.0 - AccountType::SAVINGS -> 0.02 + AccountType.BASIC -> 0.0 + AccountType.SAVINGS -> 0.02 } }`) if err != nil { @@ -106,8 +113,8 @@ func TestGeneratePayloadMatchExpression(t *testing.T) { enum Outcome { Success(String), Failure(String) } fun message(outcome: Outcome): String { return match (outcome) { - Outcome::Success(value) -> value - Outcome::Failure(reason) -> reason + Outcome.Success(value) -> value + Outcome.Failure(reason) -> reason } }`) if err != nil { @@ -129,8 +136,8 @@ func TestRejectInvalidMatchExpression(t *testing.T) { source string want string }{ - {`package demo enum State { On, Off } fun value(state: State): Int { return match (state) { State::On -> 1 } }`, "missing Off"}, - {`package demo enum State { On, Off } fun value(state: State): Int { return match (state) { State::On -> 1 State::Off -> "off" } }`, "has type String, expected Int"}, + {`package demo enum State { On, Off } fun value(state: State): Int { return match (state) { State.On -> 1 } }`, "missing Off"}, + {`package demo enum State { On, Off } fun value(state: State): Int { return match (state) { State.On -> 1 State.Off -> "off" } }`, "has type String, expected Int"}, } { prog, err := Parse(test.source) if err != nil { diff --git a/internal/lang/generate_go.go b/internal/lang/generate_go.go index cd4b4b5..7d12ac7 100644 --- a/internal/lang/generate_go.go +++ b/internal/lang/generate_go.go @@ -1051,18 +1051,18 @@ func (g *goGenerator) stmt(stmt Stmt, tail []Stmt) error { seen := map[string]bool{} for _, c := range s.Cases { if c.EnumName != enumName { - return fmt.Errorf("match case %s::%s does not match enum %s", c.EnumName, c.VariantName, enumName) + return fmt.Errorf("match case %s.%s does not match enum %s", c.EnumName, c.VariantName, enumName) } if seen[c.VariantName] { - return fmt.Errorf("duplicate match case %s::%s", enumName, c.VariantName) + return fmt.Errorf("duplicate match case %s.%s", enumName, c.VariantName) } seen[c.VariantName] = true variant := enumVariant(decl, c.VariantName) if variant == nil { - return fmt.Errorf("unknown variant %s::%s", enumName, c.VariantName) + return fmt.Errorf("unknown variant %s.%s", enumName, c.VariantName) } if len(c.Bindings) != len(variant.PayloadTypes) { - return fmt.Errorf("match case %s::%s expects %d bindings", enumName, c.VariantName, len(variant.PayloadTypes)) + return fmt.Errorf("match case %s.%s expects %d bindings", enumName, c.VariantName, len(variant.PayloadTypes)) } } for _, variant := range decl.Variants { @@ -1250,6 +1250,16 @@ func (g *goGenerator) expr(expr Expr, expectedType string) (string, error) { } return fmt.Sprintf("%s %s %s", left, e.Op, right), nil case CallExpr: + if selector, ok := e.Callee.(SelectorExpr); ok { + if receiver, ok := selector.Receiver.(IdentExpr); ok { + if receiver.Name == "Result" { + return g.expr(EnumVariantExpr{EnumName: receiver.Name, VariantName: selector.Name, Values: e.Args}, expectedType) + } + if _, ok := g.enums[receiver.Name]; ok { + return g.expr(EnumVariantExpr{EnumName: receiver.Name, VariantName: selector.Name, Values: e.Args}, expectedType) + } + } + } if ident, ok := e.Callee.(IdentExpr); ok && coroutineBuiltins[ident.Name] { switch ident.Name { case "runBlocking": @@ -1607,6 +1617,18 @@ func (g *goGenerator) expr(expr Expr, expectedType string) (string, error) { } return call, nil case SelectorExpr: + if receiver, ok := e.Receiver.(IdentExpr); ok { + if decl, ok := g.enums[receiver.Name]; ok { + variant := enumVariant(decl, e.Name) + if variant == nil { + return "", fmt.Errorf("unknown variant %s.%s", receiver.Name, e.Name) + } + if len(variant.PayloadTypes) != 0 { + return "", fmt.Errorf("variant %s.%s requires %d values", receiver.Name, e.Name, len(variant.PayloadTypes)) + } + return g.expr(EnumVariantExpr{EnumName: receiver.Name, VariantName: e.Name}, expectedType) + } + } if receiverType := g.exprType(e.Receiver); strings.HasSuffix(receiverType, "?") { return "", fmt.Errorf("nullable receiver %s requires ?. or !! before .%s", receiverType, e.Name) } @@ -1685,11 +1707,11 @@ func (g *goGenerator) expr(expr Expr, expectedType string) (string, error) { if e.EnumName == "Result" { base, args, ok := parseGenericType(expectedType) if !ok || base != "Result" || len(args) != 2 { - return "", fmt.Errorf("Result::%s requires an expected Result type", e.VariantName) + return "", fmt.Errorf("Result.%s requires an expected Result type", e.VariantName) } if e.VariantName == "Ok" { if len(e.Values) != 1 { - return "", fmt.Errorf("Result::Ok expects one value") + return "", fmt.Errorf("Result.Ok expects one value") } value, err := g.expr(e.Values[0], args[0]) if err != nil { @@ -1699,7 +1721,7 @@ func (g *goGenerator) expr(expr Expr, expectedType string) (string, error) { } if e.VariantName == "Err" { if len(e.Values) != 1 { - return "", fmt.Errorf("Result::Err expects one error") + return "", fmt.Errorf("Result.Err expects one error") } value, err := g.expr(e.Values[0], "Error") if err != nil { @@ -1721,10 +1743,10 @@ func (g *goGenerator) expr(expr Expr, expectedType string) (string, error) { } } if variant == nil { - return "", fmt.Errorf("unknown variant %s::%s", e.EnumName, e.VariantName) + return "", fmt.Errorf("unknown variant %s.%s", e.EnumName, e.VariantName) } if len(e.Values) != len(variant.PayloadTypes) { - return "", fmt.Errorf("variant %s::%s expects %d values", e.EnumName, e.VariantName, len(variant.PayloadTypes)) + return "", fmt.Errorf("variant %s.%s expects %d values", e.EnumName, e.VariantName, len(variant.PayloadTypes)) } if enumIsString(decl) { return e.EnumName + e.VariantName, nil @@ -1757,18 +1779,18 @@ func (g *goGenerator) valueMatch(match MatchExpr, expectedType string) (string, seen := map[string]bool{} for _, c := range match.Cases { if c.EnumName != enumName { - return "", fmt.Errorf("match case %s::%s does not match enum %s", c.EnumName, c.VariantName, enumName) + return "", fmt.Errorf("match case %s.%s does not match enum %s", c.EnumName, c.VariantName, enumName) } if seen[c.VariantName] { - return "", fmt.Errorf("duplicate match case %s::%s", enumName, c.VariantName) + return "", fmt.Errorf("duplicate match case %s.%s", enumName, c.VariantName) } seen[c.VariantName] = true variant := enumVariant(decl, c.VariantName) if variant == nil { - return "", fmt.Errorf("unknown variant %s::%s", enumName, c.VariantName) + return "", fmt.Errorf("unknown variant %s.%s", enumName, c.VariantName) } if len(c.Bindings) != len(variant.PayloadTypes) { - return "", fmt.Errorf("match case %s::%s expects %d bindings", enumName, c.VariantName, len(variant.PayloadTypes)) + return "", fmt.Errorf("match case %s.%s expects %d bindings", enumName, c.VariantName, len(variant.PayloadTypes)) } } for _, variant := range decl.Variants { @@ -1804,7 +1826,7 @@ func (g *goGenerator) valueMatch(match MatchExpr, expectedType string) (string, armType := g.exprType(c.Value) g.popScope() if armType != "" && armType != resultType { - return "", fmt.Errorf("match expression arm %s::%s has type %s, expected %s", enumName, c.VariantName, armType, resultType) + return "", fmt.Errorf("match expression arm %s.%s has type %s, expected %s", enumName, c.VariantName, armType, resultType) } } value, err := g.expr(match.Value, enumName) @@ -3110,6 +3132,13 @@ func (g *goGenerator) exprType(expr Expr) string { case BoolExpr: return "Boolean" case CallExpr: + if selector, ok := e.Callee.(SelectorExpr); ok { + if receiver, ok := selector.Receiver.(IdentExpr); ok { + if _, ok := g.enums[receiver.Name]; ok { + return receiver.Name + } + } + } if ident, ok := e.Callee.(IdentExpr); ok && ident.Name == "keys" && len(e.Args) == 1 { if _, args, ok := parseGenericType(g.exprType(e.Args[0])); ok && len(args) == 2 { return "List<" + args[0] + ">" @@ -3173,6 +3202,11 @@ func (g *goGenerator) exprType(expr Expr) string { } } case SelectorExpr: + if receiver, ok := e.Receiver.(IdentExpr); ok { + if _, ok := g.enums[receiver.Name]; ok { + return receiver.Name + } + } if class, ok := g.classForType(g.exprType(e.Receiver)); ok { for _, field := range class.Fields { if field.Name == e.Name { diff --git a/internal/lang/lexer.go b/internal/lang/lexer.go index 99ce740..54646c2 100644 --- a/internal/lang/lexer.go +++ b/internal/lang/lexer.go @@ -93,9 +93,6 @@ func (l *lexer) next() (token, error) { case '.': return token{kind: tokenDot, lexeme: ".", pos: start}, nil case ':': - if l.match(':') { - return token{kind: tokenDoubleColon, lexeme: "::", pos: start}, nil - } return token{kind: tokenColon, lexeme: ":", pos: start}, nil case ';': return token{kind: tokenSemicolon, lexeme: ";", pos: start}, nil diff --git a/internal/lang/mapping.go b/internal/lang/mapping.go index 4d25dd2..a9b09d6 100644 --- a/internal/lang/mapping.go +++ b/internal/lang/mapping.go @@ -97,7 +97,7 @@ func (g *goGenerator) validateMapping(source, target, path string, seen map[stri } for _, sourceVariant := range sourceEnum.Variants { targetVariant := enumVariant(targetEnum, sourceVariant.Name) - variantPath := path + "::" + sourceVariant.Name + variantPath := path + "." + sourceVariant.Name if targetVariant == nil { return fmt.Errorf("cannot map %s: target enum %s has no compatible variant", variantPath, targetEnum.Name) } @@ -158,7 +158,7 @@ func (g *goGenerator) emitMapping(pair mappingPair) error { g.indentLevel++ fields := make([]string, 0, len(sourceVariant.PayloadTypes)) for i := range sourceVariant.PayloadTypes { - expr, err := g.mappingExpr(fmt.Sprintf("value.Value%d", i), sourceVariant.PayloadTypes[i], targetVariant.PayloadTypes[i], sourceEnum.Name+"::"+sourceVariant.Name) + expr, err := g.mappingExpr(fmt.Sprintf("value.Value%d", i), sourceVariant.PayloadTypes[i], targetVariant.PayloadTypes[i], sourceEnum.Name+"."+sourceVariant.Name) if err != nil { return err } diff --git a/internal/lang/parser.go b/internal/lang/parser.go index 711bc29..86b0b7c 100644 --- a/internal/lang/parser.go +++ b/internal/lang/parser.go @@ -751,7 +751,7 @@ func (p *parser) parseMatch() (Stmt, error) { if err != nil { return nil, err } - if _, err := p.expect(tokenDoubleColon, "expected '::' in match case"); err != nil { + if _, err := p.expect(tokenDot, "expected '.' in match case"); err != nil { return nil, err } variant, err := p.expect(tokenIdent, "expected variant name") @@ -813,7 +813,7 @@ func (p *parser) parseMatchExpr() (Expr, error) { if err != nil { return nil, err } - if _, err := p.expect(tokenDoubleColon, "expected '::' in match case"); err != nil { + if _, err := p.expect(tokenDot, "expected '.' in match case"); err != nil { return nil, err } variant, err := p.expect(tokenIdent, "expected variant name") @@ -1029,31 +1029,6 @@ func (p *parser) parsePrefix() (Expr, error) { tok := p.advance() switch tok.kind { case tokenIdent: - if p.match(tokenDoubleColon) { - variant, err := p.expect(tokenIdent, "expected enum variant") - if err != nil { - return nil, err - } - var values []Expr - if p.match(tokenLParen) { - if !p.check(tokenRParen) { - for { - value, err := p.parseExpr(0) - if err != nil { - return nil, err - } - values = append(values, value) - if !p.match(tokenComma) { - break - } - } - } - if _, err := p.expect(tokenRParen, "expected ')' after variant values"); err != nil { - return nil, err - } - } - return p.parsePostfix(EnumVariantExpr{EnumName: tok.lexeme, VariantName: variant.lexeme, Values: values}) - } return p.parsePostfix(IdentExpr{Name: tok.lexeme}) case tokenInt: return IntExpr{Value: tok.lexeme}, nil diff --git a/internal/lang/result_test.go b/internal/lang/result_test.go index 1965560..c685329 100644 --- a/internal/lang/result_test.go +++ b/internal/lang/result_test.go @@ -10,7 +10,7 @@ func TestResultQuestionPropagatesGoError(t *testing.T) { import strconv fun parse(value: String): Result { val parsed = strconv.atoi(value)? - return Result::Ok(parsed) + return Result.Ok(parsed) }`) if err != nil { t.Fatal(err) @@ -74,8 +74,8 @@ fun changeDirectory(path: String): Result { return os.chdir(path) } func TestResultQuestionPropagatesGotlinResult(t *testing.T) { prog, err := Parse(`package demo import errors -fun inner(ok: Boolean): Result { if (!ok) { return Result::Err(errors.new("failed")) }; return Result::Ok("ok") } -fun outer(): Result { val value = inner(true)?; return Result::Ok(value) }`) +fun inner(ok: Boolean): Result { if (!ok) { return Result.Err(errors.new("failed")) }; return Result.Ok("ok") } +fun outer(): Result { val value = inner(true)?; return Result.Ok(value) }`) if err != nil { t.Fatal(err) } @@ -127,7 +127,7 @@ import strconv fun parse(value: String): Result { val input = value val parsed = strconv.atoi(input)? - return Result::Ok(parsed) + return Result.Ok(parsed) }`) if err != nil { t.Fatal(err) diff --git a/internal/lang/token.go b/internal/lang/token.go index 5dbded9..c027d55 100644 --- a/internal/lang/token.go +++ b/internal/lang/token.go @@ -3,73 +3,72 @@ package lang type tokenKind string const ( - tokenEOF tokenKind = "EOF" - tokenIdent tokenKind = "IDENT" - tokenInt tokenKind = "INT" - tokenFloat tokenKind = "FLOAT" - tokenString tokenKind = "STRING" - tokenTrue tokenKind = "TRUE" - tokenFalse tokenKind = "FALSE" - tokenNull tokenKind = "NULL" - tokenImport tokenKind = "IMPORT" - tokenPackage tokenKind = "PACKAGE" - tokenClass tokenKind = "CLASS" - tokenData tokenKind = "DATA" - tokenWorker tokenKind = "WORKER" - tokenInterface tokenKind = "INTERFACE" - tokenEnum tokenKind = "ENUM" - tokenMatch tokenKind = "MATCH" - tokenFun tokenKind = "FUN" - tokenSuspend tokenKind = "SUSPEND" - tokenOverride tokenKind = "OVERRIDE" - tokenPrivate tokenKind = "PRIVATE" - tokenVal tokenKind = "VAL" - tokenVar tokenKind = "VAR" - tokenIf tokenKind = "IF" - tokenElse tokenKind = "ELSE" - tokenWhile tokenKind = "WHILE" - tokenFor tokenKind = "FOR" - tokenIn tokenKind = "IN" - tokenSelect tokenKind = "SELECT" - tokenReturn tokenKind = "RETURN" - tokenGo tokenKind = "GO" - tokenDefer tokenKind = "DEFER" - tokenTry tokenKind = "TRY" - tokenCatch tokenKind = "CATCH" - tokenThrow tokenKind = "THROW" - tokenLParen tokenKind = "(" - tokenRParen tokenKind = ")" - tokenLBrace tokenKind = "{" - tokenRBrace tokenKind = "}" - tokenLBracket tokenKind = "[" - tokenRBracket tokenKind = "]" - tokenComma tokenKind = "," - tokenDot tokenKind = "." - tokenColon tokenKind = ":" - tokenDoubleColon tokenKind = "::" - tokenSemicolon tokenKind = ";" - tokenPlus tokenKind = "+" - tokenMinus tokenKind = "-" - tokenStar tokenKind = "*" - tokenSlash tokenKind = "/" - tokenPercent tokenKind = "%" - tokenBang tokenKind = "!" - tokenAssign tokenKind = "=" - tokenPlusAssign tokenKind = "+=" - tokenEq tokenKind = "==" - tokenNeq tokenKind = "!=" - tokenLt tokenKind = "<" - tokenLte tokenKind = "<=" - tokenGt tokenKind = ">" - tokenGte tokenKind = ">=" - tokenAnd tokenKind = "&&" - tokenAmp tokenKind = "&" - tokenAt tokenKind = "@" - tokenQuestion tokenKind = "?" - tokenSafeDot tokenKind = "?." - tokenDoubleBang tokenKind = "!!" - tokenOr tokenKind = "||" - tokenArrow tokenKind = "->" + tokenEOF tokenKind = "EOF" + tokenIdent tokenKind = "IDENT" + tokenInt tokenKind = "INT" + tokenFloat tokenKind = "FLOAT" + tokenString tokenKind = "STRING" + tokenTrue tokenKind = "TRUE" + tokenFalse tokenKind = "FALSE" + tokenNull tokenKind = "NULL" + tokenImport tokenKind = "IMPORT" + tokenPackage tokenKind = "PACKAGE" + tokenClass tokenKind = "CLASS" + tokenData tokenKind = "DATA" + tokenWorker tokenKind = "WORKER" + tokenInterface tokenKind = "INTERFACE" + tokenEnum tokenKind = "ENUM" + tokenMatch tokenKind = "MATCH" + tokenFun tokenKind = "FUN" + tokenSuspend tokenKind = "SUSPEND" + tokenOverride tokenKind = "OVERRIDE" + tokenPrivate tokenKind = "PRIVATE" + tokenVal tokenKind = "VAL" + tokenVar tokenKind = "VAR" + tokenIf tokenKind = "IF" + tokenElse tokenKind = "ELSE" + tokenWhile tokenKind = "WHILE" + tokenFor tokenKind = "FOR" + tokenIn tokenKind = "IN" + tokenSelect tokenKind = "SELECT" + tokenReturn tokenKind = "RETURN" + tokenGo tokenKind = "GO" + tokenDefer tokenKind = "DEFER" + tokenTry tokenKind = "TRY" + tokenCatch tokenKind = "CATCH" + tokenThrow tokenKind = "THROW" + tokenLParen tokenKind = "(" + tokenRParen tokenKind = ")" + tokenLBrace tokenKind = "{" + tokenRBrace tokenKind = "}" + tokenLBracket tokenKind = "[" + tokenRBracket tokenKind = "]" + tokenComma tokenKind = "," + tokenDot tokenKind = "." + tokenColon tokenKind = ":" + tokenSemicolon tokenKind = ";" + tokenPlus tokenKind = "+" + tokenMinus tokenKind = "-" + tokenStar tokenKind = "*" + tokenSlash tokenKind = "/" + tokenPercent tokenKind = "%" + tokenBang tokenKind = "!" + tokenAssign tokenKind = "=" + tokenPlusAssign tokenKind = "+=" + tokenEq tokenKind = "==" + tokenNeq tokenKind = "!=" + tokenLt tokenKind = "<" + tokenLte tokenKind = "<=" + tokenGt tokenKind = ">" + tokenGte tokenKind = ">=" + tokenAnd tokenKind = "&&" + tokenAmp tokenKind = "&" + tokenAt tokenKind = "@" + tokenQuestion tokenKind = "?" + tokenSafeDot tokenKind = "?." + tokenDoubleBang tokenKind = "!!" + tokenOr tokenKind = "||" + tokenArrow tokenKind = "->" ) var keywords = map[string]tokenKind{ diff --git a/tools/vscode-gotlin/snippets/gotlin.code-snippets b/tools/vscode-gotlin/snippets/gotlin.code-snippets index be95183..477320a 100644 --- a/tools/vscode-gotlin/snippets/gotlin.code-snippets +++ b/tools/vscode-gotlin/snippets/gotlin.code-snippets @@ -67,13 +67,13 @@ "prefix": "match", "body": [ "match (${1:result}) {", - " ${2:Result}::${3:Success}(${4:value}) -> {", + " ${2:Result}.${3:Success}(${4:value}) -> {", " $5", " }", - " ${2:Result}::${6:Failure}(${7:reason}) -> {", + " ${2:Result}.${6:Failure}(${7:reason}) -> {", " $8", " }", - " ${2:Result}::${9:Pending} -> {", + " ${2:Result}.${9:Pending} -> {", " $0", " }", "}" @@ -84,8 +84,8 @@ "prefix": "matchvalue", "body": [ "val ${1:value} = match (${2:result}) {", - " ${3:Result}::${4:Success}(${5:item}) -> ${5:item}", - " ${3:Result}::${6:Failure}(${7:reason}) -> ${7:reason}", + " ${3:Result}.${4:Success}(${5:item}) -> ${5:item}", + " ${3:Result}.${6:Failure}(${7:reason}) -> ${7:reason}", " $0", "}" ], @@ -111,7 +111,7 @@ "body": [ "fun ${1:name}(${2}): Result<${3:Value}, Error> {", " val ${4:value} = ${5:operation}()?", - " return Result::Ok(${4:value})", + " return Result.Ok(${4:value})", "}" ], "description": "Function with Rust-style Result propagation" @@ -120,8 +120,8 @@ "prefix": "resultmatch", "body": [ "match (${1:result}) {", - " Result::Ok(${2:value}) -> { $3 }", - " Result::Err(${4:error}) -> { $0 }", + " Result.Ok(${2:value}) -> { $3 }", + " Result.Err(${4:error}) -> { $0 }", "}" ], "description": "Match a Result value" diff --git a/tools/vscode-gotlin/syntaxes/gotlin.tmLanguage.json b/tools/vscode-gotlin/syntaxes/gotlin.tmLanguage.json index afd07fc..505b926 100644 --- a/tools/vscode-gotlin/syntaxes/gotlin.tmLanguage.json +++ b/tools/vscode-gotlin/syntaxes/gotlin.tmLanguage.json @@ -356,10 +356,6 @@ "name": "keyword.operator.arrow.gotlin", "match": "->" }, - { - "name": "punctuation.accessor.enum.gotlin", - "match": "::" - }, { "name": "keyword.operator.arithmetic.gotlin", "match": "[+\\-*/%<>]"