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

Quelle  writedocs.go   Sprache: unbekannt

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

// Copyright 2017 Google Inc. All rights reserved.
//
// 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 main

import (
 "bytes"
 "html/template"
 "io/ioutil"
 "path/filepath"
 "sort"

 "android/soong/android"

 "github.com/google/blueprint/bootstrap"
 "github.com/google/blueprint/bootstrap/bpdoc"
)

type perPackageTemplateData struct {
 Name    string
 Modules []moduleTypeTemplateData
}

type moduleTypeTemplateData struct {
 Name       string
 Synopsis   template.HTML
 Properties []bpdoc.Property
}

// The properties in this map are displayed first, according to their rank.
// TODO(jungjw): consider providing module type-dependent ranking
var propertyRank = map[string]int{
 "name":             0,
 "src":              1,
 "srcs":             2,
 "exclude_srcs":     3,
 "defaults":         4,
 "host_supported":   5,
 "device_supported": 6,
}

// For each module type, extract its documentation and convert it to the template data.
func moduleTypeDocsToTemplates(moduleTypeList []*bpdoc.ModuleType) []moduleTypeTemplateData {
 result := make([]moduleTypeTemplateData, 0)

 // Combine properties from all PropertyStruct's and reorder them -- first the ones
 // with rank, then the rest of the properties in alphabetic order.
 for _, m := range moduleTypeList {
  item := moduleTypeTemplateData{
   Name:       m.Name,
   Synopsis:   m.Text,
   Properties: make([]bpdoc.Property, 0),
  }
  props := make([]bpdoc.Property, 0)
  for _, propStruct := range m.PropertyStructs {
   props = append(props, propStruct.Properties...)
  }
  sort.Slice(props, func(i, j int) bool {
   if rankI, ok := propertyRank[props[i].Name]; ok {
    if rankJ, ok := propertyRank[props[j].Name]; ok {
     return rankI < rankJ
    } else {
     return true
    }
   }
   if _, ok := propertyRank[props[j].Name]; ok {
    return false
   }
   return props[i].Name < props[j].Name
  })
  // Eliminate top-level duplicates. TODO(jungjw): improve bpdoc to handle this.
  previousPropertyName := ""
  for _, prop := range props {
   if prop.Name == previousPropertyName {
    oldProp := &item.Properties[len(item.Properties)-1].Properties
    bpdoc.CollapseDuplicateProperties(oldProp, &prop.Properties)
   } else {
    item.Properties = append(item.Properties, prop)
   }
   previousPropertyName = prop.Name
  }
  result = append(result, item)
 }
 sort.Slice(result, func(i, j int) bool { return result[i].Name < result[j].Name })
 return result
}

func getPackages(ctx *android.Context) ([]*bpdoc.Package, error) {
 moduleTypeFactories := android.ModuleTypeFactoriesForDocs()
 return bootstrap.ModuleTypeDocs(ctx.Context, moduleTypeFactories)
}

func writeDocs(ctx *android.Context, filename string) error {
 packages, err := getPackages(ctx)
 if err != nil {
  return err
 }

 // Produce the top-level, package list page first.
 tmpl := template.Must(template.Must(template.New("file").Parse(packageListTemplate)).Parse(copyBaseUrl))
 buf := &bytes.Buffer{}
 err = tmpl.Execute(buf, packages)
 if err == nil {
  err = ioutil.WriteFile(filename, buf.Bytes(), 0666)
 }

 // Now, produce per-package module lists with detailed information, and a list
 // of keywords.
 keywordsTmpl := template.Must(template.New("file").Parse(keywordsTemplate))
 keywordsBuf := &bytes.Buffer{}
 for _, pkg := range packages {
  // We need a module name getter/setter function because I couldn't
  // find a way to keep it in a variable defined within the template.
  currentModuleName := ""
  tmpl := template.Must(
   template.Must(template.New("file").Funcs(map[string]interface{}{
    "setModule": func(moduleName string) string {
     currentModuleName = moduleName
     return ""
    },
    "getModule": func() string {
     return currentModuleName
    },
   }).Parse(perPackageTemplate)).Parse(copyBaseUrl))
  buf := &bytes.Buffer{}
  modules := moduleTypeDocsToTemplates(pkg.ModuleTypes)
  data := perPackageTemplateData{Name: pkg.Name, Modules: modules}
  err = tmpl.Execute(buf, data)
  if err != nil {
   return err
  }
  pkgFileName := filepath.Join(filepath.Dir(filename), pkg.Name+".html")
  err = ioutil.WriteFile(pkgFileName, buf.Bytes(), 0666)
  if err != nil {
   return err
  }
  err = keywordsTmpl.Execute(keywordsBuf, data)
  if err != nil {
   return err
  }
 }

 // Write out list of keywords. This includes all module and property names, which is useful for
 // building syntax highlighters.
 keywordsFilename := filepath.Join(filepath.Dir(filename), "keywords.txt")
 err = ioutil.WriteFile(keywordsFilename, keywordsBuf.Bytes(), 0666)

 return err
}

// TODO(jungjw): Consider ordering by name.
const (
 packageListTemplate = `
<html>
<head>
<title>Build Docs</title>
<style>
#main {
  padding: 48px;
}

table{
  table-layout: fixed;
}

td {
  word-wrap:break-word;
}

/* The following entries are copied from source.android.com's css file. */
td,td code {
    color: #202124
}

th,th code {
    color: #fff;
    font: 500 16px/24px Roboto,sans-serif
}

td,table.responsive tr:not(.alt) td td:first-child,table.responsive td tr:not(.alt) td:first-child {
    background: rgba(255,255,255,.95);
    vertical-align: top
}

td,td code {
    padding: 7px 8px 8px
}

tr {
    border: 0;
    background: #78909c;
    border-top: 1px solid #cfd8dc
}

th,td {
    border: 0;
    margin: 0;
    text-align: left
}

th {
    height: 48px;
    padding: 8px;
    vertical-align: middle
}

table {
    border: 0;
    border-collapse: collapse;
    border-spacing: 0;
    font: 14px/20px Roboto,sans-serif;
    margin: 16px 0;
    width: 100%
}

h1 {
    color: #80868b;
    font: 300 34px/40px Roboto,sans-serif;
    letter-spacing: -0.01em;
    margin: 40px 0 20px
}

h1,h2,h3,h4,h5,h6 {
    overflow: hidden;
    padding: 0;
    text-overflow: ellipsis
}

:link,:visited {
    color: #039be5;
    outline: 0;
    text-decoration: none
}

body,html {
    color: #202124;
    font: 400 16px/24px Roboto,sans-serif;
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-smoothing: antialiased;
    height: 100%;
    margin: 0;
    -webkit-text-size-adjust: 100%;
    -moz-text-size-adjust: 100%;
    -ms-text-size-adjust: 100%;
    text-size-adjust: 100%
}

html {
    -webkit-box-sizing: border-box;
    box-sizing: border-box
}

*,*::before,*::after {
    -webkit-box-sizing: inherit;
    box-sizing: inherit
}

body,div,dl,dd,form,img,input,figure,menu {
    margin: 0;
    padding: 0
}
</style>
{{template "copyBaseUrl"}}
</head>
<body>
<div id="main">
<H1>Soong Modules Reference</H1>
The latest versions of Android use the Soong build system, which greatly simplifies build
configuration over the previous Make-based system. This site contains the generated reference
files for the Soong build system.

<table class="module_types" summary="Table of Soong module types sorted by package">
  <thead>
    <tr>
      <th style="width:20%">Package</th>
      <th style="width:80%">Module types</th>
    </tr>
  </thead>
  <tbody>
    {{range $pkg := .}}
      <tr>
        <td>{{.Path}}</td>
        <td>
        {{range $i, $mod := .ModuleTypes}}{{if $i}}, {{end}}<a href="{{$pkg.Name}}.html#{{$mod.Name}}">{{$mod.Name}}</a>{{end}}
        </td>
      </tr>
    {{end}}
  </tbody>
</table>
</div>
</body>
</html>
`

 perPackageTemplate = `
<html>
<head>
<title>Build Docs</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
<style>
.accordion,.simple{margin-left:1.5em;text-indent:-1.5em;margin-top:.25em}
.collapsible{border-width:0 0 0 1;margin-left:.25em;padding-left:.25em;border-style:solid;
  border-color:grey;display:none;}
span.fixed{display: block; float: left; clear: left; width: 1em;}
ul {
 list-style-type: none;
  margin: 0;
  padding: 0;
  width: 30ch;
  background-color: #f1f1f1;
  position: fixed;
  height: 100%;
  overflow: auto;
}
li a {
  display: block;
  color: #000;
  padding: 8px 16px;
  text-decoration: none;
}

li a.active {
  background-color: #4CAF50;
  color: white;
}

li a:hover:not(.active) {
  background-color: #555;
  color: white;
}
</style>
{{template "copyBaseUrl"}}
</head>
<body>
{{- /* Fixed sidebar with module types */ -}}
<ul>
<li><h3>{{.Name}} package</h3></li>
{{range $moduleType := .Modules}}<li><a href="{{$.Name}}.html#{{$moduleType.Name}}">{{$moduleType.Name}}</a></li>
{{end -}}
</ul>
{{/* Main panel with H1 section per module type */}}
<div style="margin-left:30ch;padding:1px 16px;">
{{range $moduleType := .Modules}}
 {{setModule $moduleType.Name}}
 <p>
  <h2 id="{{$moduleType.Name}}">{{$moduleType.Name}}</h2>
  {{if $moduleType.Synopsis }}{{$moduleType.Synopsis}}{{else}}<i>Missing synopsis</i>{{end}}
  {{- /* Comma-separated list of module attributes' links module attributes */ -}}
 <div class="breadcrumb">
    {{range $i,$prop := $moduleType.Properties }}
    {{ if gt $i 0 }}, {{end -}}
    <a href={{$.Name}}.html#{{getModule}}.{{$prop.Name}}>{{$prop.Name}}</a>
  {{- end -}}
  </div>
 {{- /* Property description */ -}}
 {{- template "properties" $moduleType.Properties -}}
{{- end -}}

{{define "properties" -}}
  {{range .}}
    {{if .Properties -}}
      <div class="accordion"  id="{{getModule}}.{{.Name}}">
        <span class="fixed">⊕</span><b>{{.Name}}</b>
        <i>{{.Type}}</i>
        {{- range .OtherNames -}}, {{.}}{{- end -}}
      </div>
      <div class="collapsible">
        {{- .Text}} {{range .OtherTexts}}{{.}}{{end}}
        {{template "properties" .Properties -}}
      </div>
    {{- else -}}
      <div class="simple" id="{{getModule}}.{{.Name}}">
        <span class="fixed"> </span><b>{{.Name}} {{range .OtherNames}}, {{.}}{{end -}}</b>
        <i>{{.Type}}</i>
        {{- if .Text -}}{{if ne .Text "\n"}}, {{end}}{{.Text}}{{- end -}}
        {{- with .OtherTexts -}}{{.}}{{- end -}}
 {{- if .Default -}}<i>Default: {{.Default}}</i>{{- end -}}
      </div>
    {{- end}}
  {{- end -}}
{{- end -}}
</div>
<script>
  accordions = document.getElementsByClassName('accordion');
  for (i=0; i < accordions.length; ++i) {
    accordions[i].addEventListener("click", function() {
      var panel = this.nextElementSibling;
      var child = this.firstElementChild;
      if (panel.style.display === "block") {
          panel.style.display = "none";
          child.textContent = '\u2295';
      } else {
          panel.style.display = "block";
          child.textContent = '\u2296';
      }
    });
  }
</script>
</body>
`

 copyBaseUrl = `
{{define "copyBaseUrl"}}
<script type="text/javascript">
window.addEventListener('message', (e) => {
  if (e != null && e.data != null && e.data.type === "SET_BASE" && e.data.base != null) {
    const existingBase = document.querySelector('base');
    if (existingBase != null) {
      existingBase.parentElement.removeChild(existingBase);
    }

    const base = document.createElement('base');
    base.setAttribute('href', e.data.base);
    document.head.appendChild(base);
  }
});
</script>
{{end}}
`

 keywordsTemplate = `
{{range $moduleType := .Modules}}{{$moduleType.Name}}:{{range $property := $moduleType.Properties}}{{$property.Name}},{{end}}
{{end}}
`
)

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