mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Disallow any keyword followed by an exclaimation mark
This commit is contained in:
parent
0acd59b4d6
commit
9e6c249dca
13 changed files with 23 additions and 83 deletions
|
@ -1,4 +1,5 @@
|
|||
use crate::ast::TryTarget;
|
||||
use crate::keyword::is_allowed_identifier;
|
||||
use crate::parser::Progress::{self, *};
|
||||
use crate::parser::{BadInputError, EExpr, ParseResult, Parser};
|
||||
use crate::state::State;
|
||||
|
@ -60,7 +61,7 @@ pub fn lowercase_ident<'a>() -> impl Parser<'a, &'a str, ()> {
|
|||
move |_, state: State<'a>, _min_indent: u32| match chomp_lowercase_part(state.bytes()) {
|
||||
Err(progress) => Err((progress, ())),
|
||||
Ok(ident) => {
|
||||
if crate::keyword::KEYWORDS.iter().any(|kw| &ident == kw) {
|
||||
if !is_allowed_identifier(&ident) {
|
||||
Err((NoProgress, ()))
|
||||
} else {
|
||||
let width = ident.len();
|
||||
|
@ -87,7 +88,7 @@ pub fn lowercase_ident_keyword_e<'a>() -> impl Parser<'a, &'a str, ()> {
|
|||
move |_, state: State<'a>, _min_indent: u32| match chomp_lowercase_part(state.bytes()) {
|
||||
Err(progress) => Err((progress, ())),
|
||||
Ok(ident) => {
|
||||
if crate::keyword::KEYWORDS.iter().any(|kw| &ident == kw) {
|
||||
if !is_allowed_identifier(&ident) {
|
||||
Err((MadeProgress, ()))
|
||||
} else {
|
||||
let width = ident.len();
|
||||
|
@ -137,7 +138,7 @@ pub fn unqualified_ident<'a>() -> impl Parser<'a, &'a str, ()> {
|
|||
move |_, state: State<'a>, _min_indent: u32| match chomp_anycase_part(state.bytes()) {
|
||||
Err(progress) => Err((progress, ())),
|
||||
Ok(ident) => {
|
||||
if crate::keyword::KEYWORDS.iter().any(|kw| &ident == kw) {
|
||||
if !is_allowed_identifier(&ident) {
|
||||
Err((MadeProgress, ()))
|
||||
} else {
|
||||
let width = ident.len();
|
||||
|
@ -166,8 +167,8 @@ pub fn parse_ident<'a>(
|
|||
if let Ident::Access { module_name, parts } = ident {
|
||||
if module_name.is_empty() {
|
||||
if let Some(first) = parts.first() {
|
||||
for keyword in crate::keyword::KEYWORDS.iter() {
|
||||
if first == &Accessor::RecordField(keyword) {
|
||||
if let Accessor::RecordField(ident) = first {
|
||||
if !is_allowed_identifier(ident) {
|
||||
return Err((NoProgress, EExpr::Start(initial.pos())));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,13 @@ pub const WHERE: &str = "where";
|
|||
// These keywords are valid in headers
|
||||
pub const PLATFORM: &str = "platform";
|
||||
|
||||
pub const KEYWORDS: [&str; 12] = [
|
||||
pub const KEYWORDS: [&str; 11] = [
|
||||
IF, THEN, ELSE, WHEN, AS, IS, DBG, IMPORT, EXPECT, RETURN, CRASH,
|
||||
"expect!", // not itself a keyword, but it's problematic if we allow an identifier like this!
|
||||
];
|
||||
|
||||
pub fn is_allowed_identifier(mut ident: &str) -> bool {
|
||||
if ident.ends_with('!') {
|
||||
ident = &ident[..ident.len() - 1];
|
||||
}
|
||||
!crate::keyword::KEYWORDS.iter().any(|kw| &ident == kw)
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Expr(Start(@0), @0)
|
|
@ -0,0 +1,3 @@
|
|||
D=return!-
|
||||
e
|
||||
z#
|
|
@ -0,0 +1 @@
|
|||
Expr(Start(@6), @0)
|
|
@ -0,0 +1 @@
|
|||
Expr(BadExprEnd(@5), @0)
|
|
@ -1 +0,0 @@
|
|||
dbg ! -(!if!)
|
|
@ -1,19 +0,0 @@
|
|||
@0-9 Apply(
|
||||
@0-3 Dbg,
|
||||
[
|
||||
@3-9 UnaryOp(
|
||||
@4-9 UnaryOp(
|
||||
@5-9 UnaryOp(
|
||||
@6-9 Var {
|
||||
module_name: "",
|
||||
ident: "if!",
|
||||
},
|
||||
@5-6 Not,
|
||||
),
|
||||
@4-5 Negate,
|
||||
),
|
||||
@3-4 Not,
|
||||
),
|
||||
],
|
||||
Space,
|
||||
)
|
|
@ -1,2 +0,0 @@
|
|||
d when!
|
||||
s
|
|
@ -1,52 +0,0 @@
|
|||
@0-14 Defs(
|
||||
Defs {
|
||||
tags: [
|
||||
EitherIndex(2147483648),
|
||||
],
|
||||
regions: [
|
||||
@0-11,
|
||||
],
|
||||
space_before: [
|
||||
Slice<roc_parse::ast::CommentOrNewline> { start: 0, length: 0 },
|
||||
],
|
||||
space_after: [
|
||||
Slice<roc_parse::ast::CommentOrNewline> { start: 0, length: 0 },
|
||||
],
|
||||
spaces: [],
|
||||
type_defs: [],
|
||||
value_defs: [
|
||||
Body(
|
||||
@0-3 RecordDestructure(
|
||||
Collection {
|
||||
items: [],
|
||||
final_comments: [
|
||||
Newline,
|
||||
],
|
||||
},
|
||||
),
|
||||
@4-11 Apply(
|
||||
@4-5 Var {
|
||||
module_name: "",
|
||||
ident: "d",
|
||||
},
|
||||
[
|
||||
@6-11 Var {
|
||||
module_name: "",
|
||||
ident: "when!",
|
||||
},
|
||||
],
|
||||
Space,
|
||||
),
|
||||
),
|
||||
],
|
||||
},
|
||||
@13-14 SpaceBefore(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "s",
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
)
|
|
@ -190,6 +190,8 @@ mod test_snapshots {
|
|||
fail/backpassing_after_annotation.expr,
|
||||
fail/bound_variable.expr,
|
||||
fail/comment_with_tab.expr,
|
||||
fail/d_assign_return_bang.expr,
|
||||
fail/dbg_bang_neg_bang_if_bang.expr,
|
||||
fail/def_missing_final_expression.expr,
|
||||
fail/def_without_newline.expr,
|
||||
fail/deprecated_interpolated_string.expr,
|
||||
|
@ -197,6 +199,7 @@ mod test_snapshots {
|
|||
fail/elm_function_syntax.expr,
|
||||
fail/empty_or_pattern.expr,
|
||||
fail/empty_record_assign_expect_bang.expr,
|
||||
fail/empty_record_assignment_d_when_bang.expr,
|
||||
fail/empty_return.expr,
|
||||
fail/error_inline_alias_argument_uppercase.expr,
|
||||
fail/error_inline_alias_not_an_alias.expr,
|
||||
|
@ -387,7 +390,6 @@ mod test_snapshots {
|
|||
pass/crazy_pat_ann.expr,
|
||||
pass/curried_function_type.expr,
|
||||
pass/dbg.expr,
|
||||
pass/dbg_bang_neg_bang_if_bang.expr,
|
||||
pass/dbg_double.expr,
|
||||
pass/dbg_double_newline.expr,
|
||||
pass/dbg_extra_parens.expr,
|
||||
|
@ -421,7 +423,6 @@ mod test_snapshots {
|
|||
pass/empty_record_assign_return.expr,
|
||||
pass/empty_record_assign_tag.expr,
|
||||
pass/empty_record_assignment.expr,
|
||||
pass/empty_record_assignment_d_when_bang.expr,
|
||||
pass/empty_record_eq_dbg.expr,
|
||||
pass/empty_record_eq_newlines_doubleeq.expr,
|
||||
pass/empty_record_newline_assign.expr,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue