// ResolveStaticMember attempts to resolve a member (child) with the given name under this named scope, which // must be Static. func (nsi *namedScopeInfo) ResolveStaticMember(name string, module compilercommon.InputSource, staticType typegraph.TypeReference) (namedScopeInfo, error) { if !nsi.IsStatic() { return namedScopeInfo{}, fmt.Errorf("Could not find static name '%v' under non-static scope", name) } if nsi.typeInfo != nil { typeMember, rerr := staticType.ResolveAccessibleMember(name, module, typegraph.MemberResolutionStatic) if rerr != nil { return namedScopeInfo{}, rerr } return namedScopeInfo{srg.SRGNamedScope{}, typeMember, nsi.sb}, nil } else { namedScopeOrImport, found := nsi.srgInfo.ResolveNameUnderScope(name) if !found { return namedScopeInfo{}, fmt.Errorf("Could not find static name '%v' under %v %v", name, nsi.srgInfo.Title(), nsi.srgInfo.Name()) } return nsi.sb.processSRGNameOrInfo(namedScopeOrImport) } }
// scopeSmlNormalAttribute scopes an SML expression attribute under a declaration. func (sb *scopeBuilder) scopeSmlAttribute(node compilergraph.GraphNode, propsType typegraph.TypeReference, context scopeContext) (string, bool) { attributeName := node.Get(parser.NodeSmlAttributeName) // If the props type is a struct or class, ensure that the attribute name exists. var allowedValueType = sb.sg.tdg.AnyTypeReference() if propsType.IsRefToStruct() || propsType.IsRefToClass() { module := compilercommon.InputSource(node.Get(parser.NodePredicateSource)) resolvedMember, rerr := propsType.ResolveAccessibleMember(attributeName, module, typegraph.MemberResolutionInstance) if rerr != nil { sb.decorateWithError(node, "%v", rerr) return attributeName, false } allowedValueType = resolvedMember.AssignableType() } else { // The props type must be a mapping, so the value must match it value type. allowedValueType = propsType.Generics()[0] } // Scope the attribute value (if any). If none, then we default to a boolean value. var attributeValueType = sb.sg.tdg.BoolTypeReference() valueNode, hasValueNode := node.TryGetNode(parser.NodeSmlAttributeValue) if hasValueNode { attributeValueScope := sb.getScope(valueNode, context) if !attributeValueScope.GetIsValid() { return attributeName, false } attributeValueType = attributeValueScope.ResolvedTypeRef(sb.sg.tdg) } // Ensure it matches the assignable value type. if serr := attributeValueType.CheckSubTypeOf(allowedValueType); serr != nil { sb.decorateWithError(node, "Cannot assign value of type %v for attribute %v: %v", attributeValueType, attributeName, serr) return attributeName, false } return attributeName, true }