mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Replace using with from
This commit is contained in:
parent
5c327e249e
commit
551e3af9d0
@ -728,33 +728,29 @@ fn import_expr(p: &mut Parser) -> Option<Expr> {
|
|||||||
let start = p.next_start();
|
let start = p.next_start();
|
||||||
p.assert(Token::Import);
|
p.assert(Token::Import);
|
||||||
|
|
||||||
|
let imports = if p.eat_if(Token::Star) {
|
||||||
|
// This is the wildcard scenario.
|
||||||
|
Imports::Wildcard
|
||||||
|
} else {
|
||||||
|
// This is the list of identifiers scenario.
|
||||||
|
p.start_group(Group::Imports, TokenMode::Code);
|
||||||
|
let items = collection(p).0;
|
||||||
|
if items.is_empty() {
|
||||||
|
p.expected_at("import items", p.prev_end());
|
||||||
|
}
|
||||||
|
p.end_group();
|
||||||
|
Imports::Idents(idents(p, items))
|
||||||
|
};
|
||||||
|
|
||||||
let mut import_expr = None;
|
let mut import_expr = None;
|
||||||
if let Some(path) = expr(p) {
|
if p.expect(Token::From) {
|
||||||
let imports = if p.expect(Token::Using) {
|
if let Some(path) = expr(p) {
|
||||||
if p.eat_if(Token::Star) {
|
import_expr = Some(Expr::Import(ImportExpr {
|
||||||
// This is the wildcard scenario.
|
span: p.span(start),
|
||||||
Imports::Wildcard
|
imports,
|
||||||
} else {
|
path: Box::new(path),
|
||||||
// This is the list of identifier scenario.
|
}));
|
||||||
p.start_group(Group::Expr, TokenMode::Code);
|
}
|
||||||
let items = collection(p).0;
|
|
||||||
if items.is_empty() {
|
|
||||||
p.expected_at("import items", p.prev_end());
|
|
||||||
}
|
|
||||||
|
|
||||||
let idents = idents(p, items);
|
|
||||||
p.end_group();
|
|
||||||
Imports::Idents(idents)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Imports::Idents(vec![])
|
|
||||||
};
|
|
||||||
|
|
||||||
import_expr = Some(Expr::Import(ImportExpr {
|
|
||||||
span: p.span(start),
|
|
||||||
imports,
|
|
||||||
path: Box::new(path),
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
import_expr
|
import_expr
|
||||||
|
@ -51,6 +51,8 @@ pub enum Group {
|
|||||||
Stmt,
|
Stmt,
|
||||||
/// A group for a single expression, ended by a line break.
|
/// A group for a single expression, ended by a line break.
|
||||||
Expr,
|
Expr,
|
||||||
|
/// A group for import items, ended by a semicolon, line break or `from`.
|
||||||
|
Imports,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> Parser<'s> {
|
impl<'s> Parser<'s> {
|
||||||
@ -128,6 +130,7 @@ impl<'s> Parser<'s> {
|
|||||||
Group::Brace => self.assert(Token::LeftBrace),
|
Group::Brace => self.assert(Token::LeftBrace),
|
||||||
Group::Stmt => {}
|
Group::Stmt => {}
|
||||||
Group::Expr => {}
|
Group::Expr => {}
|
||||||
|
Group::Imports => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +152,7 @@ impl<'s> Parser<'s> {
|
|||||||
Group::Brace => Some((Token::RightBrace, true)),
|
Group::Brace => Some((Token::RightBrace, true)),
|
||||||
Group::Stmt => Some((Token::Semicolon, false)),
|
Group::Stmt => Some((Token::Semicolon, false)),
|
||||||
Group::Expr => None,
|
Group::Expr => None,
|
||||||
|
Group::Imports => None,
|
||||||
} {
|
} {
|
||||||
if self.next == Some(end) {
|
if self.next == Some(end) {
|
||||||
// Bump the delimeter and return. No need to rescan in this case.
|
// Bump the delimeter and return. No need to rescan in this case.
|
||||||
@ -361,6 +365,7 @@ impl<'s> Parser<'s> {
|
|||||||
Token::RightBracket => self.inside(Group::Bracket),
|
Token::RightBracket => self.inside(Group::Bracket),
|
||||||
Token::RightBrace => self.inside(Group::Brace),
|
Token::RightBrace => self.inside(Group::Brace),
|
||||||
Token::Semicolon => self.inside(Group::Stmt),
|
Token::Semicolon => self.inside(Group::Stmt),
|
||||||
|
Token::From => self.inside(Group::Imports),
|
||||||
Token::Space(n) => n >= 1 && self.stop_at_newline(),
|
Token::Space(n) => n >= 1 && self.stop_at_newline(),
|
||||||
_ => false,
|
_ => false,
|
||||||
} {
|
} {
|
||||||
@ -371,7 +376,10 @@ impl<'s> Parser<'s> {
|
|||||||
/// Whether the active group ends at a newline.
|
/// Whether the active group ends at a newline.
|
||||||
fn stop_at_newline(&self) -> bool {
|
fn stop_at_newline(&self) -> bool {
|
||||||
let active = self.groups.last().map(|group| group.kind);
|
let active = self.groups.last().map(|group| group.kind);
|
||||||
matches!(active, Some(Group::Stmt) | Some(Group::Expr))
|
matches!(
|
||||||
|
active,
|
||||||
|
Some(Group::Stmt) | Some(Group::Expr) | Some(Group::Imports)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether we are inside the given group.
|
/// Whether we are inside the given group.
|
||||||
|
@ -496,7 +496,7 @@ fn keyword(id: &str) -> Option<Token<'static>> {
|
|||||||
"return" => Token::Return,
|
"return" => Token::Return,
|
||||||
"import" => Token::Import,
|
"import" => Token::Import,
|
||||||
"include" => Token::Include,
|
"include" => Token::Include,
|
||||||
"using" => Token::Using,
|
"from" => Token::From,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -440,9 +440,9 @@ impl Pretty for ForPattern {
|
|||||||
impl Pretty for ImportExpr {
|
impl Pretty for ImportExpr {
|
||||||
fn pretty(&self, p: &mut Printer) {
|
fn pretty(&self, p: &mut Printer) {
|
||||||
p.push_str("import ");
|
p.push_str("import ");
|
||||||
self.path.pretty(p);
|
|
||||||
p.push_str(" using ");
|
|
||||||
self.imports.pretty(p);
|
self.imports.pretty(p);
|
||||||
|
p.push_str(" from ");
|
||||||
|
self.path.pretty(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,7 +737,7 @@ mod tests {
|
|||||||
roundtrip("#while x {y}");
|
roundtrip("#while x {y}");
|
||||||
roundtrip("#for x in y {z}");
|
roundtrip("#for x in y {z}");
|
||||||
roundtrip("#for k, x in y {z}");
|
roundtrip("#for k, x in y {z}");
|
||||||
roundtrip("#import \"file.typ\" using *");
|
roundtrip("#import * from \"file.typ\"");
|
||||||
roundtrip("#include \"chapter1.typ\"");
|
roundtrip("#include \"chapter1.typ\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ pub enum Expr {
|
|||||||
While(WhileExpr),
|
While(WhileExpr),
|
||||||
/// A for loop expression: `for x in y { z }`.
|
/// A for loop expression: `for x in y { z }`.
|
||||||
For(ForExpr),
|
For(ForExpr),
|
||||||
/// An import expression: `import "utils.typ" using a, b, c`.
|
/// An import expression: `import a, b, c from "utils.typ"`.
|
||||||
Import(ImportExpr),
|
Import(ImportExpr),
|
||||||
/// An include expression: `include "chapter1.typ"`.
|
/// An include expression: `include "chapter1.typ"`.
|
||||||
Include(IncludeExpr),
|
Include(IncludeExpr),
|
||||||
@ -466,7 +466,7 @@ pub struct LetExpr {
|
|||||||
pub init: Option<Box<Expr>>,
|
pub init: Option<Box<Expr>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An import expression: `import "utils.typ" using a, b, c`.
|
/// An import expression: `import a, b, c from "utils.typ"`.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ImportExpr {
|
pub struct ImportExpr {
|
||||||
/// The source code location.
|
/// The source code location.
|
||||||
|
@ -101,8 +101,8 @@ pub enum Token<'s> {
|
|||||||
Import,
|
Import,
|
||||||
/// The `include` keyword.
|
/// The `include` keyword.
|
||||||
Include,
|
Include,
|
||||||
/// The `using` keyword.
|
/// The `from` keyword.
|
||||||
Using,
|
From,
|
||||||
/// One or more whitespace characters.
|
/// One or more whitespace characters.
|
||||||
///
|
///
|
||||||
/// The contained `usize` denotes the number of newlines that were contained
|
/// The contained `usize` denotes the number of newlines that were contained
|
||||||
@ -254,7 +254,7 @@ impl<'s> Token<'s> {
|
|||||||
Self::Return => "keyword `return`",
|
Self::Return => "keyword `return`",
|
||||||
Self::Import => "keyword `import`",
|
Self::Import => "keyword `import`",
|
||||||
Self::Include => "keyword `include`",
|
Self::Include => "keyword `include`",
|
||||||
Self::Using => "keyword `using`",
|
Self::From => "keyword `from`",
|
||||||
Self::Space(_) => "space",
|
Self::Space(_) => "space",
|
||||||
Self::Text(_) => "text",
|
Self::Text(_) => "text",
|
||||||
Self::UnicodeEscape(_) => "unicode escape sequence",
|
Self::UnicodeEscape(_) => "unicode escape sequence",
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.2 KiB |
@ -21,7 +21,7 @@
|
|||||||
---
|
---
|
||||||
// Double block creates a scope.
|
// Double block creates a scope.
|
||||||
{{
|
{{
|
||||||
import "target.typ" using b
|
import b from "target.typ"
|
||||||
test(b, 1)
|
test(b, 1)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -4,21 +4,21 @@
|
|||||||
// Test importing semantics.
|
// Test importing semantics.
|
||||||
|
|
||||||
// A named import.
|
// A named import.
|
||||||
#import "target.typ" using item
|
#import item from "target.typ"
|
||||||
#test(item(1, 2), 3)
|
#test(item(1, 2), 3)
|
||||||
|
|
||||||
// Test that this will be overwritten.
|
// Test that this will be overwritten.
|
||||||
#let value = [foo]
|
#let value = [foo]
|
||||||
|
|
||||||
// Import multiple things.
|
// Import multiple things.
|
||||||
// Error: 28-29 expected expression, found comma
|
// Error: 9-10 expected expression, found comma
|
||||||
#import "target.typ" using ,fn, value
|
#import ,fn, value from "target.typ"
|
||||||
#fn[Like and Subscribe!]
|
#fn[Like and Subscribe!]
|
||||||
#value
|
#value
|
||||||
|
|
||||||
// Code mode
|
// Code mode
|
||||||
{
|
{
|
||||||
import "target.typ" using b
|
import b from "target.typ"
|
||||||
test(b, 1)
|
test(b, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,91 +29,92 @@
|
|||||||
#d
|
#d
|
||||||
|
|
||||||
// A wildcard import.
|
// A wildcard import.
|
||||||
#import "target.typ" using *
|
#import * from "target.typ"
|
||||||
|
|
||||||
// It exists now!
|
// It exists now!
|
||||||
#d
|
#d
|
||||||
|
|
||||||
|
// Who needs whitespace anyways?
|
||||||
|
#import*from"target.typ"
|
||||||
|
|
||||||
|
// Should output `Hi`.
|
||||||
|
// Stop at semicolon.
|
||||||
|
#import a, c from "target.typ";bye
|
||||||
|
|
||||||
|
// Allow the trailing comma.
|
||||||
|
#import a, c, from "target.typ"
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test bad imports.
|
// Test bad imports.
|
||||||
// Ref: false
|
// Ref: false
|
||||||
|
|
||||||
// Error: 9-11 file not found
|
// Error: 19-21 file not found
|
||||||
#import "" using name
|
#import name from ""
|
||||||
|
|
||||||
// Error: 9-20 file not found
|
// Error: 16-27 file not found
|
||||||
#import "lib/0.2.1" using *
|
#import * from "lib/0.2.1"
|
||||||
|
|
||||||
// Error: 9-20 file not found
|
|
||||||
#import "lib@0.2.1" using *
|
|
||||||
|
|
||||||
// Some non-text stuff.
|
// Some non-text stuff.
|
||||||
// Error: 9-30 file is not valid utf-8
|
// Error: 16-37 file is not valid utf-8
|
||||||
#import "../../res/rhino.png" using *
|
#import * from "../../res/rhino.png"
|
||||||
|
|
||||||
// Unresolved import.
|
// Unresolved import.
|
||||||
// Error: 28-40 unresolved import
|
// Error: 9-21 unresolved import
|
||||||
#import "target.typ" using non_existing
|
#import non_existing from "target.typ"
|
||||||
|
|
||||||
// Cyclic import.
|
// Cyclic import.
|
||||||
// Error: 9-34 cyclic import
|
// Error: 16-41 cyclic import
|
||||||
#import "./importable/cycle1.typ" using *
|
#import * from "./importable/cycle1.typ"
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test syntax.
|
// Test bad syntax.
|
||||||
|
|
||||||
// Missing file.
|
// Error: 2:8 expected import items
|
||||||
// Error: 9-10 expected expression, found star
|
// Error: 1:8 expected keyword `from`
|
||||||
#import *
|
#import
|
||||||
|
|
||||||
// Should output `"target.typ"`.
|
// Error: 2:9-2:19 expected identifier
|
||||||
// Error: 1-7 unexpected keyword `using`
|
// Error: 1:19 expected keyword `from`
|
||||||
#using "target.typ"
|
#import "file.typ"
|
||||||
|
|
||||||
// Should output `target`.
|
// Error: 2:16-2:19 expected identifier
|
||||||
// Error: 3:9-4:8 file not found
|
// Error: 1:22 expected keyword `from`
|
||||||
// Error: 3:8 expected semicolon or line break
|
#import afrom, "b", c
|
||||||
// Error: 2:8 expected keyword `using`
|
|
||||||
#import "target.typ
|
|
||||||
using "target
|
|
||||||
|
|
||||||
// Should output `@ 0.2.1 using`.
|
// Error: 8 expected import items
|
||||||
// Error: 2:21 expected semicolon or line break
|
#import from "target.typ"
|
||||||
// Error: 1:21 expected keyword `using`
|
|
||||||
#import "target.typ" @ 0.2.1 using *
|
|
||||||
|
|
||||||
// Error: 3:21 expected keyword `using`
|
// Error: 2:9-2:10 expected expression, found assignment operator
|
||||||
// Error: 2:21 expected semicolon or line break
|
// Error: 1:10 expected import items
|
||||||
// Error: 1:22-1:28 unexpected keyword `using`
|
#import = from "target.typ"
|
||||||
#import "target.typ" #using *
|
|
||||||
|
|
||||||
// Error: 2:21 expected semicolon or line break
|
// Error: 15 expected expression
|
||||||
// Error: 1:21 expected keyword `using`
|
#import * from
|
||||||
#import "target.typ" usinga,b,c
|
|
||||||
|
|
||||||
// Error: 27 expected import items
|
|
||||||
#import "target.typ" using
|
|
||||||
|
|
||||||
// Error: 2:28-2:29 expected expression, found assignment operator
|
|
||||||
// Error: 1:29 expected import items
|
|
||||||
#import "target.typ" using =
|
|
||||||
|
|
||||||
// Allow the trailing comma.
|
|
||||||
#import "target.typ" using a, c,
|
|
||||||
|
|
||||||
// An additional trailing comma.
|
// An additional trailing comma.
|
||||||
// Error: 36-37 expected expression, found comma
|
// Error: 17-18 expected expression, found comma
|
||||||
#import "target.typ" using a, b, c,,
|
#import a, b, c,, from "target.typ"
|
||||||
|
|
||||||
// Star in the list.
|
// Should output `"target.typ"`.
|
||||||
// Error: 2:31-2:32 expected expression, found star
|
// Error: 1-6 unexpected keyword `from`
|
||||||
// Error: 32-33 expected expression, found comma
|
#from "target.typ"
|
||||||
#import "target.typ" using a, *, b
|
|
||||||
|
|
||||||
// Stop at semicolon.
|
// Should output `target`.
|
||||||
#import "target.typ" using a, c;Hi
|
// Error: 2:16-3:2 file not found
|
||||||
|
// Error: 2:2 expected semicolon or line break
|
||||||
|
#import * from "target.typ
|
||||||
|
"target
|
||||||
|
|
||||||
// Who needs whitespace anyways?
|
// Should output `@ 0.2.1`.
|
||||||
#import "target.typ"using *
|
// Error: 28 expected semicolon or line break
|
||||||
#import"target.typ"using*
|
#import * from "target.typ" @ 0.2.1
|
||||||
#import "target.typ"using *
|
|
||||||
|
// A star in the list.
|
||||||
|
// Error: 2:12-2:13 expected expression, found star
|
||||||
|
// Error: 1:13-1:14 expected expression, found comma
|
||||||
|
#import a, *, b from "target.typ"
|
||||||
|
|
||||||
|
// An item after a star.
|
||||||
|
// Should output `, a from "target.typ"`.
|
||||||
|
// Error: 10 expected keyword `from`
|
||||||
|
#import *, a from "target.typ"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Ref: false
|
// Ref: false
|
||||||
|
|
||||||
// Error: 9-21 cyclic import
|
// Error: 16-28 cyclic import
|
||||||
#import "cycle2.typ" using *
|
#import * from "cycle2.typ"
|
||||||
#let inaccessible = "wow"
|
#let inaccessible = "wow"
|
||||||
|
|
||||||
This is the first element of an import cycle.
|
This is the first element of an import cycle.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Ref: false
|
// Ref: false
|
||||||
|
|
||||||
// Error: 9-21 cyclic import
|
// Error: 16-28 cyclic import
|
||||||
#import "cycle1.typ" using *
|
#import * from "cycle1.typ"
|
||||||
#let val = "much cycle"
|
#let val = "much cycle"
|
||||||
|
|
||||||
This is the second element of an import cycle.
|
This is the second element of an import cycle.
|
||||||
|
@ -119,7 +119,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "keyword.other.typst",
|
"name": "keyword.other.typst",
|
||||||
"match": "(#)(as|in|with|from|using)\\b",
|
"match": "(#)(as|in|with|from)\\b",
|
||||||
"captures": { "1": { "name": "punctuation.definition.keyword.typst" } }
|
"captures": { "1": { "name": "punctuation.definition.keyword.typst" } }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -231,7 +231,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "keyword.other.typst",
|
"name": "keyword.other.typst",
|
||||||
"match": "\\b(pub|let|as|in|with|import|include|from|using)\\b"
|
"match": "\\b(pub|let|as|in|with|import|include|from)\\b"
|
||||||
},
|
},
|
||||||
{ "include": "#constants" },
|
{ "include": "#constants" },
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user