Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  name_interface.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 blueprint

import (
 "fmt"
 "sort"
 "strings"
 "unicode"
)

// This file exposes the logic of locating a module via a query string, to enable
// other projects to override it if desired.
// The default name resolution implementation, SimpleNameInterface,
// just treats the query string as a module name, and does a simple map lookup.

// A ModuleGroup just points to a moduleGroup to allow external packages to refer
// to a moduleGroup but not use it
type ModuleGroup struct {
 *moduleGroup
}

func (h *ModuleGroup) String() string {
 return h.moduleGroup.name
}

// The Namespace interface is just a marker interface for usage by the NameInterface,
// to allow a NameInterface to specify that a certain parameter should be a Namespace.
// In practice, a specific NameInterface will expect to only give and receive structs of
// the same concrete type, but because Go doesn't support generics, we use a marker interface
// for a little bit of clarity, and expect implementers to do typecasting instead.
type Namespace interface {
 namespace(Namespace)
}
type NamespaceMarker struct {
}

func (m *NamespaceMarker) namespace(Namespace) {
}

// A NameInterface tells how to locate modules by name.
// There should only be one name interface per Context, but potentially many namespaces
type NameInterface interface {
 // Gets called when a new module is created
 NewModule(ctx NamespaceContext, group ModuleGroup, module Module) (namespace Namespace, err []error)

 // Gets called when a module was pruned from the build tree by SourceRootDirs
 NewSkippedModule(ctx NamespaceContext, name string, skipInfo SkippedModuleInfo)

 // Finds the module with the given name
 ModuleFromName(moduleName string, namespace Namespace) (group ModuleGroup, found bool)

 // Finds if the module with the given name was skipped
 SkippedModuleFromName(moduleName string, namespace Namespace) (skipInfos []SkippedModuleInfo, skipped bool)

 // Returns an error indicating that the given module could not be found.
 // The error contains some diagnostic information about where the dependency can be found.
 MissingDependencyError(depender string, dependerNamespace Namespace, depName string, guess []string) (err error)

 // Rename
 Rename(oldName string, newName string, namespace Namespace) []error

 // Returns all modules in a deterministic order.
 AllModules() []ModuleGroup

 // gets the namespace for a given path
 GetNamespace(ctx NamespaceContext) (namespace Namespace)

 // returns a deterministic, unique, arbitrary string for the given name in the given namespace
 UniqueName(ctx NamespaceContext, name string) (unique string)
}

// A NamespaceContext stores the information given to a NameInterface to enable the NameInterface
// to choose the namespace for any given module
type NamespaceContext interface {
 ModulePath() string
}

type namespaceContextImpl struct {
 modulePath string
}

func newNamespaceContext(moduleInfo *moduleInfo) (ctx NamespaceContext) {
 return &namespaceContextImpl{moduleInfo.pos.Filename}
}

func newNamespaceContextFromFilename(filename string) NamespaceContext {
 return &namespaceContextImpl{filename}
}

func (ctx *namespaceContextImpl) ModulePath() string {
 return ctx.modulePath
}

type SkippedModuleInfo struct {
 filename string
 reason   string
}

// a SimpleNameInterface just stores all modules in a map based on name
type SimpleNameInterface struct {
 modules        map[string]ModuleGroup
 skippedModules map[string][]SkippedModuleInfo
}

func NewSimpleNameInterface() *SimpleNameInterface {
 return &SimpleNameInterface{
  modules:        make(map[string]ModuleGroup),
  skippedModules: make(map[string][]SkippedModuleInfo),
 }
}

func (s *SimpleNameInterface) NewModule(ctx NamespaceContext, group ModuleGroup, module Module) (namespace Namespace, err []error) {
 name := group.name
 if group, present := s.modules[name]; present {
  return nil, []error{
   // seven characters at the start of the second line to align with the string "error: "
   fmt.Errorf("module %q already defined\n"+
    "       %s <-- previous definition here", name, group.modules.firstModule().pos),
  }
 }

 if !IsValidModuleName(name) {
  return nil, []error{
   // seven characters at the start of the second line to align with the string "error: "
   fmt.Errorf("module %q should use a valid name.\n"+
    "       Special chars like spaces are not allowed.", name),
  }
 }

 s.modules[name] = group

 return nil, []error{}
}

// Leters, Digits, Underscore, `+` (libc++), `.` are valid chars for module names.
// Additional chars like `-` were added to the list to account for module names
// that predate the enforcement of this check.
var allowedSpecialCharsInModuleNames = map[rune]bool{
 '_': true,
 '-': true,
 '.': true,
 '/': true,
 '@': true,
 '+': true,
 '&': true,
}

func IsValidModuleName(name string) bool {
 for _, c := range name {
  _, allowedSpecialChar := allowedSpecialCharsInModuleNames[c]
  valid := unicode.IsLetter(c) || unicode.IsDigit(c) || allowedSpecialChar
  if !valid {
   return false
  }
 }
 return len(name) > 0
}

func (s *SimpleNameInterface) NewSkippedModule(ctx NamespaceContext, name string, info SkippedModuleInfo) {
 if name == "" {
  return
 }
 s.skippedModules[name] = append(s.skippedModules[name], info)
}

func (s *SimpleNameInterface) ModuleFromName(moduleName string, namespace Namespace) (group ModuleGroup, found bool) {
 group, found = s.modules[moduleName]
 return group, found
}

func (s *SimpleNameInterface) SkippedModuleFromName(moduleName string, namespace Namespace) (skipInfos []SkippedModuleInfo, skipped bool) {
 skipInfos, skipped = s.skippedModules[moduleName]
 return
}

func (s *SimpleNameInterface) Rename(oldName string, newName string, namespace Namespace) (errs []error) {
 existingGroup, exists := s.modules[newName]
 if exists {
  return []error{
   // seven characters at the start of the second line to align with the string "error: "
   fmt.Errorf("renaming module %q to %q conflicts with existing module\n"+
    "       %s <-- existing module defined here",
    oldName, newName, existingGroup.modules.firstModule().pos),
  }
 }

 group, exists := s.modules[oldName]
 if !exists {
  return []error{fmt.Errorf("module %q to renamed to %q doesn't exist", oldName, newName)}
 }
 s.modules[newName] = group
 delete(s.modules, group.name)
 group.name = newName
 return nil
}

func (s *SimpleNameInterface) AllModules() []ModuleGroup {
 groups := make([]ModuleGroup, 0, len(s.modules))
 for _, group := range s.modules {
  groups = append(groups, group)
 }

 duplicateName := ""
 less := func(i, j int) bool {
  if groups[i].name == groups[j].name {
   duplicateName = groups[i].name
  }
  return groups[i].name < groups[j].name
 }
 sort.Slice(groups, less)
 if duplicateName != "" {
  // It is permitted to have two moduleGroup's with the same name, but not within the same
  // Namespace. The SimpleNameInterface should catch this in NewModule, however, so this
  // should never happen.
  panic(fmt.Sprintf("Duplicate moduleGroup name %q", duplicateName))
 }
 return groups
}

func (s *SimpleNameInterface) MissingDependencyError(depender string, dependerNamespace Namespace, dependency string, guess []string) (err error) {
 skipInfos, skipped := s.SkippedModuleFromName(dependency, dependerNamespace)
 if skipped {
  filesFound := make([]string, 0, len(skipInfos))
  reasons := make([]string, 0, len(skipInfos))
  for _, info := range skipInfos {
   filesFound = append(filesFound, info.filename)
   reasons = append(reasons, info.reason)
  }
  return fmt.Errorf(
   "module %q depends on skipped module %q; %q was defined in files(s) [%v], but was skipped for reason(s) [%v]",
   depender,
   dependency,
   dependency,
   strings.Join(filesFound, ", "),
   strings.Join(reasons, "; "),
  )
 }

 guessString := ""
 if len(guess) > 0 {
  guessString = fmt.Sprintf(" Did you mean %q?", guess)
 }
 return fmt.Errorf("%q depends on undefined module %q.%s", depender, dependency, guessString)
}

func (s *SimpleNameInterface) GetNamespace(ctx NamespaceContext) Namespace {
 return nil
}

func (s *SimpleNameInterface) UniqueName(ctx NamespaceContext, name string) (unique string) {
 return name
}

[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