Tidy final var code somewhat

This commit is contained in:
Tad Hardesty 2019-12-05 21:35:16 -08:00
parent 2b8598bfeb
commit a8b42b57a8
2 changed files with 13 additions and 18 deletions

View file

@ -54,13 +54,13 @@ be enabled:
#define SHOULD_CALL_PARENT(X) set SpacemanDMM_should_call_parent = X
#define UNLINT(X) SpacemanDMM_unlint(X)
#define SHOULD_NOT_OVERRIDE(X) set SpacemanDMM_should_not_override = X
#define FINAL_VAR var/final
#define FINAL_VAR var/final
#else
#define RETURN_TYPE(X)
#define SHOULD_CALL_PARENT(X)
#define UNLINT(X) X
#define SHOULD_NOT_OVERRIDE(X)
#define FINAL_VAR var
#define FINAL_VAR var
#endif
```
@ -92,7 +92,7 @@ Use `set SpacemanDMM_should_not_override = 1` to raise a warning for any child
procs that override this one, regardless of if it calls parent or not.
This functions in a similar way to the `final` keyword in some languages.
### `final` vars
### Final variables
Use the above definition of FINAL_VAR to declare vars as `final`, `var/final/foo` such that overriding their value isn't permitted by types that inherit it.
```

View file

@ -497,28 +497,24 @@ fn error<S: Into<String>>(location: Location, desc: S) -> DMError {
// Variable analyzer
pub fn check_var_defs(objtree: &ObjectTree, context: &Context) {
for (path, nodeindex) in objtree.types.iter() {
guard!(let Some(atype) = objtree.graph.node_weight(*nodeindex)
else { continue });
for (path, _) in objtree.types.iter() {
guard!(let Some(typeref) = objtree.find(path)
else { continue });
for parent_typeref in typeref.iter_parent_types() {
if parent_typeref.is_root() {
for parent in typeref.iter_parent_types() {
if parent.is_root() {
break;
}
let parent = parent_typeref.get();
if &parent.path == path {
continue
continue;
}
for (varname, typevar) in atype.vars.iter() {
for (varname, typevar) in typeref.vars.iter() {
if varname == "vars" {
continue;
}
guard!(let Some(parentvar) = parent.vars.get(varname)
else { continue });
@ -530,16 +526,15 @@ pub fn check_var_defs(objtree: &ObjectTree, context: &Context) {
continue;
}
DMError::new(mydecl.location, format!("{} redeclares {}", path, varname))
.with_note(decl.location, "var declared here")
.register(context);
.with_note(decl.location, "var declared here")
.register(context);
}
if decl.var_type.is_final {
DMError::new(typevar.value.location, format!("{} overrides final var {}", path, varname))
.with_note(decl.location, "var declared here")
.register(context);
.with_note(decl.location, "var declared here")
.register(context);
}
}
}
}