Skip to content

Commit

Permalink
Merge pull request #101 from dfinance/windows-line-endings
Browse files Browse the repository at this point in the history
add \r\n -> \n conversion with source map
  • Loading branch information
mkurnikov authored Jul 20, 2020
2 parents a913873 + 3e531db commit 1535914
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 3 deletions.
6 changes: 3 additions & 3 deletions crates/dialects/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::lang::executor::{
use crate::lang::{check_defs, into_exec_compiler_error, replace_sender_placeholder};
use crate::shared::errors::{CompilerError, ExecCompilerError, FileSourceMap, ProjectSourceMap};
use crate::shared::results::{ChainStateChanges, ResourceChange};
use crate::shared::ProvidedAccountAddress;
use crate::shared::{line_endings, ProvidedAccountAddress};

pub trait Dialect {
fn name(&self) -> &str;
Expand All @@ -34,9 +34,9 @@ pub trait Dialect {
file: MoveFile,
sender: &ProvidedAccountAddress,
) -> Result<(Vec<Definition>, FileSourceMap), ExecCompilerError> {
let (fname, mut source_text) = file;
let (fname, source_text) = file;

let mut file_source_map = FileSourceMap::default();
let (mut source_text, mut file_source_map) = line_endings::normalize(source_text);
source_text = replace_sender_placeholder(
source_text,
&sender.normalized_original,
Expand Down
62 changes: 62 additions & 0 deletions crates/dialects/src/shared/line_endings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use crate::shared::errors::FileSourceMap;
use std::str::Chars;

struct NewNormalized<'a> {
chars: Chars<'a>,
prev_was_carriage_return: bool,
pos: usize,
source_map: &'a mut FileSourceMap,
}

impl<'a> NewNormalized<'a> {
fn inner_next(&mut self) -> Option<char> {
self.pos += 1;
self.chars.next()
}
}

const PATTERN_LENGTH: usize = 2;

impl Iterator for NewNormalized<'_> {
type Item = char;

fn next(&mut self) -> Option<char> {
match self.inner_next() {
Some('\n') if self.prev_was_carriage_return => {
self.source_map.insert_layer(self.pos - PATTERN_LENGTH, 1);

self.prev_was_carriage_return = false;
match self.inner_next() {
Some('\r') => {
self.prev_was_carriage_return = true;
Some('\n')
}
any => {
self.prev_was_carriage_return = false;
any
}
}
}
Some('\r') => {
self.prev_was_carriage_return = true;
Some('\n')
}
any => {
self.prev_was_carriage_return = false;
any
}
}
}
}

pub fn normalize(s: String) -> (String, FileSourceMap) {
let mut source_map = FileSourceMap::default();
let normalized = NewNormalized {
chars: s.chars(),
prev_was_carriage_return: false,
pos: 0,
source_map: &mut source_map,
};
let normalized_string = normalized.collect::<String>();
(normalized_string, source_map)
}
1 change: 1 addition & 0 deletions crates/dialects/src/shared/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use move_lang::shared::Address;
pub mod addresses;
pub mod bech32;
pub mod errors;
pub mod line_endings;
pub mod results;

#[derive(Debug, Clone)]
Expand Down
20 changes: 20 additions & 0 deletions crates/integration_tests/tests/test_compilation_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,4 +644,24 @@ module DFI {
"Invalid \'use\'. Unbound module: \'0x0::UnknownPayments\'"
);
}

#[test]
fn test_windows_line_endings_are_allowed() {
let script_text = "script { fun main() {} \r\n } \r\n";
let errors = diagnostics(script_text);
assert!(errors.is_empty(), "{:#?}", errors);
}

#[test]
fn test_windows_line_endings_do_not_offset_errors() {
let script_text = "script {\r\n func main() {} \r\n }";
let errors = diagnostics(script_text);
assert_eq!(errors.len(), 1);
assert_eq!(errors[0].range, range((1, 1), (1, 5)));

let script_text = "script {\r\n\r\n\r\n func main() {} \r\n }";
let errors = diagnostics(script_text);
assert_eq!(errors.len(), 1);
assert_eq!(errors[0].range, range((3, 1), (3, 5)));
}
}

0 comments on commit 1535914

Please sign in to comment.