Skip to content

Commit

Permalink
sass#568: attempt add option to not translate unicode
Browse files Browse the repository at this point in the history
  • Loading branch information
yringler committed Oct 23, 2019
1 parent 3b36b5e commit caa8895
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 39 deletions.
20 changes: 10 additions & 10 deletions lib/src/ast/sass/statement/stylesheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ class Stylesheet extends ParentStatement {
///
/// Throws a [SassFormatException] if parsing fails.
factory Stylesheet.parse(String contents, Syntax syntax,
{url, Logger logger}) {
{url, Logger logger, bool allowUnicodeEscapes}) {
switch (syntax) {
case Syntax.sass:
return Stylesheet.parseSass(contents, url: url, logger: logger);
return Stylesheet.parseSass(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);
case Syntax.scss:
return Stylesheet.parseScss(contents, url: url, logger: logger);
return Stylesheet.parseScss(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);
case Syntax.css:
return Stylesheet.parseCss(contents, url: url, logger: logger);
return Stylesheet.parseCss(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);
default:
throw ArgumentError("Unknown syntax $syntax.");
}
Expand All @@ -76,24 +76,24 @@ class Stylesheet extends ParentStatement {
/// If passed, [url] is the name of the file from which [contents] comes.
///
/// Throws a [SassFormatException] if parsing fails.
factory Stylesheet.parseSass(String contents, {url, Logger logger}) =>
SassParser(contents, url: url, logger: logger).parse();
factory Stylesheet.parseSass(String contents, {url, Logger logger, bool allowUnicodeEscapes}) =>
SassParser(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes).parse();

/// Parses an SCSS stylesheet from [contents].
///
/// If passed, [url] is the name of the file from which [contents] comes.
///
/// Throws a [SassFormatException] if parsing fails.
factory Stylesheet.parseScss(String contents, {url, Logger logger}) =>
ScssParser(contents, url: url, logger: logger).parse();
factory Stylesheet.parseScss(String contents, {url, Logger logger, bool allowUnicodeEscapes}) =>
ScssParser(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes).parse();

/// Parses a plain CSS stylesheet from [contents].
///
/// If passed, [url] is the name of the file from which [contents] comes.
///
/// Throws a [SassFormatException] if parsing fails.
factory Stylesheet.parseCss(String contents, {url, Logger logger}) =>
CssParser(contents, url: url, logger: logger).parse();
factory Stylesheet.parseCss(String contents, {url, Logger logger, bool allowUnicodeEscapes}) =>
CssParser(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes).parse();

T accept<T>(StatementVisitor<T> visitor) => visitor.visitStylesheet(this);

Expand Down
10 changes: 6 additions & 4 deletions lib/src/async_compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ Future<CompileResult> compileAsync(String path,
int indentWidth,
LineFeed lineFeed,
bool sourceMap = false,
bool charset = true}) async {
bool charset = true,
bool allowUnicodeEscapes}) async {
// If the syntax is different than the importer would default to, we have to
// parse the file manually and we can't store it in the cache.
Stylesheet stylesheet;
Expand All @@ -49,7 +50,7 @@ Future<CompileResult> compileAsync(String path,
} else {
stylesheet = Stylesheet.parse(
readFile(path), syntax ?? Syntax.forPath(path),
url: p.toUri(path), logger: logger);
url: p.toUri(path), logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);
}

return await _compileStylesheet(
Expand Down Expand Up @@ -87,9 +88,10 @@ Future<CompileResult> compileStringAsync(String source,
LineFeed lineFeed,
url,
bool sourceMap = false,
bool charset = true}) async {
bool charset = true,
bool allowUnicodeEscapes}) async {
var stylesheet =
Stylesheet.parse(source, syntax ?? Syntax.scss, url: url, logger: logger);
Stylesheet.parse(source, syntax ?? Syntax.scss, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);

return _compileStylesheet(
stylesheet,
Expand Down
10 changes: 6 additions & 4 deletions lib/src/compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ CompileResult compile(String path,
int indentWidth,
LineFeed lineFeed,
bool sourceMap = false,
bool charset = true}) {
bool charset = true,
bool allowUnicodeEscapes}) {
// If the syntax is different than the importer would default to, we have to
// parse the file manually and we can't store it in the cache.
Stylesheet stylesheet;
Expand All @@ -58,7 +59,7 @@ CompileResult compile(String path,
} else {
stylesheet = Stylesheet.parse(
readFile(path), syntax ?? Syntax.forPath(path),
url: p.toUri(path), logger: logger);
url: p.toUri(path), logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);
}

return _compileStylesheet(
Expand Down Expand Up @@ -96,9 +97,10 @@ CompileResult compileString(String source,
LineFeed lineFeed,
url,
bool sourceMap = false,
bool charset = true}) {
bool charset = true,
bool allowUnicodeEscapes }) {
var stylesheet =
Stylesheet.parse(source, syntax ?? Syntax.scss, url: url, logger: logger);
Stylesheet.parse(source, syntax ?? Syntax.scss, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);

return _compileStylesheet(
stylesheet,
Expand Down
12 changes: 8 additions & 4 deletions lib/src/executable/compile_stylesheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ Future<void> compileStylesheet(ExecutableOptions options, StylesheetGraph graph,
importer: FilesystemImporter('.'),
style: options.style,
sourceMap: options.emitSourceMap,
charset: options.charset)
charset: options.charset,
allowUnicodeEscapes: options.asciiOnly)
: await compileAsync(source,
syntax: syntax,
logger: options.logger,
importCache: importCache,
style: options.style,
sourceMap: options.emitSourceMap,
charset: options.charset);
charset: options.charset,
allowUnicodeEscapes: options.asciiOnly);
} else {
result = source == null
? compileString(await readStdin(),
Expand All @@ -87,14 +89,16 @@ Future<void> compileStylesheet(ExecutableOptions options, StylesheetGraph graph,
importer: FilesystemImporter('.'),
style: options.style,
sourceMap: options.emitSourceMap,
charset: options.charset)
charset: options.charset,
allowUnicodeEscapes: options.asciiOnly)
: compile(source,
syntax: syntax,
logger: options.logger,
importCache: graph.importCache,
style: options.style,
sourceMap: options.emitSourceMap,
charset: options.charset);
charset: options.charset,
allowUnicodeEscapes: options.asciiOnly);
}
} on SassException catch (error) {
if (options.emitErrorCss) {
Expand Down
8 changes: 7 additions & 1 deletion lib/src/executable/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ class ExecutableOptions {
..addFlag('help',
abbr: 'h', help: 'Print this usage information.', negatable: false)
..addFlag('version',
help: 'Print the version of Dart Sass.', negatable: false);
help: 'Print the version of Dart Sass.', negatable: false)
..addFlag('ascii-only',
help:
'Don\'t translate unicode escape sequences to utf-8 during parsing.');

return parser;
}();
Expand Down Expand Up @@ -170,6 +173,9 @@ class ExecutableOptions {
/// Whether to silence normal output.
bool get quiet => _options['quiet'] as bool;

/// Whether unicode escape sequences should be translated to utf-8 during parsing.
bool get asciiOnly => _options['ascii-only'] as bool;

/// The logger to use to emit messages from Sass.
Logger get logger => quiet ? Logger.quiet : Logger.stderr(color: color);

Expand Down
4 changes: 2 additions & 2 deletions lib/src/parse/css.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ final _disallowedFunctionNames =
class CssParser extends ScssParser {
bool get plainCss => true;

CssParser(String contents, {url, Logger logger})
: super(contents, url: url, logger: logger);
CssParser(String contents, {url, Logger logger, bool allowUnicodeEscapes})
: super(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);

void silentComment() {
var start = scanner.state;
Expand Down
37 changes: 29 additions & 8 deletions lib/src/parse/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class Parser {
@protected
final Logger logger;

/// Whether unicode escape sequences should be parsed into utf-8.
final bool allowUnicodeEscapes;

/// Parses [text] as a CSS identifier and returns the result.
///
/// Throws a [SassFormatException] if parsing fails.
Expand All @@ -48,7 +51,7 @@ class Parser {
Parser(text, logger: logger)._isVariableDeclarationLike();

@protected
Parser(String contents, {url, Logger logger})
Parser(String contents, {url, Logger logger, this.allowUnicodeEscapes = true})
: scanner = SpanScanner(contents, sourceUrl: url),
logger = logger ?? const Logger.stderr();

Expand Down Expand Up @@ -170,7 +173,7 @@ class Parser {
} else if (isNameStart(first)) {
text.writeCharCode(scanner.readChar());
} else if (first == $backslash) {
text.write(escape(identifierStart: true));
text.write(escape(identifierStart: true, encodeUnicode: false));
} else {
scanner.error("Expected identifier.");
}
Expand Down Expand Up @@ -429,6 +432,22 @@ class Parser {

// ## Characters

// Constructs hex code from input.
String readHex() {
assert(isHex(scanner.peekChar()));

String rawHex = "";
for (var i = 0; i < 6; i++) {
var next = scanner.peekChar();
if (next == null || !isHex(next)) break;
rawHex += String.fromCharCode(next);
}

scanCharIf(isWhitespace);

return rawHex;
}

/// Consumes an escape sequence and returns the text that defines it.
///
/// If [identifierStart] is true, this normalizes the escape sequence as
Expand All @@ -446,14 +465,16 @@ class Parser {
scanner.error("Expected escape sequence.");
return null;
} else if (isHex(first)) {
for (var i = 0; i < 6; i++) {
var next = scanner.peekChar();
if (next == null || !isHex(next)) break;
value *= 16;
value += asHex(scanner.readChar());
var rawHex = readHex();
if (!allowUnicodeEscapes) {
return rawHex;
}

scanCharIf(isWhitespace);
value = rawHex.runes.reduce((total, current) {
total *= 16;
total += asHex(current);
return total;
});
} else {
value = scanner.readChar();
}
Expand Down
4 changes: 2 additions & 2 deletions lib/src/parse/sass.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class SassParser extends StylesheetParser {

bool get indented => true;

SassParser(String contents, {url, Logger logger})
: super(contents, url: url, logger: logger);
SassParser(String contents, {url, Logger logger, bool allowUnicodeEscapes})
: super(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);

Interpolation styleRuleSelector() {
var start = scanner.state;
Expand Down
4 changes: 2 additions & 2 deletions lib/src/parse/scss.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class ScssParser extends StylesheetParser {
bool get indented => false;
int get currentIndentation => null;

ScssParser(String contents, {url, Logger logger})
: super(contents, url: url, logger: logger);
ScssParser(String contents, {url, Logger logger, bool allowUnicodeEscapes})
: super(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);

Interpolation styleRuleSelector() => almostAnyValue();

Expand Down
4 changes: 2 additions & 2 deletions lib/src/parse/stylesheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ abstract class StylesheetParser extends Parser {
@protected
SilentComment lastSilentComment;

StylesheetParser(String contents, {url, Logger logger})
: super(contents, url: url, logger: logger);
StylesheetParser(String contents, {url, Logger logger, bool allowUnicodeEscapes})
: super(contents, url: url, logger: logger, allowUnicodeEscapes: allowUnicodeEscapes);

// ## Statements

Expand Down

0 comments on commit caa8895

Please sign in to comment.