diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bcdbc8c7..cc5fbeb4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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): * `---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 @@ -85,6 +85,9 @@ JS API): * `---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 diff --git a/lib/index.mjs b/lib/index.mjs index 374e98e9..ff94ed4e 100644 --- a/lib/index.mjs +++ b/lib/index.mjs @@ -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; @@ -95,6 +96,10 @@ export default { defaultExportDeprecation(); return sass.SassFunction; }, + get SassMixin() { + defaultExportDeprecation(); + return sass.SassMixin; + }, get SassList() { defaultExportDeprecation(); return sass.SassList; diff --git a/lib/index.ts b/lib/index.ts index c79ffec2..69005262 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -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'; diff --git a/lib/src/protofier.ts b/lib/src/protofier.ts index 0092cc11..e2d7f951 100644 --- a/lib/src/protofier.ts +++ b/lib/src/protofier.ts @@ -24,6 +24,7 @@ import { CalculationOperation, CalculationOperator, } from './value/calculations'; +import {SassMixin} from './value/mixin'; /** * A class that converts [Value] objects into protobufs. @@ -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', @@ -322,6 +327,9 @@ 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); diff --git a/lib/src/value/index.ts b/lib/src/value/index.ts index d7c95f8e..6e5129fe 100644 --- a/lib/src/value/index.ts +++ b/lib/src/value/index.ts @@ -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. @@ -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. * diff --git a/lib/src/value/mixin.ts b/lib/src/value/mixin.ts new file mode 100644 index 00000000..1d8ecd86 --- /dev/null +++ b/lib/src/value/mixin.ts @@ -0,0 +1,41 @@ +// 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 { + /** + * 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; + + constructor(id: number) { + super(); + this.id = id; + } + + equals(other: Value): boolean { + return other instanceof SassMixin && other.id === this.id; + } + + hashCode(): number { + return hash(this.id); + } + + toString(): string { + return ``; + } + + assertMixin(): SassMixin { + return this; + } +} diff --git a/package.json b/package.json index 32bdafa6..567126ac 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/tool/get-embedded-compiler.ts b/tool/get-embedded-compiler.ts index 2b702a2a..cb8b7245 100644 --- a/tool/get-embedded-compiler.ts +++ b/tool/get-embedded-compiler.ts @@ -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.