From 11111e5733b189127dc2c4934d67693b9bc6e764 Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 6 Dec 2023 12:05:07 -0800 Subject: Support visibility control and default to `internal`. (#3380) * Support visibility control and default to `internal`. * Fix wip. * Fixes. * Fix. * Fix test. * Add legacy language detection and compatibility for existing code. * Add doc. --------- Co-authored-by: Yong He --- source/slang/slang-check-modifier.cpp | 84 ++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'source/slang/slang-check-modifier.cpp') diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index 569804ff4..339ecba4c 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -950,7 +950,7 @@ namespace Slang { if (auto parentExtension = as(varDecl->parentDecl)) { - auto originalMemberLookup = lookUpMember(m_astBuilder, this, varDecl->getName(), parentExtension->targetType); + auto originalMemberLookup = lookUpMember(m_astBuilder, this, varDecl->getName(), parentExtension->targetType, parentExtension->ownedScope); LookupResult filteredResult; for (auto item : originalMemberLookup.items) { @@ -1042,6 +1042,23 @@ namespace Slang } } + if (as(m)) + { + if (as(syntaxNode) || as(syntaxNode)) + { + getSink()->diagnose(m, Diagnostics::invalidUseOfPrivateVisibility, as(syntaxNode)); + } + else if (auto decl = as(syntaxNode)) + { + // Interface requirements can't be private. + if (isInterfaceRequirement(decl)) + { + getSink()->diagnose(m, Diagnostics::invalidUseOfPrivateVisibility, as(syntaxNode)); + } + } + } + + // Default behavior is to leave things as they are, // and assume that modifiers are mostly already checked. // @@ -1054,6 +1071,71 @@ namespace Slang return m; } + void SemanticsVisitor::checkVisibility(Decl* decl) + { + if (as(decl)) + { + return; + } + ShortList typesToVerify; + if (auto varDecl = as(decl)) + { + typesToVerify.add(varDecl->type); + } + else if (auto callable = as(decl)) + { + typesToVerify.add(callable->returnType); + typesToVerify.add(callable->errorType); + for (auto param : callable->getParameters()) + { + typesToVerify.add(param->type); + } + } + else if (auto propertyDecl = as(decl)) + { + typesToVerify.add(propertyDecl->type); + } + else if (as(decl)) + { + } + else if (auto typeDecl = as(decl)) + { + typesToVerify.add(typeDecl->type); + } + else + { + return; + } + auto thisVisibility = getDeclVisibility(decl); + + // First, we check that the decl's type does not have lower visibility. + for (auto type : typesToVerify) + { + if (!type) + continue; + DeclVisibility typeVisibility = getTypeVisibility(type); + if (typeVisibility < thisVisibility) + { + getSink()->diagnose(decl, Diagnostics::useOfLessVisibleType, decl, type); + break; + } + } + + // Next, we check that the decl does not have higher visiblity than its parent. + Decl* parentDecl = decl; + for (; parentDecl; parentDecl = parentDecl->parentDecl) + { + if (as(parentDecl)) + break; + } + if (!parentDecl) + return; + auto parentVisibility = getDeclVisibility(parentDecl); + if (thisVisibility > parentVisibility) + { + getSink()->diagnose(decl, Diagnostics::declCannotHaveHigherVisibility, decl, parentDecl); + } + } void SemanticsVisitor::checkModifiers(ModifiableSyntaxNode* syntaxNode) { -- cgit v1.2.3