From 59691aeeb013c5bb7cdaa31a6fc572eebd8be610 Mon Sep 17 00:00:00 2001 From: Yong He Date: Tue, 16 Jan 2018 10:52:10 -0800 Subject: Allow extension on interface (#369) This completes item 5 in issue #361. The interesting change is that when checking for interface conformance, we include the requirements (include transitive interfaces) defined in extensions as well. (check.cpp line 1946) All the other changes are for one thing: reoder the semantic checkings to two explicit stages: check header and check body. In check header phase, we check everything except function bodies, register all extensions with their target decls, then check interface conformances for all concrete types. In body checking phase, we look inside the function bodies and check concrete statements/expressions. This change ensures that we take extension into consideration in all places where it should be. --- source/slang/syntax.h | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'source/slang/syntax.h') diff --git a/source/slang/syntax.h b/source/slang/syntax.h index ab26b1f6d..93e421977 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -1098,32 +1098,52 @@ namespace Slang // Declarations // + inline ExtensionDecl* GetCandidateExtensions(DeclRef const& declRef) + { + return declRef.getDecl()->candidateExtensions; + } + inline FilteredMemberRefList getMembers(DeclRef const& declRef) { return FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions); } - template - inline FilteredMemberRefList getMembersOfType(DeclRef const& declRef) + // TODO: change this to return a lazy list instead of constructing actual list + inline List> getMembersWithExt(DeclRef const& declRef) { - return FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions); + List> rs; + for (auto d : FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions)) + rs.Add(d); + if (auto aggDeclRef = declRef.As()) + { + for (auto ext = GetCandidateExtensions(aggDeclRef); ext; ext = ext->nextCandidateExtension) + { + for (auto mbr : getMembers(DeclRef(ext, declRef.substitutions))) + rs.Add(mbr); + } + } + return rs; } - inline ExtensionDecl* GetCandidateExtensions(DeclRef const& declRef) + template + inline FilteredMemberRefList getMembersOfType(DeclRef const& declRef) { - return declRef.getDecl()->candidateExtensions; + return FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions); } template - inline FilteredMemberRefList getMembersOfTypeWithExt(DeclRef const& declRef) + inline List> getMembersOfTypeWithExt(DeclRef const& declRef) { - auto rs = getMembersOfType(declRef); + List> rs; + for (auto d : getMembersOfType(declRef)) + rs.Add(d); if (auto aggDeclRef = declRef.As()) { for (auto ext = GetCandidateExtensions(aggDeclRef); ext; ext = ext->nextCandidateExtension) { auto extMembers = getMembersOfType(DeclRef(ext, declRef.substitutions)); - const_cast>&>(rs.decls).AddRange(extMembers.decls); + for (auto mbr : extMembers) + rs.Add(mbr); } } return rs; -- cgit v1.2.3