mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Even shorter error annotations
Error annotations are now relative to the first following non-comment line.
This commit is contained in:
parent
4fb58acafd
commit
9950627789
@ -24,8 +24,8 @@
|
|||||||
// Error: 2-3 expected expression, found closing paren
|
// Error: 2-3 expected expression, found closing paren
|
||||||
{)}
|
{)}
|
||||||
|
|
||||||
// Error: 2:4 expected comma
|
// Error: 4 expected comma
|
||||||
// Error: 1:4-1:6 expected expression, found end of block comment
|
// Error: 4-6 expected expression, found end of block comment
|
||||||
{(1*/2)}
|
{(1*/2)}
|
||||||
|
|
||||||
// Error: 6-8 expected expression, found invalid token
|
// Error: 6-8 expected expression, found invalid token
|
||||||
|
@ -7,13 +7,13 @@
|
|||||||
{1u}
|
{1u}
|
||||||
|
|
||||||
// Should output `1`.
|
// Should output `1`.
|
||||||
// Error: 2:3 expected semicolon or line break
|
// Error: 3 expected semicolon or line break
|
||||||
// Error: 1:4-1:5 cannot join integer with integer
|
// Error: 4-5 cannot join integer with integer
|
||||||
{1 2}
|
{1 2}
|
||||||
|
|
||||||
// Should output `2`.
|
// Should output `2`.
|
||||||
// Error: 2:12 expected semicolon or line break
|
// Error: 12 expected semicolon or line break
|
||||||
// Error: 1:22 expected semicolon or line break
|
// Error: 22 expected semicolon or line break
|
||||||
{let x = -1 let y = 3 x + y}
|
{let x = -1 let y = 3 x + y}
|
||||||
|
|
||||||
// Should output `3`.
|
// Should output `3`.
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
// Error: 8 expected comma
|
// Error: 8 expected comma
|
||||||
#args(1 2)
|
#args(1 2)
|
||||||
|
|
||||||
// Error: 2:7-2:8 expected identifier
|
// Error: 7-8 expected identifier
|
||||||
// Error: 1:9 expected expression
|
// Error: 9 expected expression
|
||||||
#args(1:)
|
#args(1:)
|
||||||
|
|
||||||
// Error: 7-8 expected identifier
|
// Error: 7-8 expected identifier
|
||||||
@ -34,6 +34,6 @@
|
|||||||
{args(}
|
{args(}
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 3:1 expected quote
|
// Error: 2:1 expected quote
|
||||||
// Error: 2:1 expected closing paren
|
// Error: 2:1 expected closing paren
|
||||||
#args("]
|
#args("]
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
{
|
{
|
||||||
let f(x) = x + 1
|
let f(x) = x + 1
|
||||||
|
|
||||||
// Error: 2:10-2:15 unexpected argument
|
// Error: 10-15 unexpected argument
|
||||||
// Error: 1:17-1:24 unexpected argument
|
// Error: 17-24 unexpected argument
|
||||||
f(1, "two", () => x)
|
f(1, "two", () => x)
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ https:/* block comments don't ... */
|
|||||||
|
|
||||||
---
|
---
|
||||||
// End should not appear without start.
|
// End should not appear without start.
|
||||||
// Error: 1:7-1:9 unexpected end of block comment
|
// Error: 7-9 unexpected end of block comment
|
||||||
/* */ */
|
/* */ */
|
||||||
|
|
||||||
// Unterminated is okay.
|
// Unterminated is okay.
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
{(a: 1, b)}
|
{(a: 1, b)}
|
||||||
|
|
||||||
// Identified as dictionary due to initial colon.
|
// Identified as dictionary due to initial colon.
|
||||||
// Error: 4:4-4:5 expected named pair, found expression
|
// Error: 4-5 expected named pair, found expression
|
||||||
// Error: 3:5 expected comma
|
// Error: 5 expected comma
|
||||||
// Error: 2:12-2:16 expected identifier
|
// Error: 12-16 expected identifier
|
||||||
// Error: 1:17-1:18 expected expression, found colon
|
// Error: 17-18 expected expression, found colon
|
||||||
{(:1 b:"", true::)}
|
{(:1 b:"", true::)}
|
||||||
|
@ -69,23 +69,23 @@
|
|||||||
---
|
---
|
||||||
// Test bad syntax.
|
// Test bad syntax.
|
||||||
|
|
||||||
// Error: 2:8 expected import items
|
// Error: 8 expected import items
|
||||||
// Error: 1:8 expected keyword `from`
|
// Error: 8 expected keyword `from`
|
||||||
#import
|
#import
|
||||||
|
|
||||||
// Error: 2:9-2:19 expected identifier
|
// Error: 9-19 expected identifier
|
||||||
// Error: 1:19 expected keyword `from`
|
// Error: 19 expected keyword `from`
|
||||||
#import "file.typ"
|
#import "file.typ"
|
||||||
|
|
||||||
// Error: 2:16-2:19 expected identifier
|
// Error: 16-19 expected identifier
|
||||||
// Error: 1:22 expected keyword `from`
|
// Error: 22 expected keyword `from`
|
||||||
#import afrom, "b", c
|
#import afrom, "b", c
|
||||||
|
|
||||||
// Error: 8 expected import items
|
// Error: 8 expected import items
|
||||||
#import from "target.typ"
|
#import from "target.typ"
|
||||||
|
|
||||||
// Error: 2:9-2:10 expected expression, found assignment operator
|
// Error: 9-10 expected expression, found assignment operator
|
||||||
// Error: 1:10 expected import items
|
// Error: 10 expected import items
|
||||||
#import = from "target.typ"
|
#import = from "target.typ"
|
||||||
|
|
||||||
// Error: 15 expected expression
|
// Error: 15 expected expression
|
||||||
@ -100,7 +100,7 @@
|
|||||||
#from "target.typ"
|
#from "target.typ"
|
||||||
|
|
||||||
// Should output `target`.
|
// Should output `target`.
|
||||||
// Error: 2:16-3:2 file not found
|
// Error: 1:16-2:2 file not found
|
||||||
// Error: 2:2 expected semicolon or line break
|
// Error: 2:2 expected semicolon or line break
|
||||||
#import * from "target.typ
|
#import * from "target.typ
|
||||||
"target
|
"target
|
||||||
@ -110,8 +110,8 @@
|
|||||||
#import * from "target.typ" @ 0.2.1
|
#import * from "target.typ" @ 0.2.1
|
||||||
|
|
||||||
// A star in the list.
|
// A star in the list.
|
||||||
// Error: 2:12-2:13 expected expression, found star
|
// Error: 12-13 expected expression, found star
|
||||||
// Error: 1:13-1:14 expected expression, found comma
|
// Error: 13-14 expected expression, found comma
|
||||||
#import a, *, b from "target.typ"
|
#import a, *, b from "target.typ"
|
||||||
|
|
||||||
// An item after a star.
|
// An item after a star.
|
||||||
|
@ -52,8 +52,8 @@ Three
|
|||||||
#let v4 = 4 Four
|
#let v4 = 4 Four
|
||||||
|
|
||||||
// Terminated by semicolon even though we are in a paren group.
|
// Terminated by semicolon even though we are in a paren group.
|
||||||
// Error: 2:19 expected expression
|
// Error: 19 expected expression
|
||||||
// Error: 1:19 expected closing paren
|
// Error: 19 expected closing paren
|
||||||
#let v5 = (1, 2 + ; Five
|
#let v5 = (1, 2 + ; Five
|
||||||
|
|
||||||
#test(v1, 1)
|
#test(v1, 1)
|
||||||
|
@ -25,14 +25,14 @@
|
|||||||
// Error: 2-8 cannot apply 'not' to array
|
// Error: 2-8 cannot apply 'not' to array
|
||||||
{not ()}
|
{not ()}
|
||||||
|
|
||||||
// Error: 1:2-1:12 cannot apply '<=' to relative and relative
|
// Error: 2-12 cannot apply '<=' to relative and relative
|
||||||
{30% <= 40%}
|
{30% <= 40%}
|
||||||
|
|
||||||
// Special messages for +, -, * and /.
|
// Special messages for +, -, * and /.
|
||||||
// Error: 4:03-4:10 cannot add integer and string
|
// Error: 03-10 cannot add integer and string
|
||||||
// Error: 3:12-3:19 cannot subtract integer from relative
|
// Error: 12-19 cannot subtract integer from relative
|
||||||
// Error: 2:21-2:29 cannot multiply integer with boolean
|
// Error: 21-29 cannot multiply integer with boolean
|
||||||
// Error: 1:31-1:39 cannot divide integer by length
|
// Error: 31-39 cannot divide integer by length
|
||||||
{(1 + "2", 40% - 1, 2 * true, 3 / 12pt)}
|
{(1 + "2", 40% - 1, 2 * true, 3 / 12pt)}
|
||||||
|
|
||||||
// Error: 14-22 cannot apply '+=' to integer and string
|
// Error: 14-22 cannot apply '+=' to integer and string
|
||||||
|
@ -38,8 +38,8 @@ Expanded by height.
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Radius wins over width and height.
|
// Radius wins over width and height.
|
||||||
// Error: 2:23-2:34 unexpected argument
|
// Error: 23-34 unexpected argument
|
||||||
// Error: 1:36-1:49 unexpected argument
|
// Error: 36-49 unexpected argument
|
||||||
#circle(radius: 10pt, width: 50pt, height: 100pt, fill: eastern)
|
#circle(radius: 10pt, width: 50pt, height: 100pt, fill: eastern)
|
||||||
|
|
||||||
// Width wins over height.
|
// Width wins over height.
|
||||||
|
@ -11,8 +11,8 @@ Auto-sized square. \
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Length wins over width and height.
|
// Length wins over width and height.
|
||||||
// Error: 2:9-2:20 unexpected argument
|
// Error: 09-20 unexpected argument
|
||||||
// Error: 1:22-1:34 unexpected argument
|
// Error: 22-34 unexpected argument
|
||||||
#square(width: 10cm, height: 20cm, length: 1cm, fill: rgb("eb5278"))
|
#square(width: 10cm, height: 20cm, length: 1cm, fill: rgb("eb5278"))
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -59,9 +59,9 @@ Emoji: 🐪, 🌋, 🏞
|
|||||||
// Error: 7-12 unexpected argument
|
// Error: 7-12 unexpected argument
|
||||||
#font(false)[]
|
#font(false)[]
|
||||||
|
|
||||||
// Error: 3:14-3:18 expected font style, found font weight
|
// Error: 14-18 expected font style, found font weight
|
||||||
// Error: 2:28-2:34 expected font weight, found string
|
// Error: 28-34 expected font weight, found string
|
||||||
// Error: 1:43-1:44 expected string or array of strings, found integer
|
// Error: 43-44 expected string or array of strings, found integer
|
||||||
#font(style: bold, weight: "thin", serif: 0)[]
|
#font(style: bold, weight: "thin", serif: 0)[]
|
||||||
|
|
||||||
// Warning: 15-19 should be between 100 and 900
|
// Warning: 15-19 should be between 100 and 900
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
// Alpha channel.
|
// Alpha channel.
|
||||||
#test(rgb(1.0, 0.0, 0.0, 0.5), rgb("ff000080"))
|
#test(rgb(1.0, 0.0, 0.0, 0.5), rgb("ff000080"))
|
||||||
|
|
||||||
// Warning: 2:11-2:14 should be between 0.0 and 1.0
|
// Warning: 11-14 should be between 0.0 and 1.0
|
||||||
// Warning: 1:16-1:20 should be between 0.0 and 1.0
|
// Warning: 16-20 should be between 0.0 and 1.0
|
||||||
#test(rgb(-30, 15.5, 0.5), rgb("00ff80"))
|
#test(rgb(-30, 15.5, 0.5), rgb("00ff80"))
|
||||||
|
|
||||||
// Error: 11-15 missing argument: blue component
|
// Error: 11-15 missing argument: blue component
|
||||||
@ -18,7 +18,7 @@
|
|||||||
// Error: 11-16 invalid color
|
// Error: 11-16 invalid color
|
||||||
#test(rgb("lol"), error)
|
#test(rgb("lol"), error)
|
||||||
|
|
||||||
// Error: 3:11-3:11 missing argument: red component
|
// Error: 11 missing argument: red component
|
||||||
// Error: 2:11-2:11 missing argument: green component
|
// Error: 11 missing argument: green component
|
||||||
// Error: 1:11-1:11 missing argument: blue component
|
// Error: 11 missing argument: blue component
|
||||||
#test(rgb(), black)
|
#test(rgb(), black)
|
||||||
|
@ -13,7 +13,7 @@ use walkdir::WalkDir;
|
|||||||
use typst::cache::Cache;
|
use typst::cache::Cache;
|
||||||
use typst::color::Color;
|
use typst::color::Color;
|
||||||
use typst::diag::{Diag, DiagSet, Level};
|
use typst::diag::{Diag, DiagSet, Level};
|
||||||
use typst::eval::{eval, EvalContext, FuncArgs, FuncValue, Scope, Value};
|
use typst::eval::{eval, Scope, Value};
|
||||||
use typst::exec::{exec, State};
|
use typst::exec::{exec, State};
|
||||||
use typst::geom::{self, Length, PathElement, Point, Sides, Size};
|
use typst::geom::{self, Length, PathElement, Point, Sides, Size};
|
||||||
use typst::image::ImageId;
|
use typst::image::ImageId;
|
||||||
@ -323,9 +323,8 @@ fn parse_metadata(src: &str, map: &LineMap) -> (Option<bool>, DiagSet) {
|
|||||||
let mut diags = DiagSet::new();
|
let mut diags = DiagSet::new();
|
||||||
let mut compare_ref = None;
|
let mut compare_ref = None;
|
||||||
|
|
||||||
for (i, line) in src.lines().enumerate() {
|
let lines: Vec<_> = src.lines().map(str::trim).collect();
|
||||||
let line = line.trim();
|
for (i, line) in lines.iter().enumerate() {
|
||||||
|
|
||||||
if line.starts_with("// Ref: false") {
|
if line.starts_with("// Ref: false") {
|
||||||
compare_ref = Some(false);
|
compare_ref = Some(false);
|
||||||
}
|
}
|
||||||
@ -346,11 +345,14 @@ fn parse_metadata(src: &str, map: &LineMap) -> (Option<bool>, DiagSet) {
|
|||||||
s.eat_while(|c| c.is_numeric()).parse().unwrap()
|
s.eat_while(|c| c.is_numeric()).parse().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let comments =
|
||||||
|
lines[i ..].iter().take_while(|line| line.starts_with("//")).count();
|
||||||
|
|
||||||
let pos = |s: &mut Scanner| -> Pos {
|
let pos = |s: &mut Scanner| -> Pos {
|
||||||
let first = num(s);
|
let first = num(s);
|
||||||
let (delta, column) =
|
let (delta, column) =
|
||||||
if s.eat_if(':') { (first, num(s)) } else { (1, first) };
|
if s.eat_if(':') { (first, num(s)) } else { (1, first) };
|
||||||
let line = i as u32 + 1 + delta;
|
let line = (i + comments) as u32 + delta;
|
||||||
map.pos(Location::new(line, column)).unwrap()
|
map.pos(Location::new(line, column)).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -365,27 +367,25 @@ fn parse_metadata(src: &str, map: &LineMap) -> (Option<bool>, DiagSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn register_helpers(scope: &mut Scope, panics: Rc<RefCell<Vec<Panic>>>) {
|
fn register_helpers(scope: &mut Scope, panics: Rc<RefCell<Vec<Panic>>>) {
|
||||||
pub fn args(_: &mut EvalContext, args: &mut FuncArgs) -> Value {
|
scope.def_const("error", Value::Error);
|
||||||
|
|
||||||
|
scope.def_func("args", |_, args| {
|
||||||
let repr = typst::pretty::pretty(args);
|
let repr = typst::pretty::pretty(args);
|
||||||
args.items.clear();
|
args.items.clear();
|
||||||
Value::template(move |ctx| {
|
Value::template(move |ctx| {
|
||||||
ctx.set_monospace();
|
ctx.set_monospace();
|
||||||
ctx.push_text(&repr);
|
ctx.push_text(&repr);
|
||||||
})
|
})
|
||||||
}
|
});
|
||||||
|
|
||||||
let test = move |ctx: &mut EvalContext, args: &mut FuncArgs| -> Value {
|
scope.def_func("test", move |ctx, args| {
|
||||||
let lhs = args.expect::<Value>(ctx, "left-hand side");
|
let lhs = args.expect::<Value>(ctx, "left-hand side");
|
||||||
let rhs = args.expect::<Value>(ctx, "right-hand side");
|
let rhs = args.expect::<Value>(ctx, "right-hand side");
|
||||||
if lhs != rhs {
|
if lhs != rhs {
|
||||||
panics.borrow_mut().push(Panic { pos: args.span.start, lhs, rhs });
|
panics.borrow_mut().push(Panic { pos: args.span.start, lhs, rhs });
|
||||||
}
|
}
|
||||||
Value::None
|
Value::None
|
||||||
};
|
});
|
||||||
|
|
||||||
scope.def_const("error", Value::Error);
|
|
||||||
scope.def_const("args", FuncValue::new(Some("args".into()), args));
|
|
||||||
scope.def_const("test", FuncValue::new(Some("test".into()), test));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_diag(diag: &Diag, map: &LineMap, lines: u32) {
|
fn print_diag(diag: &Diag, map: &LineMap, lines: u32) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user