Skip to content

Commit 22c3ed3

Browse files
committed
Merge branch 'master' of github.com:RustPython/RustPython into update-docs
2 parents c64a974 + 69980c2 commit 22c3ed3

File tree

8 files changed

+133
-142
lines changed

8 files changed

+133
-142
lines changed

.travis.yml

+43-65
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,44 @@
1-
language: rust
2-
rust: stable
3-
cache: cargo
41

52
matrix:
63
fast_finish: true
74
include:
8-
- name: rust unittests and doctests
5+
- name: Run rust tests
96
language: rust
107
rust: stable
118
cache: cargo
129
script:
1310
- cargo build --verbose --all
1411
- cargo test --verbose --all
12+
env:
13+
# Prevention of cache corruption.
14+
# See: https://docs.travis-ci.com/user/caching/#caches-and-build-matrices
15+
- JOBCACHE=1
1516

1617
# To test the snippets, we use Travis' Python environment (because
1718
# installing rust ourselves is a lot easier than installing Python)
1819
- name: python test snippets
1920
language: python
2021
python: 3.6
2122
cache:
22-
pip: true
23-
# Because we're using the Python Travis environment, we can't use
24-
# the built-in cargo cacher
25-
directories:
26-
- /home/travis/.cargo
27-
- target
23+
- pip
24+
- cargo
2825
env:
26+
- JOBCACHE=2
2927
- TRAVIS_RUST_VERSION=stable
3028
- CODE_COVERAGE=false
3129
script: tests/.travis-runner.sh
32-
- name: rustfmt
30+
31+
- name: Check rust code style with rustfmt
3332
language: rust
3433
rust: stable
3534
cache: cargo
3635
before_script:
37-
- rustup component add rustfmt-preview
36+
- rustup component add rustfmt
3837
script:
39-
# Code references the generated python.rs, so put something in
40-
# place to make `cargo fmt` happy. (We use `echo` rather than
41-
# `touch` because rustfmt complains about the empty file touch
42-
# creates.)
43-
- echo > parser/src/python.rs
4438
- cargo fmt --all -- --check
39+
env:
40+
- JOBCACHE=3
41+
4542
- name: publish documentation
4643
language: rust
4744
rust: stable
@@ -50,7 +47,17 @@ matrix:
5047
- cargo doc --no-deps --all
5148
if: branch = release
5249
env:
53-
- DEPLOY_DOC=true
50+
- JOBCACHE=4
51+
deploy:
52+
- provider: pages
53+
repo: RustPython/website
54+
target-branch: master
55+
local-dir: target/doc
56+
skip-cleanup: true
57+
# Set in the settings page of your repository, as a secure variable
58+
github-token: $WEBSITE_GITHUB_TOKEN
59+
keep-history: true
60+
5461
- name: WASM online demo
5562
language: rust
5663
rust: stable
@@ -65,42 +72,38 @@ matrix:
6572
- npm run dist
6673
if: branch = release
6774
env:
68-
- DEPLOY_DEMO=true
69-
- name: cargo-clippy
70-
language: rust
71-
rust: stable
72-
cache: cargo
73-
before_script:
74-
- rustup component add clippy
75-
script:
76-
- cargo clippy
75+
- JOBCACHE=5
76+
deploy:
77+
- provider: pages
78+
repo: RustPython/demo
79+
target-branch: master
80+
local-dir: wasm/demo/dist
81+
skip-cleanup: true
82+
# Set in the settings page of your repository, as a secure variable
83+
github-token: $WEBSITE_GITHUB_TOKEN
84+
keep-history: true
85+
7786
- name: Code Coverage
7887
language: python
7988
python: 3.6
8089
cache:
81-
pip: true
82-
# Because we're using the Python Travis environment, we can't use
83-
# the built-in cargo cacher
84-
directories:
85-
- /home/travis/.cargo
86-
- target
90+
- pip
91+
- cargo
8792
script:
8893
- tests/.travis-runner.sh
8994
# Only do code coverage on master via a cron job.
9095
if: branch = master AND type = cron
9196
env:
97+
- JOBCACHE=6
9298
- TRAVIS_RUST_VERSION=nightly
9399
- CODE_COVERAGE=true
100+
94101
- name: test WASM
95102
language: python
96103
python: 3.6
97104
cache:
98-
pip: true
99-
# Because we're using the Python Travis environment, we can't use
100-
# the built-in cargo cacher
101-
directories:
102-
- /home/travis/.cargo
103-
- target
105+
- pip
106+
- cargo
104107
addons:
105108
firefox: latest
106109
install:
@@ -109,30 +112,5 @@ matrix:
109112
script:
110113
- wasm/tests/.travis-runner.sh
111114
env:
115+
- JOBCACHE=7
112116
- TRAVIS_RUST_VERSION=stable
113-
allow_failures:
114-
- name: cargo-clippy
115-
116-
deploy:
117-
- provider: pages
118-
repo: RustPython/website
119-
target-branch: master
120-
local-dir: target/doc
121-
skip-cleanup: true
122-
# Set in the settings page of your repository, as a secure variable
123-
github-token: $WEBSITE_GITHUB_TOKEN
124-
keep-history: true
125-
on:
126-
branch: release
127-
condition: $DEPLOY_DOC = true
128-
- provider: pages
129-
repo: RustPython/demo
130-
target-branch: master
131-
local-dir: wasm/demo/dist
132-
skip-cleanup: true
133-
# Set in the settings page of your repository, as a secure variable
134-
github-token: $WEBSITE_GITHUB_TOKEN
135-
keep-history: true
136-
on:
137-
branch: release
138-
condition: $DEPLOY_DEMO = true

azure-pipelines.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ jobs:
88
vmImage: 'vs2017-win2016'
99
strategy:
1010
matrix:
11-
Python37:
12-
python.version: '3.7'
11+
Python36:
12+
python.version: '3.6'
1313
maxParallel: 10
1414

1515
steps:

compiler/src/error.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustpython_parser::error::ParseError;
1+
use rustpython_parser::error::{ParseError, ParseErrorType};
22
use rustpython_parser::lexer::Location;
33

44
use std::error::Error;
@@ -13,8 +13,8 @@ pub struct CompileError {
1313
impl From<ParseError> for CompileError {
1414
fn from(error: ParseError) -> Self {
1515
CompileError {
16-
error: CompileErrorType::Parse(error),
17-
location: Default::default(), // TODO: extract location from parse error!
16+
error: CompileErrorType::Parse(error.error),
17+
location: error.location,
1818
}
1919
}
2020
}
@@ -28,7 +28,7 @@ pub enum CompileErrorType {
2828
/// Expected an expression got a statement
2929
ExpectExpr,
3030
/// Parser error
31-
Parse(ParseError),
31+
Parse(ParseErrorType),
3232
SyntaxError(String),
3333
/// Multiple `*` detected
3434
StarArgs,
@@ -56,7 +56,7 @@ impl fmt::Display for CompileError {
5656
}?;
5757

5858
// Print line number:
59-
write!(f, " at line {:?}", self.location.row())
59+
write!(f, " at {}", self.location)
6060
}
6161
}
6262

parser/src/error.rs

+45-33
Original file line numberDiff line numberDiff line change
@@ -3,71 +3,83 @@
33
extern crate lalrpop_util;
44
use self::lalrpop_util::ParseError as InnerError;
55

6-
use crate::lexer::{LexicalError, Location};
6+
use crate::lexer::{LexicalError, LexicalErrorType, Location};
77
use crate::token::Tok;
88

99
use std::error::Error;
1010
use std::fmt;
1111

12-
// A token of type `Tok` was observed, with a span given by the two Location values
13-
type TokSpan = (Location, Tok, Location);
14-
1512
/// Represents an error during parsing
1613
#[derive(Debug, PartialEq)]
17-
pub enum ParseError {
14+
pub struct ParseError {
15+
pub error: ParseErrorType,
16+
pub location: Location,
17+
}
18+
19+
#[derive(Debug, PartialEq)]
20+
pub enum ParseErrorType {
1821
/// Parser encountered an unexpected end of input
19-
EOF(Option<Location>),
22+
EOF,
2023
/// Parser encountered an extra token
21-
ExtraToken(TokSpan),
24+
ExtraToken(Tok),
2225
/// Parser encountered an invalid token
23-
InvalidToken(Location),
26+
InvalidToken,
2427
/// Parser encountered an unexpected token
25-
UnrecognizedToken(TokSpan, Vec<String>),
28+
UnrecognizedToken(Tok, Vec<String>),
2629
/// Maps to `User` type from `lalrpop-util`
27-
Other,
30+
Lexical(LexicalErrorType),
2831
}
2932

3033
/// Convert `lalrpop_util::ParseError` to our internal type
3134
impl From<InnerError<Location, Tok, LexicalError>> for ParseError {
3235
fn from(err: InnerError<Location, Tok, LexicalError>) -> Self {
3336
match err {
3437
// TODO: Are there cases where this isn't an EOF?
35-
InnerError::InvalidToken { location } => ParseError::EOF(Some(location)),
36-
InnerError::ExtraToken { token } => ParseError::ExtraToken(token),
37-
// Inner field is a unit-like enum `LexicalError::StringError` with no useful info
38-
InnerError::User { .. } => ParseError::Other,
38+
InnerError::InvalidToken { location } => ParseError {
39+
error: ParseErrorType::EOF,
40+
location,
41+
},
42+
InnerError::ExtraToken { token } => ParseError {
43+
error: ParseErrorType::ExtraToken(token.1),
44+
location: token.0,
45+
},
46+
InnerError::User { error } => ParseError {
47+
error: ParseErrorType::Lexical(error.error),
48+
location: error.location,
49+
},
3950
InnerError::UnrecognizedToken { token, expected } => {
4051
match token {
41-
Some(tok) => ParseError::UnrecognizedToken(tok, expected),
52+
Some(tok) => ParseError {
53+
error: ParseErrorType::UnrecognizedToken(tok.1, expected),
54+
location: tok.0,
55+
},
4256
// EOF was observed when it was unexpected
43-
None => ParseError::EOF(None),
57+
None => ParseError {
58+
error: ParseErrorType::EOF,
59+
location: Default::default(),
60+
},
4461
}
4562
}
4663
}
4764
}
4865
}
4966

5067
impl fmt::Display for ParseError {
68+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69+
write!(f, "{} at {}", self.error, self.location)
70+
}
71+
}
72+
73+
impl fmt::Display for ParseErrorType {
5174
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5275
match *self {
53-
ParseError::EOF(ref location) => {
54-
if let Some(l) = location {
55-
write!(f, "Got unexpected EOF at: {:?}", l)
56-
} else {
57-
write!(f, "Got unexpected EOF")
58-
}
59-
}
60-
ParseError::ExtraToken(ref t_span) => {
61-
write!(f, "Got extraneous token: {:?} at: {:?}", t_span.1, t_span.0)
62-
}
63-
ParseError::InvalidToken(ref location) => {
64-
write!(f, "Got invalid token at: {:?}", location)
65-
}
66-
ParseError::UnrecognizedToken(ref t_span, _) => {
67-
write!(f, "Got unexpected token: {:?} at {:?}", t_span.1, t_span.0)
76+
ParseErrorType::EOF => write!(f, "Got unexpected EOF"),
77+
ParseErrorType::ExtraToken(ref tok) => write!(f, "Got extraneous token: {:?}", tok),
78+
ParseErrorType::InvalidToken => write!(f, "Got invalid token"),
79+
ParseErrorType::UnrecognizedToken(ref tok, _) => {
80+
write!(f, "Got unexpected token: {:?}", tok)
6881
}
69-
// This is user defined, it probably means a more useful error should have been given upstream.
70-
ParseError::Other => write!(f, "Got unsupported token(s)"),
82+
ParseErrorType::Lexical(ref error) => write!(f, "{}", error),
7183
}
7284
}
7385
}

parser/src/lexer.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use num_traits::Num;
1010
use serde::{Deserialize, Serialize};
1111
use std::cmp::Ordering;
1212
use std::collections::HashMap;
13+
use std::fmt;
1314
use std::str::FromStr;
1415
use unic_emoji_char::is_emoji_presentation;
1516
use unicode_xid::UnicodeXID;
@@ -59,13 +60,13 @@ pub struct Lexer<T: Iterator<Item = char>> {
5960
keywords: HashMap<String, Tok>,
6061
}
6162

62-
#[derive(Debug)]
63+
#[derive(Debug, PartialEq)]
6364
pub struct LexicalError {
6465
pub error: LexicalErrorType,
6566
pub location: Location,
6667
}
6768

68-
#[derive(Debug)]
69+
#[derive(Debug, PartialEq)]
6970
pub enum LexicalErrorType {
7071
StringError,
7172
UnicodeError,
@@ -74,12 +75,32 @@ pub enum LexicalErrorType {
7475
OtherError(String),
7576
}
7677

78+
impl fmt::Display for LexicalErrorType {
79+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80+
match *self {
81+
LexicalErrorType::StringError => write!(f, "Got unexpected string"),
82+
LexicalErrorType::UnicodeError => write!(f, "Got unexpected unicode"),
83+
LexicalErrorType::NestingError => write!(f, "Got unexpected nesting"),
84+
LexicalErrorType::UnrecognizedToken { tok } => {
85+
write!(f, "Got unexpected token {}", tok)
86+
}
87+
LexicalErrorType::OtherError(ref msg) => write!(f, "{}", msg),
88+
}
89+
}
90+
}
91+
7792
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
7893
pub struct Location {
7994
row: usize,
8095
column: usize,
8196
}
8297

98+
impl fmt::Display for Location {
99+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100+
write!(f, "line {} column {}", self.row, self.column)
101+
}
102+
}
103+
83104
impl Location {
84105
pub fn new(row: usize, column: usize) -> Self {
85106
Location { row, column }

0 commit comments

Comments
 (0)