diff options
| author | Yong He <yonghe@outlook.com> | 2023-12-06 12:05:07 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-06 12:05:07 -0800 |
| commit | 11111e5733b189127dc2c4934d67693b9bc6e764 (patch) | |
| tree | 0ba84df3e856eb104abec2ecac47242bc70a7b7d /source/slang/slang-check-modifier.cpp | |
| parent | fa6d8717d02912697c09f2d7de802723ac6d6e47 (diff) | |
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 <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-check-modifier.cpp')
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 84 |
1 files changed, 83 insertions, 1 deletions
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<ExtensionDecl>(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<PrivateModifier>(m)) + { + if (as<AggTypeDeclBase>(syntaxNode) || as<NamespaceDeclBase>(syntaxNode)) + { + getSink()->diagnose(m, Diagnostics::invalidUseOfPrivateVisibility, as<Decl>(syntaxNode)); + } + else if (auto decl = as<Decl>(syntaxNode)) + { + // Interface requirements can't be private. + if (isInterfaceRequirement(decl)) + { + getSink()->diagnose(m, Diagnostics::invalidUseOfPrivateVisibility, as<Decl>(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<AccessorDecl>(decl)) + { + return; + } + ShortList<Type*> typesToVerify; + if (auto varDecl = as<VarDeclBase>(decl)) + { + typesToVerify.add(varDecl->type); + } + else if (auto callable = as<CallableDecl>(decl)) + { + typesToVerify.add(callable->returnType); + typesToVerify.add(callable->errorType); + for (auto param : callable->getParameters()) + { + typesToVerify.add(param->type); + } + } + else if (auto propertyDecl = as<PropertyDecl>(decl)) + { + typesToVerify.add(propertyDecl->type); + } + else if (as<AggTypeDeclBase>(decl)) + { + } + else if (auto typeDecl = as<TypeDefDecl>(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<AggTypeDeclBase>(parentDecl)) + break; + } + if (!parentDecl) + return; + auto parentVisibility = getDeclVisibility(parentDecl); + if (thisVisibility > parentVisibility) + { + getSink()->diagnose(decl, Diagnostics::declCannotHaveHigherVisibility, decl, parentDecl); + } + } void SemanticsVisitor::checkModifiers(ModifiableSyntaxNode* syntaxNode) { |
