mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-09 19:45:13 +02:00
[pitboss] sweep after phase 14: 5 deferred items resolved
This commit is contained in:
parent
bd1bd0ce84
commit
919bc4e7e2
4 changed files with 64 additions and 48 deletions
|
|
@ -524,13 +524,18 @@ fn generate_harness_java(spec: &HarnessSpec, shape: JavaShape, entry_class: &str
|
|||
""
|
||||
};
|
||||
|
||||
// Reflection imports are only used by shapes whose helpers / catch
|
||||
// clause reference them; emitting them for `StaticMethod` /
|
||||
// `StaticMain` produces unused-import warnings under javac -Xlint.
|
||||
let imports = if shape_uses_reflection(shape) {
|
||||
"import java.lang.reflect.Method;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\n\n"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
format!(
|
||||
r#"// Nyx dynamic harness — auto-generated, do not edit (Phase 14 — JavaShape::{shape:?}).
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class NyxHarness {{
|
||||
{imports}public class NyxHarness {{
|
||||
{probe}
|
||||
{helpers}
|
||||
public static void main(String[] args) {{
|
||||
|
|
@ -557,6 +562,7 @@ public class NyxHarness {{
|
|||
}}
|
||||
"#,
|
||||
shape = shape,
|
||||
imports = imports,
|
||||
probe = probe,
|
||||
helpers = helpers,
|
||||
pre_call = pre_call,
|
||||
|
|
@ -989,4 +995,53 @@ mod tests {
|
|||
let harness = emit(&spec).unwrap();
|
||||
assert_eq!(harness.entry_subpath, Some("Entry.java".to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_shape_reads_file_and_returns_shape() {
|
||||
// Drive the public `detect_shape(spec)` wrapper end-to-end:
|
||||
// write a representative source to a tempfile, then assert the
|
||||
// wrapper reads it and produces the expected JavaShape variant.
|
||||
let dir = std::env::temp_dir().join(format!(
|
||||
"nyx_detect_shape_{}",
|
||||
std::process::id()
|
||||
));
|
||||
let _ = std::fs::create_dir_all(&dir);
|
||||
let cases: &[(&str, &str, &str, EntryKind, JavaShape)] = &[
|
||||
(
|
||||
"Servlet.java",
|
||||
"import javax.servlet.http.HttpServletRequest;\npublic class Servlet extends HttpServlet { public void doGet(HttpServletRequest r, HttpServletResponse w) {} }",
|
||||
"doGet",
|
||||
EntryKind::HttpRoute,
|
||||
JavaShape::ServletDoGet,
|
||||
),
|
||||
(
|
||||
"Spring.java",
|
||||
"@RestController\npublic class Spring { @GetMapping(\"/x\") public String run(String p) { return p; } }",
|
||||
"run",
|
||||
EntryKind::HttpRoute,
|
||||
JavaShape::SpringController,
|
||||
),
|
||||
(
|
||||
"MainClass.java",
|
||||
"public class MainClass { public static void main(String[] args) {} }",
|
||||
"main",
|
||||
EntryKind::CliSubcommand,
|
||||
JavaShape::StaticMain,
|
||||
),
|
||||
(
|
||||
"Plain.java",
|
||||
"public class Plain { public static void run(String p) {} }",
|
||||
"run",
|
||||
EntryKind::Function,
|
||||
JavaShape::StaticMethod,
|
||||
),
|
||||
];
|
||||
for (name, body, entry_name, kind, expected) in cases {
|
||||
let path = dir.join(name);
|
||||
std::fs::write(&path, body).expect("write fixture");
|
||||
let spec = make_spec_with(*kind, entry_name, path.to_str().unwrap());
|
||||
assert_eq!(detect_shape(&spec), *expected, "case {name}");
|
||||
}
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,24 +50,6 @@ pub fn emit(spec: &HarnessSpec) -> Result<HarnessSource, UnsupportedReason> {
|
|||
js_shared::emit(spec, false)
|
||||
}
|
||||
|
||||
/// Derive the JS module name from an entry file path.
|
||||
///
|
||||
/// Always returns `"entry"` because the JS harness stages the entry file at
|
||||
/// `workdir/entry.js` so `require('./entry')` is the only path that resolves
|
||||
/// regardless of the source file's original name.
|
||||
pub fn entry_module_name(_entry_file: &str) -> String {
|
||||
"entry".to_owned()
|
||||
}
|
||||
|
||||
/// Derive the entry filename from an entry file path.
|
||||
///
|
||||
/// Always `"entry.js"` for the JS surface; TypeScript uses `"entry.ts"` (see
|
||||
/// [`crate::dynamic::lang::typescript`]) and ESM-default shapes use
|
||||
/// `"entry.mjs"` (handled inside `js_shared`).
|
||||
pub fn entry_module_filename(_entry_file: &str) -> String {
|
||||
"entry.js".to_owned()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
@ -164,11 +146,4 @@ mod tests {
|
|||
assert!(hint.contains("Phase 13"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn entry_module_name_is_always_entry_to_match_copy_destination() {
|
||||
assert_eq!(entry_module_name("src/handlers/login.js"), "entry");
|
||||
assert_eq!(entry_module_name("app.ts"), "entry");
|
||||
assert_eq!(entry_module_name("handler.mjs"), "entry");
|
||||
assert_eq!(entry_module_name("no_ext"), "entry");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -988,7 +988,7 @@ fn finalize_spec(
|
|||
sink_line: u32,
|
||||
derivation: SpecDerivationStrategy,
|
||||
) -> HarnessSpec {
|
||||
let toolchain_id = toolchain_id_for_lang(lang).to_owned();
|
||||
let toolchain_id = default_toolchain_id(lang).to_owned();
|
||||
let stubs_required = StubKind::for_cap(expected_cap);
|
||||
let mut spec = HarnessSpec {
|
||||
finding_id: format!("{:016x}", diag.stable_hash),
|
||||
|
|
@ -1031,7 +1031,7 @@ pub fn outermost_entry(steps: &[crate::evidence::FlowStep]) -> Option<EntryRef>
|
|||
|
||||
/// Default toolchain label for a language (informational; harness builder
|
||||
/// may override for locally-installed compilers/runtimes).
|
||||
fn toolchain_id_for_lang(lang: Lang) -> &'static str {
|
||||
pub fn default_toolchain_id(lang: Lang) -> &'static str {
|
||||
match lang {
|
||||
Lang::Rust => "rust-stable",
|
||||
Lang::C => "gcc-stable",
|
||||
|
|
|
|||
|
|
@ -283,17 +283,7 @@ pub fn run_shape_fixture_lang(
|
|||
u64::from_le_bytes(bytes.as_bytes()[..8].try_into().unwrap())
|
||||
});
|
||||
|
||||
let toolchain_id = match lang {
|
||||
nyx_scanner::symbol::Lang::Python => "python-3",
|
||||
nyx_scanner::symbol::Lang::JavaScript | nyx_scanner::symbol::Lang::TypeScript => "node-20",
|
||||
nyx_scanner::symbol::Lang::Rust => "rust-stable",
|
||||
nyx_scanner::symbol::Lang::Go => "go-1.21",
|
||||
nyx_scanner::symbol::Lang::Java => "java-17",
|
||||
nyx_scanner::symbol::Lang::Php => "php-8",
|
||||
nyx_scanner::symbol::Lang::Ruby => "ruby-3",
|
||||
nyx_scanner::symbol::Lang::C => "gcc",
|
||||
nyx_scanner::symbol::Lang::Cpp => "g++",
|
||||
};
|
||||
let toolchain_id = nyx_scanner::dynamic::spec::default_toolchain_id(lang);
|
||||
|
||||
let spec = HarnessSpec {
|
||||
finding_id: spec_hash.clone(),
|
||||
|
|
@ -482,11 +472,7 @@ pub fn run_harness_snapshot_lang(
|
|||
std::fs::copy(&fixture_src, &dst).expect("copy fixture into tempdir");
|
||||
let entry_file = dst.to_string_lossy().into_owned();
|
||||
|
||||
let toolchain_id = match lang {
|
||||
nyx_scanner::symbol::Lang::Python => "python-3",
|
||||
nyx_scanner::symbol::Lang::JavaScript | nyx_scanner::symbol::Lang::TypeScript => "node-20",
|
||||
_ => "unknown",
|
||||
};
|
||||
let toolchain_id = nyx_scanner::dynamic::spec::default_toolchain_id(lang);
|
||||
|
||||
let spec = HarnessSpec {
|
||||
finding_id: "0000000000000001".into(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue