Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/build/build/soong/mk2rbc/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 17 kB image not shown  

Quelle  expr.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mk2rbc

import (
 "fmt"
 "strings"
)

// Represents an expression in the Starlark code. An expression has a type.
type starlarkExpr interface {
 starlarkNode
 typ() starlarkType
 // Emit the code to copy the expression, otherwise we will end up
 // with source and target pointing to the same list.
 emitListVarCopy(gctx *generationContext)
 // Return the expression, calling the transformer func for
 // every expression in the tree. If the transformer func returns non-nil,
 // its result is used in place of the expression it was called with in the
 // resulting expression. The resulting starlarkExpr will contain as many
 // of the same objects from the original expression as possible.
 transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr
}

func maybeString(expr starlarkExpr) (string, bool) {
 if x, ok := expr.(*stringLiteralExpr); ok {
  return x.literal, true
 }
 return "", false
}

type stringLiteralExpr struct {
 literal string
}

func (s *stringLiteralExpr) emit(gctx *generationContext) {
 gctx.writef("%q", s.literal)
}

func (_ *stringLiteralExpr) typ() starlarkType {
 return starlarkTypeString
}

func (s *stringLiteralExpr) emitListVarCopy(gctx *generationContext) {
 s.emit(gctx)
}

func (s *stringLiteralExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 if replacement := transformer(s); replacement != nil {
  return replacement
 } else {
  return s
 }
}

// Integer literal
type intLiteralExpr struct {
 literal int
}

func (s *intLiteralExpr) emit(gctx *generationContext) {
 gctx.writef("%d", s.literal)
}

func (_ *intLiteralExpr) typ() starlarkType {
 return starlarkTypeInt
}

func (s *intLiteralExpr) emitListVarCopy(gctx *generationContext) {
 s.emit(gctx)
}

func (s *intLiteralExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 if replacement := transformer(s); replacement != nil {
  return replacement
 } else {
  return s
 }
}

// Boolean literal
type boolLiteralExpr struct {
 literal bool
}

func (b *boolLiteralExpr) emit(gctx *generationContext) {
 if b.literal {
  gctx.write("True")
 } else {
  gctx.write("False")
 }
}

func (_ *boolLiteralExpr) typ() starlarkType {
 return starlarkTypeBool
}

func (b *boolLiteralExpr) emitListVarCopy(gctx *generationContext) {
 b.emit(gctx)
}

func (b *boolLiteralExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 if replacement := transformer(b); replacement != nil {
  return replacement
 } else {
  return b
 }
}

type globalsExpr struct {
}

func (g *globalsExpr) emit(gctx *generationContext) {
 gctx.write("g")
}

func (g *globalsExpr) typ() starlarkType {
 return starlarkTypeUnknown
}

func (g *globalsExpr) emitListVarCopy(gctx *generationContext) {
 g.emit(gctx)
}

func (g *globalsExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 if replacement := transformer(g); replacement != nil {
  return replacement
 } else {
  return g
 }
}

// interpolateExpr represents Starlark's interpolation operator <string> % list
// we break <string> into a list of chunks, i.e., "first%second%third" % (X, Y)
// will have chunks = ["first", "second", "third"] and args = [X, Y]
type interpolateExpr struct {
 chunks []string // string chunks, separated by '%'
 args   []starlarkExpr
}

func NewInterpolateExpr(parts []starlarkExpr) starlarkExpr {
 result := &interpolateExpr{}
 needString := true
 for _, part := range parts {
  if needString {
   if strLit, ok := part.(*stringLiteralExpr); ok {
    result.chunks = append(result.chunks, strLit.literal)
   } else {
    result.chunks = append(result.chunks, "")
   }
   needString = false
  } else {
   if strLit, ok := part.(*stringLiteralExpr); ok {
    result.chunks[len(result.chunks)-1] += strLit.literal
   } else {
    result.args = append(result.args, part)
    needString = true
   }
  }
 }
 if len(result.chunks) == len(result.args) {
  result.chunks = append(result.chunks, "")
 }
 if len(result.args) == 0 {
  return &stringLiteralExpr{literal: strings.Join(result.chunks, "")}
 }
 return result
}

func (xi *interpolateExpr) emit(gctx *generationContext) {
 if len(xi.chunks) != len(xi.args)+1 {
  panic(fmt.Errorf("malformed interpolateExpr: #chunks(%d) != #args(%d)+1",
   len(xi.chunks), len(xi.args)))
 }
 // Generate format as join of chunks, but first escape '%' in them
 format := strings.ReplaceAll(xi.chunks[0], "%", "%%")
 for _, chunk := range xi.chunks[1:] {
  format += "%s" + strings.ReplaceAll(chunk, "%", "%%")
 }
 gctx.writef("%q %% ", format)
 emitArg := func(arg starlarkExpr) {
  if arg.typ() == starlarkTypeList {
   gctx.write(`" ".join(`)
   arg.emit(gctx)
   gctx.write(`)`)
  } else {
   arg.emit(gctx)
  }
 }
 if len(xi.args) == 1 {
  emitArg(xi.args[0])
 } else {
  sep := "("
  for _, arg := range xi.args {
   gctx.write(sep)
   emitArg(arg)
   sep = ", "
  }
  gctx.write(")")
 }
}

func (_ *interpolateExpr) typ() starlarkType {
 return starlarkTypeString
}

func (xi *interpolateExpr) emitListVarCopy(gctx *generationContext) {
 xi.emit(gctx)
}

func (xi *interpolateExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 for i := range xi.args {
  xi.args[i] = xi.args[i].transform(transformer)
 }
 if replacement := transformer(xi); replacement != nil {
  return replacement
 } else {
  return xi
 }
}

type variableRefExpr struct {
 ref variable
}

func NewVariableRefExpr(ref variable) starlarkExpr {
 if predefined, ok := ref.(*predefinedVariable); ok {
  return predefined.value
 }
 return &variableRefExpr{ref}
}

func (v *variableRefExpr) emit(gctx *generationContext) {
 v.ref.emitGet(gctx)
}

func (v *variableRefExpr) typ() starlarkType {
 return v.ref.valueType()
}

func (v *variableRefExpr) emitListVarCopy(gctx *generationContext) {
 v.emit(gctx)
 if v.typ() == starlarkTypeList {
  gctx.write("[:]") // this will copy the list
 }
}

func (v *variableRefExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 if replacement := transformer(v); replacement != nil {
  return replacement
 } else {
  return v
 }
}

type toStringExpr struct {
 expr starlarkExpr
}

func (s *toStringExpr) emit(ctx *generationContext) {
 switch s.expr.typ() {
 case starlarkTypeString, starlarkTypeUnknown:
  // Assume unknown types are strings already.
  s.expr.emit(ctx)
 case starlarkTypeList:
  ctx.write(`" ".join(`)
  s.expr.emit(ctx)
  ctx.write(")")
 case starlarkTypeInt:
  ctx.write(`("%d" % (`)
  s.expr.emit(ctx)
  ctx.write("))")
 case starlarkTypeBool:
  ctx.write(`("true" if (`)
  s.expr.emit(ctx)
  ctx.write(`) else "")`)
 case starlarkTypeVoid:
  ctx.write(`""`)
 default:
  panic("Unknown starlark type!")
 }
}

func (s *toStringExpr) typ() starlarkType {
 return starlarkTypeString
}

func (s *toStringExpr) emitListVarCopy(gctx *generationContext) {
 s.emit(gctx)
}

func (s *toStringExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 s.expr = s.expr.transform(transformer)
 if replacement := transformer(s); replacement != nil {
  return replacement
 } else {
  return s
 }
}

type notExpr struct {
 expr starlarkExpr
}

func (n *notExpr) emit(ctx *generationContext) {
 ctx.write("not ")
 n.expr.emit(ctx)
}

func (_ *notExpr) typ() starlarkType {
 return starlarkTypeBool
}

func (n *notExpr) emitListVarCopy(gctx *generationContext) {
 n.emit(gctx)
}

func (n *notExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 n.expr = n.expr.transform(transformer)
 if replacement := transformer(n); replacement != nil {
  return replacement
 } else {
  return n
 }
}

type eqExpr struct {
 left, right starlarkExpr
 isEq        bool // if false, it's !=
}

func (eq *eqExpr) emit(gctx *generationContext) {
 if eq.left.typ() != eq.right.typ() {
  eq.left = &toStringExpr{expr: eq.left}
  eq.right = &toStringExpr{expr: eq.right}
 }

 // General case
 eq.left.emit(gctx)
 if eq.isEq {
  gctx.write(" == ")
 } else {
  gctx.write(" != ")
 }
 eq.right.emit(gctx)
}

func (_ *eqExpr) typ() starlarkType {
 return starlarkTypeBool
}

func (eq *eqExpr) emitListVarCopy(gctx *generationContext) {
 eq.emit(gctx)
}

func (eq *eqExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 eq.left = eq.left.transform(transformer)
 eq.right = eq.right.transform(transformer)
 if replacement := transformer(eq); replacement != nil {
  return replacement
 } else {
  return eq
 }
}

type listExpr struct {
 items []starlarkExpr
}

func (l *listExpr) emit(gctx *generationContext) {
 if !gctx.inAssignment || len(l.items) < 2 {
  gctx.write("[")
  sep := ""
  for _, item := range l.items {
   gctx.write(sep)
   item.emit(gctx)
   sep = ", "
  }
  gctx.write("]")
  return
 }

 gctx.write("[")
 gctx.indentLevel += 2

 for _, item := range l.items {
  gctx.newLine()
  item.emit(gctx)
  gctx.write(",")
 }
 gctx.indentLevel -= 2
 gctx.newLine()
 gctx.write("]")
}

func (_ *listExpr) typ() starlarkType {
 return starlarkTypeList
}

func (l *listExpr) emitListVarCopy(gctx *generationContext) {
 l.emit(gctx)
}

func (l *listExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 itemsCopy := make([]starlarkExpr, len(l.items))
 for i, item := range l.items {
  itemsCopy[i] = item.transform(transformer)
 }
 l.items = itemsCopy
 if replacement := transformer(l); replacement != nil {
  return replacement
 } else {
  return l
 }
}

func newStringListExpr(items []string) *listExpr {
 v := listExpr{}
 for _, item := range items {
  v.items = append(v.items, &stringLiteralExpr{item})
 }
 return &v
}

// concatExpr generates expr1 + expr2 + ... + exprN in Starlark.
type concatExpr struct {
 items []starlarkExpr
}

func (c *concatExpr) emit(gctx *generationContext) {
 if len(c.items) == 1 {
  c.items[0].emit(gctx)
  return
 }

 if !gctx.inAssignment {
  c.items[0].emit(gctx)
  for _, item := range c.items[1:] {
   gctx.write(" + ")
   item.emit(gctx)
  }
  return
 }
 gctx.write("(")
 c.items[0].emit(gctx)
 gctx.indentLevel += 2
 for _, item := range c.items[1:] {
  gctx.write(" +")
  gctx.newLine()
  item.emit(gctx)
 }
 gctx.write(")")
 gctx.indentLevel -= 2
}

func (_ *concatExpr) typ() starlarkType {
 return starlarkTypeList
}

func (c *concatExpr) emitListVarCopy(gctx *generationContext) {
 c.emit(gctx)
}

func (c *concatExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 itemsCopy := make([]starlarkExpr, len(c.items))
 for i, item := range c.items {
  itemsCopy[i] = item.transform(transformer)
 }
 c.items = itemsCopy
 if replacement := transformer(c); replacement != nil {
  return replacement
 } else {
  return c
 }
}

// inExpr generates <expr> [not] in <list>
type inExpr struct {
 expr  starlarkExpr
 list  starlarkExpr
 isNot bool
}

func (i *inExpr) emit(gctx *generationContext) {
 i.expr.emit(gctx)
 if i.isNot {
  gctx.write(" not in ")
 } else {
  gctx.write(" in ")
 }
 i.list.emit(gctx)
}

func (_ *inExpr) typ() starlarkType {
 return starlarkTypeBool
}

func (i *inExpr) emitListVarCopy(gctx *generationContext) {
 i.emit(gctx)
}

func (i *inExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 i.expr = i.expr.transform(transformer)
 i.list = i.list.transform(transformer)
 if replacement := transformer(i); replacement != nil {
  return replacement
 } else {
  return i
 }
}

type indexExpr struct {
 array starlarkExpr
 index starlarkExpr
}

func (ix *indexExpr) emit(gctx *generationContext) {
 ix.array.emit(gctx)
 gctx.write("[")
 ix.index.emit(gctx)
 gctx.write("]")
}

func (ix *indexExpr) typ() starlarkType {
 return starlarkTypeString
}

func (ix *indexExpr) emitListVarCopy(gctx *generationContext) {
 ix.emit(gctx)
}

func (ix *indexExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 ix.array = ix.array.transform(transformer)
 ix.index = ix.index.transform(transformer)
 if replacement := transformer(ix); replacement != nil {
  return replacement
 } else {
  return ix
 }
}

type callExpr struct {
 object     starlarkExpr // nil if static call
 name       string
 args       []starlarkExpr
 returnType starlarkType
}

func (cx *callExpr) emit(gctx *generationContext) {
 if cx.object != nil {
  gctx.write("(")
  cx.object.emit(gctx)
  gctx.write(")")
  gctx.write(".", cx.name, "(")
 } else {
  gctx.write(cx.name, "(")
 }
 sep := ""
 for _, arg := range cx.args {
  gctx.write(sep)
  arg.emit(gctx)
  sep = ", "
 }
 gctx.write(")")
}

func (cx *callExpr) typ() starlarkType {
 return cx.returnType
}

func (cx *callExpr) emitListVarCopy(gctx *generationContext) {
 cx.emit(gctx)
}

func (cx *callExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 if cx.object != nil {
  cx.object = cx.object.transform(transformer)
 }
 for i := range cx.args {
  cx.args[i] = cx.args[i].transform(transformer)
 }
 if replacement := transformer(cx); replacement != nil {
  return replacement
 } else {
  return cx
 }
}

type ifExpr struct {
 condition starlarkExpr
 ifTrue    starlarkExpr
 ifFalse   starlarkExpr
}

func (i *ifExpr) emit(gctx *generationContext) {
 gctx.write("(")
 i.ifTrue.emit(gctx)
 gctx.write(" if ")
 i.condition.emit(gctx)
 gctx.write(" else ")
 i.ifFalse.emit(gctx)
 gctx.write(")")
}

func (i *ifExpr) typ() starlarkType {
 tType := i.ifTrue.typ()
 fType := i.ifFalse.typ()
 if tType != fType && tType != starlarkTypeUnknown && fType != starlarkTypeUnknown {
  panic("Conflicting types in if expression")
 }
 if tType != starlarkTypeUnknown {
  return tType
 } else {
  return fType
 }
}

func (i *ifExpr) emitListVarCopy(gctx *generationContext) {
 i.emit(gctx)
}

func (i *ifExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 i.condition = i.condition.transform(transformer)
 i.ifTrue = i.ifTrue.transform(transformer)
 i.ifFalse = i.ifFalse.transform(transformer)
 if replacement := transformer(i); replacement != nil {
  return replacement
 } else {
  return i
 }
}

type identifierExpr struct {
 name string
}

func (i *identifierExpr) emit(gctx *generationContext) {
 gctx.write(i.name)
}

func (i *identifierExpr) typ() starlarkType {
 return starlarkTypeUnknown
}

func (i *identifierExpr) emitListVarCopy(gctx *generationContext) {
 i.emit(gctx)
}

func (i *identifierExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 if replacement := transformer(i); replacement != nil {
  return replacement
 } else {
  return i
 }
}

type foreachExpr struct {
 varName string
 list    starlarkExpr
 action  starlarkExpr
}

func (f *foreachExpr) emit(gctx *generationContext) {
 gctx.write("[")
 f.action.emit(gctx)
 gctx.write(" for " + f.varName + " in ")
 f.list.emit(gctx)
 gctx.write("]")
}

func (f *foreachExpr) typ() starlarkType {
 return starlarkTypeList
}

func (f *foreachExpr) emitListVarCopy(gctx *generationContext) {
 f.emit(gctx)
}

func (f *foreachExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 f.list = f.list.transform(transformer)
 f.action = f.action.transform(transformer)
 if replacement := transformer(f); replacement != nil {
  return replacement
 } else {
  return f
 }
}

type binaryOpExpr struct {
 left, right starlarkExpr
 op          string
 returnType  starlarkType
}

func (b *binaryOpExpr) emit(gctx *generationContext) {
 b.left.emit(gctx)
 gctx.write(" " + b.op + " ")
 b.right.emit(gctx)
}

func (b *binaryOpExpr) typ() starlarkType {
 return b.returnType
}

func (b *binaryOpExpr) emitListVarCopy(gctx *generationContext) {
 b.emit(gctx)
}

func (b *binaryOpExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 b.left = b.left.transform(transformer)
 b.right = b.right.transform(transformer)
 if replacement := transformer(b); replacement != nil {
  return replacement
 } else {
  return b
 }
}

type badExpr struct {
 errorLocation ErrorLocation
 message       string
}

func (b *badExpr) emit(gctx *generationContext) {
 gctx.emitConversionError(b.errorLocation, b.message)
}

func (_ *badExpr) typ() starlarkType {
 return starlarkTypeUnknown
}

func (b *badExpr) emitListVarCopy(gctx *generationContext) {
 b.emit(gctx)
}

func (b *badExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
 if replacement := transformer(b); replacement != nil {
  return replacement
 } else {
  return b
 }
}

func maybeConvertToStringList(expr starlarkExpr) starlarkExpr {
 if xString, ok := expr.(*stringLiteralExpr); ok {
  return newStringListExpr(strings.Fields(xString.literal))
 }
 return expr
}

func isEmptyString(expr starlarkExpr) bool {
 x, ok := expr.(*stringLiteralExpr)
 return ok && x.literal == ""
}

func negateExpr(expr starlarkExpr) starlarkExpr {
 switch typedExpr := expr.(type) {
 case *notExpr:
  return typedExpr.expr
 case *inExpr:
  typedExpr.isNot = !typedExpr.isNot
  return typedExpr
 case *eqExpr:
  typedExpr.isEq = !typedExpr.isEq
  return typedExpr
 case *binaryOpExpr:
  switch typedExpr.op {
  case ">":
   typedExpr.op = "<="
   return typedExpr
  case "<":
   typedExpr.op = ">="
   return typedExpr
  case ">=":
   typedExpr.op = "<"
   return typedExpr
  case "<=":
   typedExpr.op = ">"
   return typedExpr
  default:
   return ¬Expr{expr: expr}
  }
 default:
  return ¬Expr{expr: expr}
 }
}

[Dauer der Verarbeitung: 0.2 Sekunden, vorverarbeitet 2026-06-28]