Skip to content
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

Port graph editor to new AST #4113

Merged
merged 97 commits into from
Feb 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
593d2f7
introduce ast-parser abstraction layer
kazcw Jan 23, 2023
fdb4dbf
produce Ast from enso-parser Tree
kazcw Nov 29, 2022
e16f66c
eliminate parser-bridge-tests
kazcw Jan 25, 2023
61e814b
integrate enso-parser-bridge into ast-parser
kazcw Jan 25, 2023
cc6eacc
replace scala parser in frontend
kazcw Jan 25, 2023
23409f0
translating types...
kazcw Jan 26, 2023
9f6a6bf
eliminate spaceless ast
kazcw Jan 26, 2023
a9b0129
whitespace
kazcw Jan 27, 2023
85ece1e
ast::Tree
kazcw Jan 27, 2023
707dfb2
wip: spantree
kazcw Jan 27, 2023
23bf2a4
wip: TreeCrumbs
kazcw Jan 27, 2023
6714b51
remove old types
kazcw Jan 31, 2023
565bb4f
wip
kazcw Jan 31, 2023
926569b
fix after rebase
kazcw Jan 31, 2023
1b6dce8
fix SpanTree generation (needed tokens)
kazcw Feb 1, 2023
da4d63f
refactor
kazcw Feb 1, 2023
af8c5e7
new test
kazcw Feb 1, 2023
f25a627
debugging
kazcw Feb 1, 2023
4248c44
dead code
kazcw Feb 1, 2023
60fe00c
wip: documented nodes
kazcw Feb 1, 2023
740d9c1
cleanup
kazcw Feb 1, 2023
15bad70
wip doc comments
kazcw Feb 2, 2023
ecef766
eliminate orphan blocks
kazcw Feb 2, 2023
af7c8a4
wip doc comments
kazcw Feb 2, 2023
c8ed885
cut Ast deserialization
kazcw Feb 2, 2023
256e52b
doc comments
kazcw Feb 2, 2023
956195b
Merge remote-tracking branch 'origin/develop' into parser-port-graph-…
kazcw Feb 2, 2023
d3a7239
fix tests
kazcw Feb 2, 2023
459670d
dead code
kazcw Feb 2, 2023
acfeae4
cut Ast serialization
kazcw Feb 2, 2023
bf5f435
import analysis
kazcw Feb 2, 2023
02e7bcc
fix test failures
kazcw Feb 2, 2023
378cc50
Merge remote-tracking branch 'origin/develop' into parser-port-graph-…
kazcw Feb 2, 2023
5567ded
lambda analysis
kazcw Feb 2, 2023
903939e
cleanup tests
kazcw Feb 2, 2023
95c7917
wip: alias analysis for case-of
kazcw Feb 2, 2023
538a027
update test
kazcw Feb 3, 2023
7260042
implement DocComment pretty_text
kazcw Feb 3, 2023
f9ad1e9
Merge remote-tracking branch 'origin/develop' into parser-port-graph-…
kazcw Feb 3, 2023
2c0521c
multi-line pretty_text
kazcw Feb 3, 2023
e448b1a
support parens in argument definitions
kazcw Feb 3, 2023
545aaa4
pass more tests
kazcw Feb 3, 2023
5923269
attach IDs to nodes
kazcw Feb 3, 2023
4f8d7cd
implement whitespace case
kazcw Feb 3, 2023
c44aea9
parsing is no longer fallible
kazcw Feb 3, 2023
d218a92
fmt
kazcw Feb 3, 2023
76620c6
support more syntax cases
kazcw Feb 5, 2023
e20ad3f
lint
kazcw Feb 5, 2023
560880f
TODO
kazcw Feb 5, 2023
55d900f
operator IDs
kazcw Feb 5, 2023
9085236
refactor
kazcw Feb 5, 2023
f132d38
exclude spacing from ID start ranges
kazcw Feb 5, 2023
deb27fd
clean up
kazcw Feb 5, 2023
893fa01
Merge remote-tracking branch 'origin/develop' into parser-port-graph-…
kazcw Feb 5, 2023
c4e49fa
dead code
kazcw Feb 5, 2023
5866114
handle more spacing cases
kazcw Feb 5, 2023
041e647
translate MultipleOperatorError
kazcw Feb 5, 2023
862bb93
offset-aware doccomment deconstruction
kazcw Feb 5, 2023
b63d0d9
refactor
kazcw Feb 5, 2023
0b685c4
eliminate paren special case
kazcw Feb 5, 2023
08ee510
set id and kind in span tree
kazcw Feb 5, 2023
b4b2086
parse borrowed str
kazcw Feb 6, 2023
ebe9db0
deserialize metadata in parse_with_metadata
kazcw Feb 6, 2023
e1f16fe
dead code
kazcw Feb 6, 2023
a8b6e41
fix subtree enumeration bug
kazcw Feb 6, 2023
6cc158d
lint
kazcw Feb 6, 2023
cc124fd
lambda is span tree leaf; also update some tests
kazcw Feb 6, 2023
d72a12a
debugging info
kazcw Feb 6, 2023
0005aab
fix doc comment newline selection
kazcw Feb 6, 2023
24f55d9
use new parser associativity
kazcw Feb 6, 2023
b5c9a59
debugging
kazcw Feb 6, 2023
47741a0
metadata error handling
kazcw Feb 6, 2023
295da12
full operator block support
kazcw Feb 6, 2023
b96fc7c
Merge remote-tracking branch 'origin/develop' into parser-port-graph-…
kazcw Feb 6, 2023
aabe822
fix Mod logic
kazcw Feb 6, 2023
265213b
annotations
kazcw Feb 6, 2023
cea3280
variable base names
kazcw Feb 6, 2023
0c5ecd2
no ID for module
kazcw Feb 6, 2023
7f6fa6a
update tests
kazcw Feb 6, 2023
2174b0a
fix app metadata parsing
kazcw Feb 6, 2023
709166b
no ports for children of parens
kazcw Feb 6, 2023
563f920
update backend tests
kazcw Feb 7, 2023
083dd9f
fmt
kazcw Feb 7, 2023
50ccfc9
limited support for disable-comments
kazcw Feb 7, 2023
9e769a9
clean up
kazcw Feb 7, 2023
0c737b9
Merge remote-tracking branch 'origin/develop' into parser-port-graph-…
kazcw Feb 7, 2023
d37114e
fix
kazcw Feb 7, 2023
eef2c0f
handle odd None cases in translation
kazcw Feb 7, 2023
684f3ed
full comment representation
kazcw Feb 7, 2023
bea098c
rename crate
kazcw Feb 8, 2023
5279cd1
organize
kazcw Feb 8, 2023
45beda6
cleanup / document
kazcw Feb 8, 2023
e61b8b9
prune unused ids
kazcw Feb 8, 2023
38b6c4b
fix lost-ID-sync case
kazcw Feb 8, 2023
4f4b35f
fmt
kazcw Feb 8, 2023
197ddb1
Merge branch 'develop' into wip/kw/parser/port-graph-editor
kazcw Feb 9, 2023
8109712
Merge branch 'develop' into wip/kw/parser/port-graph-editor
mergify[bot] Feb 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,285 changes: 695 additions & 590 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ resolver = "2"
# where plausible.
members = [
"app/gui",
"app/gui/language/parser",
"app/gui/enso-profiler-enso-data",
"build/cli",
"build/macros",
Expand Down
3 changes: 2 additions & 1 deletion app/gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ ensogl-hardcoded-theme = { path = "../../lib/rust/ensogl/app/theme/hardcoded" }
ensogl-drop-manager = { path = "../../lib/rust/ensogl/component/drop-manager" }
fuzzly = { path = "../../lib/rust/fuzzly" }
ast = { path = "language/ast/impl" }
parser = { path = "language/parser" }
parser-scala = { path = "language/parser-scala" }
ide-view = { path = "view" }
engine-protocol = { path = "controller/engine-protocol" }
json-rpc = { path = "../../lib/rust/json-rpc" }
parser-scala = { path = "language/parser" }
span-tree = { path = "language/span-tree" }
bimap = { version = "0.4.0" }
console_error_panic_hook = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion app/gui/controller/double-representation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ crate-type = ["cdylib", "rlib"]

[dependencies]
ast = { path = "../../language/ast/impl" }
parser = { path = "../../language/parser" }
engine-protocol = { path = "../engine-protocol" }
parser-scala = { path = "../../language/parser" }
enso-data-structures = { path = "../../../../lib/rust/data-structures" }
enso-prelude = { path = "../../../../lib/rust/prelude" }
enso-profiler = { path = "../../../../lib/rust/profiler" }
Expand Down
27 changes: 4 additions & 23 deletions app/gui/controller/double-representation/src/alias_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,6 @@ impl AliasAnalyzer {
self.process_assignment(&assignment);
} else if let Some(lambda) = ast::macros::as_lambda(ast) {
self.process_lambda(&lambda);
} else if let Ok(macro_match) = ast::known::Match::try_from(ast) {
// Macros (except for lambdas which were covered in the previous check) never introduce
// new scopes or different context. We skip the keywords ("if" in "if-then-else" is not
// an identifier) and process the matched subtrees as usual.
self.process_given_subtrees(macro_match.shape(), macro_match.iter_pat_match_subcrumbs())
} else if let Ok(ambiguous) = ast::known::Ambiguous::try_from(ast) {
self.process_given_subtrees(ambiguous.shape(), ambiguous.iter_pat_match_subcrumbs())
} else if self.is_in_pattern() {
// We are in the pattern (be it a lambda's or assignment's left side). Three options:
// 1) This is a destructuring pattern match using infix syntax, like `head,tail`.
Expand Down Expand Up @@ -371,8 +364,6 @@ mod tests {
use super::test_utils::*;
use super::*;

wasm_bindgen_test_configure!(run_in_browser);

/// Checks if actual observed sequence of located identifiers matches the expected one.
/// Expected identifiers are described as code spans in the node's text representation.
fn validate_identifiers(
Expand All @@ -386,7 +377,7 @@ mod tests {
}

/// Runs the test for the given test case description.
fn run_case(parser: &parser_scala::Parser, case: Case) {
fn run_case(parser: &parser::Parser, case: Case) {
debug!("\n===========================================================================\n");
debug!("Case: {}", case.code);
let ast = parser.parse_line_ast(&case.code).unwrap();
Expand All @@ -397,15 +388,15 @@ mod tests {
}

/// Runs the test for the test case expressed using markdown notation. See `Case` for details.
fn run_markdown_case(parser: &parser_scala::Parser, marked_code: impl AsRef<str>) {
fn run_markdown_case(parser: &parser::Parser, marked_code: impl AsRef<str>) {
debug!("Running test case for {}", marked_code.as_ref());
let case = Case::from_markdown(marked_code.as_ref());
run_case(parser, case)
}

#[wasm_bindgen_test]
#[test]
fn test_alias_analysis() {
let parser = parser_scala::Parser::new_or_panic();
let parser = parser::Parser::new();
let test_cases = [
"»foo«",
"«five» = 5",
Expand Down Expand Up @@ -433,21 +424,11 @@ mod tests {
"»A« -> »b«",
"a -> »A« -> a",
"a -> a -> »A«",
"x»,«y -> »B«",
"x»,«y -> y",
"x »,« »Y« -> _",
"(»foo«)",
"(«foo») = (»bar«)",
"if »A« then »B«",
"if »a« then »b« else »c«",
"case »foo« of\n »Number« a -> a\n »Wildcard« -> »bar«\n a»,«b -> a",
// === Macros Ambiguous ===
"(»foo«",
"if »a«",
"case »a«",
// "->»a«", // TODO [mwu] restore (and implement) when parser is able to parse this
// "a ->", // TODO [mwu] restore (and implement) when parser is able to parse this

// === Definition ===
"«foo» a b c = »foo« a »d«",
"«foo» a b c = d -> a d",
Expand Down
27 changes: 13 additions & 14 deletions app/gui/controller/double-representation/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ mod tests {

use ast::crumbs;
use ast::crumbs::InfixCrumb;
use parser_scala::Parser;
use parser::Parser;

struct TestRun {
graph: GraphInfo,
Expand All @@ -182,7 +182,7 @@ mod tests {
}

fn from_main_def(code: impl Str) -> TestRun {
let parser = Parser::new_or_panic();
let parser = Parser::new();
let module = parser.parse_module(code, default()).unwrap();
let definition = DefinitionInfo::from_root_line(&module.lines[0]).unwrap();
Self::from_definition(definition)
Expand All @@ -199,15 +199,15 @@ mod tests {
}
}

#[wasm_bindgen_test]
#[test]
pub fn connection_listing_test_plain() {
use InfixCrumb::LeftOperand;
use InfixCrumb::RightOperand;

let code_block = r"
d,e = p
d = p
a = d
b = e
b = d
c = a + b
fun a = a b
f = fun 2";
Expand All @@ -221,35 +221,35 @@ f = fun 2";
assert_eq!(&c.destination.crumbs, &crumbs![RightOperand, LeftOperand]);

let c = &run.connections[1];
assert_eq!(run.endpoint_node_repr(&c.source), "b = e");
assert_eq!(run.endpoint_node_repr(&c.source), "b = d");
assert_eq!(&c.source.crumbs, &crumbs![LeftOperand]);
assert_eq!(run.endpoint_node_repr(&c.destination), "c = a + b");
assert_eq!(&c.destination.crumbs, &crumbs![RightOperand, RightOperand]);

let c = &run.connections[2];
assert_eq!(run.endpoint_node_repr(&c.source), "d,e = p");
assert_eq!(&c.source.crumbs, &crumbs![LeftOperand, LeftOperand]);
assert_eq!(run.endpoint_node_repr(&c.source), "d = p");
assert_eq!(&c.source.crumbs, &crumbs![LeftOperand]);
assert_eq!(run.endpoint_node_repr(&c.destination), "a = d");
assert_eq!(&c.destination.crumbs, &crumbs![RightOperand]);

let c = &run.connections[3];
assert_eq!(run.endpoint_node_repr(&c.source), "d,e = p");
assert_eq!(&c.source.crumbs, &crumbs![LeftOperand, RightOperand]);
assert_eq!(run.endpoint_node_repr(&c.destination), "b = e");
assert_eq!(run.endpoint_node_repr(&c.source), "d = p");
assert_eq!(&c.source.crumbs, &crumbs![LeftOperand]);
assert_eq!(run.endpoint_node_repr(&c.destination), "b = d");
assert_eq!(&c.destination.crumbs, &crumbs![RightOperand]);

// Note that line `fun a = a b` des not introduce any connections, as it is a definition.

assert_eq!(run.connections.len(), 4);
}

#[wasm_bindgen_test]
#[test]
pub fn inline_definition() {
let run = TestRun::from_main_def("main = a");
assert!(run.connections.is_empty());
}

#[wasm_bindgen_test]
#[test]
pub fn listing_dependent_nodes() {
let code_block = "\
f,g = p
Expand All @@ -259,7 +259,6 @@ f = fun 2";
d = a + b
e = b";
let mut expected_dependent_nodes = HashMap::<&'static str, Vec<&'static str>>::new();
expected_dependent_nodes.insert("f,g = p", vec!["a = f", "b = g", "d = a + b", "e = b"]);
expected_dependent_nodes.insert("a = f", vec!["d = a + b"]);
expected_dependent_nodes.insert("b = g", vec!["d = a + b", "e = b"]);
expected_dependent_nodes.insert("c = 2", vec![]);
Expand Down
56 changes: 23 additions & 33 deletions app/gui/controller/double-representation/src/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use ast::crumbs::InfixCrumb;
use ast::crumbs::Located;
use ast::known;
use ast::opr;
use parser_scala::Parser;
use parser::Parser;
use std::iter::FusedIterator;


Expand Down Expand Up @@ -284,9 +284,7 @@ impl DefinitionInfo {
let elem = line.elem.ok_or(MissingLineWithAst)?;
let off = line.off;
let first_line = ast::BlockLine { elem, off };
let is_orphan = false;
let ty = ast::BlockType::Discontinuous {};
let block = ast::Block { ty, indent, empty_lines, first_line, lines, is_orphan };
let block = ast::Block { indent, empty_lines, first_line, lines };
let body_ast = Ast::new(block, None);
self.set_body_ast(body_ast);
Ok(())
Expand Down Expand Up @@ -603,10 +601,6 @@ mod tests {
use crate::module;
use crate::INDENT;

use wasm_bindgen_test::wasm_bindgen_test;

wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);

fn assert_eq_strings(lhs: Vec<impl Str>, rhs: Vec<impl Str>) {
let lhs = lhs.iter().map(|s| s.as_ref()).collect_vec();
let rhs = rhs.iter().map(|s| s.as_ref()).collect_vec();
Expand All @@ -621,9 +615,9 @@ mod tests {
format!(" {line}")
}

#[wasm_bindgen_test]
#[test]
fn generating_definition_to_add() {
let parser = Parser::new_or_panic();
let parser = Parser::new();
let mut to_add = ToAdd {
name: DefinitionName::new_method("Main", "add"),
explicit_parameter_names: vec!["arg1".into(), "arg2".into()],
Expand All @@ -649,9 +643,9 @@ mod tests {
assert_eq!(ast.repr(), "Main.add arg1 arg2 =\n arg1 + arg2\n arg1 - arg2");
}

#[wasm_bindgen_test]
#[test]
fn definition_name_tests() {
let parser = parser_scala::Parser::new_or_panic();
let parser = parser::Parser::new();
let ast = parser.parse_line_ast("Foo.Bar.baz").unwrap();
let name = DefinitionName::from_ast(&ast).unwrap();

Expand All @@ -664,26 +658,26 @@ mod tests {
assert_eq!(ast.get_traversing(&name.extended_target[1].crumbs).unwrap().repr(), "Bar");
}

#[wasm_bindgen_test]
#[test]
fn definition_name_rejecting_incomplete_names() {
let parser = parser_scala::Parser::new_or_panic();
let parser = parser::Parser::new();
let ast = parser.parse_line_ast("Foo. .baz").unwrap();
assert!(DefinitionName::from_ast(&ast).is_none());
}

#[wasm_bindgen_test]
#[test]
fn definition_info_name() {
let parser = parser_scala::Parser::new_or_panic();
let parser = parser::Parser::new();
let ast = parser.parse_line_ast("Foo.bar a b c = baz").unwrap();
let definition = DefinitionInfo::from_root_line_ast(&ast).unwrap();

assert_eq!(definition.name.to_string(), "Foo.bar");
assert_eq!(ast.get_traversing(&definition.name.crumbs).unwrap().repr(), "Foo.bar");
}

#[wasm_bindgen_test]
#[test]
fn located_definition_args() {
let parser = parser_scala::Parser::new_or_panic();
let parser = parser::Parser::new();
let ast = parser.parse_line_ast("foo bar baz = a + b + c").unwrap();
let definition = DefinitionInfo::from_root_line_ast(&ast).unwrap();
let (arg0, arg1) = definition.args.expect_tuple();
Expand All @@ -700,7 +694,7 @@ mod tests {
assert_eq!(ast.get_traversing(&arg1.crumbs).unwrap(), &arg1.item);
}

#[wasm_bindgen_test]
#[test]
fn match_is_not_definition() {
let cons = Ast::cons("Foo");
let arg = Ast::number(5);
Expand All @@ -723,28 +717,24 @@ mod tests {
assert!(def_opt.is_some());
}

#[wasm_bindgen_test]
#[test]
fn list_definition_test() {
let parser = parser_scala::Parser::new_or_panic();
let parser = parser::Parser::new();

// TODO [mwu]
// Due to a parser bug, extension methods defining operators cannot be currently
// correctly recognized. When it is fixed, the following should be also supported
// and covered in test: `Int.+ a = _` and `Int.+ = _`.
// Issue link: https://github.com/enso-org/enso/issues/565
let definition_lines = vec![
"main = _",
"Foo.Bar.foo = _",
"Foo.Bar.baz a b = _",
"+ = _",
"+ a = _",
"Int.+ a = _",
"bar = _",
"add a b = 50",
"* a b = _",
];
let expected_def_names_in_module =
vec!["main", "Foo.Bar.foo", "Foo.Bar.baz", "+", "bar", "add", "*"];
vec!["main", "Foo.Bar.foo", "Foo.Bar.baz", "+", "Int.+", "bar", "add", "*"];
// In definition there are no extension methods nor arg-less definitions.
let expected_def_names_in_def = vec!["add", "*"];
let expected_def_names_in_def = vec!["+", "add", "*"];

// === Program with definitions in root ===
let program = definition_lines.join("\n");
Expand All @@ -770,7 +760,7 @@ mod tests {
assert_eq_strings(to_names(&nested_defs), expected_def_names_in_def);
}

#[wasm_bindgen_test]
#[test]
fn finding_root_definition() {
let program_to_expected_main_pos = vec![
("main = bar", 0),
Expand All @@ -780,7 +770,7 @@ mod tests {
("foo = bar\n\nmain = bar", 2),
];

let parser = parser_scala::Parser::new_or_panic();
let parser = parser::Parser::new();
let main_id = Id::new_plain_name("main");
for (program, expected_line_index) in program_to_expected_main_pos {
let module = parser.parse_module(program, default()).unwrap();
Expand All @@ -793,7 +783,7 @@ mod tests {
}
}

#[wasm_bindgen_test]
#[test]
fn getting_nested_definition() {
let program = r"
main =
Expand All @@ -806,7 +796,7 @@ main =

add foo bar";

let module = parser_scala::Parser::new_or_panic().parse_module(program, default()).unwrap();
let module = parser::Parser::new().parse_module(program, default()).unwrap();
let check_def = |id, expected_body| {
let definition = module::get_definition(&module, &id).unwrap();
assert_eq!(definition.body().repr(), expected_body);
Expand Down
Loading