Skip to content

Commit

Permalink
Fix the performance of selector span expansion (#1929)
Browse files Browse the repository at this point in the history
Instead of calling `SourceFile.getText()`, which creates string copies
of a substantial subset of the text of the file every time, this
directly accesses the file's underlying code units without doing any
copies.

Closes #1913
  • Loading branch information
nex3 committed Apr 6, 2023
1 parent 4ddd8f5 commit 702a7ee
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 20 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

* **Potentially breaking change:** Drop support for End-of-Life Node.js 12.

* Fix remaining cases for the performance regression introduced in 1.59.0.

### Embedded Sass

* The JS embedded host now loads files from the working directory when using the
Expand Down
32 changes: 16 additions & 16 deletions lib/src/interpolation_map.dart
Expand Up @@ -6,7 +6,6 @@ import 'dart:math' as math;

import 'package:charcode/charcode.dart';
import 'package:source_span/source_span.dart';
import 'package:string_scanner/string_scanner.dart';

import 'ast/sass.dart';
import 'util/character.dart';
Expand Down Expand Up @@ -125,21 +124,21 @@ class InterpolationMap {
/// comment before the expression, but since it's only used for error
/// reporting that's probably fine.
int _expandInterpolationSpanLeft(FileLocation start) {
var source = start.file.getText(0, start.offset);
var source = start.file.codeUnits;
var i = start.offset - 1;
while (true) {
var prev = source.codeUnitAt(i--);
while (i >= 0) {
var prev = source[i--];
if (prev == $lbrace) {
if (source.codeUnitAt(i) == $hash) break;
if (source[i] == $hash) break;
} else if (prev == $slash) {
var second = source.codeUnitAt(i--);
var second = source[i--];
if (second == $asterisk) {
while (true) {
var char = source.codeUnitAt(i--);
var char = source[i--];
if (char != $asterisk) continue;

do {
char = source.codeUnitAt(i--);
char = source[i--];
} while (char == $asterisk);
if (char == $slash) break;
}
Expand All @@ -153,28 +152,29 @@ class InterpolationMap {
/// Given the end of a [FileSpan] covering an interpolated expression, returns
/// the offset of the interpolation's closing `}`.
int _expandInterpolationSpanRight(FileLocation end) {
var scanner = StringScanner(end.file.getText(end.offset));
while (true) {
var next = scanner.readChar();
var source = end.file.codeUnits;
var i = end.offset;
while (i < source.length) {
var next = source[i++];
if (next == $rbrace) break;
if (next == $slash) {
var second = scanner.readChar();
var second = source[i++];
if (second == $slash) {
while (!isNewline(scanner.readChar())) {}
while (!isNewline(source[i++])) {}
} else if (second == $asterisk) {
while (true) {
var char = scanner.readChar();
var char = source[i++];
if (char != $asterisk) continue;

do {
char = scanner.readChar();
char = source[i++];
} while (char == $asterisk);
if (char == $slash) break;
}
}
}
}

return end.offset + scanner.position;
return i;
}
}
4 changes: 4 additions & 0 deletions pkg/sass_api/CHANGELOG.md
@@ -1,3 +1,7 @@
## 6.2.0

* No user-visible changes.

## 6.1.0

* No user-visible changes.
Expand Down
4 changes: 2 additions & 2 deletions pkg/sass_api/pubspec.yaml
Expand Up @@ -2,15 +2,15 @@ name: sass_api
# Note: Every time we add a new Sass AST node, we need to bump the *major*
# version because it's a breaking change for anyone who's implementing the
# visitor interface(s).
version: 6.1.0
version: 6.2.0
description: Additional APIs for Dart Sass.
homepage: https://github.com/sass/dart-sass

environment:
sdk: ">=2.17.0 <3.0.0"

dependencies:
sass: 1.60.0
sass: 1.61.0

dev_dependencies:
dartdoc: ^5.0.0
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
@@ -1,5 +1,5 @@
name: sass
version: 1.61.0-dev
version: 1.61.0
description: A Sass implementation in Dart.
homepage: https://github.com/sass/dart-sass

Expand All @@ -23,7 +23,7 @@ dependencies:
path: ^1.8.0
pub_semver: ^2.0.0
source_maps: ^0.10.10
source_span: ^1.8.1
source_span: ^1.10.0
stack_trace: ^1.10.0
stream_transform: ^2.0.0
string_scanner: ^1.1.0
Expand Down

0 comments on commit 702a7ee

Please sign in to comment.