Spracherkennung für: .go vermutete Sprache: Abap {ABAP[60] SPS[52] Fortran[40]} [Methode: maximale Elemente, drei Dimensionen]
// Copyright
2014 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 "sync"
// A liveTracker tracks the values
of live variables, rules,
and pools. An
// entity
is made
"live" when it
is referenced directly
or indirectly
by a build
//
definition.
When an entity
is made live its value
is computed based
on the
// configuration.
type liveTracker struct {
sync.Mutex
config
interface{} // Used
to evaluate variable, rule,
and pool values.
ctx
*Context // Used to evaluate globs
variables map[Variable]
*ninjaString
pools map[Pool]
*poolDef
rules map[Rule]
*ruleDef
}
func newLiveTracker(ctx
*Context, config interface{}) *liveTracker {
return &liveTracker{
ctx: ctx,
config: config,
variables: make(map[Variable]
*ninjaString),
pools: make(map[Pool]
*poolDef),
rules: make(map[Rule]
*ruleDef),
}
}
func (l
*liveTracker) AddBuildDefDeps(def *buildDef) error {
l.Lock()
defer l.Unlock()
ruleDef, err := l.innerAddRule(def.Rule)
if err != nil {
return err
}
def.RuleDef = ruleDef
err = l.innerAddNinjaStringListDeps(def.Outputs)
if err != nil {
return err
}
err = l.innerAddNinjaStringListDeps(def.Inputs)
if err != nil {
return err
}
err = l.innerAddNinjaStringListDeps(def.Implicits)
if err != nil {
return err
}
err = l.innerAddNinjaStringListDeps(def.OrderOnly)
if err != nil {
return err
}
err = l.innerAddNinjaStringListDeps(def.Validations)
if err != nil {
return err
}
for _, value := range def.Variables {
err = l.innerAddNinjaStringDeps(value)
if err != nil {
return err
}
}
for _, value := range def.Args {
err = l.innerAddNinjaStringDeps(value)
if err != nil {
return err
}
}
return nil
}
func (l
*liveTracker) addRule(r Rule) (def *ruleDef, err error) {
l.Lock()
defer l.Unlock()
return l.innerAddRule(r)
}
func (l
*liveTracker) innerAddRule(r Rule) (def *ruleDef, err error) {
def, ok := l.rules[r]
if !ok {
def, err = r.def(l.config)
if err == errRuleIsBuiltin {
// No need
to do anything
for built-
in rules.
return nil, nil
}
if err != nil {
return nil, err
}
if def.Pool != nil {
err = l.innerAddPool(def.Pool)
if err != nil {
return nil, err
}
}
err = l.innerAddNinjaStringListDeps(def.CommandDeps)
if err != nil {
return nil, err
}
err = l.innerAddNinjaStringListDeps(def.CommandOrderOnly)
if err != nil {
return nil, err
}
for _, value := range def.Variables {
err = l.innerAddNinjaStringDeps(value)
if err != nil {
return nil, err
}
}
l.rules[r] = def
}
return
}
func (l
*liveTracker) addPool(p Pool) error {
l.Lock()
defer l.Unlock()
return l.innerAddPool(p)
}
func (l
*liveTracker) innerAddPool(p Pool) error {
_, ok := l.pools[p]
if !ok {
def, err := p.def(l.config)
if err == errPoolIsBuiltin {
// No need
to do anything
for built-
in rules.
return nil
}
if err != nil {
return err
}
l.pools[p] = def
}
return nil
}
func (l
*liveTracker) addVariable(v Variable) error {
l.Lock()
defer l.Unlock()
return l.innerAddVariable(v)
}
func (l
*liveTracker) innerAddVariable(v Variable) error {
_, ok := l.variables[v]
if !ok {
ctx := &variableFuncContext{l.ctx}
value, err := v.value(ctx, l.config)
if err == errVariableIsArg {
// This variable
is a placeholder
for an argument that can be passed
//
to a rule. It has no value
and thus doesn
't reference any other
// variables.
return nil
}
if err != nil {
return err
}
l.variables[v] = value
err = l.innerAddNinjaStringDeps(value)
if err != nil {
return err
}
}
return nil
}
func (l
*liveTracker) addNinjaStringListDeps(list []*ninjaString) error {
l.Lock()
defer l.Unlock()
return l.innerAddNinjaStringListDeps(list)
}
func (l
*liveTracker) innerAddNinjaStringListDeps(list []*ninjaString) error {
for _, str := range list {
err := l.innerAddNinjaStringDeps(str)
if err != nil {
return err
}
}
return nil
}
func (l
*liveTracker) addNinjaStringDeps(str *ninjaString) error {
l.Lock()
defer l.Unlock()
return l.innerAddNinjaStringDeps(str)
}
func (l
*liveTracker) innerAddNinjaStringDeps(str *ninjaString) error {
for _, v := range str.Variables() {
err := l.innerAddVariable(v)
if err != nil {
return err
}
}
return nil
}
func (l
*liveTracker) Eval(n *ninjaString) (string, error) {
l.Lock()
defer l.Unlock()
return n.Eval(l.variables)
}
func (l
*liveTracker) RemoveVariableIfLive(v Variable) bool {
l.Lock()
defer l.Unlock()
_, isLive := l.variables[v]
if isLive {
delete(l.variables, v)
}
return isLive
}
func (l
*liveTracker) RemoveRuleIfLive(r Rule) bool {
l.Lock()
defer l.Unlock()
_, isLive := l.rules[r]
if isLive {
delete(l.rules, r)
}
return isLive
}