Skip to content

Commit

Permalink
add first class mixins
Browse files Browse the repository at this point in the history
  • Loading branch information
connorskees committed Sep 29, 2023
1 parent 6849715 commit 8e0bb25
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 5 deletions.
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):

* `--<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);


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;

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

equals(other: Value): boolean {
return this.id === undefined
? other === this
: other instanceof SassMixin && other.id === this.id;
}

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

0 comments on commit 8e0bb25

Please sign in to comment.