MCPcopy Index your code
hub / github.com/expr-lang/expr / memberNode

Method memberNode

checker/checker.go:515–603  ·  view source on GitHub ↗
(node *ast.MemberNode)

Source from the content-addressed store, hash-verified

513}
514
515func (v *Checker) memberNode(node *ast.MemberNode) Nature {
516 // $env variable
517 if an, ok := node.Node.(*ast.IdentifierNode); ok && an.Value == "$env" {
518 if name, ok := node.Property.(*ast.StringNode); ok {
519 strict := v.config.Strict
520 if node.Optional {
521 // If user explicitly set optional flag, then we should not
522 // throw error if field is not found (as user trying to handle
523 // this case). But if user did not set optional flag, then we
524 // should throw error if field is not found & v.config.Strict.
525 strict = false
526 }
527 return v.ident(node, name.Value, strict, false /* no builtins and no functions */)
528 }
529 return Nature{}
530 }
531
532 base := v.visit(node.Node)
533 prop := v.visit(node.Property)
534
535 if base.IsUnknown(&v.config.NtCache) {
536 return Nature{}
537 }
538
539 if name, ok := node.Property.(*ast.StringNode); ok {
540 if base.Nil {
541 return v.error(node, "type nil has no field %s", name.Value)
542 }
543
544 // First, check methods defined on base type itself,
545 // independent of which type it is. Without dereferencing.
546 if m, ok := base.MethodByName(&v.config.NtCache, name.Value); ok {
547 return m
548 }
549 }
550
551 base = base.Deref(&v.config.NtCache)
552
553 switch base.Kind {
554 case reflect.Map:
555 // If the map key is a pointer, we should not dereference the property.
556 if !prop.AssignableTo(base.Key(&v.config.NtCache)) {
557 propDeref := prop.Deref(&v.config.NtCache)
558 if propDeref.AssignableTo(base.Key(&v.config.NtCache)) {
559 prop = propDeref
560 }
561 }
562 if !prop.AssignableTo(base.Key(&v.config.NtCache)) && !prop.IsUnknown(&v.config.NtCache) {
563 return v.error(node.Property, "cannot use %s to get an element from %s", prop.String(), base.String())
564 }
565 if prop, ok := node.Property.(*ast.StringNode); ok && base.TypeData != nil {
566 if field, ok := base.Fields[prop.Value]; ok {
567 return field
568 } else if base.Strict {
569 return v.error(node.Property, "unknown field %s", prop.Value)
570 }
571 }
572 return base.Elem(&v.config.NtCache)

Callers 1

visitMethod · 0.95

Implementers 3

Configconf/config.go
Checkerchecker/checker.go
OperatorOverloadingpatcher/operator_override.go

Calls 12

identMethod · 0.95
visitMethod · 0.95
errorMethod · 0.95
IsUnknownMethod · 0.80
MethodByNameMethod · 0.80
DerefMethod · 0.80
AssignableToMethod · 0.80
KeyMethod · 0.80
ElemMethod · 0.80
FieldByNameMethod · 0.80
FromTypeMethod · 0.80
StringMethod · 0.65

Tested by

no test coverage detected