-
Notifications
You must be signed in to change notification settings - Fork 11.3k
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
[move-compiler] Added preliminary support for writing linters #12650
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 6 Ignored Deployments
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outstanding! Thanks!
Just a few minor things, and mostly looking for your thoughts/feedback on a few things
crates/sui-move-build/src/lib.rs
Outdated
self.build_and_lint(path, false) | ||
} | ||
|
||
pub fn build_and_lint(self, path: PathBuf, lint: bool) -> SuiResult<CompiledPackage> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should lint
here be a flag on self: BuildConfig
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. Adding a function felt less-invasive but considering that in most cases BuildConfig
is created with a single function, it does not matter much, and having a flag in BuildConfig
does look cleaner. Thanks!
let msg = "You may be trying to share an owned object."; | ||
let uid_msg = "This argument should in most cases come from an object created within the same function."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is fine? Maybe?
Just brainstorming:
let msg = "You may be trying to share an owned object."; | |
let uid_msg = "This argument should in most cases come from an object created within the same function."; | |
let msg = "Potential abort from sharing an object not created this transaction."; | |
let uid_msg = "Creating a fresh object in this same function will ensure this does not abort."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went for yet another variant combining (sort of) the two proposals.
(f.arguments.exp.loc, uid_msg) | ||
); | ||
if let Value::NotFreshObj(l) = args[0] { | ||
d.add_secondary_label((l, "A potentially shared object coming from here")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
d.add_secondary_label((l, "A potentially shared object coming from here")) | |
d.add_secondary_label((l, "A potentially owned object coming from here")) |
Is this flipped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh...
if let L::Unpack(_, _, fields) = l_ { | ||
for (f, l) in fields { | ||
let v = if is_obj(l) { | ||
<Self::State as SimpleDomain>::Value::NotFreshObj(f.loc()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange, does just Value::NotFreshObj
error here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As it happens, it does... Probably copypasta and/or some artifact of an earlier implementation based off a branch.
}; | ||
self.lvalue(context, state, l, v) | ||
} | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thoughts on the bool thing? (where true is skip and false is continue)
I came up with it and I find it a bit confusing reading it lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't give it that much thought but I found it pretty sensible to work with.
Ok(()) | ||
} | ||
|
||
fn run_tests(path: &Path) -> anyhow::Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
@@ -743,6 +743,36 @@ fn has_compiled_module_magic_number(path: &str) -> bool { | |||
num_bytes_read == BinaryConstants::MOVE_MAGIC_SIZE && magic == BinaryConstants::MOVE_MAGIC | |||
} | |||
|
|||
pub fn move_check_for_errors( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really relevant for this PR just a comment:
We might want to rename it and flesh out this API (as it also does warnings now... this function is super old fwiw)
if update_baseline { | ||
if has_diags { | ||
fs::write(exp_path, rendered_diags)?; | ||
} else if exp_path.is_file() { | ||
fs::remove_file(exp_path)?; | ||
} | ||
return Ok(()); | ||
} | ||
|
||
let exp_exists = exp_path.is_file(); | ||
if exp_exists { | ||
let expected_diags = fs::read_to_string(exp_path)?; | ||
if rendered_diags != expected_diags { | ||
let msg = format!( | ||
"Expected output differ from the actual one:\n{}", | ||
format_diff(expected_diags, rendered_diags), | ||
); | ||
anyhow::bail!(add_update_baseline_fix(msg)); | ||
} | ||
} else { | ||
let msg = format!("Unexpected output :\n{}", rendered_diags); | ||
anyhow::bail!(add_update_baseline_fix(msg)); | ||
} | ||
|
||
Ok(()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also not relevant for this PR, but I've copy-pasted this so many times. We should maybe make a library for this or something idk
const SHARE_OWNED_DIAG: DiagnosticInfo = custom( | ||
"Lint ", | ||
Severity::Warning, | ||
/* category */ 1, | ||
/* code */ 1, | ||
"possible owned object share", | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any feedback you have for making this easier to manage? (specifically on the category/code side of things)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not at the moment, but I will think about it when writing more lints!
769481f
to
79013e9
Compare
## Description Added support for writing linters: - integration with Sui CLI - a simple testing harness - an example linter to signal sharing of potentially owned objects ## Test Plan Additional testing framework being part of this PR can be used to test individual linters. --- If your changes are not user-facing and not a breaking change, you can skip the following section. Otherwise, please indicate what changed, and then add to the Release Notes section as highlighted during the release process. ### Type of Change (Check all that apply) - [ ] protocol change - [x] user-visible impact - [ ] breaking change for a client SDKs - [ ] breaking change for FNs (FN binary must upgrade) - [ ] breaking change for validators or node operators (must upgrade binaries) - [ ] breaking change for on-chain data layout - [ ] necessitate either a data wipe or data migration ### Release notes Developers may now opt into running linters when building/testing/publishing/upgrading packages via CLI by specifying the `--lint` flag.
Description
Added support for writing linters:
Test Plan
Additional testing framework being part of this PR can be used to test individual linters.
If your changes are not user-facing and not a breaking change, you can skip the following section. Otherwise, please indicate what changed, and then add to the Release Notes section as highlighted during the release process.
Type of Change (Check all that apply)
Release notes
Developers may now opt into running linters when building/testing/publishing/upgrading packages via CLI by specifying the
--lint
flag.