Skip to content

Commit

Permalink
Provide syntax warnings to Java (#10645)
Browse files Browse the repository at this point in the history
Translate syntax warnings and attach to IR when translating operator applications.

We should ensure that all Trees are checked for warnings and every warning is attached to some IR. That would require a bit of refactoring: In TreeToIr, we could define helpers wrapping every IR constructor and accepting a `Tree` parameter. The `Tree` could be used to populate the `IdentifiedLocation` when constructing the IR type, and then to attach all warnings after constructing the IR object.

# Important Notes
- Update JNI dependency.
- Introduces a `cargo bench` runner for parser.
  • Loading branch information
kazcw authored Jul 24, 2024
1 parent 7e08702 commit 8b48637
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 58 deletions.
72 changes: 49 additions & 23 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.enso.compiler.core.ir.Name;
import org.enso.compiler.core.ir.Pattern;
import org.enso.compiler.core.ir.Type;
import org.enso.compiler.core.ir.Warning;
import org.enso.compiler.core.ir.expression.Application;
import org.enso.compiler.core.ir.expression.Case;
import org.enso.compiler.core.ir.expression.Comment;
Expand All @@ -35,6 +36,7 @@
import org.enso.syntax2.Base;
import org.enso.syntax2.DocComment;
import org.enso.syntax2.Line;
import org.enso.syntax2.Parser;
import org.enso.syntax2.TextElement;
import org.enso.syntax2.Token;
import org.enso.syntax2.Tree;
Expand Down Expand Up @@ -918,7 +920,9 @@ yield switch (op.codeRepr()) {
var lhs = unnamedCallArgument(app.getLhs());
var rhs = unnamedCallArgument(app.getRhs());
var loc = getIdentifiedLocation(app);
yield applyOperator(op, lhs, rhs, loc);
var ir = applyOperator(op, lhs, rhs, loc);
attachTranslatedWarnings(ir, app);
yield ir;
}
};
}
Expand Down Expand Up @@ -1197,6 +1201,14 @@ yield translateFunction(fun, name, isOperator, fun.getArgs(), fun.getBody(),
};
}

private void attachTranslatedWarnings(IR ir, Tree tree) {
for (var warning : tree.getWarnings()) {
var message = Parser.getWarningMessage(warning);
var irWarning = new Warning.Syntax(ir, message);
ir.diagnostics().add(irWarning);
}
}

private Operator applyOperator(Token.Operator op, CallArgument lhs, CallArgument rhs,
Option<IdentifiedLocation> loc) {
var name = new Name.Literal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,19 @@ object Warning {
override def diagnosticKeys(): Array[Any] = Array(ir.name)
}

case class Syntax(ir: IR, message: String) extends Warning {

/** @return a human-readable description of this error condition.
*/
override def message(source: (IdentifiedLocation => String)): String =
message

/** The location at which the diagnostic occurs. */
override val location: Option[IdentifiedLocation] = ir.location

/** The important keys identifying identity of the diagnostic
*/
override def diagnosticKeys(): Array[Any] = Array()
}

}
73 changes: 64 additions & 9 deletions lib/rust/parser/debug/src/bin/bench_parse.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Parses Enso sources, measuring time spent in the parser.
#![feature(test)]
// === Non-Standard Linter Configuration ===
#![allow(clippy::option_map_unit_fn)]
#![allow(clippy::precedence)]
Expand All @@ -11,24 +12,78 @@



// =============
// === Tests ===
// =============
// ===========
// === CLI ===
// ===========

fn main() {
let args = std::env::args().skip(1);
let parser = enso_parser::Parser::new();
let parse_time: std::time::Duration = args
.map(|path| {
let code = std::fs::read_to_string(path).unwrap();
let mut code = code.as_str();
if let Some((_meta, code_)) = enso_parser::metadata::parse(code) {
code = code_;
}
let code = read_source(path).unwrap();
let start = std::time::Instant::now();
std::hint::black_box(parser.run(code));
std::hint::black_box(parser.run(&code));
start.elapsed()
})
.sum();
println!("Parse time: {} ms", parse_time.as_millis());
}

fn read_source(path: impl AsRef<Path>) -> io::Result<String> {
let code = fs::read_to_string(path)?;
Ok(if let Some((_meta, code)) = enso_parser::metadata::parse(&code) {
code.to_owned()
} else {
code
})
}



// ===============================
// === `cargo bench` interface ===
// ===============================

extern crate test;

use std::fs::DirEntry;
use std::fs::{self};
use std::io;
use std::path::Path;

fn visit_files<F: FnMut(&DirEntry)>(dir: &Path, f: &mut F) -> io::Result<()> {
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_files(&path, f)?;
} else {
f(&entry);
}
}
}
Ok(())
}

#[bench]
fn bench_std_lib(b: &mut test::Bencher) {
let mut sources = vec![];
visit_files(Path::new("../../../../distribution/lib"), &mut |dir_ent| {
let path = dir_ent.path();
if let Some(ext) = path.extension() {
if ext == "enso" {
sources.push(read_source(path).unwrap())
}
}
})
.unwrap();
let parser = enso_parser::Parser::new();
b.bytes = sources.iter().map(|s| s.len() as u64).sum();
b.iter(|| {
for source in &sources {
test::black_box(parser.run(source));
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ private Parser(long stateIn) {

private static native long getMetadata(long state);

private static native String getWarningTemplate(int warningId);

static native long getUuidHigh(long metadata, long codeOffset, long codeLength);

static native long getUuidLow(long metadata, long codeOffset, long codeLength);
Expand Down Expand Up @@ -131,6 +133,10 @@ public Tree parse(CharSequence input) {
return Tree.deserialize(message);
}

public static String getWarningMessage(Warning warning) {
return getWarningTemplate(warning.getId());
}

@Override
public void close() {
freeState(state);
Expand Down
2 changes: 1 addition & 1 deletion lib/rust/parser/jni/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ license-file = "../../LICENSE"
[dependencies]
enso-prelude = { path = "../../prelude" }
enso-parser = { path = "../" }
jni = "0.19.0"
jni = "0.21.0"

[lib]
name = "enso_parser"
Expand Down
Loading

0 comments on commit 8b48637

Please sign in to comment.