Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation of a PostCSS-compatible parser JS API #2304

Merged
merged 18 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,12 @@ updates:
- "/.github/util/*/"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directories:
- "/"
- "/package"
- "/pkg/sass-parser"
ignore:
dependency-name: "sass"
schedule:
interval: "weekly"
27 changes: 24 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ jobs:
run: dart run grinder protobuf pkg-pub-deploy
env: {PUB_CREDENTIALS: "${{ secrets.PUB_CREDENTIALS }}"}

deploy_sub_packages:
name: Deploy Sub-Packages
deploy_sass_api:
name: Deploy sass_api
runs-on: ubuntu-latest
needs: [deploy_pub]

Expand All @@ -113,12 +113,33 @@ jobs:
with: {github-token: "${{ github.token }}"}

- name: Deploy
run: dart run grinder deploy-sub-packages
run: dart run grinder deploy-sass-api
env:
PUB_CREDENTIALS: "${{ secrets.PUB_CREDENTIALS }}"
GH_TOKEN: "${{ secrets.GH_TOKEN }}"
GH_USER: sassbot

deploy_sass_parser:
name: Deploy sass-parser
runs-on: ubuntu-latest
needs: [deploy_npm]

steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GH_TOKEN }}

- run: npm publish
env:
NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'

- name: Get version
id: version
run: |
echo "version=$(jq .version pkg/sass-parser/package.json)" | tee --append "$GITHUB_OUTPUT"
- run: git tag sass-parser/${{ steps.version.outputs.version }}
- run: git push --tag

deploy_homebrew:
name: Deploy Homebrew
runs-on: ubuntu-latest
Expand Down
72 changes: 72 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,75 @@ jobs:
run: dart run test -p chrome -j 2
env:
CHROME_EXECUTABLE: chrome

sass_parser_tests:
name: "sass-parser Tests | Dart ${{ matrix.dart_channel }} | Node ${{ matrix.node-version }}"
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
dart_channel: [stable]
node-version: ['lts/*']
include:
# Test older LTS versions
#
# TODO: Test on lts/-2 and lts/-3 once they support
# `structuredClone()` (that is, once they're v18 or later).
- os: ubuntu-latest
dart_channel: stable
node-version: lts/-1
# Test LTS version with dart dev channel
- os: ubuntu-latest
dart_channel: dev
node-version: 'lts/*'

steps:
- uses: actions/checkout@v4
- uses: ./.github/util/initialize
with:
dart-sdk: ${{ matrix.dart_channel }}
github-token: ${{ github.token }}
node-version: ${{ matrix.node-version }}

- run: dart run grinder pkg-npm-dev
env: {UPDATE_SASS_SASS_REPO: false}
- run: npm link
working-directory: build/npm
- run: npm install
working-directory: pkg/sass-parser/
- run: npm link sass
working-directory: pkg/sass-parser/
- name: Run tests
run: npm test
working-directory: pkg/sass-parser/

sass_parser_static_analysis:
name: "sass-parser Static Analysis"
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: {node-version: 'lts/*'}
- run: npm install
working-directory: pkg/sass-parser/
- name: Run static analysis
run: npm run check
working-directory: pkg/sass-parser/

# TODO - postcss/postcss#1958: Enable this once PostCSS doesn't have TypeDoc
# warnings.

# sass_parser_typedoc:
# name: "sass-parser Typedoc"
# runs-on: ubuntu-latest
#
# steps:
# - uses: actions/checkout@v4
# - uses: actions/setup-node@v4
# with: {node-version: 'lts/*'}
# - run: npm install
# working-directory: pkg/sass-parser/
# - run: npm run typedoc
# working-directory: pkg/sass-parser/
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ pubspec.lock
package-lock.json
/benchmark/source
node_modules/
dist/
/doc/api
/pkg/*/doc/api
/pkg/sass-parser/doc

# Generated protocol buffer files.
*.pb*.dart
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ A [Dart][dart] implementation of [Sass][sass]. **Sass makes CSS fun**.
<table>
<tr>
<td>
<img width="118px" alt="Sass logo" src="https://rawgit.com/sass/sass-site/master/source/assets/img/logos/logo.svg" />
<img width="118px" alt="Sass logo" src="https://rawgit.com/sass/sass-site/main/source/assets/img/logos/logo.svg" />
</td>
<td valign="middle">
<a href="https://www.npmjs.com/package/sass"><img width="100%" alt="npm statistics" src="https://nodei.co/npm/sass.png?downloads=true"></a>
Expand All @@ -14,6 +14,8 @@ A [Dart][dart] implementation of [Sass][sass]. **Sass makes CSS fun**.
<a href="https://github.com/sass/dart-sass/actions"><img alt="GitHub actions build status" src="https://github.com/sass/dart-sass/workflows/CI/badge.svg"></a>
</td>
<td>
<a href="https://front-end.social/@sass"><img alt="@[email protected] on Fediverse" src="https://img.shields.io/mastodon/follow/110159358073946175?domain=https%3A%2F%2Ffront-end.social"></a>
<br>
<a href="https://twitter.com/SassCSS"><img alt="@SassCSS on Twitter" src="https://img.shields.io/twitter/follow/SassCSS?label=%40SassCSS&style=social"></a>
<br>
<a href="https://stackoverflow.com/questions/tagged/sass"><img alt="stackoverflow" src="https://img.shields.io/stackexchange/stackoverflow/t/sass?label=Sass%20questions&logo=stackoverflow&style=social"></a>
Expand Down
7 changes: 6 additions & 1 deletion lib/src/ast/sass/expression.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,20 @@ import '../../value.dart';
import '../../visitor/interface/expression.dart';
import '../sass.dart';

// Note: despite not defining any methods here, this hsa to be a concrete class
nex3 marked this conversation as resolved.
Show resolved Hide resolved
// so we can expose its accept() function to the JS parser.

/// A SassScript expression in a Sass syntax tree.
///
/// {@category AST}
/// {@category Parsing}
@sealed
abstract interface class Expression implements SassNode {
abstract class Expression implements SassNode {
/// Calls the appropriate visit method on [visitor].
T accept<T>(ExpressionVisitor<T> visitor);

Expression();

/// Parses an expression from [contents].
///
/// If passed, [url] is the name of the file from which [contents] comes.
Expand Down
5 changes: 4 additions & 1 deletion lib/src/ast/sass/expression/binary_operation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'list.dart';
/// A binary operator, as in `1 + 2` or `$this and $other`.
///
/// {@category AST}
final class BinaryOperationExpression implements Expression {
final class BinaryOperationExpression extends Expression {
/// The operator being invoked.
final BinaryOperator operator;

Expand Down Expand Up @@ -111,6 +111,9 @@ final class BinaryOperationExpression implements Expression {
///
/// {@category AST}
enum BinaryOperator {
// Note: When updating these operators, also update
// pkg/sass-parser/lib/src/expression/binary-operation.ts.

/// The Microsoft equals operator, `=`.
singleEquals('single equals', '=', 0),

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/boolean.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import '../expression.dart';
/// A boolean literal, `true` or `false`.
///
/// {@category AST}
final class BooleanExpression implements Expression {
final class BooleanExpression extends Expression {
/// The value of this expression.
final bool value;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/color.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import '../expression.dart';
/// A color literal.
///
/// {@category AST}
final class ColorExpression implements Expression {
final class ColorExpression extends Expression {
/// The value of this color.
final SassColor value;

Expand Down
4 changes: 2 additions & 2 deletions lib/src/ast/sass/expression/function.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import '../reference.dart';
/// interpolation.
///
/// {@category AST}
final class FunctionExpression
implements Expression, CallableInvocation, SassReference {
final class FunctionExpression extends Expression
implements CallableInvocation, SassReference {
/// The namespace of the function being invoked, or `null` if it's invoked
/// without a namespace.
final String? namespace;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/if.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import '../../../visitor/interface/expression.dart';
/// evaluated.
///
/// {@category AST}
final class IfExpression implements Expression, CallableInvocation {
final class IfExpression extends Expression implements CallableInvocation {
/// The declaration of `if()`, as though it were a normal function.
static final declaration = ArgumentDeclaration.parse(
r"@function if($condition, $if-true, $if-false) {");
Expand Down
4 changes: 2 additions & 2 deletions lib/src/ast/sass/expression/interpolated_function.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import '../interpolation.dart';
/// This is always a plain CSS function.
///
/// {@category AST}
final class InterpolatedFunctionExpression
implements Expression, CallableInvocation {
final class InterpolatedFunctionExpression extends Expression
implements CallableInvocation {
/// The name of the function being invoked.
final Interpolation name;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'unary_operation.dart';
/// A list literal.
///
/// {@category AST}
final class ListExpression implements Expression {
final class ListExpression extends Expression {
/// The elements of this list.
final List<Expression> contents;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import '../expression.dart';
/// A map literal.
///
/// {@category AST}
final class MapExpression implements Expression {
final class MapExpression extends Expression {
/// The pairs in this map.
///
/// This is a list of pairs rather than a map because a map may have two keys
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/null.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import '../expression.dart';
/// A null literal.
///
/// {@category AST}
final class NullExpression implements Expression {
final class NullExpression extends Expression {
final FileSpan span;

NullExpression(this.span);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/number.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import '../expression.dart';
/// A number literal.
///
/// {@category AST}
final class NumberExpression implements Expression {
final class NumberExpression extends Expression {
/// The numeric value.
final double value;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/parenthesized.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import '../expression.dart';
/// An expression wrapped in parentheses.
///
/// {@category AST}
final class ParenthesizedExpression implements Expression {
final class ParenthesizedExpression extends Expression {
/// The internal expression.
final Expression expression;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/selector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import '../expression.dart';
/// A parent selector reference, `&`.
///
/// {@category AST}
final class SelectorExpression implements Expression {
final class SelectorExpression extends Expression {
final FileSpan span;

SelectorExpression(this.span);
Expand Down
7 changes: 4 additions & 3 deletions lib/src/ast/sass/expression/string.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import '../interpolation.dart';
/// A string literal.
///
/// {@category AST}
final class StringExpression implements Expression {
final class StringExpression extends Expression {
/// Interpolation that, when evaluated, produces the contents of this string.
///
/// Unlike [asInterpolation], escapes are resolved and quotes are not
/// included.
/// If this is a quoted string, escapes are resolved and quotes are not
/// included in this text (unlike [asInterpolation]). If it's an unquoted
/// string, escapes are *not* resolved.
final Interpolation text;

/// Whether `this` has quotes.
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/supports.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import '../supports_condition.dart';
/// doesn't include the function name wrapping the condition.
///
/// {@category AST}
final class SupportsExpression implements Expression {
final class SupportsExpression extends Expression {
/// The condition itself.
final SupportsCondition condition;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/unary_operation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'list.dart';
/// A unary operator, as in `+$var` or `not fn()`.
///
/// {@category AST}
final class UnaryOperationExpression implements Expression {
final class UnaryOperationExpression extends Expression {
/// The operator being invoked.
final UnaryOperator operator;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/value.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import '../expression.dart';
/// constructed dynamically, as for the `call()` function.
///
/// {@category AST}
final class ValueExpression implements Expression {
final class ValueExpression extends Expression {
/// The embedded value.
final Value value;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/expression/variable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import '../reference.dart';
/// A Sass variable.
///
/// {@category AST}
final class VariableExpression implements Expression, SassReference {
final class VariableExpression extends Expression implements SassReference {
/// The namespace of the variable being referenced, or `null` if it's
/// referenced without a namespace.
final String? namespace;
Expand Down
5 changes: 4 additions & 1 deletion lib/src/ast/sass/statement.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import '../../visitor/interface/statement.dart';
import 'node.dart';

// Note: despite not defining any methods here, this hsa to be a concrete class
nex3 marked this conversation as resolved.
Show resolved Hide resolved
// so we can expose its accept() function to the JS parser.

/// A statement in a Sass syntax tree.
///
/// {@category AST}
abstract interface class Statement implements SassNode {
abstract class Statement implements SassNode {
/// Calls the appropriate visit method on [visitor].
T accept<T>(StatementVisitor<T> visitor);
}
2 changes: 1 addition & 1 deletion lib/src/ast/sass/statement/content_rule.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import '../statement.dart';
/// caller.
///
/// {@category AST}
final class ContentRule implements Statement {
final class ContentRule extends Statement {
/// The arguments pass to this `@content` rule.
///
/// This will be an empty invocation if `@content` has no arguments.
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/sass/statement/debug_rule.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import '../statement.dart';
/// This prints a Sass value for debugging purposes.
///
/// {@category AST}
final class DebugRule implements Statement {
final class DebugRule extends Statement {
/// The expression to print.
final Expression expression;

Expand Down
Loading