pub struct ScopeContext {Show 13 fields
prev: Option<Box<ScopeHistory>>,
this: ScopeEntry,
root: ScopeEntry,
names: HashMap<String, usize>,
list_names: HashMap<String, usize>,
named: Vec<ScopeEntry>,
is_input: Vec<Option<Token>>,
is_builder: bool,
is_unrooted: bool,
strict_scopes: bool,
no_warn: bool,
source: Token,
traceback: Vec<ActionOrEvent>,
}
Expand description
The ScopeContext
represents what we know about the scopes leading to the Block
currently being validated.
Fields§
§prev: Option<Box<ScopeHistory>>
prev
is a chain of all the known previous scopes.
this: ScopeEntry
Normally, this
starts as a ScopeEntry::Rootref
, but there are cases where the
relationship to root is not known.
root: ScopeEntry
root is always a ScopeEntry::Scope
names: HashMap<String, usize>
Names of named scopes; the values are indices into the named
vector.
Names should only be added, never removed, and indices should stay consistent.
This is because the indices are also used by ScopeEntry::Named
values throughout this ScopeContext
.
names
and list_names
occupy separate namespaces, but index into the same named
array.
list_names: HashMap<String, usize>
§named: Vec<ScopeEntry>
Named scope values are ScopeEntry::Scope
or ScopeEntry::Named
or ScopeEntry::Rootref
.
Invariant: there are no cycles in the array via ScopeEntry::Named
entries.
is_input: Vec<Option<Token>>
Same indices as named
, is a token iff the named scope is expected to be set on entry to the current scope context.
Invariant: named
and is_input
are the same length.
is_builder: bool
Is this scope level a level in progress? is_builder
is used when evaluating scope chains
like root.liege.primary_title
. It affects the handling of prev
, because the builder
scope is not a real scope level yet.
is_unrooted: bool
Was this ScopeContext
created as an unrooted context? Unrooted means we do not know
whether this
and root
are the same at the start. Unrooted scopes start with an extra
prev
level, so they need to be cleaned up differently.
strict_scopes: bool
Is this scope context one where all the named scopes are (or should be) known in advance?
If strict_scopes
is false, then the ScopeContext
will assume any name might be a valid
scope name that we just don’t know about yet.
no_warn: bool
A special flag for scope contexts that are known to be wrong. It’s used for the
scope_override
config file feature. If no_warn
is set then this ScopeContext
will not
emit any reports.
source: Token
A token indicating where this context was created and its named scopes were initialized.
traceback: Vec<ActionOrEvent>
A history of the actions and events that were triggered on the way from source
to the
current context.
Implementations§
Source§impl ScopeContext
impl ScopeContext
Sourcepub fn new<T: Into<Token>>(root: Scopes, token: T) -> Self
pub fn new<T: Into<Token>>(root: Scopes, token: T) -> Self
Make a new ScopeContext
, with this
and root
the same, and root
of the given scope
types. token
is used when reporting errors about the use of root
.
Sourcepub fn new_unrooted<T: Into<Token>>(this: Scopes, token: T) -> Self
pub fn new_unrooted<T: Into<Token>>(this: Scopes, token: T) -> Self
Make a new ScopeContext
, with this
and root
unconnected, and this
of the given scope
types. token
is used when reporting errors about the use of this
, root
, or prev
.
This function is useful for the scope contexts created for scripted effects, scripted
triggers, and script values. In those, it’s not known what the caller’s root
is.
Sourcepub fn set_strict_scopes(&mut self, strict: bool)
pub fn set_strict_scopes(&mut self, strict: bool)
Declare whether all the named scopes in this scope context are known. Default is true.
Set this to false in for example events, which start with the scopes defined by their triggering context.
Having strict scopes set to true makes the ScopeContext
emit errors when encountering
unknown scope names.
Sourcepub fn is_strict(&self) -> bool
pub fn is_strict(&self) -> bool
Return whether this ScopeContext
has strict scopes set to true.
See Self::set_strict_scopes
.
Sourcepub fn set_no_warn(&mut self, no_warn: bool)
pub fn set_no_warn(&mut self, no_warn: bool)
Set whether this ScopeContext
should emit reports at all. no_warn
defaults to false.
It’s used for scope contexts that are known to be wrong, related to the scope_override
config file feature.
Sourcepub fn set_source<T: Into<Token>>(&mut self, source: T)
pub fn set_source<T: Into<Token>>(&mut self, source: T)
Change this context’s source
value to something more appropriate than the default (which
is the token passed to new
).
Sourcefn root_for(&self, trace: ActionOrEvent) -> Option<Self>
fn root_for(&self, trace: ActionOrEvent) -> Option<Self>
Helper function for root_for_event
and root_for_action
.
Sourcepub fn root_for_event<T: Into<Token>>(&self, event_id: T) -> Option<Self>
pub fn root_for_event<T: Into<Token>>(&self, event_id: T) -> Option<Self>
Create a ScopeContext
to use for a triggered event, if validating the event with this
scope context is useful.
Sourcepub fn root_for_action<T: Into<Token>>(&self, action: T) -> Option<Self>
pub fn root_for_action<T: Into<Token>>(&self, action: T) -> Option<Self>
Create a ScopeContext
to use for a triggered action, if validating the action with this
scope context is useful.
Sourcepub fn change_root<T: Into<Token>>(&mut self, root: Scopes, token: T)
pub fn change_root<T: Into<Token>>(&mut self, root: Scopes, token: T)
Change the scope type and related token of root
for this ScopeContext
.
This function is mainly used in the setup of a ScopeContext
before using it.
It’s a bit of a hack and shouldn’t be used.
TODO: get rid of this.
Sourcepub fn define_name<T: Into<Token>>(
&mut self,
name: &str,
scopes: Scopes,
token: T,
)
pub fn define_name<T: Into<Token>>( &mut self, name: &str, scopes: Scopes, token: T, )
Declare that this ScopeContext
contains a named scope of the given name and type,
supplied by the game engine.
The associated token
will be used in error reports related to this named scope.
Sourcepub fn define_name_token<T: Into<Token>>(
&mut self,
name: &str,
scopes: Scopes,
token: T,
)
pub fn define_name_token<T: Into<Token>>( &mut self, name: &str, scopes: Scopes, token: T, )
Declare that this ScopeContext
contains a named scope of the given name and type,
not supplied by the game engine but deduced from script.
The associated token
will be used in error reports related to this named scope.
The token should reflect why we think the named scope has the scope type it has.
Sourcepub fn is_name_defined(&mut self, name: &str) -> Option<Scopes>
pub fn is_name_defined(&mut self, name: &str) -> Option<Scopes>
Look up a named scope and return its scope types if it’s known.
Callers should probably check Self::is_strict()
as well.
Sourcepub fn exists_scope<T: Into<Token>>(&mut self, name: &str, token: T)
pub fn exists_scope<T: Into<Token>>(&mut self, name: &str, token: T)
This is called when the script does exists = scope:name
.
It records name
as “known”, but with no scope type information, and records that the
caller is expected to provide this scope.
The ScopeContext
is not smart enough to track optionally existing scopes. It assumes
that if you do exists
on a scope, then from that point on it exists. Improving this would
be a big project.
Sourcepub fn define_list<T: Into<Token>>(
&mut self,
name: &str,
scopes: Scopes,
token: T,
)
pub fn define_list<T: Into<Token>>( &mut self, name: &str, scopes: Scopes, token: T, )
Declare that this ScopeContext
contains a list of the given name and type,
supplied by the game engine.
The associated token
will be used in error reports related to this list.
Lists and named scopes exist in different namespaces, but under the hood
ScopeContext
treats them the same. This means that lists are expected to
contain items of a single scope type, which sometimes leads to false positives.
Sourcepub fn save_current_scope(&mut self, name: &str)
pub fn save_current_scope(&mut self, name: &str)
This is like Self::define_name()
, but scope:name
is declared equal to the current this
.
Sourcepub fn define_or_expect_list(&mut self, name: &Token)
pub fn define_or_expect_list(&mut self, name: &Token)
If list name
exists, narrow its scope type down to this
, otherwise define it
as having the same scope type as this
.
Sourcepub fn expect_list(&mut self, name: &Token)
pub fn expect_list(&mut self, name: &Token)
Expect list name
to be known and (with strict scopes) warn if it isn’t.
Narrow the type of this
down to the list’s type.
Sourcepub fn open_scope(&mut self, scopes: Scopes, token: Token)
pub fn open_scope(&mut self, scopes: Scopes, token: Token)
Open a new scope level of scopes
scope type. Record token
as the reason for this type.
This is mostly used by iterators.
prev
will refer to the previous scope level.
Sourcepub fn open_builder(&mut self)
pub fn open_builder(&mut self)
Open a new, temporary scope level. Initially it will have its this
the same as the
previous level’s this
.
The purpose is to handle scope chains like root.liege.primary_title
. Call the replace_
functions to update the value of this
, and at the end either confirm the new scope level
with Self::finalize_builder()
or discard it with Self::close()
.
Sourcepub fn finalize_builder(&mut self)
pub fn finalize_builder(&mut self)
Declare that the temporary scope level opened with Self::open_builder()
is a real scope level.
Sourcepub fn replace(&mut self, scopes: Scopes, token: Token)
pub fn replace(&mut self, scopes: Scopes, token: Token)
Replace the this
in a temporary scope level with the given scopes
type and record
token
as the reason for this type.
This is used when a scope chain starts with something absolute like faith:catholic
.
Sourcepub fn replace_root(&mut self)
pub fn replace_root(&mut self)
Replace the this
in a temporary scope level with a reference to root
.
Sourcepub fn replace_prev(&mut self)
pub fn replace_prev(&mut self)
Replace the this
in a temporary scope level with a reference to the previous scope level.
Sourcepub fn replace_this(&mut self)
pub fn replace_this(&mut self)
Replace the this
in a temporary scope level with a reference to the real level below it.
This is usually a no-op, used when scope chains start with this
. If a scope chain has
this
in the middle of the chain (which itself will trigger a warning) then it resets the
temporary scope level to the way it started.
Sourcepub fn replace_named_scope(&mut self, name: &str, token: Token)
pub fn replace_named_scope(&mut self, name: &str, token: Token)
Replace the this
in a temporary scope level with a reference to the named scope name
.
This is used when a scope chain starts with scope:name
. The token
is expected to be the
scope:name
token.
Sourcepub fn replace_list_entry(&mut self, name: &str, token: &Token)
pub fn replace_list_entry(&mut self, name: &str, token: &Token)
Replace the this
in a temporary scope level with a reference to the scope type of the
list name
.
This is used in list iterators. The token
is expected to be the token for the name of the
list.
Sourcepub fn can_be(&self, scopes: Scopes) -> bool
pub fn can_be(&self, scopes: Scopes) -> bool
Return true iff it’s possible that this
is the same type as one of the scopes
types.
Sourcepub fn must_be(&self, scopes: Scopes) -> bool
pub fn must_be(&self, scopes: Scopes) -> bool
Return true iff this
is known to be one of the types of scopes
Sourcepub fn scopes_reason(&self) -> (Scopes, &Reason)
pub fn scopes_reason(&self) -> (Scopes, &Reason)
Return the possible scope types for the current scope layer, together with the reason why we think that.
Sourcepub fn log_traceback(&self, builder: ReportBuilderStage3) -> ReportBuilderStage3
pub fn log_traceback(&self, builder: ReportBuilderStage3) -> ReportBuilderStage3
Add messages to a report that describe where this ScopeContext
came from.
Sourcepub fn expect(&mut self, scopes: Scopes, reason: &Reason)
pub fn expect(&mut self, scopes: Scopes, reason: &Reason)
Record that the this
in the current scope level is one of the scope types scopes
, and
if this is new information, record token
as the reason we think that.
Emit an error if what we already know about this
is incompatible with scopes
.
Sourcefn expect3(&mut self, scopes: Scopes, reason: &Reason, key: &Token)
fn expect3(&mut self, scopes: Scopes, reason: &Reason, key: &Token)
Like Self::expect()
, but the error emitted will be located at token key
.
This function is used when the expectation of scope compatibility comes from key
, for
example when matching up a caller’s scope context with a scripted effect’s scope context.
Sourcepub fn expect_compatibility(&mut self, other: &ScopeContext, key: &Token)
pub fn expect_compatibility(&mut self, other: &ScopeContext, key: &Token)
Compare this scope context to other
, with key
as the token that identifies other
.
This function examines the root
, this
, prev
, and named scopes of the two scope
contexts and warns about any contradictions it finds.
It expects self
to be the caller and other
to be the callee.
Trait Implementations§
Source§impl Clone for ScopeContext
impl Clone for ScopeContext
Source§fn clone(&self) -> ScopeContext
fn clone(&self) -> ScopeContext
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl Debug for ScopeContext
impl Debug for ScopeContext
Source§impl Drop for ScopeContext
impl Drop for ScopeContext
Source§impl<'a> From<&'a mut ScopeContext> for FieldScopeContext<'a>
impl<'a> From<&'a mut ScopeContext> for FieldScopeContext<'a>
Source§fn from(sc: &'a mut ScopeContext) -> Self
fn from(sc: &'a mut ScopeContext) -> Self
Auto Trait Implementations§
impl Freeze for ScopeContext
impl RefUnwindSafe for ScopeContext
impl Send for ScopeContext
impl Sync for ScopeContext
impl Unpin for ScopeContext
impl UnwindSafe for ScopeContext
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> Downcast for Twhere
T: AsAny + ?Sized,
impl<T> Downcast for Twhere
T: AsAny + ?Sized,
§fn downcast_ref<T>(&self) -> Option<&T>where
T: AsAny,
fn downcast_ref<T>(&self) -> Option<&T>where
T: AsAny,
Any
.§fn downcast_mut<T>(&mut self) -> Option<&mut T>where
T: AsAny,
fn downcast_mut<T>(&mut self) -> Option<&mut T>where
T: AsAny,
Any
.§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.