pub struct Policy { /* private fields */ }Expand description
A language’s complete scoping policy.
Start from a preset (kraken, php,
python) or new (the lexical default, the
same as Kraken), then adjust with the with_* setters. The policy is plain
data, normally read from the language’s sketch.
§Examples
use resolve_lang::{ClassScope, Hoist, ItemClass, Namespace, Policy};
let p = Policy::new()
.with_hoisting(ItemClass::Fn, Hoist::AfterDecl)
.with_class_scope(ClassScope::BodyOnly)
.with_merge(Namespace::Type, Namespace::Value);
assert_eq!(p.hoisting(ItemClass::Fn), Hoist::AfterDecl);
assert_eq!(p.table(Namespace::Type), Namespace::Value);Implementations§
Source§impl Policy
impl Policy
Sourcepub const fn new() -> Self
pub const fn new() -> Self
The lexical default (equal to kraken): every item
hoisted to its scope; separate value, type, and macro tables with
modules sharing the type table; class members visible in methods;
isolated nested modules; Self:: early, parent::/static::
unsupported; visibility enforced with private items visible to child
modules; globs, aliases, and declared re-exports.
§Examples
use resolve_lang::{ItemClass, Namespace, NsSet, Policy};
let p = Policy::new();
assert_eq!(p.occupies(ItemClass::Record), NsSet::of(&[Namespace::Type, Namespace::Value]));
assert!(p.visibility_enforced());Sourcepub const fn php() -> Self
pub const fn php() -> Self
PHP (and Mox): functions, classes, interfaces, enums, and constants are
visible in their whole namespace wherever declared; class members are
reached only through self::/parent::/static:: (late static
binding for static::); use imports are file-local and have no
globs; global $x may name a global that does not exist yet.
§Examples
use resolve_lang::{Hoist, ItemClass, Policy};
let p = Policy::php();
assert_eq!(p.hoisting(ItemClass::Class), Hoist::Module);
assert!(!p.globs_allowed());
assert!(p.implicit_globals());Sourcepub const fn python() -> Self
pub const fn python() -> Self
Python (and Mercury): one table for every kind of name; a name bound anywhere in a scope belongs to the whole scope; class bodies are not visible to methods; redefinition rebinds; visibility is convention only; imports become module attributes.
§Examples
use resolve_lang::{Namespace, Policy};
let p = Policy::python();
assert_eq!(p.table(Namespace::Type), Namespace::Value);
assert_eq!(p.table(Namespace::Module), Namespace::Value);
assert!(!p.visibility_enforced());Sourcepub const fn with_hoisting(self, class: ItemClass, hoist: Hoist) -> Self
pub const fn with_hoisting(self, class: ItemClass, hoist: Hoist) -> Self
Sets when items of class become visible.
§Examples
use resolve_lang::{Hoist, ItemClass, Policy};
let p = Policy::new().with_hoisting(ItemClass::Global, Hoist::AfterDecl);
assert_eq!(p.hoisting(ItemClass::Global), Hoist::AfterDecl);Sourcepub const fn with_occupies(self, class: ItemClass, set: NsSet) -> Self
pub const fn with_occupies(self, class: ItemClass, set: NsSet) -> Self
Sets the namespaces items of class define their name in. Imports
ignore this (an import binds whatever its target defines).
§Examples
use resolve_lang::{ItemClass, Namespace, NsSet, Policy};
// Rust: a braced struct defines no constructor value.
let p = Policy::new().with_occupies(ItemClass::Record, NsSet::single(Namespace::Type));
assert!(!p.occupies(ItemClass::Record).contains(Namespace::Value));Sourcepub const fn with_merge(self, from: Namespace, into: Namespace) -> Self
pub const fn with_merge(self, from: Namespace, into: Namespace) -> Self
Merges namespace from into the table of into: afterwards both (and
everything already merged with either) share one table, so a name
defined in one conflicts with and is found by the other.
§Examples
use resolve_lang::{Namespace, Policy};
let p = Policy::new().with_merge(Namespace::Value, Namespace::Type);
// Modules already share the type table, so all three are one table now.
assert_eq!(p.table(Namespace::Value), p.table(Namespace::Module));Sourcepub const fn with_shadowing(self, shadowing: Shadowing) -> Self
pub const fn with_shadowing(self, shadowing: Shadowing) -> Self
Sets the shadowing rule for binders.
§Examples
use resolve_lang::{Policy, Shadowing};
assert_eq!(Policy::new().with_shadowing(Shadowing::DenyLocals).shadowing(), Shadowing::DenyLocals);Sourcepub const fn with_redefinition(self, redefinition: Redefinition) -> Self
pub const fn with_redefinition(self, redefinition: Redefinition) -> Self
Sets what duplicate definitions mean.
§Examples
use resolve_lang::{Policy, Redefinition};
let p = Policy::new().with_redefinition(Redefinition::LastWins);
assert_eq!(p.redefinition(), Redefinition::LastWins);Sourcepub const fn with_class_scope(self, class_scope: ClassScope) -> Self
pub const fn with_class_scope(self, class_scope: ClassScope) -> Self
Sets what code inside a class sees of its members.
§Examples
use resolve_lang::{ClassScope, Policy};
let p = Policy::new().with_class_scope(ClassScope::Qualified);
assert_eq!(p.class_scope(), ClassScope::Qualified);Sourcepub const fn with_module_scope(self, module_scope: ModuleScope) -> Self
pub const fn with_module_scope(self, module_scope: ModuleScope) -> Self
Sets whether nested modules see outer names.
§Examples
use resolve_lang::{ModuleScope, Policy};
let p = Policy::new().with_module_scope(ModuleScope::Lexical);
assert_eq!(p.module_scope(), ModuleScope::Lexical);Sourcepub const fn with_roots(
self,
self_root: RootBinding,
parent_root: RootBinding,
static_root: RootBinding,
) -> Self
pub const fn with_roots( self, self_root: RootBinding, parent_root: RootBinding, static_root: RootBinding, ) -> Self
Sets how self::, parent::, and static:: bind.
§Examples
use resolve_lang::{Policy, RootBinding};
let p = Policy::new().with_roots(RootBinding::Early, RootBinding::Early, RootBinding::Late);
assert_eq!(p.parent_root(), RootBinding::Early);Sourcepub const fn with_visibility(
self,
enforce: bool,
private_to_descendants: bool,
) -> Self
pub const fn with_visibility( self, enforce: bool, private_to_descendants: bool, ) -> Self
Sets whether visibility is enforced, and whether private items of a module are visible to its descendant modules.
§Examples
use resolve_lang::Policy;
let p = Policy::new().with_visibility(true, false);
assert!(p.visibility_enforced());
assert!(!p.private_to_descendants());Sourcepub const fn with_imports(
self,
globs: bool,
aliases: bool,
reexport: Reexport,
) -> Self
pub const fn with_imports( self, globs: bool, aliases: bool, reexport: Reexport, ) -> Self
Sets which import forms the language has, and how imports re-export.
§Examples
use resolve_lang::{Policy, Reexport};
let p = Policy::new().with_imports(false, true, Reexport::Never);
assert!(!p.globs_allowed());
assert!(p.aliases_allowed());Sourcepub const fn with_implicit_globals(self, implicit: bool) -> Self
pub const fn with_implicit_globals(self, implicit: bool) -> Self
Sets whether a global declaration naming no known global binds a host
global (Res::Extern) instead of being reported.
§Examples
use resolve_lang::Policy;
assert!(Policy::new().with_implicit_globals(true).implicit_globals());Sourcepub const fn hoisting(&self, class: ItemClass) -> Hoist
pub const fn hoisting(&self, class: ItemClass) -> Hoist
When items of class become visible.
§Examples
use resolve_lang::{Hoist, ItemClass, Policy};
assert_eq!(Policy::new().hoisting(ItemClass::Fn), Hoist::Scope);Sourcepub const fn occupies(&self, class: ItemClass) -> NsSet
pub const fn occupies(&self, class: ItemClass) -> NsSet
The namespaces items of class define their name in (before merging).
§Examples
use resolve_lang::{ItemClass, Namespace, Policy};
assert!(Policy::new().occupies(ItemClass::Fn).contains(Namespace::Value));Sourcepub const fn table(&self, ns: Namespace) -> Namespace
pub const fn table(&self, ns: Namespace) -> Namespace
The table namespace ns is stored in after merging.
§Examples
use resolve_lang::{Namespace, Policy};
assert_eq!(Policy::new().table(Namespace::Module), Namespace::Type);
assert_eq!(Policy::new().table(Namespace::Value), Namespace::Value);Sourcepub const fn shadowing(&self) -> Shadowing
pub const fn shadowing(&self) -> Shadowing
The shadowing rule.
§Examples
use resolve_lang::{Policy, Shadowing};
assert_eq!(Policy::new().shadowing(), Shadowing::Allow);Sourcepub const fn redefinition(&self) -> Redefinition
pub const fn redefinition(&self) -> Redefinition
What duplicate definitions mean.
§Examples
use resolve_lang::{Policy, Redefinition};
assert_eq!(Policy::php().redefinition(), Redefinition::Error);Sourcepub const fn class_scope(&self) -> ClassScope
pub const fn class_scope(&self) -> ClassScope
What code inside a class sees of its members.
§Examples
use resolve_lang::{ClassScope, Policy};
assert_eq!(Policy::new().class_scope(), ClassScope::Lexical);Sourcepub const fn module_scope(&self) -> ModuleScope
pub const fn module_scope(&self) -> ModuleScope
Whether nested modules see outer names.
§Examples
use resolve_lang::{ModuleScope, Policy};
assert_eq!(Policy::php().module_scope(), ModuleScope::Lexical);Sourcepub const fn self_root(&self) -> RootBinding
pub const fn self_root(&self) -> RootBinding
How self:: binds.
§Examples
use resolve_lang::{Policy, RootBinding};
assert_eq!(Policy::python().self_root(), RootBinding::Unsupported);Sourcepub const fn parent_root(&self) -> RootBinding
pub const fn parent_root(&self) -> RootBinding
How parent:: binds.
§Examples
use resolve_lang::{Policy, RootBinding};
assert_eq!(Policy::kraken().parent_root(), RootBinding::Unsupported);Sourcepub const fn static_root(&self) -> RootBinding
pub const fn static_root(&self) -> RootBinding
How static:: binds.
§Examples
use resolve_lang::{Policy, RootBinding};
assert_eq!(Policy::php().static_root(), RootBinding::Late);Sourcepub const fn visibility_enforced(&self) -> bool
pub const fn visibility_enforced(&self) -> bool
Whether visibility (Vis) is enforced.
§Examples
use resolve_lang::Policy;
assert!(Policy::php().visibility_enforced());Sourcepub const fn private_to_descendants(&self) -> bool
pub const fn private_to_descendants(&self) -> bool
Whether private items of a module are visible in its descendant modules (Rust’s rule).
§Examples
use resolve_lang::Policy;
assert!(Policy::new().private_to_descendants());Sourcepub const fn globs_allowed(&self) -> bool
pub const fn globs_allowed(&self) -> bool
Whether glob imports are allowed.
§Examples
use resolve_lang::Policy;
assert!(Policy::python().globs_allowed());Sourcepub const fn aliases_allowed(&self) -> bool
pub const fn aliases_allowed(&self) -> bool
Whether aliased imports (use x as y) are allowed.
§Examples
use resolve_lang::Policy;
assert!(Policy::php().aliases_allowed());Sourcepub const fn reexport(&self) -> Reexport
pub const fn reexport(&self) -> Reexport
How imports re-export.
§Examples
use resolve_lang::{Policy, Reexport};
assert_eq!(Policy::php().reexport(), Reexport::Never);Sourcepub const fn implicit_globals(&self) -> bool
pub const fn implicit_globals(&self) -> bool
Whether an unknown global name binds a host global.
§Examples
use resolve_lang::Policy;
assert!(!Policy::kraken().implicit_globals());