Skip to content

Commit

Permalink
Recover class Foo { .. } as struct (FuelLabs#2751)
Browse files Browse the repository at this point in the history
* recover 'class Foo { .. }' as struct

* class => struct recovery: tweak wording

Co-authored-by: Mohammad Fawaz <[email protected]>
  • Loading branch information
Centril and mohammadfawaz authored Sep 12, 2022
1 parent 227db1d commit ff038fb
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 5 deletions.
1 change: 1 addition & 0 deletions sway-ast/src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ define_keyword!(PubToken, "pub");
define_keyword!(UseToken, "use");
define_keyword!(AsToken, "as");
define_keyword!(StructToken, "struct");
define_keyword!(ClassToken, "class"); // Not in the language! Exists for recovery.
define_keyword!(EnumToken, "enum");
define_keyword!(SelfToken, "self");
define_keyword!(FnToken, "fn");
Expand Down
2 changes: 2 additions & 0 deletions sway-parse/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ pub enum ParseErrorKind {
UnnecessaryVisibilityQualifier { visibility: Ident },
#[error("Expected a doc comment.")]
ExpectedDocComment,
#[error("Use the `struct` keyword to define records, instead of `class`.")]
UnexpectedClass,
}

#[derive(Debug, Error, Clone, PartialEq, Eq, Hash)]
Expand Down
15 changes: 12 additions & 3 deletions sway-parse/src/item/item_struct.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
use crate::{Parse, ParseResult, Parser};
use crate::{Parse, ParseErrorKind, ParseResult, Parser};

use sway_ast::keywords::{OpenAngleBracketToken, WhereToken};
use sway_ast::keywords::{ClassToken, Keyword, OpenAngleBracketToken, StructToken, WhereToken};
use sway_ast::ItemStruct;
use sway_types::Spanned;

impl Parse for ItemStruct {
fn parse(parser: &mut Parser) -> ParseResult<ItemStruct> {
// Parse `struct`, or recover on `class` as if `struct` was written.
let struct_token = if let Some(ct) = parser.take::<ClassToken>() {
parser.emit_error(ParseErrorKind::UnexpectedClass);
StructToken::new(ct.span())
} else {
parser.parse()?
};

Ok(ItemStruct {
visibility: None,
struct_token: parser.parse()?,
struct_token,
name: parser.parse()?,
generics: parser.guarded_parse::<OpenAngleBracketToken, _>()?,
where_clause_opt: parser.guarded_parse::<WhereToken, _>()?,
Expand Down
8 changes: 6 additions & 2 deletions sway-parse/src/item/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::{Parse, ParseErrorKind, ParseResult, ParseToEnd, Parser, ParserConsumed};

use sway_ast::keywords::{
AbiToken, ConstToken, EnumToken, FnToken, ImplToken, MutToken, OpenAngleBracketToken, RefToken,
SelfToken, StorageToken, StructToken, TraitToken, UseToken, WhereToken,
AbiToken, ClassToken, ConstToken, EnumToken, FnToken, ImplToken, MutToken,
OpenAngleBracketToken, RefToken, SelfToken, StorageToken, StructToken, TraitToken, UseToken,
WhereToken,
};
use sway_ast::{
FnArg, FnArgs, FnSignature, ItemConst, ItemEnum, ItemFn, ItemKind, ItemStruct, ItemTrait,
Expand Down Expand Up @@ -30,6 +31,9 @@ impl Parse for ItemKind {
let kind = if let Some(mut item) = parser.guarded_parse::<UseToken, ItemUse>()? {
item.visibility = visibility.take();
ItemKind::Use(item)
} else if let Some(mut item) = parser.guarded_parse::<ClassToken, ItemStruct>()? {
item.visibility = visibility.take();
ItemKind::Struct(item)
} else if let Some(mut item) = parser.guarded_parse::<StructToken, ItemStruct>()? {
item.visibility = visibility.take();
ItemKind::Struct(item)
Expand Down
1 change: 1 addition & 0 deletions sway-parse/src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ keyword_impls! {
UseToken,
AsToken,
StructToken,
ClassToken,
EnumToken,
SelfToken,
FnToken,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[[package]]
name = 'recover_class_as_struct'
source = 'root'
dependencies = []
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[project]
name = "recover_class_as_struct"
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
license = "Apache-2.0"
implicit-std = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
contract;

class Foo {
}

fn bar() -> bool {
0 // recovery witness
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
category = "fail"

# check: $()Use the `struct` keyword to define records, instead of `class`.
# check: $()Mismatched types.

0 comments on commit ff038fb

Please sign in to comment.