From 134354c68768c0e3530c02678e12cb02f5646e8a Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 1 Nov 2017 13:16:26 -0400 Subject: Adding support for associated types. --- source/slang/syntax.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 5 deletions(-) (limited to 'source/slang/syntax.cpp') diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 97f3cfb15..fd7fc0e14 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -959,15 +959,60 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr AssocTypeDeclRefType::SubstituteImpl(Substitutions* subst, int* ioDiff) { - auto parentType = this->GetDeclRef().GetParent().SubstituteImpl(subst, ioDiff); - if (auto aggDeclRef = parentType.As()) + if (!sourceType) + return this; + if (auto parentDeclRefType = sourceType->As()) { - Decl* targetTypeDecl = nullptr; - if (aggDeclRef.getDecl()->memberDictionary.TryGetValue(this->GetDeclRef().decl->getName(), targetTypeDecl)) + auto parentDeclRef = parentDeclRefType->declRef; + DeclRef newParentDeclRef = parentDeclRef.As(); + // search for a substitution that might apply to us + for (auto s = subst; s; s = s->outer.Ptr()) { - return DeclRefType::Create(this->session, DeclRef(targetTypeDecl, parentType.substitutions)); + // the generic decl associated with the substitution list must be + // the generic decl that declared this parameter + auto genericDecl = s->genericDecl; + if (genericDecl != parentDeclRef.getDecl()->ParentDecl) + continue; + int index = 0; + for (auto m : genericDecl->Members) + { + if (m.Ptr() == parentDeclRef.getDecl()) + { + // We've found it, so return the corresponding specialization argument + (*ioDiff)++; + if (auto declRef = s->args[index].As()) + { + newParentDeclRef = (*declRef).declRef.As(); + goto searchEnd; + } + } + else if (auto typeParam = m.As()) + { + index++; + } + else if (auto valParam = m.As()) + { + index++; + } + else + { + } + } + } + searchEnd: + if (newParentDeclRef) + { + Decl* targetTypeDecl = nullptr; + if (newParentDeclRef.getDecl()->memberDictionary.TryGetValue(this->GetDeclRef().decl->getName(), targetTypeDecl)) + { + if (auto typeDefDecl = targetTypeDecl->As()) + return GetType(DeclRef(typeDefDecl, subst)); + else + return DeclRefType::Create(this->getSession(), DeclRef(targetTypeDecl, subst)); + } } } + return this; } @@ -981,6 +1026,69 @@ void Type::accept(IValVisitor* visitor, void* extra) return this; } + // GenericConstraintDeclRefType + + String GenericConstraintDeclRefType::ToString() + { + // TODO: what is appropriate here? + return ""; + } + + bool GenericConstraintDeclRefType::EqualsImpl(Type * type) + { + if (auto other = type->As()) + { + return supType->Equals(other->supType) && subType->Equals(other->subType); + } + return false; + } + + RefPtr GenericConstraintDeclRefType::SubstituteImpl(Substitutions* subst, int* ioDiff) + { + auto genParamDecl = subType.As()->declRef.As(); + // search for a substitution that might apply to us + for (auto s = subst; s; s = s->outer.Ptr()) + { + // the generic decl associated with the substitution list must be + // the generic decl that declared this parameter + auto genericDecl = s->genericDecl; + if (genericDecl != genParamDecl.getDecl()->ParentDecl) + continue; + int index = 0; + for (auto m : genericDecl->Members) + { + if (m.Ptr() == genParamDecl.getDecl()) + { + // We've found it, so return the corresponding specialization argument + (*ioDiff)++; + return s->args[index]; + } + else if (auto typeParam = m.As()) + { + index++; + } + else if (auto valParam = m.As()) + { + index++; + } + else + { + } + } + } + return this; + } + + int GenericConstraintDeclRefType::GetHashCode() + { + return combineHash(subType.GetHashCode(), supType.GetHashCode()); + } + + Type* GenericConstraintDeclRefType::CreateCanonicalType() + { + return this; + } + // ArithmeticExpressionType // VectorExpressionType -- cgit v1.2.3