mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
rebase: bump the golang-dependencies group with 1 update
Bumps the golang-dependencies group with 1 update: [golang.org/x/crypto](https://github.com/golang/crypto). Updates `golang.org/x/crypto` from 0.16.0 to 0.17.0 - [Commits](https://github.com/golang/crypto/compare/v0.16.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor dependency-group: golang-dependencies ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
mergify[bot]
parent
1ad79314f9
commit
e5d9b68d36
go.modgo.summodules.txt
vendor
github.com
distribution
reference
docker
fsnotify
fsnotify
google
cel-go
cel
checker
BUILD.bazelchecker.gocost.go
decls
env.goerrors.goformat.gomapping.gooptions.goprinter.goscopes.gostandard.gotypes.gocommon
ext
BUILD.bazelREADME.mdbindings.goencoders.goguards.golists.gomath.gonative.goprotos.gosets.gostrings.go
interpreter
BUILD.bazelactivation.goattribute_patterns.goattributes.godecorators.godispatcher.goevalstate.goformatting.go
functions
interpretable.gointerpreter.goplanner.goprune.goruntimecost.goparser
grpc-ecosystem
grpc-gateway
opencontainers
selinux
go.etcd.io
etcd
api
v3
client
go.opentelemetry.io
contrib
instrumentation
google.golang.org
grpc
net
http
otelhttp
otel
.codespellignore.codespellrc.gitignore.golangci.yml.lycheeignoreCHANGELOG.mdCODEOWNERSCONTRIBUTING.mdMakefileREADME.mdRELEASING.mdhandler.go
attribute
baggage
codes
exporters
otlp
internal
otlptrace
README.mdexporter.go
otlptracegrpc
version.gointernal
metric.gometric
asyncfloat64.goasyncint64.goconfig.godoc.go
requirements.txtembedded
global
instrument.goinstrument
internal
meter.gonoop.gosyncfloat64.gosyncint64.gosdk
internal
resource
auto.gobuiltin.goconfig.gocontainer.godoc.goenv.gohost_id.gohost_id_bsd.gohost_id_darwin.gohost_id_exec.gohost_id_linux.gohost_id_readfile.gohost_id_unsupported.gohost_id_windows.goos.goos_release_unix.goprocess.goresource.go
trace
batch_span_processor.goprovider.gosampling.gosimple_span_processor.gospan.gospan_exporter.gospan_processor.gotracer.goversion.go
version.gosemconv
internal
v1.17.0
v1.21.0
trace
version.goversions.yamlproto
otlp
collector
common
resource
trace
golang.org
x
k8s.io
component-helpers
node
util
sysctl
kube-openapi
pkg
builder3
cached
common
handler
handler3
internal
openapiconv
spec3
encoding.goexample.goexternal_documentation.gofuzz.goheader.gomedia_type.gooperation.goparameter.gopath.gorequest_body.goresponse.gosecurity_scheme.goserver.gospec.go
validation
spec
kubernetes
pkg
test
e2e
framework
.import-restrictionsOWNERSREADME.mdbugs.goexpect.goginkgowrapper.go
internal
junit
metrics
node
pod
pv
ssh
test_context.gotimeouts.goutil.govolume
storage
utils
testing-manifests
kubectl
sample-device-plugin
scheduling
utils
utils
sigs.k8s.io
apiserver-network-proxy
structured-merge-diff
416
vendor/github.com/google/cel-go/checker/checker.go
generated
vendored
416
vendor/github.com/google/cel-go/checker/checker.go
generated
vendored
@ -18,15 +18,13 @@ package checker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/google/cel-go/checker/decls"
|
||||
"github.com/google/cel-go/common"
|
||||
"github.com/google/cel-go/common/ast"
|
||||
"github.com/google/cel-go/common/containers"
|
||||
"github.com/google/cel-go/common/decls"
|
||||
"github.com/google/cel-go/common/operators"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"github.com/google/cel-go/common/types"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
@ -37,8 +35,8 @@ type checker struct {
|
||||
mappings *mapping
|
||||
freeTypeVarCounter int
|
||||
sourceInfo *exprpb.SourceInfo
|
||||
types map[int64]*exprpb.Type
|
||||
references map[int64]*exprpb.Reference
|
||||
types map[int64]*types.Type
|
||||
references map[int64]*ast.ReferenceInfo
|
||||
}
|
||||
|
||||
// Check performs type checking, giving a typed AST.
|
||||
@ -47,40 +45,38 @@ type checker struct {
|
||||
// descriptions of protocol buffers, and a registry for errors.
|
||||
// Returns a CheckedExpr proto, which might not be usable if
|
||||
// there are errors in the error registry.
|
||||
func Check(parsedExpr *exprpb.ParsedExpr,
|
||||
source common.Source,
|
||||
env *Env) (*exprpb.CheckedExpr, *common.Errors) {
|
||||
func Check(parsedExpr *exprpb.ParsedExpr, source common.Source, env *Env) (*ast.CheckedAST, *common.Errors) {
|
||||
errs := common.NewErrors(source)
|
||||
c := checker{
|
||||
env: env,
|
||||
errors: &typeErrors{common.NewErrors(source)},
|
||||
errors: &typeErrors{errs: errs},
|
||||
mappings: newMapping(),
|
||||
freeTypeVarCounter: 0,
|
||||
sourceInfo: parsedExpr.GetSourceInfo(),
|
||||
types: make(map[int64]*exprpb.Type),
|
||||
references: make(map[int64]*exprpb.Reference),
|
||||
types: make(map[int64]*types.Type),
|
||||
references: make(map[int64]*ast.ReferenceInfo),
|
||||
}
|
||||
c.check(parsedExpr.GetExpr())
|
||||
|
||||
// Walk over the final type map substituting any type parameters either by their bound value or
|
||||
// by DYN.
|
||||
m := make(map[int64]*exprpb.Type)
|
||||
for k, v := range c.types {
|
||||
m[k] = substitute(c.mappings, v, true)
|
||||
m := make(map[int64]*types.Type)
|
||||
for id, t := range c.types {
|
||||
m[id] = substitute(c.mappings, t, true)
|
||||
}
|
||||
|
||||
return &exprpb.CheckedExpr{
|
||||
return &ast.CheckedAST{
|
||||
Expr: parsedExpr.GetExpr(),
|
||||
SourceInfo: parsedExpr.GetSourceInfo(),
|
||||
TypeMap: m,
|
||||
ReferenceMap: c.references,
|
||||
}, c.errors.Errors
|
||||
}, errs
|
||||
}
|
||||
|
||||
func (c *checker) check(e *exprpb.Expr) {
|
||||
if e == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch e.GetExprKind().(type) {
|
||||
case *exprpb.Expr_ConstExpr:
|
||||
literal := e.GetConstExpr()
|
||||
@ -113,53 +109,51 @@ func (c *checker) check(e *exprpb.Expr) {
|
||||
case *exprpb.Expr_ComprehensionExpr:
|
||||
c.checkComprehension(e)
|
||||
default:
|
||||
c.errors.ReportError(
|
||||
c.location(e), "Unrecognized ast type: %v", reflect.TypeOf(e))
|
||||
c.errors.unexpectedASTType(e.GetId(), c.location(e), e)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *checker) checkInt64Literal(e *exprpb.Expr) {
|
||||
c.setType(e, decls.Int)
|
||||
c.setType(e, types.IntType)
|
||||
}
|
||||
|
||||
func (c *checker) checkUint64Literal(e *exprpb.Expr) {
|
||||
c.setType(e, decls.Uint)
|
||||
c.setType(e, types.UintType)
|
||||
}
|
||||
|
||||
func (c *checker) checkStringLiteral(e *exprpb.Expr) {
|
||||
c.setType(e, decls.String)
|
||||
c.setType(e, types.StringType)
|
||||
}
|
||||
|
||||
func (c *checker) checkBytesLiteral(e *exprpb.Expr) {
|
||||
c.setType(e, decls.Bytes)
|
||||
c.setType(e, types.BytesType)
|
||||
}
|
||||
|
||||
func (c *checker) checkDoubleLiteral(e *exprpb.Expr) {
|
||||
c.setType(e, decls.Double)
|
||||
c.setType(e, types.DoubleType)
|
||||
}
|
||||
|
||||
func (c *checker) checkBoolLiteral(e *exprpb.Expr) {
|
||||
c.setType(e, decls.Bool)
|
||||
c.setType(e, types.BoolType)
|
||||
}
|
||||
|
||||
func (c *checker) checkNullLiteral(e *exprpb.Expr) {
|
||||
c.setType(e, decls.Null)
|
||||
c.setType(e, types.NullType)
|
||||
}
|
||||
|
||||
func (c *checker) checkIdent(e *exprpb.Expr) {
|
||||
identExpr := e.GetIdentExpr()
|
||||
// Check to see if the identifier is declared.
|
||||
if ident := c.env.LookupIdent(identExpr.GetName()); ident != nil {
|
||||
c.setType(e, ident.GetIdent().GetType())
|
||||
c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().GetValue()))
|
||||
c.setType(e, ident.Type())
|
||||
c.setReference(e, ast.NewIdentReference(ident.Name(), ident.Value()))
|
||||
// Overwrite the identifier with its fully qualified name.
|
||||
identExpr.Name = ident.GetName()
|
||||
identExpr.Name = ident.Name()
|
||||
return
|
||||
}
|
||||
|
||||
c.setType(e, decls.Error)
|
||||
c.errors.undeclaredReference(
|
||||
c.location(e), c.env.container.Name(), identExpr.GetName())
|
||||
c.setType(e, types.ErrorType)
|
||||
c.errors.undeclaredReference(e.GetId(), c.location(e), c.env.container.Name(), identExpr.GetName())
|
||||
}
|
||||
|
||||
func (c *checker) checkSelect(e *exprpb.Expr) {
|
||||
@ -174,9 +168,9 @@ func (c *checker) checkSelect(e *exprpb.Expr) {
|
||||
|
||||
// Rewrite the node to be a variable reference to the resolved fully-qualified
|
||||
// variable name.
|
||||
c.setType(e, ident.GetIdent().GetType())
|
||||
c.setReference(e, newIdentReference(ident.GetName(), ident.GetIdent().GetValue()))
|
||||
identName := ident.GetName()
|
||||
c.setType(e, ident.Type())
|
||||
c.setReference(e, ast.NewIdentReference(ident.Name(), ident.Value()))
|
||||
identName := ident.Name()
|
||||
e.ExprKind = &exprpb.Expr_IdentExpr{
|
||||
IdentExpr: &exprpb.Expr_Ident{
|
||||
Name: identName,
|
||||
@ -188,7 +182,7 @@ func (c *checker) checkSelect(e *exprpb.Expr) {
|
||||
|
||||
resultType := c.checkSelectField(e, sel.GetOperand(), sel.GetField(), false)
|
||||
if sel.TestOnly {
|
||||
resultType = decls.Bool
|
||||
resultType = types.BoolType
|
||||
}
|
||||
c.setType(e, substitute(c.mappings, resultType, false))
|
||||
}
|
||||
@ -200,16 +194,17 @@ func (c *checker) checkOptSelect(e *exprpb.Expr) {
|
||||
field := call.GetArgs()[1]
|
||||
fieldName, isString := maybeUnwrapString(field)
|
||||
if !isString {
|
||||
c.errors.ReportError(c.location(field), "unsupported optional field selection: %v", field)
|
||||
c.errors.notAnOptionalFieldSelection(field.GetId(), c.location(field), field)
|
||||
return
|
||||
}
|
||||
|
||||
// Perform type-checking using the field selection logic.
|
||||
resultType := c.checkSelectField(e, operand, fieldName, true)
|
||||
c.setType(e, substitute(c.mappings, resultType, false))
|
||||
c.setReference(e, ast.NewFunctionReference("select_optional_field"))
|
||||
}
|
||||
|
||||
func (c *checker) checkSelectField(e, operand *exprpb.Expr, field string, optional bool) *exprpb.Type {
|
||||
func (c *checker) checkSelectField(e, operand *exprpb.Expr, field string, optional bool) *types.Type {
|
||||
// Interpret as field selection, first traversing down the operand.
|
||||
c.check(operand)
|
||||
operandType := substitute(c.mappings, c.getType(operand), false)
|
||||
@ -218,38 +213,37 @@ func (c *checker) checkSelectField(e, operand *exprpb.Expr, field string, option
|
||||
targetType, isOpt := maybeUnwrapOptional(operandType)
|
||||
|
||||
// Assume error type by default as most types do not support field selection.
|
||||
resultType := decls.Error
|
||||
switch kindOf(targetType) {
|
||||
case kindMap:
|
||||
resultType := types.ErrorType
|
||||
switch targetType.Kind() {
|
||||
case types.MapKind:
|
||||
// Maps yield their value type as the selection result type.
|
||||
mapType := targetType.GetMapType()
|
||||
resultType = mapType.GetValueType()
|
||||
case kindObject:
|
||||
resultType = targetType.Parameters()[1]
|
||||
case types.StructKind:
|
||||
// Objects yield their field type declaration as the selection result type, but only if
|
||||
// the field is defined.
|
||||
messageType := targetType
|
||||
if fieldType, found := c.lookupFieldType(c.location(e), messageType.GetMessageType(), field); found {
|
||||
resultType = fieldType.Type
|
||||
if fieldType, found := c.lookupFieldType(e.GetId(), messageType.TypeName(), field); found {
|
||||
resultType = fieldType
|
||||
}
|
||||
case kindTypeParam:
|
||||
case types.TypeParamKind:
|
||||
// Set the operand type to DYN to prevent assignment to a potentially incorrect type
|
||||
// at a later point in type-checking. The isAssignable call will update the type
|
||||
// substitutions for the type param under the covers.
|
||||
c.isAssignable(decls.Dyn, targetType)
|
||||
c.isAssignable(types.DynType, targetType)
|
||||
// Also, set the result type to DYN.
|
||||
resultType = decls.Dyn
|
||||
resultType = types.DynType
|
||||
default:
|
||||
// Dynamic / error values are treated as DYN type. Errors are handled this way as well
|
||||
// in order to allow forward progress on the check.
|
||||
if !isDynOrError(targetType) {
|
||||
c.errors.typeDoesNotSupportFieldSelection(c.location(e), targetType)
|
||||
c.errors.typeDoesNotSupportFieldSelection(e.GetId(), c.location(e), targetType)
|
||||
}
|
||||
resultType = decls.Dyn
|
||||
resultType = types.DynType
|
||||
}
|
||||
|
||||
// If the target type was optional coming in, then the result must be optional going out.
|
||||
if isOpt || optional {
|
||||
return decls.NewOptionalType(resultType)
|
||||
return types.NewOptionalType(resultType)
|
||||
}
|
||||
return resultType
|
||||
}
|
||||
@ -277,15 +271,14 @@ func (c *checker) checkCall(e *exprpb.Expr) {
|
||||
// Check for the existence of the function.
|
||||
fn := c.env.LookupFunction(fnName)
|
||||
if fn == nil {
|
||||
c.errors.undeclaredReference(
|
||||
c.location(e), c.env.container.Name(), fnName)
|
||||
c.setType(e, decls.Error)
|
||||
c.errors.undeclaredReference(e.GetId(), c.location(e), c.env.container.Name(), fnName)
|
||||
c.setType(e, types.ErrorType)
|
||||
return
|
||||
}
|
||||
// Overwrite the function name with its fully qualified resolved name.
|
||||
call.Function = fn.GetName()
|
||||
call.Function = fn.Name()
|
||||
// Check to see whether the overload resolves.
|
||||
c.resolveOverloadOrError(c.location(e), e, fn, nil, args)
|
||||
c.resolveOverloadOrError(e, fn, nil, args)
|
||||
return
|
||||
}
|
||||
|
||||
@ -303,8 +296,8 @@ func (c *checker) checkCall(e *exprpb.Expr) {
|
||||
// be an inaccurate representation of the desired evaluation behavior.
|
||||
// Overwrite with fully-qualified resolved function name sans receiver target.
|
||||
call.Target = nil
|
||||
call.Function = fn.GetName()
|
||||
c.resolveOverloadOrError(c.location(e), e, fn, nil, args)
|
||||
call.Function = fn.Name()
|
||||
c.resolveOverloadOrError(e, fn, nil, args)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -314,22 +307,21 @@ func (c *checker) checkCall(e *exprpb.Expr) {
|
||||
fn := c.env.LookupFunction(fnName)
|
||||
// Function found, attempt overload resolution.
|
||||
if fn != nil {
|
||||
c.resolveOverloadOrError(c.location(e), e, fn, target, args)
|
||||
c.resolveOverloadOrError(e, fn, target, args)
|
||||
return
|
||||
}
|
||||
// Function name not declared, record error.
|
||||
c.errors.undeclaredReference(c.location(e), c.env.container.Name(), fnName)
|
||||
c.setType(e, types.ErrorType)
|
||||
c.errors.undeclaredReference(e.GetId(), c.location(e), c.env.container.Name(), fnName)
|
||||
}
|
||||
|
||||
func (c *checker) resolveOverloadOrError(
|
||||
loc common.Location,
|
||||
e *exprpb.Expr,
|
||||
fn *exprpb.Decl, target *exprpb.Expr, args []*exprpb.Expr) {
|
||||
e *exprpb.Expr, fn *decls.FunctionDecl, target *exprpb.Expr, args []*exprpb.Expr) {
|
||||
// Attempt to resolve the overload.
|
||||
resolution := c.resolveOverload(loc, fn, target, args)
|
||||
resolution := c.resolveOverload(e, fn, target, args)
|
||||
// No such overload, error noted in the resolveOverload call, type recorded here.
|
||||
if resolution == nil {
|
||||
c.setType(e, decls.Error)
|
||||
c.setType(e, types.ErrorType)
|
||||
return
|
||||
}
|
||||
// Overload found.
|
||||
@ -338,10 +330,9 @@ func (c *checker) resolveOverloadOrError(
|
||||
}
|
||||
|
||||
func (c *checker) resolveOverload(
|
||||
loc common.Location,
|
||||
fn *exprpb.Decl, target *exprpb.Expr, args []*exprpb.Expr) *overloadResolution {
|
||||
call *exprpb.Expr, fn *decls.FunctionDecl, target *exprpb.Expr, args []*exprpb.Expr) *overloadResolution {
|
||||
|
||||
var argTypes []*exprpb.Type
|
||||
var argTypes []*types.Type
|
||||
if target != nil {
|
||||
argTypes = append(argTypes, c.getType(target))
|
||||
}
|
||||
@ -349,55 +340,75 @@ func (c *checker) resolveOverload(
|
||||
argTypes = append(argTypes, c.getType(arg))
|
||||
}
|
||||
|
||||
var resultType *exprpb.Type
|
||||
var checkedRef *exprpb.Reference
|
||||
for _, overload := range fn.GetFunction().GetOverloads() {
|
||||
var resultType *types.Type
|
||||
var checkedRef *ast.ReferenceInfo
|
||||
for _, overload := range fn.OverloadDecls() {
|
||||
// Determine whether the overload is currently considered.
|
||||
if c.env.isOverloadDisabled(overload.GetOverloadId()) {
|
||||
if c.env.isOverloadDisabled(overload.ID()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Ensure the call style for the overload matches.
|
||||
if (target == nil && overload.GetIsInstanceFunction()) ||
|
||||
(target != nil && !overload.GetIsInstanceFunction()) {
|
||||
if (target == nil && overload.IsMemberFunction()) ||
|
||||
(target != nil && !overload.IsMemberFunction()) {
|
||||
// not a compatible call style.
|
||||
continue
|
||||
}
|
||||
|
||||
overloadType := decls.NewFunctionType(overload.ResultType, overload.Params...)
|
||||
if len(overload.GetTypeParams()) > 0 {
|
||||
// Alternative type-checking behavior when the logical operators are compacted into
|
||||
// variadic AST representations.
|
||||
if fn.Name() == operators.LogicalAnd || fn.Name() == operators.LogicalOr {
|
||||
checkedRef = ast.NewFunctionReference(overload.ID())
|
||||
for i, argType := range argTypes {
|
||||
if !c.isAssignable(argType, types.BoolType) {
|
||||
c.errors.typeMismatch(
|
||||
args[i].GetId(),
|
||||
c.locationByID(args[i].GetId()),
|
||||
types.BoolType,
|
||||
argType)
|
||||
resultType = types.ErrorType
|
||||
}
|
||||
}
|
||||
if isError(resultType) {
|
||||
return nil
|
||||
}
|
||||
return newResolution(checkedRef, types.BoolType)
|
||||
}
|
||||
|
||||
overloadType := newFunctionType(overload.ResultType(), overload.ArgTypes()...)
|
||||
typeParams := overload.TypeParams()
|
||||
if len(typeParams) != 0 {
|
||||
// Instantiate overload's type with fresh type variables.
|
||||
substitutions := newMapping()
|
||||
for _, typePar := range overload.GetTypeParams() {
|
||||
substitutions.add(decls.NewTypeParamType(typePar), c.newTypeVar())
|
||||
for _, typePar := range typeParams {
|
||||
substitutions.add(types.NewTypeParamType(typePar), c.newTypeVar())
|
||||
}
|
||||
overloadType = substitute(substitutions, overloadType, false)
|
||||
}
|
||||
|
||||
candidateArgTypes := overloadType.GetFunction().GetArgTypes()
|
||||
candidateArgTypes := overloadType.Parameters()[1:]
|
||||
if c.isAssignableList(argTypes, candidateArgTypes) {
|
||||
if checkedRef == nil {
|
||||
checkedRef = newFunctionReference(overload.GetOverloadId())
|
||||
checkedRef = ast.NewFunctionReference(overload.ID())
|
||||
} else {
|
||||
checkedRef.OverloadId = append(checkedRef.GetOverloadId(), overload.GetOverloadId())
|
||||
checkedRef.AddOverload(overload.ID())
|
||||
}
|
||||
|
||||
// First matching overload, determines result type.
|
||||
fnResultType := substitute(c.mappings, overloadType.GetFunction().GetResultType(), false)
|
||||
fnResultType := substitute(c.mappings, overloadType.Parameters()[0], false)
|
||||
if resultType == nil {
|
||||
resultType = fnResultType
|
||||
} else if !isDyn(resultType) && !proto.Equal(fnResultType, resultType) {
|
||||
resultType = decls.Dyn
|
||||
} else if !isDyn(resultType) && !fnResultType.IsExactType(resultType) {
|
||||
resultType = types.DynType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if resultType == nil {
|
||||
for i, arg := range argTypes {
|
||||
argTypes[i] = substitute(c.mappings, arg, true)
|
||||
for i, argType := range argTypes {
|
||||
argTypes[i] = substitute(c.mappings, argType, true)
|
||||
}
|
||||
c.errors.noMatchingOverload(loc, fn.GetName(), argTypes, target != nil)
|
||||
resultType = decls.Error
|
||||
c.errors.noMatchingOverload(call.GetId(), c.location(call), fn.Name(), argTypes, target != nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -406,7 +417,7 @@ func (c *checker) resolveOverload(
|
||||
|
||||
func (c *checker) checkCreateList(e *exprpb.Expr) {
|
||||
create := e.GetListExpr()
|
||||
var elemsType *exprpb.Type
|
||||
var elemsType *types.Type
|
||||
optionalIndices := create.GetOptionalIndices()
|
||||
optionals := make(map[int32]bool, len(optionalIndices))
|
||||
for _, optInd := range optionalIndices {
|
||||
@ -419,16 +430,16 @@ func (c *checker) checkCreateList(e *exprpb.Expr) {
|
||||
var isOptional bool
|
||||
elemType, isOptional = maybeUnwrapOptional(elemType)
|
||||
if !isOptional && !isDyn(elemType) {
|
||||
c.errors.typeMismatch(c.location(e), decls.NewOptionalType(elemType), elemType)
|
||||
c.errors.typeMismatch(e.GetId(), c.location(e), types.NewOptionalType(elemType), elemType)
|
||||
}
|
||||
}
|
||||
elemsType = c.joinTypes(c.location(e), elemsType, elemType)
|
||||
elemsType = c.joinTypes(e, elemsType, elemType)
|
||||
}
|
||||
if elemsType == nil {
|
||||
// If the list is empty, assign free type var to elem type.
|
||||
elemsType = c.newTypeVar()
|
||||
}
|
||||
c.setType(e, decls.NewListType(elemsType))
|
||||
c.setType(e, types.NewListType(elemsType))
|
||||
}
|
||||
|
||||
func (c *checker) checkCreateStruct(e *exprpb.Expr) {
|
||||
@ -442,12 +453,12 @@ func (c *checker) checkCreateStruct(e *exprpb.Expr) {
|
||||
|
||||
func (c *checker) checkCreateMap(e *exprpb.Expr) {
|
||||
mapVal := e.GetStructExpr()
|
||||
var mapKeyType *exprpb.Type
|
||||
var mapValueType *exprpb.Type
|
||||
var mapKeyType *types.Type
|
||||
var mapValueType *types.Type
|
||||
for _, ent := range mapVal.GetEntries() {
|
||||
key := ent.GetMapKey()
|
||||
c.check(key)
|
||||
mapKeyType = c.joinTypes(c.location(key), mapKeyType, c.getType(key))
|
||||
mapKeyType = c.joinTypes(key, mapKeyType, c.getType(key))
|
||||
|
||||
val := ent.GetValue()
|
||||
c.check(val)
|
||||
@ -456,50 +467,54 @@ func (c *checker) checkCreateMap(e *exprpb.Expr) {
|
||||
var isOptional bool
|
||||
valType, isOptional = maybeUnwrapOptional(valType)
|
||||
if !isOptional && !isDyn(valType) {
|
||||
c.errors.typeMismatch(c.location(val), decls.NewOptionalType(valType), valType)
|
||||
c.errors.typeMismatch(val.GetId(), c.location(val), types.NewOptionalType(valType), valType)
|
||||
}
|
||||
}
|
||||
mapValueType = c.joinTypes(c.location(val), mapValueType, valType)
|
||||
mapValueType = c.joinTypes(val, mapValueType, valType)
|
||||
}
|
||||
if mapKeyType == nil {
|
||||
// If the map is empty, assign free type variables to typeKey and value type.
|
||||
mapKeyType = c.newTypeVar()
|
||||
mapValueType = c.newTypeVar()
|
||||
}
|
||||
c.setType(e, decls.NewMapType(mapKeyType, mapValueType))
|
||||
c.setType(e, types.NewMapType(mapKeyType, mapValueType))
|
||||
}
|
||||
|
||||
func (c *checker) checkCreateMessage(e *exprpb.Expr) {
|
||||
msgVal := e.GetStructExpr()
|
||||
// Determine the type of the message.
|
||||
messageType := decls.Error
|
||||
decl := c.env.LookupIdent(msgVal.GetMessageName())
|
||||
if decl == nil {
|
||||
resultType := types.ErrorType
|
||||
ident := c.env.LookupIdent(msgVal.GetMessageName())
|
||||
if ident == nil {
|
||||
c.errors.undeclaredReference(
|
||||
c.location(e), c.env.container.Name(), msgVal.GetMessageName())
|
||||
e.GetId(), c.location(e), c.env.container.Name(), msgVal.GetMessageName())
|
||||
c.setType(e, types.ErrorType)
|
||||
return
|
||||
}
|
||||
// Ensure the type name is fully qualified in the AST.
|
||||
msgVal.MessageName = decl.GetName()
|
||||
c.setReference(e, newIdentReference(decl.GetName(), nil))
|
||||
ident := decl.GetIdent()
|
||||
identKind := kindOf(ident.GetType())
|
||||
if identKind != kindError {
|
||||
if identKind != kindType {
|
||||
c.errors.notAType(c.location(e), ident.GetType())
|
||||
typeName := ident.Name()
|
||||
msgVal.MessageName = typeName
|
||||
c.setReference(e, ast.NewIdentReference(ident.Name(), nil))
|
||||
identKind := ident.Type().Kind()
|
||||
if identKind != types.ErrorKind {
|
||||
if identKind != types.TypeKind {
|
||||
c.errors.notAType(e.GetId(), c.location(e), ident.Type().DeclaredTypeName())
|
||||
} else {
|
||||
messageType = ident.GetType().GetType()
|
||||
if kindOf(messageType) != kindObject {
|
||||
c.errors.notAMessageType(c.location(e), messageType)
|
||||
messageType = decls.Error
|
||||
resultType = ident.Type().Parameters()[0]
|
||||
// Backwards compatibility test between well-known types and message types
|
||||
// In this context, the type is being instantiated by its protobuf name which
|
||||
// is not ideal or recommended, but some users expect this to work.
|
||||
if isWellKnownType(resultType) {
|
||||
typeName = getWellKnownTypeName(resultType)
|
||||
} else if resultType.Kind() == types.StructKind {
|
||||
typeName = resultType.DeclaredTypeName()
|
||||
} else {
|
||||
c.errors.notAMessageType(e.GetId(), c.location(e), resultType.DeclaredTypeName())
|
||||
resultType = types.ErrorType
|
||||
}
|
||||
}
|
||||
}
|
||||
if isObjectWellKnownType(messageType) {
|
||||
c.setType(e, getObjectWellKnownType(messageType))
|
||||
} else {
|
||||
c.setType(e, messageType)
|
||||
}
|
||||
c.setType(e, resultType)
|
||||
|
||||
// Check the field initializers.
|
||||
for _, ent := range msgVal.GetEntries() {
|
||||
@ -507,10 +522,10 @@ func (c *checker) checkCreateMessage(e *exprpb.Expr) {
|
||||
value := ent.GetValue()
|
||||
c.check(value)
|
||||
|
||||
fieldType := decls.Error
|
||||
ft, found := c.lookupFieldType(c.locationByID(ent.GetId()), messageType.GetMessageType(), field)
|
||||
fieldType := types.ErrorType
|
||||
ft, found := c.lookupFieldType(ent.GetId(), typeName, field)
|
||||
if found {
|
||||
fieldType = ft.Type
|
||||
fieldType = ft
|
||||
}
|
||||
|
||||
valType := c.getType(value)
|
||||
@ -518,11 +533,11 @@ func (c *checker) checkCreateMessage(e *exprpb.Expr) {
|
||||
var isOptional bool
|
||||
valType, isOptional = maybeUnwrapOptional(valType)
|
||||
if !isOptional && !isDyn(valType) {
|
||||
c.errors.typeMismatch(c.location(value), decls.NewOptionalType(valType), valType)
|
||||
c.errors.typeMismatch(value.GetId(), c.location(value), types.NewOptionalType(valType), valType)
|
||||
}
|
||||
}
|
||||
if !c.isAssignable(fieldType, valType) {
|
||||
c.errors.fieldTypeMismatch(c.locationByID(ent.Id), field, fieldType, valType)
|
||||
c.errors.fieldTypeMismatch(ent.GetId(), c.locationByID(ent.GetId()), field, fieldType, valType)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -533,36 +548,36 @@ func (c *checker) checkComprehension(e *exprpb.Expr) {
|
||||
c.check(comp.GetAccuInit())
|
||||
accuType := c.getType(comp.GetAccuInit())
|
||||
rangeType := substitute(c.mappings, c.getType(comp.GetIterRange()), false)
|
||||
var varType *exprpb.Type
|
||||
var varType *types.Type
|
||||
|
||||
switch kindOf(rangeType) {
|
||||
case kindList:
|
||||
varType = rangeType.GetListType().GetElemType()
|
||||
case kindMap:
|
||||
switch rangeType.Kind() {
|
||||
case types.ListKind:
|
||||
varType = rangeType.Parameters()[0]
|
||||
case types.MapKind:
|
||||
// Ranges over the keys.
|
||||
varType = rangeType.GetMapType().GetKeyType()
|
||||
case kindDyn, kindError, kindTypeParam:
|
||||
varType = rangeType.Parameters()[0]
|
||||
case types.DynKind, types.ErrorKind, types.TypeParamKind:
|
||||
// Set the range type to DYN to prevent assignment to a potentially incorrect type
|
||||
// at a later point in type-checking. The isAssignable call will update the type
|
||||
// substitutions for the type param under the covers.
|
||||
c.isAssignable(decls.Dyn, rangeType)
|
||||
c.isAssignable(types.DynType, rangeType)
|
||||
// Set the range iteration variable to type DYN as well.
|
||||
varType = decls.Dyn
|
||||
varType = types.DynType
|
||||
default:
|
||||
c.errors.notAComprehensionRange(c.location(comp.GetIterRange()), rangeType)
|
||||
varType = decls.Error
|
||||
c.errors.notAComprehensionRange(comp.GetIterRange().GetId(), c.location(comp.GetIterRange()), rangeType)
|
||||
varType = types.ErrorType
|
||||
}
|
||||
|
||||
// Create a scope for the comprehension since it has a local accumulation variable.
|
||||
// This scope will contain the accumulation variable used to compute the result.
|
||||
c.env = c.env.enterScope()
|
||||
c.env.Add(decls.NewVar(comp.GetAccuVar(), accuType))
|
||||
c.env.AddIdents(decls.NewVariable(comp.GetAccuVar(), accuType))
|
||||
// Create a block scope for the loop.
|
||||
c.env = c.env.enterScope()
|
||||
c.env.Add(decls.NewVar(comp.GetIterVar(), varType))
|
||||
c.env.AddIdents(decls.NewVariable(comp.GetIterVar(), varType))
|
||||
// Check the variable references in the condition and step.
|
||||
c.check(comp.GetLoopCondition())
|
||||
c.assertType(comp.GetLoopCondition(), decls.Bool)
|
||||
c.assertType(comp.GetLoopCondition(), types.BoolType)
|
||||
c.check(comp.GetLoopStep())
|
||||
c.assertType(comp.GetLoopStep(), accuType)
|
||||
// Exit the loop's block scope before checking the result.
|
||||
@ -574,9 +589,7 @@ func (c *checker) checkComprehension(e *exprpb.Expr) {
|
||||
}
|
||||
|
||||
// Checks compatibility of joined types, and returns the most general common type.
|
||||
func (c *checker) joinTypes(loc common.Location,
|
||||
previous *exprpb.Type,
|
||||
current *exprpb.Type) *exprpb.Type {
|
||||
func (c *checker) joinTypes(e *exprpb.Expr, previous, current *types.Type) *types.Type {
|
||||
if previous == nil {
|
||||
return current
|
||||
}
|
||||
@ -584,23 +597,23 @@ func (c *checker) joinTypes(loc common.Location,
|
||||
return mostGeneral(previous, current)
|
||||
}
|
||||
if c.dynAggregateLiteralElementTypesEnabled() {
|
||||
return decls.Dyn
|
||||
return types.DynType
|
||||
}
|
||||
c.errors.typeMismatch(loc, previous, current)
|
||||
return decls.Error
|
||||
c.errors.typeMismatch(e.GetId(), c.location(e), previous, current)
|
||||
return types.ErrorType
|
||||
}
|
||||
|
||||
func (c *checker) dynAggregateLiteralElementTypesEnabled() bool {
|
||||
return c.env.aggLitElemType == dynElementType
|
||||
}
|
||||
|
||||
func (c *checker) newTypeVar() *exprpb.Type {
|
||||
func (c *checker) newTypeVar() *types.Type {
|
||||
id := c.freeTypeVarCounter
|
||||
c.freeTypeVarCounter++
|
||||
return decls.NewTypeParamType(fmt.Sprintf("_var%d", id))
|
||||
return types.NewTypeParamType(fmt.Sprintf("_var%d", id))
|
||||
}
|
||||
|
||||
func (c *checker) isAssignable(t1 *exprpb.Type, t2 *exprpb.Type) bool {
|
||||
func (c *checker) isAssignable(t1, t2 *types.Type) bool {
|
||||
subs := isAssignable(c.mappings, t1, t2)
|
||||
if subs != nil {
|
||||
c.mappings = subs
|
||||
@ -610,7 +623,7 @@ func (c *checker) isAssignable(t1 *exprpb.Type, t2 *exprpb.Type) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *checker) isAssignableList(l1 []*exprpb.Type, l2 []*exprpb.Type) bool {
|
||||
func (c *checker) isAssignableList(l1, l2 []*types.Type) bool {
|
||||
subs := isAssignableList(c.mappings, l1, l2)
|
||||
if subs != nil {
|
||||
c.mappings = subs
|
||||
@ -620,57 +633,52 @@ func (c *checker) isAssignableList(l1 []*exprpb.Type, l2 []*exprpb.Type) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *checker) lookupFieldType(l common.Location, messageType string, fieldName string) (*ref.FieldType, bool) {
|
||||
if _, found := c.env.provider.FindType(messageType); !found {
|
||||
// This should not happen, anyway, report an error.
|
||||
c.errors.unexpectedFailedResolution(l, messageType)
|
||||
return nil, false
|
||||
func maybeUnwrapString(e *exprpb.Expr) (string, bool) {
|
||||
switch e.GetExprKind().(type) {
|
||||
case *exprpb.Expr_ConstExpr:
|
||||
literal := e.GetConstExpr()
|
||||
switch literal.GetConstantKind().(type) {
|
||||
case *exprpb.Constant_StringValue:
|
||||
return literal.GetStringValue(), true
|
||||
}
|
||||
}
|
||||
|
||||
if ft, found := c.env.provider.FindFieldType(messageType, fieldName); found {
|
||||
return ft, found
|
||||
}
|
||||
|
||||
c.errors.undefinedField(l, fieldName)
|
||||
return nil, false
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (c *checker) setType(e *exprpb.Expr, t *exprpb.Type) {
|
||||
if old, found := c.types[e.GetId()]; found && !proto.Equal(old, t) {
|
||||
c.errors.ReportError(c.location(e),
|
||||
"(Incompatible) Type already exists for expression: %v(%d) old:%v, new:%v", e, e.GetId(), old, t)
|
||||
func (c *checker) setType(e *exprpb.Expr, t *types.Type) {
|
||||
if old, found := c.types[e.GetId()]; found && !old.IsExactType(t) {
|
||||
c.errors.incompatibleType(e.GetId(), c.location(e), e, old, t)
|
||||
return
|
||||
}
|
||||
c.types[e.GetId()] = t
|
||||
}
|
||||
|
||||
func (c *checker) getType(e *exprpb.Expr) *exprpb.Type {
|
||||
func (c *checker) getType(e *exprpb.Expr) *types.Type {
|
||||
return c.types[e.GetId()]
|
||||
}
|
||||
|
||||
func (c *checker) setReference(e *exprpb.Expr, r *exprpb.Reference) {
|
||||
if old, found := c.references[e.GetId()]; found && !proto.Equal(old, r) {
|
||||
c.errors.ReportError(c.location(e),
|
||||
"Reference already exists for expression: %v(%d) old:%v, new:%v", e, e.GetId(), old, r)
|
||||
func (c *checker) setReference(e *exprpb.Expr, r *ast.ReferenceInfo) {
|
||||
if old, found := c.references[e.GetId()]; found && !old.Equals(r) {
|
||||
c.errors.referenceRedefinition(e.GetId(), c.location(e), e, old, r)
|
||||
return
|
||||
}
|
||||
c.references[e.GetId()] = r
|
||||
}
|
||||
|
||||
func (c *checker) assertType(e *exprpb.Expr, t *exprpb.Type) {
|
||||
func (c *checker) assertType(e *exprpb.Expr, t *types.Type) {
|
||||
if !c.isAssignable(t, c.getType(e)) {
|
||||
c.errors.typeMismatch(c.location(e), t, c.getType(e))
|
||||
c.errors.typeMismatch(e.GetId(), c.location(e), t, c.getType(e))
|
||||
}
|
||||
}
|
||||
|
||||
type overloadResolution struct {
|
||||
Reference *exprpb.Reference
|
||||
Type *exprpb.Type
|
||||
Type *types.Type
|
||||
Reference *ast.ReferenceInfo
|
||||
}
|
||||
|
||||
func newResolution(checkedRef *exprpb.Reference, t *exprpb.Type) *overloadResolution {
|
||||
func newResolution(r *ast.ReferenceInfo, t *types.Type) *overloadResolution {
|
||||
return &overloadResolution{
|
||||
Reference: checkedRef,
|
||||
Reference: r,
|
||||
Type: t,
|
||||
}
|
||||
}
|
||||
@ -697,10 +705,56 @@ func (c *checker) locationByID(id int64) common.Location {
|
||||
return common.NoLocation
|
||||
}
|
||||
|
||||
func newIdentReference(name string, value *exprpb.Constant) *exprpb.Reference {
|
||||
return &exprpb.Reference{Name: name, Value: value}
|
||||
func (c *checker) lookupFieldType(exprID int64, structType, fieldName string) (*types.Type, bool) {
|
||||
if _, found := c.env.provider.FindStructType(structType); !found {
|
||||
// This should not happen, anyway, report an error.
|
||||
c.errors.unexpectedFailedResolution(exprID, c.locationByID(exprID), structType)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
if ft, found := c.env.provider.FindStructFieldType(structType, fieldName); found {
|
||||
return ft.Type, found
|
||||
}
|
||||
|
||||
c.errors.undefinedField(exprID, c.locationByID(exprID), fieldName)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func newFunctionReference(overloads ...string) *exprpb.Reference {
|
||||
return &exprpb.Reference{OverloadId: overloads}
|
||||
func isWellKnownType(t *types.Type) bool {
|
||||
switch t.Kind() {
|
||||
case types.AnyKind, types.TimestampKind, types.DurationKind, types.DynKind, types.NullTypeKind:
|
||||
return true
|
||||
case types.BoolKind, types.BytesKind, types.DoubleKind, types.IntKind, types.StringKind, types.UintKind:
|
||||
return t.IsAssignableType(types.NullType)
|
||||
case types.ListKind:
|
||||
return t.Parameters()[0] == types.DynType
|
||||
case types.MapKind:
|
||||
return t.Parameters()[0] == types.StringType && t.Parameters()[1] == types.DynType
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getWellKnownTypeName(t *types.Type) string {
|
||||
if name, found := wellKnownTypes[t.Kind()]; found {
|
||||
return name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var (
|
||||
wellKnownTypes = map[types.Kind]string{
|
||||
types.AnyKind: "google.protobuf.Any",
|
||||
types.BoolKind: "google.protobuf.BoolValue",
|
||||
types.BytesKind: "google.protobuf.BytesValue",
|
||||
types.DoubleKind: "google.protobuf.DoubleValue",
|
||||
types.DurationKind: "google.protobuf.Duration",
|
||||
types.DynKind: "google.protobuf.Value",
|
||||
types.IntKind: "google.protobuf.Int64Value",
|
||||
types.ListKind: "google.protobuf.ListValue",
|
||||
types.NullTypeKind: "google.protobuf.NullValue",
|
||||
types.MapKind: "google.protobuf.Struct",
|
||||
types.StringKind: "google.protobuf.StringValue",
|
||||
types.TimestampKind: "google.protobuf.Timestamp",
|
||||
types.UintKind: "google.protobuf.UInt64Value",
|
||||
}
|
||||
)
|
||||
|
Reference in New Issue
Block a user