mirror of
https://github.com/typst/typst
synced 2025-05-21 04:25:28 +08:00
Give more specific error messages (#881)
This commit is contained in:
parent
e4b09d417e
commit
dc3017955a
@ -158,7 +158,13 @@ impl Args {
|
||||
/// argument.
|
||||
pub fn finish(self) -> SourceResult<()> {
|
||||
if let Some(arg) = self.items.first() {
|
||||
bail!(arg.span, "unexpected argument");
|
||||
bail!(
|
||||
arg.span,
|
||||
match &arg.name {
|
||||
Some(name) => eco_format!("unexpected argument: {}", name),
|
||||
_ => eco_format!("unexpected argument"),
|
||||
}
|
||||
)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use std::collections::BTreeMap;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::hash::Hash;
|
||||
|
||||
use ecow::EcoString;
|
||||
use ecow::{eco_format, EcoString};
|
||||
|
||||
use super::{Library, Value};
|
||||
use crate::diag::StrResult;
|
||||
@ -42,7 +42,7 @@ impl<'a> Scopes<'a> {
|
||||
.chain(self.scopes.iter().rev())
|
||||
.chain(self.base.map(|base| base.global.scope()))
|
||||
.find_map(|scope| scope.get(var))
|
||||
.ok_or("unknown variable")?)
|
||||
.ok_or(eco_format!("unknown variable: {}", var))?)
|
||||
}
|
||||
|
||||
/// Try to access a variable immutably in math.
|
||||
@ -51,7 +51,7 @@ impl<'a> Scopes<'a> {
|
||||
.chain(self.scopes.iter().rev())
|
||||
.chain(self.base.map(|base| base.math.scope()))
|
||||
.find_map(|scope| scope.get(var))
|
||||
.ok_or("unknown variable")?)
|
||||
.ok_or(eco_format!("unknown variable: {}", var))?)
|
||||
}
|
||||
|
||||
/// Try to access a variable mutably.
|
||||
@ -61,8 +61,8 @@ impl<'a> Scopes<'a> {
|
||||
.find_map(|scope| scope.get_mut(var))
|
||||
.ok_or_else(|| {
|
||||
match self.base.and_then(|base| base.global.scope().get(var)) {
|
||||
Some(_) => "cannot mutate a constant",
|
||||
_ => "unknown variable",
|
||||
Some(_) => eco_format!("cannot mutate a constant: {}", var),
|
||||
_ => eco_format!("unknown variable: {}", var),
|
||||
}
|
||||
})?
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ impl Lexer<'_> {
|
||||
.and_then(std::char::from_u32)
|
||||
.is_none()
|
||||
{
|
||||
return self.error("invalid unicode escape sequence");
|
||||
return self.error(eco_format!("invalid unicode codepoint: {}", hex));
|
||||
}
|
||||
|
||||
return SyntaxKind::Escape;
|
||||
@ -585,10 +585,10 @@ impl Lexer<'_> {
|
||||
SyntaxKind::Float
|
||||
} else {
|
||||
return self.error(match base {
|
||||
2 => "invalid binary number",
|
||||
8 => "invalid octal number",
|
||||
16 => "invalid hexadecimal number",
|
||||
_ => "invalid number",
|
||||
2 => eco_format!("invalid binary number: 0b{}", number),
|
||||
8 => eco_format!("invalid octal number: 0o{}", number),
|
||||
16 => eco_format!("invalid hexadecimal number: 0x{}", number),
|
||||
_ => eco_format!("invalid number: {}", number),
|
||||
});
|
||||
};
|
||||
|
||||
@ -600,7 +600,7 @@ impl Lexer<'_> {
|
||||
suffix,
|
||||
"pt" | "mm" | "cm" | "in" | "deg" | "rad" | "em" | "fr" | "%"
|
||||
) {
|
||||
return self.error("invalid number suffix");
|
||||
return self.error(eco_format!("invalid number suffix: {}", suffix));
|
||||
}
|
||||
|
||||
SyntaxKind::Numeric
|
||||
|
@ -1046,8 +1046,8 @@ fn validate_dict(p: &mut Parser, m: Marker) {
|
||||
None => first.text().clone(),
|
||||
};
|
||||
|
||||
if !used.insert(key) {
|
||||
first.convert_to_error("duplicate key");
|
||||
if !used.insert(key.clone()) {
|
||||
first.convert_to_error(eco_format!("duplicate key: {}", key));
|
||||
child.make_erroneous();
|
||||
}
|
||||
}
|
||||
@ -1073,13 +1073,19 @@ fn validate_params(p: &mut Parser, m: Marker) {
|
||||
match child.kind() {
|
||||
SyntaxKind::Ident => {
|
||||
if !used.insert(child.text().clone()) {
|
||||
child.convert_to_error("duplicate parameter");
|
||||
child.convert_to_error(eco_format!(
|
||||
"duplicate parameter: {}",
|
||||
child.text()
|
||||
));
|
||||
}
|
||||
}
|
||||
SyntaxKind::Named => {
|
||||
let Some(within) = child.children_mut().first_mut() else { return };
|
||||
if !used.insert(within.text().clone()) {
|
||||
within.convert_to_error("duplicate parameter");
|
||||
within.convert_to_error(eco_format!(
|
||||
"duplicate parameter: {}",
|
||||
within.text()
|
||||
));
|
||||
child.make_erroneous();
|
||||
}
|
||||
}
|
||||
@ -1101,7 +1107,10 @@ fn validate_params(p: &mut Parser, m: Marker) {
|
||||
continue;
|
||||
}
|
||||
if !used.insert(within.text().clone()) {
|
||||
within.convert_to_error("duplicate parameter");
|
||||
within.convert_to_error(eco_format!(
|
||||
"duplicate parameter: {}",
|
||||
within.text()
|
||||
));
|
||||
child.make_erroneous();
|
||||
}
|
||||
}
|
||||
@ -1122,7 +1131,10 @@ fn validate_args(p: &mut Parser, m: Marker) {
|
||||
if child.kind() == SyntaxKind::Named {
|
||||
let Some(within) = child.children_mut().first_mut() else { return };
|
||||
if !used.insert(within.text().clone()) {
|
||||
within.convert_to_error("duplicate argument");
|
||||
within.convert_to_error(eco_format!(
|
||||
"duplicate argument: {}",
|
||||
within.text()
|
||||
));
|
||||
child.make_erroneous();
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +224,7 @@
|
||||
// Error: 4-6 unexpected end of block comment
|
||||
#(1*/2)
|
||||
|
||||
// Error: 6-8 invalid number suffix
|
||||
// Error: 6-8 invalid number suffix: u
|
||||
#(1, 1u 2)
|
||||
|
||||
// Error: 3-4 unexpected comma
|
||||
|
@ -61,7 +61,7 @@
|
||||
// Block directly in markup also creates a scope.
|
||||
#{ let x = 1 }
|
||||
|
||||
// Error: 7-8 unknown variable
|
||||
// Error: 7-8 unknown variable: x
|
||||
#test(x, 1)
|
||||
|
||||
---
|
||||
@ -73,7 +73,7 @@
|
||||
|
||||
#test(a, 1)
|
||||
|
||||
// Error: 3-4 unknown variable
|
||||
// Error: 3-4 unknown variable: b
|
||||
#{b}
|
||||
|
||||
---
|
||||
@ -83,7 +83,7 @@
|
||||
test(b, 1)
|
||||
}}
|
||||
|
||||
// Error: 2-3 unknown variable
|
||||
// Error: 2-3 unknown variable: b
|
||||
#b
|
||||
|
||||
---
|
||||
@ -106,13 +106,13 @@
|
||||
// Content blocks also create a scope.
|
||||
#[#let x = 1]
|
||||
|
||||
// Error: 2-3 unknown variable
|
||||
// Error: 2-3 unknown variable: x
|
||||
#x
|
||||
|
||||
---
|
||||
// Multiple unseparated expressions in one line.
|
||||
|
||||
// Error: 2-4 invalid number suffix
|
||||
// Error: 2-4 invalid number suffix: u
|
||||
#1u
|
||||
|
||||
// Should output `1`.
|
||||
|
@ -44,7 +44,7 @@
|
||||
}
|
||||
|
||||
---
|
||||
// Error: 26-30 duplicate argument
|
||||
// Error: 26-30 duplicate argument: font
|
||||
#set text(font: "Arial", font: "Helvetica")
|
||||
|
||||
---
|
||||
|
@ -106,7 +106,7 @@
|
||||
---
|
||||
// Don't leak environment.
|
||||
#{
|
||||
// Error: 16-17 unknown variable
|
||||
// Error: 16-17 unknown variable: x
|
||||
let func() = x
|
||||
let x = "hi"
|
||||
func()
|
||||
@ -141,22 +141,22 @@
|
||||
test(greet("Typst"), "Hey, Typst!")
|
||||
test(greet("Typst", birthday: true), "Happy Birthday, Typst!")
|
||||
|
||||
// Error: 23-35 unexpected argument
|
||||
// Error: 23-35 unexpected argument: whatever
|
||||
test(greet("Typst", whatever: 10))
|
||||
}
|
||||
|
||||
---
|
||||
// Error: 11-12 duplicate parameter
|
||||
// Error: 11-12 duplicate parameter: x
|
||||
#let f(x, x) = none
|
||||
|
||||
---
|
||||
// Error: 14-15 duplicate parameter
|
||||
// Error: 23-24 duplicate parameter
|
||||
// Error: 35-36 duplicate parameter
|
||||
// Error: 14-15 duplicate parameter: a
|
||||
// Error: 23-24 duplicate parameter: b
|
||||
// Error: 35-36 duplicate parameter: b
|
||||
#let f(a, b, a: none, b: none, c, b) = none
|
||||
|
||||
---
|
||||
// Error: 13-14 duplicate parameter
|
||||
// Error: 13-14 duplicate parameter: a
|
||||
#let f(a, ..a) = none
|
||||
|
||||
---
|
||||
|
@ -56,11 +56,11 @@
|
||||
#test(dict, (a: 3, b: 1))
|
||||
|
||||
---
|
||||
// Error: 24-29 duplicate key
|
||||
// Error: 24-29 duplicate key: first
|
||||
#(first: 1, second: 2, first: 3)
|
||||
|
||||
---
|
||||
// Error: 17-20 duplicate key
|
||||
// Error: 17-20 duplicate key: a
|
||||
#(a: 1, "b": 2, "a": 3)
|
||||
|
||||
---
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "modules/chap1.typ"
|
||||
|
||||
// The variables of the file should not appear in this scope.
|
||||
// Error: 2-6 unknown variable
|
||||
// Error: 2-6 unknown variable: name
|
||||
#name
|
||||
|
||||
---
|
||||
|
@ -42,5 +42,5 @@
|
||||
#(numbers.sorted() = 1)
|
||||
|
||||
---
|
||||
// Error: 2-5 cannot mutate a constant
|
||||
// Error: 2-5 cannot mutate a constant: box
|
||||
#box.push(1)
|
||||
|
@ -97,7 +97,7 @@
|
||||
}
|
||||
|
||||
---
|
||||
// Error: 4-5 unknown variable
|
||||
// Error: 4-5 unknown variable: x
|
||||
#((x) = "")
|
||||
|
||||
---
|
||||
@ -110,15 +110,15 @@
|
||||
#(not x = "a")
|
||||
|
||||
---
|
||||
// Error: 7-8 unknown variable
|
||||
// Error: 7-8 unknown variable: x
|
||||
#(1 + x += 3)
|
||||
|
||||
---
|
||||
// Error: 3-4 unknown variable
|
||||
// Error: 3-4 unknown variable: z
|
||||
#(z = 1)
|
||||
|
||||
---
|
||||
// Error: 3-7 cannot mutate a constant
|
||||
// Error: 3-7 cannot mutate a constant: rect
|
||||
#(rect = "hi")
|
||||
|
||||
---
|
||||
|
@ -116,11 +116,11 @@
|
||||
#test(0xA + 0xa, 0x14)
|
||||
|
||||
---
|
||||
// Error: 2-7 invalid binary number
|
||||
// Error: 2-7 invalid binary number: 0b123
|
||||
#0b123
|
||||
|
||||
---
|
||||
// Error: 2-8 invalid hexadecimal number
|
||||
// Error: 2-8 invalid hexadecimal number: 0x123z
|
||||
#0x123z
|
||||
|
||||
---
|
||||
@ -201,7 +201,7 @@
|
||||
#(x += "thing") #test(x, "something")
|
||||
|
||||
---
|
||||
// Error: 3-6 cannot mutate a constant
|
||||
// Error: 3-6 cannot mutate a constant: box
|
||||
#(box = 1)
|
||||
|
||||
---
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
---
|
||||
// Test with unnamed function.
|
||||
// Error: 17-18 unknown variable
|
||||
// Error: 17-18 unknown variable: f
|
||||
#let f = (n) => f(n - 1)
|
||||
#f(10)
|
||||
|
||||
|
@ -27,7 +27,7 @@ let f() , ; : | + - /= == 12 "string"
|
||||
|
||||
---
|
||||
// Unicode codepoint does not exist.
|
||||
// Error: 1-11 invalid unicode escape sequence
|
||||
// Error: 1-11 invalid unicode codepoint: FFFFFF
|
||||
\u{FFFFFF}
|
||||
|
||||
---
|
||||
|
@ -56,5 +56,5 @@ Emoji: 🐪, 🌋, 🏞
|
||||
#set text(size: 10pt, 12pt)
|
||||
|
||||
---
|
||||
// Error: 11-31 unexpected argument
|
||||
// Error: 11-31 unexpected argument: something
|
||||
#set text(something: "invalid")
|
||||
|
@ -54,5 +54,5 @@ Expanded by height.
|
||||
|
||||
---
|
||||
// Radius wins over width and height.
|
||||
// Error: 23-34 unexpected argument
|
||||
// Error: 23-34 unexpected argument: width
|
||||
#circle(radius: 10pt, width: 50pt, height: 100pt, fill: eastern)
|
||||
|
@ -35,5 +35,5 @@
|
||||
|
||||
---
|
||||
// Size wins over width and height.
|
||||
// Error: 09-20 unexpected argument
|
||||
// Error: 09-20 unexpected argument: width
|
||||
#square(width: 10cm, height: 20cm, size: 1cm, fill: rgb("eb5278"))
|
||||
|
Loading…
x
Reference in New Issue
Block a user