vscode-css-languageservice 6.2.13 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -109,6 +109,7 @@
109
109
  NodeType[NodeType["LayerName"] = 85] = "LayerName";
110
110
  NodeType[NodeType["PropertyAtRule"] = 86] = "PropertyAtRule";
111
111
  NodeType[NodeType["Container"] = 87] = "Container";
112
+ NodeType[NodeType["ModuleConfig"] = 88] = "ModuleConfig";
112
113
  })(NodeType || (exports.NodeType = NodeType = {}));
113
114
  var ReferenceType;
114
115
  (function (ReferenceType) {
@@ -837,10 +838,10 @@
837
838
  get type() {
838
839
  return NodeType.Use;
839
840
  }
841
+ setParameters(value) {
842
+ return this.setNode('parameters', value);
843
+ }
840
844
  getParameters() {
841
- if (!this.parameters) {
842
- this.parameters = new Nodelist(this);
843
- }
844
845
  return this.parameters;
845
846
  }
846
847
  setIdentifier(node) {
@@ -882,16 +883,10 @@
882
883
  getIdentifier() {
883
884
  return this.identifier;
884
885
  }
885
- getMembers() {
886
- if (!this.members) {
887
- this.members = new Nodelist(this);
888
- }
889
- return this.members;
886
+ setParameters(value) {
887
+ return this.setNode('parameters', value);
890
888
  }
891
889
  getParameters() {
892
- if (!this.parameters) {
893
- this.parameters = new Nodelist(this);
894
- }
895
890
  return this.parameters;
896
891
  }
897
892
  }
@@ -287,7 +287,7 @@
287
287
  || this._parseViewPort()
288
288
  || this._parseNamespace()
289
289
  || this._parseDocument()
290
- || this._parseContainer()
290
+ || this._parseContainer(isNested)
291
291
  || this._parseUnknownAtRule();
292
292
  }
293
293
  _tryParseRuleset(isNested) {
@@ -321,6 +321,7 @@
321
321
  return this._parseMedia(true)
322
322
  || this._parseSupports(true)
323
323
  || this._parseLayer(true)
324
+ || this._parseContainer(true)
324
325
  || this._parseUnknownAtRule();
325
326
  }
326
327
  _parseRuleSetDeclaration() {
@@ -1148,7 +1149,14 @@
1148
1149
  this.resync([], [cssScanner_1.TokenType.CurlyL]); // ignore all the rules
1149
1150
  return this._parseBody(node, this._parseStylesheetStatement.bind(this));
1150
1151
  }
1151
- _parseContainer() {
1152
+ _parseContainerDeclaration(isNested = false) {
1153
+ if (isNested) {
1154
+ // if nested, the body can contain rulesets, but also declarations
1155
+ return this._tryParseRuleset(true) || this._tryToParseDeclaration() || this._parseStylesheetStatement(true);
1156
+ }
1157
+ return this._parseStylesheetStatement(false);
1158
+ }
1159
+ _parseContainer(isNested = false) {
1152
1160
  if (!this.peekKeyword('@container')) {
1153
1161
  return null;
1154
1162
  }
@@ -1156,7 +1164,7 @@
1156
1164
  this.consumeToken(); // @container
1157
1165
  node.addChild(this._parseIdent()); // optional container name
1158
1166
  node.addChild(this._parseContainerQuery());
1159
- return this._parseBody(node, this._parseStylesheetStatement.bind(this));
1167
+ return this._parseBody(node, this._parseContainerDeclaration.bind(this, isNested));
1160
1168
  }
1161
1169
  _parseContainerQuery() {
1162
1170
  // <container-query> = not <query-in-parens>
@@ -285,7 +285,7 @@
285
285
  || this._parseSupports(true) // @supports
286
286
  || this._parseLayer() // @layer
287
287
  || this._parsePropertyAtRule() // @property
288
- || this._parseContainer() // @container
288
+ || this._parseContainer(true) // @container
289
289
  || this._parseDetachedRuleSetMixin() // less detached ruleset mixin
290
290
  || this._parseVariableDeclaration() // Variable declarations
291
291
  || this._parseRuleSetDeclarationAtStatement();
@@ -230,7 +230,7 @@
230
230
  || this._parseSupports(true) // @supports
231
231
  || this._parseLayer() // @layer
232
232
  || this._parsePropertyAtRule() // @property
233
- || this._parseContainer() // @container
233
+ || this._parseContainer(true) // nested @container
234
234
  || this._parseRuleSetDeclarationAtStatement();
235
235
  }
236
236
  return this._parseVariableDeclaration() // variable declaration
@@ -716,24 +716,9 @@
716
716
  return this.finish(node, cssErrors_1.ParseError.IdentifierOrWildcardExpected);
717
717
  }
718
718
  if (this.acceptIdent('with')) {
719
- if (!this.accept(cssScanner_1.TokenType.ParenthesisL)) {
719
+ if (!node.setParameters(this._parseModuleConfig())) {
720
720
  return this.finish(node, cssErrors_1.ParseError.LeftParenthesisExpected, [cssScanner_1.TokenType.ParenthesisR]);
721
721
  }
722
- // First variable statement, no comma.
723
- if (!node.getParameters().addChild(this._parseModuleConfigDeclaration())) {
724
- return this.finish(node, cssErrors_1.ParseError.VariableNameExpected);
725
- }
726
- while (this.accept(cssScanner_1.TokenType.Comma)) {
727
- if (this.peek(cssScanner_1.TokenType.ParenthesisR)) {
728
- break;
729
- }
730
- if (!node.getParameters().addChild(this._parseModuleConfigDeclaration())) {
731
- return this.finish(node, cssErrors_1.ParseError.VariableNameExpected);
732
- }
733
- }
734
- if (!this.accept(cssScanner_1.TokenType.ParenthesisR)) {
735
- return this.finish(node, cssErrors_1.ParseError.RightParenthesisExpected);
736
- }
737
722
  }
738
723
  }
739
724
  if (!this.accept(cssScanner_1.TokenType.SemiColon) && !this.accept(cssScanner_1.TokenType.EOF)) {
@@ -741,6 +726,28 @@
741
726
  }
742
727
  return this.finish(node);
743
728
  }
729
+ _parseModuleConfig() {
730
+ const node = this.createNode(nodes.NodeType.ModuleConfig);
731
+ if (!this.accept(cssScanner_1.TokenType.ParenthesisL)) {
732
+ return null;
733
+ }
734
+ // First variable statement, no comma.
735
+ if (!node.addChild(this._parseModuleConfigDeclaration())) {
736
+ return this.finish(node, cssErrors_1.ParseError.VariableNameExpected);
737
+ }
738
+ while (this.accept(cssScanner_1.TokenType.Comma)) {
739
+ if (this.peek(cssScanner_1.TokenType.ParenthesisR)) {
740
+ break;
741
+ }
742
+ if (!node.addChild(this._parseModuleConfigDeclaration())) {
743
+ return this.finish(node, cssErrors_1.ParseError.VariableNameExpected);
744
+ }
745
+ }
746
+ if (!this.accept(cssScanner_1.TokenType.ParenthesisR)) {
747
+ return this.finish(node, cssErrors_1.ParseError.RightParenthesisExpected);
748
+ }
749
+ return this.finish(node);
750
+ }
744
751
  _parseModuleConfigDeclaration() {
745
752
  const node = this.create(nodes.ModuleConfiguration);
746
753
  if (!node.setIdentifier(this._parseVariable())) {
@@ -776,24 +783,9 @@
776
783
  }
777
784
  }
778
785
  if (this.acceptIdent('with')) {
779
- if (!this.accept(cssScanner_1.TokenType.ParenthesisL)) {
786
+ if (!node.setParameters(this._parseModuleConfig())) {
780
787
  return this.finish(node, cssErrors_1.ParseError.LeftParenthesisExpected, [cssScanner_1.TokenType.ParenthesisR]);
781
788
  }
782
- // First variable statement, no comma.
783
- if (!node.getParameters().addChild(this._parseModuleConfigDeclaration())) {
784
- return this.finish(node, cssErrors_1.ParseError.VariableNameExpected);
785
- }
786
- while (this.accept(cssScanner_1.TokenType.Comma)) {
787
- if (this.peek(cssScanner_1.TokenType.ParenthesisR)) {
788
- break;
789
- }
790
- if (!node.getParameters().addChild(this._parseModuleConfigDeclaration())) {
791
- return this.finish(node, cssErrors_1.ParseError.VariableNameExpected);
792
- }
793
- }
794
- if (!this.accept(cssScanner_1.TokenType.ParenthesisR)) {
795
- return this.finish(node, cssErrors_1.ParseError.RightParenthesisExpected);
796
- }
797
789
  }
798
790
  else if (this.peekIdent('hide') || this.peekIdent('show')) {
799
791
  if (!node.addChild(this._parseForwardVisibility())) {
@@ -13,7 +13,7 @@
13
13
  *--------------------------------------------------------------------------------------------*/
14
14
  'use strict';
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.CSSNavigation = void 0;
16
+ exports.getModuleNameFromPath = exports.CSSNavigation = void 0;
17
17
  const cssLanguageTypes_1 = require("../cssLanguageTypes");
18
18
  const l10n = require("@vscode/l10n");
19
19
  const nodes = require("../parser/cssNodes");
@@ -59,7 +59,7 @@
59
59
  getHighlightNode(document, position, stylesheet) {
60
60
  const offset = document.offsetAt(position);
61
61
  let node = nodes.getNodeAtOffset(stylesheet, offset);
62
- if (!node || node.type === nodes.NodeType.Stylesheet || node.type === nodes.NodeType.Declarations) {
62
+ if (!node || node.type === nodes.NodeType.Stylesheet || node.type === nodes.NodeType.Declarations || node.type === nodes.NodeType.ModuleConfig) {
63
63
  return;
64
64
  }
65
65
  if (node.type === nodes.NodeType.Identifier && node.parent && node.parent.type === nodes.NodeType.ClassSelector) {
@@ -418,6 +418,17 @@
418
418
  return false;
419
419
  }
420
420
  }
421
+ async getContent(uri) {
422
+ if (!this.fileSystemProvider || !this.fileSystemProvider.getContent) {
423
+ return null;
424
+ }
425
+ try {
426
+ return await this.fileSystemProvider.getContent(uri);
427
+ }
428
+ catch (err) {
429
+ return null;
430
+ }
431
+ }
421
432
  }
422
433
  exports.CSSNavigation = CSSNavigation;
423
434
  function getColorInformation(node, document) {
@@ -494,4 +505,5 @@
494
505
  // Otherwise get until first instance of '/'
495
506
  return path.substring(0, firstSlash);
496
507
  }
508
+ exports.getModuleNameFromPath = getModuleNameFromPath;
497
509
  });
@@ -4,7 +4,7 @@
4
4
  if (v !== undefined) module.exports = v;
5
5
  }
6
6
  else if (typeof define === "function" && define.amd) {
7
- define(["require", "exports", "./cssNavigation", "../parser/cssNodes", "vscode-uri", "../utils/strings"], factory);
7
+ define(["require", "exports", "./cssNavigation", "../parser/cssNodes", "vscode-uri", "../utils/strings", "../utils/resources"], factory);
8
8
  }
9
9
  })(function (require, exports) {
10
10
  /*---------------------------------------------------------------------------------------------
@@ -18,6 +18,7 @@
18
18
  const nodes = require("../parser/cssNodes");
19
19
  const vscode_uri_1 = require("vscode-uri");
20
20
  const strings_1 = require("../utils/strings");
21
+ const resources_1 = require("../utils/resources");
21
22
  class SCSSNavigation extends cssNavigation_1.CSSNavigation {
22
23
  constructor(fileSystemProvider) {
23
24
  super(fileSystemProvider, true);
@@ -42,8 +43,102 @@
42
43
  if ((0, strings_1.startsWith)(target, 'sass:')) {
43
44
  return undefined; // sass library
44
45
  }
46
+ // Following the [sass package importer](https://github.com/sass/sass/blob/f6832f974c61e35c42ff08b3640ff155071a02dd/js-api-doc/importer.d.ts#L349),
47
+ // look for the `exports` field of the module and any `sass`, `style` or `default` that matches the import.
48
+ // If it's only `pkg:module`, also look for `sass` and `style` on the root of package.json.
49
+ if (target.startsWith('pkg:')) {
50
+ return this.resolvePkgModulePath(target, documentUri, documentContext);
51
+ }
45
52
  return super.resolveReference(target, documentUri, documentContext, isRawLink);
46
53
  }
54
+ async resolvePkgModulePath(target, documentUri, documentContext) {
55
+ const bareTarget = target.replace('pkg:', '');
56
+ const moduleName = bareTarget.includes('/') ? (0, cssNavigation_1.getModuleNameFromPath)(bareTarget) : bareTarget;
57
+ const rootFolderUri = documentContext.resolveReference('/', documentUri);
58
+ const documentFolderUri = (0, resources_1.dirname)(documentUri);
59
+ const modulePath = await this.resolvePathToModule(moduleName, documentFolderUri, rootFolderUri);
60
+ if (!modulePath) {
61
+ return undefined;
62
+ }
63
+ // Since submodule exports import strings don't match the file system,
64
+ // we need the contents of `package.json` to look up the correct path.
65
+ let packageJsonContent = await this.getContent((0, resources_1.joinPath)(modulePath, 'package.json'));
66
+ if (!packageJsonContent) {
67
+ return undefined;
68
+ }
69
+ let packageJson;
70
+ try {
71
+ packageJson = JSON.parse(packageJsonContent);
72
+ }
73
+ catch (e) {
74
+ // problems parsing package.json
75
+ return undefined;
76
+ }
77
+ const subpath = bareTarget.substring(moduleName.length + 1);
78
+ if (packageJson.exports) {
79
+ if (!subpath) {
80
+ const dotExport = packageJson.exports['.'];
81
+ // look for the default/index export
82
+ // @ts-expect-error If ['.'] is a string this just produces undefined
83
+ const entry = dotExport && (dotExport['sass'] || dotExport['style'] || dotExport['default']);
84
+ // the 'default' entry can be whatever, typically .js – confirm it looks like `scss`
85
+ if (entry && entry.endsWith('.scss')) {
86
+ const entryPath = (0, resources_1.joinPath)(modulePath, entry);
87
+ return entryPath;
88
+ }
89
+ }
90
+ else {
91
+ // The import string may be with or without .scss.
92
+ // Likewise the exports entry. Look up both paths.
93
+ // However, they need to be relative (start with ./).
94
+ const lookupSubpath = subpath.endsWith('.scss') ? `./${subpath.replace('.scss', '')}` : `./${subpath}`;
95
+ const lookupSubpathScss = subpath.endsWith('.scss') ? `./${subpath}` : `./${subpath}.scss`;
96
+ const subpathObject = packageJson.exports[lookupSubpathScss] || packageJson.exports[lookupSubpath];
97
+ if (subpathObject) {
98
+ // @ts-expect-error If subpathObject is a string this just produces undefined
99
+ const entry = subpathObject['sass'] || subpathObject['styles'] || subpathObject['default'];
100
+ // the 'default' entry can be whatever, typically .js – confirm it looks like `scss`
101
+ if (entry && entry.endsWith('.scss')) {
102
+ const entryPath = (0, resources_1.joinPath)(modulePath, entry);
103
+ return entryPath;
104
+ }
105
+ }
106
+ else {
107
+ // We have a subpath, but found no matches on direct lookup.
108
+ // It may be a [subpath pattern](https://nodejs.org/api/packages.html#subpath-patterns).
109
+ for (const [maybePattern, subpathObject] of Object.entries(packageJson.exports)) {
110
+ if (!maybePattern.includes("*")) {
111
+ continue;
112
+ }
113
+ // Patterns may also be without `.scss` on the left side, so compare without on both sides
114
+ const re = new RegExp((0, strings_1.convertSimple2RegExpPattern)(maybePattern.replace('.scss', '')).replace(/\.\*/g, '(.*)'));
115
+ const match = re.exec(lookupSubpath);
116
+ if (match) {
117
+ // @ts-expect-error If subpathObject is a string this just produces undefined
118
+ const entry = subpathObject['sass'] || subpathObject['styles'] || subpathObject['default'];
119
+ // the 'default' entry can be whatever, typically .js – confirm it looks like `scss`
120
+ if (entry && entry.endsWith('.scss')) {
121
+ // The right-hand side of a subpath pattern is also a pattern.
122
+ // Replace the pattern with the match from our regexp capture group above.
123
+ const expandedPattern = entry.replace('*', match[1]);
124
+ const entryPath = (0, resources_1.joinPath)(modulePath, expandedPattern);
125
+ return entryPath;
126
+ }
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }
132
+ else if (!subpath && (packageJson.sass || packageJson.style)) {
133
+ // Fall back to a direct lookup on `sass` and `style` on package root
134
+ const entry = packageJson.sass || packageJson.style;
135
+ if (entry) {
136
+ const entryPath = (0, resources_1.joinPath)(modulePath, entry);
137
+ return entryPath;
138
+ }
139
+ }
140
+ return undefined;
141
+ }
47
142
  }
48
143
  exports.SCSSNavigation = SCSSNavigation;
49
144
  function toPathVariations(target) {
@@ -13,7 +13,7 @@
13
13
  *--------------------------------------------------------------------------------------------*/
14
14
  'use strict';
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.repeat = exports.trim = exports.getLimitedString = exports.difference = exports.endsWith = exports.startsWith = void 0;
16
+ exports.convertSimple2RegExpPattern = exports.repeat = exports.trim = exports.getLimitedString = exports.difference = exports.endsWith = exports.startsWith = void 0;
17
17
  function startsWith(haystack, needle) {
18
18
  if (haystack.length < needle.length) {
19
19
  return false;
@@ -117,4 +117,8 @@
117
117
  return s;
118
118
  }
119
119
  exports.repeat = repeat;
120
+ function convertSimple2RegExpPattern(pattern) {
121
+ return pattern.replace(/[\-\\\{\}\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&').replace(/[\*]/g, '.*');
122
+ }
123
+ exports.convertSimple2RegExpPattern = convertSimple2RegExpPattern;
120
124
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vscode-css-languageservice",
3
- "version": "6.2.13",
3
+ "version": "6.3.0",
4
4
  "description": "Language service for CSS, LESS and SCSS",
5
5
  "main": "./lib/umd/cssLanguageService.js",
6
6
  "typings": "./lib/umd/cssLanguageService",
@@ -15,17 +15,17 @@
15
15
  "url": "https://github.com/Microsoft/vscode-css-languageservice"
16
16
  },
17
17
  "devDependencies": {
18
- "@types/mocha": "^10.0.6",
18
+ "@types/mocha": "^10.0.7",
19
19
  "@types/node": "16.x",
20
- "@typescript-eslint/eslint-plugin": "^6.21.0",
21
- "@typescript-eslint/parser": "^6.21.0",
22
- "@vscode/web-custom-data": "^0.4.9",
20
+ "@typescript-eslint/eslint-plugin": "^7.13.1",
21
+ "@typescript-eslint/parser": "^7.13.1",
22
+ "@vscode/web-custom-data": "^0.4.11",
23
23
  "eslint": "^8.57.0",
24
24
  "js-beautify": "^1.15.1",
25
- "mocha": "^10.3.0",
26
- "rimraf": "^5.0.5",
25
+ "mocha": "^10.4.0",
26
+ "rimraf": "^5.0.7",
27
27
  "source-map-support": "^0.5.21",
28
- "typescript": "^5.3.3"
28
+ "typescript": "^5.4.2"
29
29
  },
30
30
  "dependencies": {
31
31
  "@vscode/l10n": "^0.0.18",