difftreelog
fix(ir-parser) identifiers can't be reserved
in: master
1 file changed
crates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth130 message,130 message,131 }131 }132 }132 }133134 fn expect_ident(&mut self) -> Result<IStr> {135 if !self.at(SyntaxKind::IDENT) {136 return Err(self.error(format!("expected identifier, got {}", self.current_desc())));137 }138 let text = self.text();139 let s: IStr = text.into();140 self.eat_any();141 Ok(s)142 }143144 fn at_ident(&self) -> bool {145 self.at(SyntaxKind::IDENT) && !is_reserved(self.lexemes[self.offset].text)146 }147}133}148134149fn spanned<T: Acyclic>(135fn spanned<T: Acyclic>(222 Ok(n)208 Ok(n)223}209}224210211fn ident(p: &mut Parser<'_>) -> Result<IStr> {212 let text = p.text();213 p.eat(SyntaxKind::IDENT)?;214 Ok(IStr::from(text))215}216225fn literal(p: &mut Parser<'_>) -> Option<LiteralType> {217fn literal(p: &mut Parser<'_>) -> Option<LiteralType> {226 let t = match p.peek() {218 let t = match p.peek() {227 T![self] => LiteralType::This,219 T![self] => LiteralType::This,289}281}290282291fn destruct(p: &mut Parser<'_>) -> Result<Destruct> {283fn destruct(p: &mut Parser<'_>) -> Result<Destruct> {292 if p.at_ident() {284 if p.at(SyntaxKind::IDENT) {293 return Ok(Destruct::Full(p.expect_ident()?));285 return Ok(Destruct::Full(ident(p)?));294 }286 }295 #[cfg(not(feature = "exp-destruct"))]287 #[cfg(not(feature = "exp-destruct"))]296 return Err(p.error(format!("expected identifier, got {}", p.current_desc())));288 return Err(p.error(format!("expected identifier, got {}", p.current_desc())));315#[cfg(feature = "exp-destruct")]307#[cfg(feature = "exp-destruct")]316fn destruct_rest(p: &mut Parser<'_>) -> Result<jrsonnet_ir::DestructRest> {308fn destruct_rest(p: &mut Parser<'_>) -> Result<jrsonnet_ir::DestructRest> {317 p.eat(T![...])?;309 p.eat(T![...])?;318 if p.at_ident() {310 if p.at(SyntaxKind::IDENT) {319 Ok(jrsonnet_ir::DestructRest::Keep(p.expect_ident()?))311 Ok(jrsonnet_ir::DestructRest::Keep(ident(p)?))320 } else {312 } else {321 Ok(jrsonnet_ir::DestructRest::Drop)313 Ok(jrsonnet_ir::DestructRest::Drop)322 }314 }372 p.try_eat(T![,]);364 p.try_eat(T![,]);373 break;365 break;374 }366 }375 let name = p.expect_ident()?;367 let name = ident(p)?;376 let into = if p.try_eat(T![:]) {368 let into = if p.try_eat(T![:]) {377 Some(destruct(p)?)369 Some(destruct(p)?)378 } else {370 } else {430 let mut named = Vec::new();422 let mut named = Vec::new();431 let mut named_started = false;423 let mut named_started = false;432 loop {424 loop {433 let is_named = p.at_ident() && {425 let is_named = p.at(SyntaxKind::IDENT) && {434 let next_offset = p.offset + 1;426 let next_offset = p.offset + 1;435 next_offset < p.lexemes.len() && p.lexemes[next_offset].kind == T![=] && {427 next_offset < p.lexemes.len() && p.lexemes[next_offset].kind == T![=]436 let after_eq = next_offset + 1;437 after_eq >= p.lexemes.len() || p.lexemes[after_eq].kind != T![=]438 }439 };428 };440 if is_named {429 if is_named {441 let name: IStr = p.expect_ident()?;430 let name: IStr = ident(p)?;442 p.eat(T![=])?;431 p.eat(T![=])?;443 let value = Rc::new(expr(p)?);432 let value = Rc::new(expr(p)?);444 named.push((name, value));433 named.push((name, value));462fn bind(p: &mut Parser<'_>) -> Result<BindSpec> {451fn bind(p: &mut Parser<'_>) -> Result<BindSpec> {463 #[cfg(feature = "exp-destruct")]452 #[cfg(feature = "exp-destruct")]464 {453 {465 if !p.at_ident() {454 if !p.at(SyntaxKind::IDENT) {466 let d = destruct(p)?;455 let d = destruct(p)?;467 p.eat(T![=])?;456 p.eat(T![=])?;468 let value = Rc::new(expr(p)?);457 let value = Rc::new(expr(p)?);469 return Ok(BindSpec::Field { into: d, value });458 return Ok(BindSpec::Field { into: d, value });470 }459 }471 }460 }472 let name = p.expect_ident()?;461 let name = ident(p)?;473 if p.try_eat(T!['(']) {462 if p.try_eat(T!['(']) {474 let ps = params(p)?;463 let ps = params(p)?;475 p.eat(T![')'])?;464 p.eat(T![')'])?;504}493}505494506fn field_name(p: &mut Parser<'_>) -> Result<FieldName> {495fn field_name(p: &mut Parser<'_>) -> Result<FieldName> {507 if p.at_ident() {496 if p.at(SyntaxKind::IDENT) {508 Ok(FieldName::Fixed(p.expect_ident()?))497 Ok(FieldName::Fixed(ident(p)?))509 } else if is_string_token(p.peek()) {498 } else if is_string_token(p.peek()) {510 Ok(FieldName::Fixed(parse_string_content(p)?))499 Ok(FieldName::Fixed(parse_string_content(p)?))511 } else if p.at(T!['[']) {500 } else if p.at(T!['[']) {776765777 SyntaxKind::IDENT => {766 SyntaxKind::IDENT => {778 let text = p.text();767 let text = p.text();779 if is_reserved(text) {780 return Err(p.error(format!("unexpected reserved word '{text}'")));781 }782 let n = spanned(p, |p| {768 let n = spanned(p, |p| {783 let s: IStr = p.text().into();769 let s: IStr = p.text().into();784 p.eat_any();770 p.eat_any();826 });812 });827 } else {813 } else {828 // ?.field814 // ?.field829 let id_spanned = spanned(p, |p| {815 let id_spanned = spanned(p, |p| Ok(Expr::Str(ident(p)?)))?;830 let name = p.expect_ident()?;831 Ok(Expr::Str(name))832 })?;833 parts.push(IndexPart {816 parts.push(IndexPart {834 span: id_spanned.span,817 span: id_spanned.span,835 value: id_spanned.value,818 value: id_spanned.value,844827845 if p.at(T![.]) {828 if p.at(T![.]) {846 p.eat(T![.])?;829 p.eat(T![.])?;847 let id_spanned = spanned(p, |p| {830 let id_spanned = spanned(p, |p| Ok(Expr::Str(ident(p)?)))?;848 let name = p.expect_ident()?;849 Ok(Expr::Str(name))850 })?;851 parts.push(IndexPart {831 parts.push(IndexPart {852 span: id_spanned.span,832 span: id_spanned.span,853 value: id_spanned.value,833 value: id_spanned.value,