compiler: Check symbol visibility from resolved module identities
87ca5d9f4f5fdd3179323943f9ad6e4e8fcaedae1353c3a1c008ad34a673c013
1 parent
05c6985b
lib/std/lang/resolver.rad
+6 -9
| 3385 | 3385 | } |
|
| 3386 | 3386 | } |
|
| 3387 | 3387 | return nil; |
|
| 3388 | 3388 | } |
|
| 3389 | 3389 | ||
| 3390 | - | /// Check if a symbol is accessible from the given scope. |
|
| 3390 | + | /// Check symbol visibility from declaration attributes and module identities. |
|
| 3391 | 3391 | /// A symbol is accessible if: |
|
| 3392 | 3392 | /// * It has the `export` attribute, OR |
|
| 3393 | 3393 | /// * It's being accessed from within the module where it was defined. |
|
| 3394 | - | unsafe fn isSymbolVisible(sym: *unsafe Symbol, symScope: *unsafe Scope, fromScope: *unsafe Scope) -> bool { |
|
| 3394 | + | fn isSymbolVisible(attrs: u32, symModuleId: ?u16, currentModuleId: ?u16) -> bool { |
|
| 3395 | 3395 | // Public symbols are visible from anywhere. |
|
| 3396 | - | if ast::hasAttribute(sym.attrs, ast::Attribute::Export) { |
|
| 3396 | + | if ast::hasAttribute(attrs, ast::Attribute::Export) { |
|
| 3397 | 3397 | return true; |
|
| 3398 | 3398 | } |
|
| 3399 | 3399 | // In test mode, @test symbols are visible from anywhere |
|
| 3400 | 3400 | // so the test runner can reference them. |
|
| 3401 | - | if ast::hasAttribute(sym.attrs, ast::Attribute::Test) { |
|
| 3401 | + | if ast::hasAttribute(attrs, ast::Attribute::Test) { |
|
| 3402 | 3402 | return true; |
|
| 3403 | 3403 | } |
|
| 3404 | 3404 | // Private symbols are only visible from the same module. |
|
| 3405 | - | let symModuleId = findModuleForScope(symScope); |
|
| 3406 | - | let currentModuleId = findModuleForScope(fromScope); |
|
| 3407 | - | ||
| 3408 | 3405 | return symModuleId == currentModuleId; |
|
| 3409 | 3406 | } |
|
| 3410 | 3407 | ||
| 3411 | 3408 | /// Resolve an access node (eg. `lang::resolver::MAX_ERRORS`) to a symbol, |
|
| 3412 | 3409 | /// starting from the given scope. |
| 3455 | 3452 | let root = path[0]; |
|
| 3456 | 3453 | let sym = findInScopeRecursive(scope, root, isAnySymbol) |
|
| 3457 | 3454 | else throw emitError(self, node, ErrorKind::UnresolvedSymbol(root)); |
|
| 3458 | 3455 | ||
| 3459 | 3456 | // Check visibility for symbol. |
|
| 3460 | - | if not isSymbolVisible(sym, scope, self.scope) { |
|
| 3457 | + | if not isSymbolVisible(sym.attrs, findModuleForScope(scope), findModuleForScope(self.scope)) { |
|
| 3461 | 3458 | throw emitError(self, node, ErrorKind::UnresolvedSymbol(root)); |
|
| 3462 | 3459 | } |
|
| 3463 | 3460 | // End condition. |
|
| 3464 | 3461 | if path.len == 1 { |
|
| 3465 | 3462 | return sym; |
| 3539 | 3536 | } |
|
| 3540 | 3537 | let childName = path[0]; |
|
| 3541 | 3538 | let childSym = findSymbolInScope(scope, childName) |
|
| 3542 | 3539 | else throw emitError(self, node, ErrorKind::UnresolvedSymbol(childName)); |
|
| 3543 | 3540 | ||
| 3544 | - | if not isSymbolVisible(childSym, scope, self.scope) { |
|
| 3541 | + | if not isSymbolVisible(childSym.attrs, findModuleForScope(scope), findModuleForScope(self.scope)) { |
|
| 3545 | 3542 | throw emitError(self, node, ErrorKind::UnresolvedSymbol(childName)); |
|
| 3546 | 3543 | } |
|
| 3547 | 3544 | return try resolveModulePathRecursive( |
|
| 3548 | 3545 | self, |
|
| 3549 | 3546 | node, |