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 5 kB image not shown  

Quelle  soong_variables.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 (
 "bytes"
 "fmt"
 "io/ioutil"
 "os"
 "regexp"
 "strings"

 mkparser "android/soong/androidmk/parser"
)

type context struct {
 includeFileScope mkparser.Scope
 registrar        variableRegistrar
}

// Scans the makefile Soong uses to generate soong.variables file,
// collecting variable names and types from the lines that look like this:
//
// $(call add_json_XXX,  <...>,             $(VAR))
func FindSoongVariables(mkFile string, includeFileScope mkparser.Scope, registrar variableRegistrar) error {
 ctx := context{includeFileScope, registrar}
 return ctx.doFind(mkFile)
}

func (ctx *context) doFind(mkFile string) error {
 mkContents, err := ioutil.ReadFile(mkFile)
 if err != nil {
  return err
 }
 parser := mkparser.NewParser(mkFile, bytes.NewBuffer(mkContents))
 nodes, errs := parser.Parse()
 if len(errs) > 0 {
  for _, e := range errs {
   fmt.Fprintln(os.Stderr, "ERROR:", e)
  }
  return fmt.Errorf("cannot parse %s", mkFile)
 }
 for _, node := range nodes {
  switch t := node.(type) {
  case *mkparser.Variable:
   ctx.handleVariable(t)
  case *mkparser.Directive:
   ctx.handleInclude(t)
  }
 }
 return nil
}

func (ctx context) NewSoongVariable(name, typeString string) {
 var valueType starlarkType
 switch typeString {
 case "bool":
  // TODO: We run into several issues later on if we type this as a bool:
  //    - We still assign bool-typed variables to strings
  //    - When emitting the final results as make code, some bool's false values have to
  //      be an empty string, and some have to be false in order to match the make variables.
  valueType = starlarkTypeString
 case "csv":
  // Only PLATFORM_VERSION_ALL_CODENAMES, and it's a list
  valueType = starlarkTypeList
 case "list":
  valueType = starlarkTypeList
 case "str":
  valueType = starlarkTypeString
 case "val":
  // Only PLATFORM_SDK_VERSION uses this, and it's integer
  valueType = starlarkTypeInt
 default:
  panic(fmt.Errorf("unknown Soong variable type %s", typeString))
 }

 ctx.registrar.NewVariable(name, VarClassSoong, valueType)
}

func (ctx context) handleInclude(t *mkparser.Directive) {
 if t.Name != "include" && t.Name != "-include" {
  return
 }
 includedPath := t.Args.Value(ctx.includeFileScope)
 err := ctx.doFind(includedPath)
 if err != nil && t.Name == "include" {
  fmt.Fprintf(os.Stderr, "cannot include %s: %s", includedPath, err)
 }
}

var callFuncRex = regexp.MustCompile("^call +add_json_(str|val|bool|csv|list) *,")

func (ctx context) handleVariable(t *mkparser.Variable) {
 // From the variable reference looking as follows:
 //  $(call json_add_TYPE,arg1,$(VAR))
 // we infer that the type of $(VAR) is TYPE
 // VAR can be a simple variable name, or another call
 // (e.g., $(call invert_bool, $(X)), from which we can infer
 // that the type of X is bool
 if prefix, v, ok := prefixedVariable(t.Name); ok && strings.HasPrefix(prefix, "call add_json") {
  if match := callFuncRex.FindStringSubmatch(prefix); match != nil {
   ctx.inferSoongVariableType(match[1], v)
   // NOTE(asmundak): sometimes arg1 (the name of the Soong variable defined
   // in this statement) may indicate that there is a Make counterpart. E.g, from
   //     $(call add_json_bool, DisablePreopt, $(call invert_bool,$(ENABLE_PREOPT)))
   // it may be inferred that there is a Make boolean variable DISABLE_PREOPT.
   // Unfortunately, Soong variable names have no 1:1 correspondence to Make variables,
   // for instance,
   //       $(call add_json_list, PatternsOnSystemOther, $(SYSTEM_OTHER_ODEX_FILTER))
   // does not mean that there is PATTERNS_ON_SYSTEM_OTHER
   // Our main interest lies in finding the variables whose values are lists, and
   // so far there are none that can be found this way, so it is not important.
  } else {
   panic(fmt.Errorf("cannot match the call: %s", prefix))
  }
 }
}

var (
 callInvertBoolRex = regexp.MustCompile("^call +invert_bool *, *$")
 callFilterBoolRex = regexp.MustCompile("^(filter|filter-out) +(true|false), *$")
)

func (ctx context) inferSoongVariableType(vType string, n *mkparser.MakeString) {
 if n.Const() {
  ctx.NewSoongVariable(n.Strings[0], vType)
  return
 }
 if prefix, v, ok := prefixedVariable(n); ok {
  if callInvertBoolRex.MatchString(prefix) || callFilterBoolRex.MatchString(prefix) {
   // It is $(call invert_bool, $(VAR)) or $(filter[-out] [false|true],$(VAR))
   ctx.inferSoongVariableType("bool", v)
  }
 }
}

// If MakeString is foo$(BAR), returns 'foo', BAR(as *MakeString) and true
func prefixedVariable(s *mkparser.MakeString) (string, *mkparser.MakeString, bool) {
 if len(s.Strings) != 2 || s.Strings[1] != "" {
  return "", nil, false
 }
 return s.Strings[0], s.Variables[0].Name, true
}

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