feat: release Dever 0.1.4 with enforceable project guidance

This commit is contained in:
Antigravity committed 2026-10-09 05:33:57 +00:00
1 parent 201bdee372
commit 89629c2197
86 files changed
+2798 -338

No files matched your search

+71 -13
View File
@@ -17,24 +17,51 @@ pub(crate) fn check(program: &mut Program) {
continue;
}
if !function.public {
let key = (function.owner, function_key(function));
if let Some(previous) = implementations.get(&key).copied() {
let previous: &Function = &program.functions[previous];
warnings.push(related("W003", format!("private function '{}' has the same implementation and contract as '{}'; consider sharing one implementation", function.name, previous.name), function.span, previous.span));
} else {
implementations.insert(key, id);
if let Some(target) = forwarding_target(function, program) {
warnings.push(related("W005", format!("private function '{}' only forwards unchanged inputs to '{}' without adding a contract; review whether this wrapper is needed", function.name, target.name), function.span, target.span));
}
if let Some(duplicate) =
duplicate_implementation(program, id, &mut implementations, "W003")
{
warnings.push(duplicate);
} else if let Some(target) = forwarding_target(function, program) {
warnings.push(related("W005", format!("private function '{}' only forwards unchanged inputs to '{}' without adding a contract; review whether this wrapper is needed", function.name, target.name), function.span, target.span));
}
}
for clause in &function.clauses {
repeated_calls(clause, program, &mut warnings);
repeated_calls(clause, program, "W004", &mut warnings);
}
}
program.warnings.extend(warnings);
}
fn duplicate_implementation(
program: &Program,
id: usize,
implementations: &mut BTreeMap<(usize, String), usize>,
code: &'static str,
) -> Option<Diagnostic> {
let function = &program.functions[id];
let key = (function.owner, function_key(function));
if let Some(previous) = implementations.get(&key).copied() {
let previous = &program.functions[previous];
let action = if code == "C016" {
"reuse one implementation"
} else {
"consider sharing one implementation"
};
Some(related(
code,
format!(
"private function '{}' has the same implementation and contract as '{}'; {action}",
function.name, previous.name
),
function.span,
previous.span,
))
} else {
implementations.insert(key, id);
None
}
}
fn related(code: &'static str, message: String, primary: Span, previous: Span) -> Diagnostic {
let mut warning = Diagnostic::error(code, message, primary);
warning.related.push(Label {
@@ -291,7 +318,12 @@ struct Computation {
result_version: usize,
}
fn repeated_calls(clause: &Clause, program: &Program, warnings: &mut Vec<Diagnostic>) {
fn repeated_calls(
clause: &Clause,
program: &Program,
code: &'static str,
diagnostics: &mut Vec<Diagnostic>,
) {
let mut versions = vec![0; clause.locals.len()];
let mut previous = BTreeMap::<String, Computation>::new();
for statement in &clause.body {
@@ -310,7 +342,17 @@ fn repeated_calls(clause: &Clause, program: &Program, warnings: &mut Vec<Diagnos
if let Some(computation) = previous.get(&key)
&& versions[computation.result_slot] == computation.result_version
{
warnings.push(related("W004", "this pure call repeats unchanged inputs while the earlier result is still available; consider reusing that result".into(), value.span, computation.span));
let action = if code == "C016" {
"reuse that result"
} else {
"consider reusing that result"
};
diagnostics.push(related(
code,
format!("this pure call repeats unchanged inputs while the earlier result is still available; {action}"),
value.span,
computation.span,
));
}
}
// A field write invalidates every projection from the containing value.
@@ -360,6 +402,7 @@ pub(crate) fn application_errors(
reachable: &BTreeSet<usize>,
) -> Vec<Diagnostic> {
let mut errors = Vec::new();
let mut implementations = BTreeMap::new();
for (id, function) in program.functions.iter().enumerate() {
let package = &program.packages[function.owner];
if package.bundled || function.port.is_some() || function.setting.is_some() {
@@ -379,12 +422,27 @@ pub(crate) fn application_errors(
),
function.span,
));
} else if !function.public {
continue;
}
if !function.public {
// Model 查询等有副作用的操作还需比较此结构键未记录的元数据。
if program.effects[id].is_empty()
&& let Some(duplicate) =
duplicate_implementation(program, id, &mut implementations, "C016")
{
errors.push(duplicate);
continue;
}
if let Some(target) = forwarding_target(function, program) {
errors.push(related("C016", format!("private function '{}' only forwards unchanged inputs to '{}' without adding a contract", function.name, target.name), function.span, target.span));
continue;
}
} else if app && trivial_model_wrapper(function) {
errors.push(Diagnostic::error("C016", format!("App function '{}' only forwards a Model CRUD operation; declare rest for plain CRUD", function.name), function.span));
continue;
}
for clause in &function.clauses {
repeated_calls(clause, program, "C016", &mut errors);
}
}
errors.sort_by_key(|error| (error.primary.source, error.primary.start));