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

add first class mixins #253

Merged
merged 6 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 6 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ These dependencies are made available in different ways depending on context.
### Local Development

When developing locally, you can download all of these dependencies by running
`npm run init`. This provides the following options for `compiler` (for the
embedded compiler), `protocol` (for the embedded protocol), and `api` (for the
JS API):
`npm install` and then `npm run init`. This provides the following options for
`compiler` (for the embedded compiler), `protocol` (for the embedded protocol),
and `api` (for the JS API):
Comment on lines +77 to +79
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content change here is to add "npm install and then ". The rest of the diff is reflowing to 80 characters.


* `--<type>-path`: The local filesystem path of the package to use. This is
useful when doing local development on both the host and its dependencies at
Expand All @@ -85,6 +85,9 @@ JS API):
* `--<type>-ref`: A Git reference for the GitHub repository of the package to
clone.

If developing locally, you will need to specify both the compiler and language.
For example: `npm run init -- --compiler-path=dart-sass --language-path=language`.

By default:

* This uses the version of the embedded protocol and compiler specified by
Expand Down
5 changes: 5 additions & 0 deletions lib/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const SassBoolean = sass.SassBoolean;
export const SassCalculation = sass.SassCalculation
export const SassColor = sass.SassColor;
export const SassFunction = sass.SassFunction;
export const SassMixin = sass.SassMixin;
export const SassList = sass.SassList;
export const SassMap = sass.SassMap;
export const SassNumber = sass.SassNumber;
Expand Down Expand Up @@ -95,6 +96,10 @@ export default {
defaultExportDeprecation();
return sass.SassFunction;
},
get SassMixin() {
defaultExportDeprecation();
return sass.SassMixin;
},
get SassList() {
defaultExportDeprecation();
return sass.SassList;
Expand Down
1 change: 1 addition & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export {sassFalse, sassTrue} from './src/value/boolean';
export {SassColor} from './src/value/color';
export {SassFunction} from './src/value/function';
export {SassMap} from './src/value/map';
export {SassMixin} from './src/value/mixin';
export {SassNumber} from './src/value/number';
export {SassString} from './src/value/string';
export {Value} from './src/value';
Expand Down
9 changes: 9 additions & 0 deletions lib/src/protofier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
CalculationOperation,
CalculationOperator,
} from './value/calculations';
import { SassMixin } from './value/mixin';

/**
* A class that converts [Value] objects into protobufs.
Expand Down Expand Up @@ -119,6 +120,10 @@ export class Protofier {
fn.signature = value.signature!;
result.value = {case: 'hostFunction', value: fn};
}
} else if (value instanceof SassMixin) {
const mixin = new proto.Value_CompilerMixin();
mixin.id = value.id;
result.value = {case: 'compilerMixin', value: mixin};
} else if (value instanceof SassCalculation) {
result.value = {
case: 'calculation',
Expand Down Expand Up @@ -322,6 +327,10 @@ export class Protofier {
'The compiler may not send Value.host_function.'
);

case 'compilerMixin':
return new SassMixin(value.value.value.id);


connorskees marked this conversation as resolved.
Show resolved Hide resolved
case 'calculation':
return this.deprotofyCalculation(value.value.value);

Expand Down
12 changes: 12 additions & 0 deletions lib/src/value/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {SassNumber} from './number';
import {SassString} from './string';
import {valueError} from '../utils';
import {SassCalculation} from './calculations';
import { SassMixin } from './mixin';

/**
* A SassScript value.
Expand Down Expand Up @@ -139,6 +140,17 @@ export abstract class Value implements ValueObject {
// TODO(awjin): Narrow the return type to SassFunction.
}

/**
* Casts `this` to `SassMixin`; throws if `this` isn't a mixin
* reference.
*
* If `this` came from a function argument, `name` is the argument name
* (without the `$`) and is used for error reporting.
*/
assertMixin(name?: string): SassMixin {
throw valueError(`${this} is not a mixin reference`, name);
}

/**
* Casts `this` to `SassMap`; throws if `this` isn't a map.
*
Expand Down
43 changes: 43 additions & 0 deletions lib/src/value/mixin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2021 Google LLC. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import {hash} from 'immutable';

import {Value} from './index';

/** A first-class SassScript mixin. */
export class SassMixin extends Value {
/**
* If this mixin is defined in the compiler, this is the unique ID that the
* compiler uses to determine which mixin it refers to.
*
* This is marked as public so that the protofier can access it, but it's not
* part of the package's public API and should not be accessed by user code.
* It may be renamed or removed without warning in the future.
*/
readonly id: number | undefined;
connorskees marked this conversation as resolved.
Show resolved Hide resolved

constructor(id: number) {
super();
this.id = id;
}

equals(other: Value): boolean {
return this.id === undefined
? other === this
: other instanceof SassMixin && other.id === this.id;
connorskees marked this conversation as resolved.
Show resolved Hide resolved
}

hashCode(): number {
return hash(this.id);
}

toString(): string {
return `<compiler mixin ${this.id}>`;
}

assertMixin(): SassMixin {
return this;
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "sass-embedded",
"version": "1.68.0",
"protocol-version": "2.2.0",
"protocol-version": "2.3.0",
"compiler-version": "1.68.0",
"description": "Node.js library that communicates with Embedded Dart Sass using the Embedded Sass protocol",
"repository": "sass/embedded-host-node",
Expand Down
2 changes: 1 addition & 1 deletion tool/get-embedded-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as shell from 'shelljs';
import * as utils from './utils';

/**
* Downlaods and builds the Embedded Dart Sass compiler.
* Downloads and builds the Embedded Dart Sass compiler.
*
* Can check out and build the source from a Git `ref` or build from the source
* at `path`. By default, checks out the latest revision from GitHub.
Expand Down