mirror of https://github.com/knative/pkg.git
98 lines
3.1 KiB
Go
98 lines
3.1 KiB
Go
/*
|
|
Copyright 2019 The Knative Authors
|
|
|
|
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 resourcetree
|
|
|
|
import (
|
|
"container/list"
|
|
"reflect"
|
|
|
|
"k8s.io/apimachinery/pkg/util/sets"
|
|
"knative.dev/pkg/test/webhook-apicoverage/coveragecalculator"
|
|
)
|
|
|
|
// ResourceTree encapsulates a tree corresponding to a resource type.
|
|
type ResourceTree struct {
|
|
ResourceName string
|
|
Root NodeInterface
|
|
Forest *ResourceForest
|
|
}
|
|
|
|
// coverageDataHelper is a encapsulator parameter type to the BuildCoverageData method
|
|
// so as to avoid long parameter list.
|
|
type coverageDataHelper struct {
|
|
typeCoverage *[]coveragecalculator.TypeCoverage
|
|
nodeRules NodeRules
|
|
fieldRules FieldRules
|
|
ignoredFields coveragecalculator.IgnoredFields
|
|
coveredTypes sets.String
|
|
}
|
|
|
|
func (r *ResourceTree) createNode(field string, parent NodeInterface, t reflect.Type) NodeInterface {
|
|
var n NodeInterface
|
|
switch t.Kind() {
|
|
case reflect.Struct:
|
|
n = new(StructKindNode)
|
|
case reflect.Array, reflect.Slice:
|
|
n = new(ArrayKindNode)
|
|
case reflect.Ptr, reflect.UnsafePointer, reflect.Uintptr:
|
|
n = new(PtrKindNode)
|
|
case reflect.Bool, reflect.String, reflect.Float32, reflect.Float64,
|
|
reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint,
|
|
reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
n = new(BasicTypeKindNode)
|
|
default:
|
|
n = new(OtherKindNode) // Maps, interfaces, etc
|
|
}
|
|
|
|
n.initialize(field, parent, t, r)
|
|
|
|
if len(t.PkgPath()) != 0 {
|
|
typeName := t.PkgPath() + "." + t.Name()
|
|
if _, ok := r.Forest.ConnectedNodes[typeName]; !ok {
|
|
r.Forest.ConnectedNodes[typeName] = list.New()
|
|
}
|
|
r.Forest.ConnectedNodes[typeName].PushBack(n)
|
|
}
|
|
|
|
return n
|
|
}
|
|
|
|
// BuildResourceTree builds a resource tree by calling into analyzeType method starting from root.
|
|
func (r *ResourceTree) BuildResourceTree(t reflect.Type) {
|
|
r.Root = r.createNode(r.ResourceName, nil, t)
|
|
r.Root.buildChildNodes(t)
|
|
}
|
|
|
|
// UpdateCoverage updates coverage data in the resource tree based on the provided reflect.Value
|
|
func (r *ResourceTree) UpdateCoverage(v reflect.Value) {
|
|
r.Root.updateCoverage(v)
|
|
}
|
|
|
|
// BuildCoverageData calculates the coverage information for a resource tree by applying provided Node and Field rules.
|
|
func (r *ResourceTree) BuildCoverageData(nodeRules NodeRules, fieldRules FieldRules,
|
|
ignoredFields coveragecalculator.IgnoredFields) []coveragecalculator.TypeCoverage {
|
|
coverageHelper := coverageDataHelper{
|
|
nodeRules: nodeRules,
|
|
fieldRules: fieldRules,
|
|
typeCoverage: &[]coveragecalculator.TypeCoverage{},
|
|
ignoredFields: ignoredFields,
|
|
coveredTypes: sets.String{},
|
|
}
|
|
r.Root.buildCoverageData(coverageHelper)
|
|
return *coverageHelper.typeCoverage
|
|
}
|