Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  node.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"

 mkparser "android/soong/androidmk/parser"
)

// A parsed node for which starlark code will be generated
// by calling emit().
type starlarkNode interface {
 emit(ctx *generationContext)
}

// Types used to keep processed makefile data:
type commentNode struct {
 text string
}

func (c *commentNode) emit(gctx *generationContext) {
 chunks := strings.Split(c.text, "\\\n")
 gctx.newLine()
 gctx.write(chunks[0]) // It has '#' at the beginning already.
 for _, chunk := range chunks[1:] {
  gctx.newLine()
  gctx.write("#", chunk)
 }
}

type moduleInfo struct {
 path            string // Converted Starlark file path
 originalPath    string // Makefile file path
 moduleLocalName string
 optional        bool
 missing         bool // a module may not exist if a module that depends on it is loaded dynamically
}

func (im moduleInfo) entryName() string {
 return im.moduleLocalName + "_init"
}

func (mi moduleInfo) name() string {
 return fmt.Sprintf("%q", MakePath2ModuleName(mi.originalPath))
}

type inheritedModule interface {
 name() string
 entryName() string
 emitSelect(gctx *generationContext)
 pathExpr() starlarkExpr
 needsLoadCheck() bool
}

type inheritedStaticModule struct {
 *moduleInfo
 loadAlways bool
}

func (im inheritedStaticModule) emitSelect(_ *generationContext) {
}

func (im inheritedStaticModule) pathExpr() starlarkExpr {
 return &stringLiteralExpr{im.path}
}

func (im inheritedStaticModule) needsLoadCheck() bool {
 return im.missing
}

type inheritedDynamicModule struct {
 path             starlarkExpr
 candidateModules []*moduleInfo
 loadAlways       bool
 location         ErrorLocation
 needsWarning     bool
}

func (i inheritedDynamicModule) name() string {
 return "_varmod"
}

func (i inheritedDynamicModule) entryName() string {
 return i.name() + "_init"
}

func (i inheritedDynamicModule) emitSelect(gctx *generationContext) {
 if i.needsWarning {
  gctx.newLine()
  gctx.writef("%s.mkwarning(%q, %q)", baseName, i.location, "Please avoid starting an include path with a variable. See https://source.android.com/setup/build/bazel/product_config/issues/includes for details.")
 }
 gctx.newLine()
 gctx.writef("_entry = {")
 gctx.indentLevel++
 for _, mi := range i.candidateModules {
  gctx.newLine()
  gctx.writef(`"%s": (%s, %s),`, mi.originalPath, mi.name(), mi.entryName())
 }
 gctx.indentLevel--
 gctx.newLine()
 gctx.write("}.get(")
 i.path.emit(gctx)
 gctx.write(")")
 gctx.newLine()
 gctx.writef("(%s, %s) = _entry if _entry else (None, None)", i.name(), i.entryName())
}

func (i inheritedDynamicModule) pathExpr() starlarkExpr {
 return i.path
}

func (i inheritedDynamicModule) needsLoadCheck() bool {
 return true
}

type inheritNode struct {
 module     inheritedModule
 loadAlways bool
}

func (inn *inheritNode) emit(gctx *generationContext) {
 // Unconditional case:
 //    maybe check that loaded
 //    rblf.inherit(handle, <module>, module_init)
 // Conditional case:
 //    if <module>_init != None:
 //      same as above
 inn.module.emitSelect(gctx)
 name := inn.module.name()
 entry := inn.module.entryName()
 if inn.loadAlways {
  gctx.emitLoadCheck(inn.module)
  gctx.newLine()
  gctx.writef("%s(handle, %s, %s)", cfnInherit, name, entry)
  return
 }

 gctx.newLine()
 gctx.writef("if %s:", entry)
 gctx.indentLevel++
 gctx.newLine()
 gctx.writef("%s(handle, %s, %s)", cfnInherit, name, entry)
 gctx.indentLevel--
}

type includeNode struct {
 module     inheritedModule
 loadAlways bool
}

func (inn *includeNode) emit(gctx *generationContext) {
 inn.module.emitSelect(gctx)
 entry := inn.module.entryName()
 if inn.loadAlways {
  gctx.emitLoadCheck(inn.module)
  gctx.newLine()
  gctx.writef("%s(g, handle)", entry)
  return
 }

 gctx.newLine()
 gctx.writef("if %s != None:", entry)
 gctx.indentLevel++
 gctx.newLine()
 gctx.writef("%s(g, handle)", entry)
 gctx.indentLevel--
}

type assignmentFlavor int

const (
 // Assignment flavors
 asgnSet      assignmentFlavor = iota // := or =
 asgnMaybeSet assignmentFlavor = iota // ?=
 asgnAppend   assignmentFlavor = iota // +=
)

type assignmentNode struct {
 lhs      variable
 value    starlarkExpr
 mkValue  *mkparser.MakeString
 flavor   assignmentFlavor
 location ErrorLocation
 isTraced bool
}

func (asgn *assignmentNode) emit(gctx *generationContext) {
 gctx.newLine()
 gctx.inAssignment = true
 asgn.lhs.emitSet(gctx, asgn)
 gctx.inAssignment = false

 if asgn.isTraced {
  gctx.newLine()
  gctx.tracedCount++
  gctx.writef(`print("%s.%d: %s := ", `, gctx.starScript.mkFile, gctx.tracedCount, asgn.lhs.name())
  asgn.lhs.emitGet(gctx)
  gctx.writef(")")
 }
}

func (asgn *assignmentNode) isSelfReferential() bool {
 if asgn.flavor == asgnAppend {
  return true
 }
 isSelfReferential := false
 asgn.value.transform(func(expr starlarkExpr) starlarkExpr {
  if ref, ok := expr.(*variableRefExpr); ok && ref.ref.name() == asgn.lhs.name() {
   isSelfReferential = true
  }
  return nil
 })
 return isSelfReferential
}

type exprNode struct {
 expr starlarkExpr
}

func (exn *exprNode) emit(gctx *generationContext) {
 gctx.newLine()
 exn.expr.emit(gctx)
}

type ifNode struct {
 isElif bool // true if this is 'elif' statement
 expr   starlarkExpr
}

func (in *ifNode) emit(gctx *generationContext) {
 ifElif := "if "
 if in.isElif {
  ifElif = "elif "
 }

 gctx.newLine()
 gctx.write(ifElif)
 in.expr.emit(gctx)
 gctx.write(":")
}

type elseNode struct{}

func (br *elseNode) emit(gctx *generationContext) {
 gctx.newLine()
 gctx.write("else:")
}

// switchCase represents as single if/elseif/else branch. All the necessary
// info about flavor (if/elseif/else) is supposed to be kept in `gate`.
type switchCase struct {
 gate  starlarkNode
 nodes []starlarkNode
}

func (cb *switchCase) emit(gctx *generationContext) {
 cb.gate.emit(gctx)
 gctx.indentLevel++
 gctx.pushVariableAssignments()
 hasStatements := false
 for _, node := range cb.nodes {
  if _, ok := node.(*commentNode); !ok {
   hasStatements = true
  }
  node.emit(gctx)
 }
 if !hasStatements {
  gctx.emitPass()
 }
 gctx.indentLevel--
 gctx.popVariableAssignments()
}

// A single complete if ... elseif ... else ... endif sequences
type switchNode struct {
 ssCases []*switchCase
}

func (ssw *switchNode) emit(gctx *generationContext) {
 for _, ssCase := range ssw.ssCases {
  ssCase.emit(gctx)
 }
}

type foreachNode struct {
 varName string
 list    starlarkExpr
 actions []starlarkNode
}

func (f *foreachNode) emit(gctx *generationContext) {
 gctx.pushVariableAssignments()
 gctx.newLine()
 gctx.writef("for %s in ", f.varName)
 f.list.emit(gctx)
 gctx.write(":")
 gctx.indentLevel++
 hasStatements := false
 for _, a := range f.actions {
  if _, ok := a.(*commentNode); !ok {
   hasStatements = true
  }
  a.emit(gctx)
 }
 if !hasStatements {
  gctx.emitPass()
 }
 gctx.indentLevel--
 gctx.popVariableAssignments()
}

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

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik