Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
fd510f4
Use tree
elegoff May 1, 2021
c69b86f
associated items
elegoff May 1, 2021
4c5a8d2
Ser WIP
elegoff May 1, 2021
64bd47e
ser ok
elegoff May 2, 2021
e56ad4e
WIP raw strings
elegoff May 4, 2021
0338014
raw strings
elegoff May 4, 2021
a3d0cc6
abi
elegoff May 4, 2021
36c577a
More raw strings
elegoff May 5, 2021
5052ce2
raw strings with later string
elegoff May 6, 2021
1b0dec6
Generics WIP
elegoff May 8, 2021
e71bcc6
Generic args new version
elegoff May 8, 2021
21b3108
Generic args
elegoff May 10, 2021
6750c22
WIP statements
elegoff May 10, 2021
8110242
Statements
elegoff May 12, 2021
ac9505e
macro rep sep
elegoff May 12, 2021
391d819
Fix number of statements in unit test
elegoff May 12, 2021
47e9f1b
Impl trait type
elegoff May 12, 2021
9b67a9b
assert_eq! in statements
elegoff May 13, 2021
3b42cc8
visibility
elegoff May 13, 2021
6f7a916
expressions except struct
elegoff May 14, 2021
bfcd261
struct pattern
elegoff May 14, 2021
343042d
fix regression on structs
elegoff May 14, 2021
1e28b82
multi raw string literals
elegoff May 14, 2021
ad1548e
Highlighting constants
elegoff May 14, 2021
bee2266
outer attributes
elegoff May 14, 2021
1a47f02
function param
elegoff May 14, 2021
1897de2
empty byte string literal
elegoff May 14, 2021
f539ebf
while loop
elegoff May 14, 2021
1fae9c2
struct field visibility
elegoff May 14, 2021
e7e0789
raw byte string
elegoff May 14, 2021
f1fd437
strings literal again
elegoff May 14, 2021
30f84e5
dot dot call param
elegoff May 15, 2021
a251c97
raw string literal starting with #
elegoff May 15, 2021
32cd1a0
index expression bracket
elegoff May 15, 2021
986cb94
match expressions
elegoff May 15, 2021
43aef81
break expression
elegoff May 15, 2021
30691a7
dot dot in index
elegoff May 15, 2021
e5e0990
match starting with match
elegoff May 15, 2021
ae37736
struct etcetera
elegoff May 15, 2021
51a7dae
byte string literal
elegoff May 15, 2021
db611cf
float literal
elegoff May 15, 2021
7e95376
tuple pattern
elegoff May 15, 2021
ba6f93c
byte escape
elegoff May 15, 2021
b5d190b
patterns starting with ref or mut
elegoff May 16, 2021
41cdcb4
byte string literal multiline
elegoff May 16, 2021
e92cdb3
byte string litteral with escaped quotes
elegoff May 16, 2021
9570dff
Comment withing string literal
elegoff May 16, 2021
ce287e5
macro match
elegoff May 16, 2021
5506674
Negation expression in IF statement
elegoff May 17, 2021
c3c5e02
extended ascii
elegoff May 17, 2021
543fd6e
known issue for regexp strings
elegoff May 17, 2021
2910243
type in trait
elegoff May 17, 2021
4efe159
bump squid bridge version
elegoff May 18, 2021
a553d22
loop label
elegoff May 18, 2021
94520e4
compilation unit
elegoff May 18, 2021
cc62b6e
continue expression
elegoff May 18, 2021
a86b626
remove commented code
elegoff May 18, 2021
852c9e7
license header
elegoff May 18, 2021
61b04db
test constant highlight
elegoff May 18, 2021
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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<sonar.version>7.9</sonar.version>
<java.version>8</java.version>
<sslr.version>1.24.0.633</sslr.version>
<sslr-squid-bridge.version>2.7.0.377</sslr-squid-bridge.version>
<sslr-squid-bridge.version>2.7.1.392</sslr-squid-bridge.version>
<mockito.version>3.6.28</mockito.version>
<assertj-core.version>3.19.0</assertj-core.version>
<jacoco.version>0.8.6</jacoco.version>
Expand Down
492 changes: 346 additions & 146 deletions rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions rust-frontend/src/test/java/org/sonar/rust/RustLexerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@
package org.sonar.rust;

import com.google.common.base.Charsets;
import com.sonar.sslr.api.AstNode;
import com.sonar.sslr.api.Token;
import com.sonar.sslr.impl.ast.AstXmlPrinter;
import org.junit.Test;
import org.sonar.sslr.parser.LexerlessGrammar;
import org.sonar.sslr.parser.ParserAdapter;
import org.sonar.sslr.tests.Assertions;

import java.nio.charset.StandardCharsets;
import java.util.List;

import static org.fest.assertions.Assertions.assertThat;
Expand Down Expand Up @@ -59,4 +64,23 @@ public void testTokens() {

;
}

@Test
public void testParsing() {


String sexpr = "#![feature(const_fn_fn_ptr_basics)]";


//Print out Ast node content for debugging purpose

ParserAdapter<LexerlessGrammar> parser = new ParserAdapter<>(StandardCharsets.UTF_8, RustGrammar.create().build());
AstNode rootNode = parser.parse(sexpr);
org.fest.assertions.Assertions.assertThat(rootNode.getType()).isSameAs(RustGrammar.COMPILATION_UNIT);
AstNode astNode = rootNode;
//org.fest.assertions.Assertions.assertThat(astNode.getNumberOfChildren()).isEqualTo(4);
System.out.println(AstXmlPrinter.print(astNode));


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public void testAttribute() {
public void testInnerAttribute() {
assertThat(RustGrammar.create().build().rule(RustGrammar.INNER_ATTRIBUTE))
.matches("#![crate_type = \"lib\"]")
.matches("#![feature(const_fn_fn_ptr_basics)]")
;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,7 @@ public class BlockExpressionTest {
*/


@Test
public void testStatements() {
assertThat(RustGrammar.create().build().rule(RustGrammar.STATEMENTS))
.matches("println!(\"hi there\");")
.matches("println!(\"hi there\");\n" +
"println!(\"how are you today ?\");")

.matches("j.set(i.get()); false")
.matches("j.set(i.get() + 1); false")
.matches("node_fetch::create_http_client(user_agent.clone(), my_data.clone()).unwrap()")
;
}

@Test
public void testAsyncBlockExpression() {
Expand All @@ -65,6 +54,9 @@ public void testAsyncBlockExpression() {
public void testBlockExpression() {
assertThat(RustGrammar.create().build().rule(RustGrammar.BLOCK_EXPRESSION))
.matches("{}")
.matches("{\n" +
" // comment\n" +
"}")
.matches("{let y=42;}")
.matches("{println!(\"hi there\");}")
.matches("{abc()}")
Expand Down Expand Up @@ -93,11 +85,9 @@ public void testBlockExpression() {
.matches("{\n" +
" self.len() as u32\n" +
" }")
/* FIXME
.matches("{\n" +
" &[b' ', b' ', b' '][0..(4 - (len & 3)) & 3]\n" +
"}")
*/

.matches("{ Box::new(move |state : Rc<RefCell<OpState>>, bufs: BufVec| -> Op {\n" +
" let mut b = 42;\n" +
Expand All @@ -106,7 +96,7 @@ public void testBlockExpression() {
.matches("{\n" +
" PathBuf::from(\"/demo_dir/\")\n" +
" }")
.matches("{PathBuf::from(r\"C:\\demo_dir\\\")}")
.matches("{PathBuf::from(r\"C:\\demodir\\\")}")
.matches("{\n" +
" if check {\n" +
" check_source_files(config, paths).res1;\n" +
Expand All @@ -115,6 +105,12 @@ public void testBlockExpression() {
" }\n" +
" Ok(())\n" +
" }")
.matches("{\n" +
" JsError {} \n" +
"}")
.matches("{\n" +
" continue 'outer;\n" +
"}")



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class CallExpressionTest {
@Test
public void testCallParams() {
assertThat(RustGrammar.create().build().rule(RustGrammar.CALL_PARAMS))
//.matches("")
.matches("..")
.matches("1i32")
.matches("{let y=42;}")
.matches("{;}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,28 @@

public class ExpressionTest {

@Test
public void testExpressionExceptStruct() {
assertThat(RustGrammar.create().build().rule(RustGrammar.EXPRESSION_EXCEPT_STRUCT))
.matches("a")
.matches("a || b")
.matches("a() || b")
.matches("a() || b()")
.matches("a || b && c")
.notMatches("my_struct{}")
.notMatches("my_struct{}.field")
.notMatches("a || not_struct {}")
.matches("matches.value_of(\"log-level\").unwrap()")
.matches("!a || b")
.matches("a || !b")
.matches("completions.is_empty() && !did_match")
.notMatches("completions.is_empty() && !did_match { None } ")
.matches("!c")
.notMatches("!c { None }")
.matches("continue 'outer")

;
}

@Test
public void testExpression() {
Expand Down Expand Up @@ -85,6 +106,13 @@ public void testExpression() {
" Ok(())\n" +
" }\n" +
" .boxed_local()")
.notMatches("is_ok {\n" +
" // empty block" +
" } ")
.matches("..")
.matches("break 42")
.matches("break Ok(Poll::Pending)")

;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public void testExpressionWithBlock() {
.matches("if run_coverage {\n" +
" println!(\"Coverage is running\");" +
" } ")
.matches("async move {}")
.notMatches("async move {}.f()")
.matches("async move {\n" +
" if check {\n" +
" check_source_files(config, paths).await?;\n" +
Expand All @@ -47,6 +49,7 @@ public void testExpressionWithBlock() {
" }\n" +
" Ok(())\n" +
" }")
.notMatches("async {}.inc()")
;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ public class ExpressionWithoutBlockTest {
public void testExpressionWithoutBlock() {
assertThat(RustGrammar.create().build().rule(RustGrammar.EXPRESSION_WITHOUT_BLOCK))
.notMatches("== b")
//TODO Litteral Expression
//TODO Path expression
//Operator expressdions
//borrow expr
.matches("&7")
.matches("& Value")
.matches("&mut array")
Expand All @@ -41,14 +37,14 @@ public void testExpressionWithoutBlock() {
.matches("&&&& mut 10")
.matches("&& && mut 10")
.matches("& & & & mut 10")
//deref
.matches("*thing")
//err propagation
.matches("foo?")

.matches("*thing") //deref

.matches("foo?")//err propagation
.matches("None?")
.matches("Some(42)?")
//negation expression
.matches("!foo")

.matches("!foo")//negation expression
.matches("-5")
.matches("-bar")
.notMatches("== b")
Expand Down Expand Up @@ -84,6 +80,7 @@ public void testExpressionWithoutBlock() {
//TODO TupleExpression
//TODO TupleIndexingExpression
//TODO StructExpression
.matches("mystruct{}")
//TODO EnumerationVariantExpression
// CallExpression

Expand All @@ -94,13 +91,14 @@ public void testExpressionWithoutBlock() {
//MethodCallExpression
//
//

.matches("async move {}.local()")
.matches("\"123\".parse()")
.matches("node_fetch::create_http_client(user_agent.clone(), my_data.clone()).unwrap()")
//FieldExpression
.matches("other.major")
//TODO ClosureExpression
//TODO ContinueExpression
//ContinueExpression
.matches("continue 'outer")
//TODO BreakExpression
//TODO RangeExpression
//ReturnExpression
Expand All @@ -116,6 +114,14 @@ public void testExpressionWithoutBlock() {
.matches("Vec::new")
.matches("Identifier::Numeric")
.matches("&[b' ', b' ', b' '][0..(4 - (len & 3)) & 3]")
.matches("async move {}.await")
.matches("async move {}.local()")
.matches("async {}.inc()")

.matches("async move {}\n" +
" .boxed()")


;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ public void tesIfExpression() {
.matches("if run_coverage {\n" +
" println!(\"Coverage is running\");" +
" } ")
.matches("if is_ok {} ")
.matches("if if_ok {} ")
.matches("if match_ok {} ")
.matches("if async_ok {} ")
.matches("if is_red || is_black {let cpt = 1 ;} else {let cpt = 0 ;}")
.matches("if is_red || is_black {}")
.matches("if is_red || is_black {} else {let cpt = 0 ;}")
.matches("if is_ok {\n" +
" // empty block\n" +
" } ")
.matches("if is_ok {} else {let x = 42;}")
.matches("if is_ok {\n" +
" // empty block\n" +
" } else {let x = 42;}")
.matches("if bytes.len() < 3 * 4 {\n" +
" println!(\"Too short\");" +
" }")
Expand Down Expand Up @@ -68,6 +82,38 @@ public void tesIfExpression() {
" }\n" +
" }\n" +
" }")
.matches("if is_ok \n" +
" {} else {\n" +
" let msg = \"Module evaluation is still pending but there are no pending ops or dynamic imports. This situation is often caused by unresolved promise.\";\n" +
" return Poll::Ready(Err(generic_error(msg)));\n" +
" }")
.matches("if is_ops || has_pending_dyn_imports || has_pending_dyn_module_evaluation\n" +
" {} else {\n" +
" let msg = \"Module evaluation is still pending but there are no pending ops or dynamic imports. This situation is often caused by unresolved promise.\";\n" +
" return Poll::Ready(Err(generic_error(msg)));\n" +
" }")
.matches("if has_ops\n" +
" || has_pending_dyn_imports\n" +
" || has_pending_dyn_module_evaluation\n" +
" {} else {\n" +
" let msg = \"Module evaluation is still pending but there are no pending ops or dynamic imports. This situation is often caused by unresolved promise.\";\n" +
" return Poll::Ready(Err(generic_error(msg)));\n" +
" }")
.matches("if has_pending_ops\n" +
" || has_pending_dyn_imports\n" +
" || has_pending_dyn_module_evaluation\n" +
" {\n" +
" // pass, will be polled again\n" +
" } else {\n" +
" let msg = \"Module evaluation is still pending but there are no pending ops or dynamic imports. This situation is often caused by unresolved promise.\";\n" +
" return Poll::Ready(Err(generic_error(msg)));\n" +
" }")
.matches("if a && b { None }")
.matches("if !c { None }")
.matches("if a && !b { None }")
.matches("if state.get_state() == MyState::KO {\n" +
" continue 'outer;\n" +
" }")


;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@

public class LoopExpressionTest {

@Test
public void testBreakExpression() {
assertThat(RustGrammar.create().build().rule(RustGrammar.BREAK_EXPRESSION))
.matches("break")
.matches("break 42")
.matches("break foo")
.matches("break a.method()")
.matches("break 'a b.method()")
.matches("break Ok(Poll::Pending)")
;
}

@Test
public void testContinueExpression() {
assertThat(RustGrammar.create().build().rule(RustGrammar.CONTINUE_EXPRESSION))
.matches("continue 'outer")

;
}

@Test
public void testLoopExpression() {
assertThat(RustGrammar.create().build().rule(RustGrammar.LOOP_EXPRESSION))
Expand All @@ -50,6 +70,10 @@ public void testLoopExpression() {
.matches("for n in 1..11 {\n" +
" sum += n;\n" +
"}")
.matches("while i < j {\n" +
" println!(\"hello\");\n" +
" i = i + 1;\n" +
"}")
;
}
}
Loading