Skip to content

Commit

Permalink
Fix lexing of attributes and doc comments in Rust lexer (#957)
Browse files Browse the repository at this point in the history
A bug was causing files starting with attributes and doc comments to
produce incorrect error nodes. This commit fixes that bug while also
allowing attributes to occur in positions other than the start of a
line, bringing it in line with Rust's grammar.
  • Loading branch information
djrenren authored and pyrmont committed Jul 18, 2019
1 parent 2805d5a commit e3598c6
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 8 deletions.
19 changes: 11 additions & 8 deletions lib/rouge/lexers/rust.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def macro_closed?

start {
@macro_delims = { ']' => 0, ')' => 0, '}' => 0 }
push :bol
}

delim_map = { '[' => ']', '(' => ')', '{' => '}' }
Expand All @@ -60,20 +61,21 @@ def macro_closed?
)x
size = /8|16|32|64/

state :start_line do
# Although not officially part of Rust, the rustdoc tool allows code in
# comments to begin with `#`. Code like this will be evaluated but not
# included in the HTML output produced by rustdoc. So that code intended
# for these comments can be higlighted with Rouge, the Rust lexer needs
# to check if the beginning of the line begins with a `# `.
state :bol do
mixin :whitespace
rule %r/\s+/, Text
rule %r/#\[/ do
token Name::Decorator; push :attribute
end
rule %r/#\s[^\n]*/, Comment::Special
rule(//) { pop! }
rule %r/#\s[^\n]*/, Comment::Preproc
end

state :attribute do
mixin :whitespace
mixin :has_literals
rule %r/[(,)=]/, Name::Decorator
rule %r/[(,)=:]/, Name::Decorator
rule %r/\]/, Name::Decorator, :pop!
rule id, Name::Decorator
end
Expand All @@ -85,8 +87,9 @@ def macro_closed?
end

state :root do
rule %r/\n/, Text, :start_line
rule %r/\n/, Text, :bol
mixin :whitespace
rule %r/#!?\[/, Name::Decorator, :attribute
rule %r/\b(?:#{Rust.keywords.join('|')})\b/, Keyword
mixin :has_literals

Expand Down
1 change: 1 addition & 0 deletions spec/visual/samples/rust
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![test(a::b)]
fn f() {
let a = String::new("hello");
let b: &str = a;
Expand Down

0 comments on commit e3598c6

Please sign in to comment.