コード例 #1
0
ファイル: namedscope.go プロジェクト: Serulian/compiler
// 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)
	}
}
コード例 #2
0
ファイル: scope_sml_expr.go プロジェクト: Serulian/compiler
// 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
}