Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow directive settings to use configs #218

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CONFIGURING.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,26 @@ The `[dmdoc]` section has the following options:

* `use_typepath_names` - Set to `true` to have dmdoc use the true typepath name instead of the value of the `name` var for types

### Directives

The `[procdirective]` section can be used to change the limitations of proc directives, the following names can be used which each corrospond to a `set SpacemanDMM_` proc directive:

* `must_call_parent`
* `must_not_override`
* `private`
* `protected`
* `must_not_sleep`
* `must_be_pure`
* `can_be_redefined`

In each section you can set the following as `true` or `false`:

* `can_be_disabled` - Allows the directive to be set false in a child proc
* `set_at_definition` - Enforces the requirement the directive be set in the proc definition
* `can_be_global` - Allows the directive to be set in global procs

See the example below on how to use these.

## Example

```toml
Expand All @@ -113,4 +133,8 @@ dreamchecker = true
[diagnostics]
duplicate_include = "error"
macro_redefined = "off"

[procdirective]
[procdirective.must_call_parent]
can_be_disabled = false
```
48 changes: 39 additions & 9 deletions src/dreamchecker/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use dm::{Context, DMError, Location, Severity};
use dm::objtree::{ObjectTree, TypeRef, ProcRef, Code};
use dm::constants::{Constant, ConstFn};
use dm::ast::*;
use dm::config::*;

use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};

Expand Down Expand Up @@ -518,6 +519,35 @@ impl DMErrorExt for DMError {
}
}

trait DirectiveFromConfig {
fn to_proc_directive(self, directive_string: &'static str) -> ProcDirective;
}

macro_rules! to_proc_directive {
($name: ident) => {
impl DirectiveFromConfig for $name {
fn to_proc_directive(self, directive_string: &'static str) -> ProcDirective {
ProcDirective {
directive: Default::default(),
directive_string,
can_be_disabled: self.can_be_disabled,
set_at_definition: self.set_at_definition,
can_be_global: self.can_be_global,
}
}
}
}
}

to_proc_directive! { MustCallParent }
to_proc_directive! { MustNotOverride }
to_proc_directive! { PrivateDirective }
to_proc_directive! { ProtectedDirective }
to_proc_directive! { MustNotSleep }
to_proc_directive! { SleepExempt }
to_proc_directive! { MustBePure }
to_proc_directive! { CanBeRedefined }

#[derive(Default)]
pub struct ViolatingProcs<'o> {
violators: HashMap<ProcRef<'o>, Vec<(String, Location)>>,
Expand Down Expand Up @@ -584,14 +614,14 @@ impl<'o> AnalyzeObjectTree<'o> {
context,
objtree,
return_type,
must_call_parent: ProcDirective::new("SpacemanDMM_should_call_parent", true, false, false),
must_not_override: ProcDirective::new("SpacemanDMM_should_not_override", false, false, false),
private: ProcDirective::new("SpacemanDMM_private_proc", false, true, false),
protected: ProcDirective::new("SpacemanDMM_protected_proc", false, true, false),
must_not_sleep: ProcDirective::new("SpacemanDMM_should_not_sleep", false, true, true),
sleep_exempt: ProcDirective::new("SpacemanDMM_allowed_to_sleep", false, true, true),
must_be_pure: ProcDirective::new("SpacemanDMM_should_be_pure", false, true, true),
can_be_redefined: ProcDirective::new("SpacemanDMM_can_be_redefined", false, false, false),
must_call_parent: context.config().procdirective.must_call_parent.to_proc_directive("SpacemanDMM_should_call_parent"),
must_not_override: context.config().procdirective.must_not_override.to_proc_directive("SpacemanDMM_should_not_override"),
private: context.config().procdirective.private.to_proc_directive("SpacemanDMM_private_proc"),
protected: context.config().procdirective.protected.to_proc_directive("SpacemanDMM_protected_proc"),
must_not_sleep: context.config().procdirective.must_not_sleep.to_proc_directive("SpacemanDMM_should_not_sleep"),
sleep_exempt: context.config().procdirective.sleep_exempt.to_proc_directive("SpacemanDMM_allowed_to_sleep"),
must_be_pure: context.config().procdirective.must_be_pure.to_proc_directive("SpacemanDMM_should_be_pure"),
can_be_redefined: context.config().procdirective.can_be_redefined.to_proc_directive("SpacemanDMM_can_be_redefined"),
used_kwargs: Default::default(),
call_tree: Default::default(),
sleeping_procs: Default::default(),
Expand All @@ -613,8 +643,8 @@ impl<'o> AnalyzeObjectTree<'o> {
#[inline]
fn add_directive_or_error(&mut self, proc: ProcRef<'o>, directive: &str, expr: &Expression, location: Location) {
let procdirective = match directive {
"SpacemanDMM_should_not_override" => &mut self.must_not_override,
"SpacemanDMM_should_call_parent" => &mut self.must_call_parent,
"SpacemanDMM_should_not_override" => &mut self.must_not_override,
"SpacemanDMM_private_proc" => &mut self.private,
"SpacemanDMM_protected_proc" => &mut self.protected,
"SpacemanDMM_should_not_sleep" => &mut self.must_not_sleep,
Expand Down
4 changes: 2 additions & 2 deletions src/dreamchecker/test_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub fn check_errors_match<S: Into<Cow<'static, str>>>(buffer: S, errorlist: &[(u
));
}
}
if iter.next().is_some() {
panic!("found more errors than was expected");
if let Some(nexterror) = iter.next() {
panic!(format!("found more errors than was expected, next was: {}:{}:{}", nexterror.location().line, nexterror.location().column, nexterror.description()));
}
}
45 changes: 45 additions & 0 deletions src/dreammaker/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub struct Config {
// tool-specific configuration
pub langserver: Langserver,
pub dmdoc: DMDoc,
pub procdirective: ProcDirectiveSection,
}

/// General error display options
Expand Down Expand Up @@ -186,3 +187,47 @@ impl From<toml::de::Error> for Error {
Error::Toml(err)
}
}

#[derive(Debug, Deserialize, Default, Clone)]
#[serde(default)]
pub struct ProcDirectiveSection {
pub must_call_parent: MustCallParent,
pub must_not_override: MustNotOverride,
pub private: PrivateDirective,
pub protected: ProtectedDirective,
pub must_not_sleep: MustNotSleep,
pub sleep_exempt: SleepExempt,
pub must_be_pure: MustBePure,
pub can_be_redefined: CanBeRedefined,
}

macro_rules! procdirective {
($name: ident $cbd: tt $sad: tt $cbg: tt) => {
#[derive(Debug, Deserialize, Clone, Copy)]
#[serde(default)]
pub struct $name {
pub can_be_disabled: bool,
pub set_at_definition: bool,
pub can_be_global: bool,
}

impl Default for $name {
fn default() -> Self {
$name {
can_be_disabled: $cbd,
set_at_definition: $sad,
can_be_global: $cbg,
}
}
}
};
}

procdirective! {MustCallParent true false false}
procdirective! {MustNotOverride false false false}
procdirective! {PrivateDirective false true false}
procdirective! {ProtectedDirective false true false}
procdirective! {MustNotSleep false true true}
procdirective! {SleepExempt false true true}
procdirective! {MustBePure false true true}
procdirective! {CanBeRedefined false false false}