fix: Reject parse trees with missing nodes #587
19 changed files with 48 additions and 29 deletions
|
@ -1,4 +1,4 @@
|
|||
class MyClass {
|
||||
public:
|
||||
int field_1;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,4 +8,4 @@ class MyClass {
|
|||
=======
|
||||
char field_3;
|
||||
>>>>>>> RIGHT
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,4 +8,4 @@ class MyClass {
|
|||
=======
|
||||
char field_3;
|
||||
>>>>>>> RIGHT
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,4 +3,4 @@ class MyClass {
|
|||
int field_1;
|
||||
private:
|
||||
size_t field_2;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,4 +2,4 @@ class MyClass {
|
|||
public:
|
||||
int field_1;
|
||||
char field_3;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
struct my_struct {
|
||||
int field_1;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,4 +3,4 @@ struct my_struct {
|
|||
char field_2;
|
||||
size_t field_3;
|
||||
void* pointer;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,4 +2,4 @@ struct my_struct {
|
|||
int field_1;
|
||||
char field_2;
|
||||
size_t field_3;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
struct my_struct {
|
||||
int field_1;
|
||||
void* pointer;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,4 +5,4 @@ class MyClass {
|
|||
printf("too few arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,4 +13,4 @@ class MyClass {
|
|||
void run(bool reallyFast) {
|
||||
printf("world\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,4 +9,4 @@ class MyClass {
|
|||
void run() {
|
||||
printf("hello\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,4 +9,4 @@ class MyClass {
|
|||
void run(bool reallyFast) {
|
||||
printf("world\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,4 +5,4 @@ class MyClass {
|
|||
printf("too few arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,4 +13,4 @@ class MyClass {
|
|||
void runFast() {
|
||||
printf("world\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,4 +9,4 @@ class MyClass {
|
|||
void run() {
|
||||
printf("hello\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,4 +9,4 @@ class MyClass {
|
|||
void runFast() {
|
||||
printf("world\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
39
src/ast.rs
39
src/ast.rs
|
@ -319,13 +319,22 @@ impl<'a> AstNode<'a> {
|
|||
let idx = local_source.ceil_char_boundary(32);
|
||||
|
||||
return Err(format!(
|
||||
"parse error at {}:{}..{}:{}, starting with: {}",
|
||||
"parse error at {}:{}..{}:{}, starting with: `{}`",
|
||||
full_range.start_point.row,
|
||||
full_range.start_point.column,
|
||||
full_range.end_point.row,
|
||||
full_range.end_point.column,
|
||||
&local_source[..idx]
|
||||
));
|
||||
} else if node.is_missing() {
|
||||
let full_range = node.range();
|
||||
|
||||
return Err(format!(
|
||||
"parse error at {}:{}, expected `{}`",
|
||||
full_range.start_point.row,
|
||||
full_range.start_point.column,
|
||||
node.kind(),
|
||||
));
|
||||
}
|
||||
|
||||
// if this is a leaf that spans multiple lines, create one child per line,
|
||||
|
@ -1222,7 +1231,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
parse,
|
||||
Err("parse error at 1:1..1:3, starting with: {,".to_string())
|
||||
Err("parse error at 1:1..1:3, starting with: `{,`".to_string())
|
||||
);
|
||||
|
||||
let parse = AstNode::parse(
|
||||
|
@ -1234,10 +1243,20 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
parse,
|
||||
Err("parse error at 0:0..0:39, starting with: 属于个人的非赢利性开源".to_string())
|
||||
Err("parse error at 0:0..0:39, starting with: `属于个人的非赢利性开源`".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_token() {
|
||||
let ctx = ctx();
|
||||
let lang_profile = LangProfile::detect_from_filename("test.java")
|
||||
.expect("Could not load the Java lang profile");
|
||||
let parse = AstNode::parse("class Test {", lang_profile, &ctx.arena, &ctx.ref_arena);
|
||||
|
||||
assert_eq!(parse, Err("parse error at 0:12, expected `}`".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn heights() {
|
||||
let ctx = ctx();
|
||||
|
@ -1625,7 +1644,7 @@ mod tests {
|
|||
{
|
||||
"a": [
|
||||
1,
|
||||
2,
|
||||
2
|
||||
],
|
||||
"b": {
|
||||
"c": "foo"
|
||||
|
@ -1643,7 +1662,7 @@ mod tests {
|
|||
"\
|
||||
\"a\": [
|
||||
1,
|
||||
2,
|
||||
2
|
||||
]"
|
||||
);
|
||||
assert_eq!(entry_a.indentation_shift(), Some(" "));
|
||||
|
@ -1653,7 +1672,7 @@ mod tests {
|
|||
"\
|
||||
\"a\": [
|
||||
1,
|
||||
2,
|
||||
2
|
||||
]"
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -1661,7 +1680,7 @@ mod tests {
|
|||
"\
|
||||
\"a\": [
|
||||
1,
|
||||
2,
|
||||
2
|
||||
]"
|
||||
);
|
||||
|
||||
|
@ -1670,7 +1689,7 @@ mod tests {
|
|||
"\
|
||||
[
|
||||
1,
|
||||
2,
|
||||
2
|
||||
]"
|
||||
);
|
||||
assert_eq!(array.indentation_shift(), None);
|
||||
|
@ -1680,7 +1699,7 @@ mod tests {
|
|||
"\
|
||||
[
|
||||
1,
|
||||
2,
|
||||
2
|
||||
]"
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -1688,7 +1707,7 @@ mod tests {
|
|||
"\
|
||||
[
|
||||
1,
|
||||
2,
|
||||
2
|
||||
]"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -569,10 +569,10 @@ fn foo() {
|
|||
#[test]
|
||||
fn dont_bundle_into_delims() {
|
||||
let ctx = ctx();
|
||||
let source = "(/* this is a comment */)";
|
||||
let source = "fn test(/* this is a comment */) {}";
|
||||
let rs = ctx.parse("a.rs", source);
|
||||
|
||||
let tup = rs[0][0];
|
||||
let tup = rs[0][2];
|
||||
assert_n_children(tup, 3);
|
||||
let comment = tup[1];
|
||||
assert_eq!(comment.kind, "block_comment");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue