diff options
| author | Yong He <yonghe@outlook.com> | 2017-11-01 13:16:26 -0400 |
|---|---|---|
| committer | Yong He <yonghe@outlook.com> | 2017-11-01 13:16:26 -0400 |
| commit | 134354c68768c0e3530c02678e12cb02f5646e8a (patch) | |
| tree | 20a9ae10db6790ddc5032315b85efd94fc672cff /source/slang/syntax.cpp | |
| parent | b623864fe609e6912cdd2e350aa70cf7e441e1d3 (diff) | |
Adding support for associated types.
Diffstat (limited to 'source/slang/syntax.cpp')
| -rw-r--r-- | source/slang/syntax.cpp | 118 |
1 files changed, 113 insertions, 5 deletions
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<Val> AssocTypeDeclRefType::SubstituteImpl(Substitutions* subst, int* ioDiff) { - auto parentType = this->GetDeclRef().GetParent().SubstituteImpl(subst, ioDiff); - if (auto aggDeclRef = parentType.As<AggTypeDecl>()) + if (!sourceType) + return this; + if (auto parentDeclRefType = sourceType->As<DeclRefType>()) { - Decl* targetTypeDecl = nullptr; - if (aggDeclRef.getDecl()->memberDictionary.TryGetValue(this->GetDeclRef().decl->getName(), targetTypeDecl)) + auto parentDeclRef = parentDeclRefType->declRef; + DeclRef<AggTypeDecl> newParentDeclRef = parentDeclRef.As<AggTypeDecl>(); + // search for a substitution that might apply to us + for (auto s = subst; s; s = s->outer.Ptr()) { - return DeclRefType::Create(this->session, DeclRef<Decl>(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<DeclRefType>()) + { + newParentDeclRef = (*declRef).declRef.As<AggTypeDecl>(); + goto searchEnd; + } + } + else if (auto typeParam = m.As<GenericTypeParamDecl>()) + { + index++; + } + else if (auto valParam = m.As<GenericValueParamDecl>()) + { + index++; + } + else + { + } + } + } + searchEnd: + if (newParentDeclRef) + { + Decl* targetTypeDecl = nullptr; + if (newParentDeclRef.getDecl()->memberDictionary.TryGetValue(this->GetDeclRef().decl->getName(), targetTypeDecl)) + { + if (auto typeDefDecl = targetTypeDecl->As<TypeDefDecl>()) + return GetType(DeclRef<TypeDefDecl>(typeDefDecl, subst)); + else + return DeclRefType::Create(this->getSession(), DeclRef<Decl>(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 "<GenericConstraintType>"; + } + + bool GenericConstraintDeclRefType::EqualsImpl(Type * type) + { + if (auto other = type->As<GenericConstraintDeclRefType>()) + { + return supType->Equals(other->supType) && subType->Equals(other->subType); + } + return false; + } + + RefPtr<Val> GenericConstraintDeclRefType::SubstituteImpl(Substitutions* subst, int* ioDiff) + { + auto genParamDecl = subType.As<DeclRefType>()->declRef.As<GenericTypeParamDecl>(); + // 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<GenericTypeParamDecl>()) + { + index++; + } + else if (auto valParam = m.As<GenericValueParamDecl>()) + { + index++; + } + else + { + } + } + } + return this; + } + + int GenericConstraintDeclRefType::GetHashCode() + { + return combineHash(subType.GetHashCode(), supType.GetHashCode()); + } + + Type* GenericConstraintDeclRefType::CreateCanonicalType() + { + return this; + } + // ArithmeticExpressionType // VectorExpressionType |
