Use dot notation for enum variants
This commit is contained in:
parent
ab783c33ed
commit
117d188194
13 changed files with 162 additions and 154 deletions
|
|
@ -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<T, Error> type", e.VariantName)
|
||||
return "", fmt.Errorf("Result.%s requires an expected Result<T, Error> 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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue