Skip to content

Commit 9e354f0

Browse files
connorskeesnex3
andauthored
Add first class mixins (#253)
Co-authored-by: Natalie Weizenbaum <[email protected]>
1 parent c9dee9b commit 9e354f0

File tree

8 files changed

+75
-5
lines changed

8 files changed

+75
-5
lines changed

CONTRIBUTING.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ These dependencies are made available in different ways depending on context.
7474
### Local Development
7575

7676
When developing locally, you can download all of these dependencies by running
77-
`npm run init`. This provides the following options for `compiler` (for the
78-
embedded compiler), `protocol` (for the embedded protocol), and `api` (for the
79-
JS API):
77+
`npm install` and then `npm run init`. This provides the following options for
78+
`compiler` (for the embedded compiler), `protocol` (for the embedded protocol),
79+
and `api` (for the JS API):
8080

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

88+
If developing locally, you will need to specify both the compiler and language.
89+
For example: `npm run init -- --compiler-path=dart-sass --language-path=language`.
90+
8891
By default:
8992

9093
* This uses the version of the embedded protocol and compiler specified by

lib/index.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const SassBoolean = sass.SassBoolean;
1313
export const SassCalculation = sass.SassCalculation
1414
export const SassColor = sass.SassColor;
1515
export const SassFunction = sass.SassFunction;
16+
export const SassMixin = sass.SassMixin;
1617
export const SassList = sass.SassList;
1718
export const SassMap = sass.SassMap;
1819
export const SassNumber = sass.SassNumber;
@@ -95,6 +96,10 @@ export default {
9596
defaultExportDeprecation();
9697
return sass.SassFunction;
9798
},
99+
get SassMixin() {
100+
defaultExportDeprecation();
101+
return sass.SassMixin;
102+
},
98103
get SassList() {
99104
defaultExportDeprecation();
100105
return sass.SassList;

lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export {sassFalse, sassTrue} from './src/value/boolean';
1212
export {SassColor} from './src/value/color';
1313
export {SassFunction} from './src/value/function';
1414
export {SassMap} from './src/value/map';
15+
export {SassMixin} from './src/value/mixin';
1516
export {SassNumber} from './src/value/number';
1617
export {SassString} from './src/value/string';
1718
export {Value} from './src/value';

lib/src/protofier.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
CalculationOperation,
2525
CalculationOperator,
2626
} from './value/calculations';
27+
import {SassMixin} from './value/mixin';
2728

2829
/**
2930
* A class that converts [Value] objects into protobufs.
@@ -119,6 +120,10 @@ export class Protofier {
119120
fn.signature = value.signature!;
120121
result.value = {case: 'hostFunction', value: fn};
121122
}
123+
} else if (value instanceof SassMixin) {
124+
const mixin = new proto.Value_CompilerMixin();
125+
mixin.id = value.id;
126+
result.value = {case: 'compilerMixin', value: mixin};
122127
} else if (value instanceof SassCalculation) {
123128
result.value = {
124129
case: 'calculation',
@@ -322,6 +327,9 @@ export class Protofier {
322327
'The compiler may not send Value.host_function.'
323328
);
324329

330+
case 'compilerMixin':
331+
return new SassMixin(value.value.value.id);
332+
325333
case 'calculation':
326334
return this.deprotofyCalculation(value.value.value);
327335

lib/src/value/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {SassNumber} from './number';
1212
import {SassString} from './string';
1313
import {valueError} from '../utils';
1414
import {SassCalculation} from './calculations';
15+
import {SassMixin} from './mixin';
1516

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

143+
/**
144+
* Casts `this` to `SassMixin`; throws if `this` isn't a mixin
145+
* reference.
146+
*
147+
* If `this` came from a function argument, `name` is the argument name
148+
* (without the `$`) and is used for error reporting.
149+
*/
150+
assertMixin(name?: string): SassMixin {
151+
throw valueError(`${this} is not a mixin reference`, name);
152+
}
153+
142154
/**
143155
* Casts `this` to `SassMap`; throws if `this` isn't a map.
144156
*

lib/src/value/mixin.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2021 Google LLC. Use of this source code is governed by an
2+
// MIT-style license that can be found in the LICENSE file or at
3+
// https://opensource.org/licenses/MIT.
4+
5+
import {hash} from 'immutable';
6+
7+
import {Value} from './index';
8+
9+
/** A first-class SassScript mixin. */
10+
export class SassMixin extends Value {
11+
/**
12+
* This is the unique ID that the compiler uses to determine which mixin it
13+
* refers to.
14+
*
15+
* This is marked as public so that the protofier can access it, but it's not
16+
* part of the package's public API and should not be accessed by user code.
17+
* It may be renamed or removed without warning in the future.
18+
*/
19+
readonly id: number;
20+
21+
constructor(id: number) {
22+
super();
23+
this.id = id;
24+
}
25+
26+
equals(other: Value): boolean {
27+
return other instanceof SassMixin && other.id === this.id;
28+
}
29+
30+
hashCode(): number {
31+
return hash(this.id);
32+
}
33+
34+
toString(): string {
35+
return `<compiler mixin ${this.id}>`;
36+
}
37+
38+
assertMixin(): SassMixin {
39+
return this;
40+
}
41+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sass-embedded",
33
"version": "1.68.0",
4-
"protocol-version": "2.2.0",
4+
"protocol-version": "2.3.0",
55
"compiler-version": "1.68.0",
66
"description": "Node.js library that communicates with Embedded Dart Sass using the Embedded Sass protocol",
77
"repository": "sass/embedded-host-node",

tool/get-embedded-compiler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as shell from 'shelljs';
88
import * as utils from './utils';
99

1010
/**
11-
* Downlaods and builds the Embedded Dart Sass compiler.
11+
* Downloads and builds the Embedded Dart Sass compiler.
1212
*
1313
* Can check out and build the source from a Git `ref` or build from the source
1414
* at `path`. By default, checks out the latest revision from GitHub.

0 commit comments

Comments
 (0)