Skip to content

Commit 00bdcca

Browse files
committed
Fix another case we have something that looks like a mixing that is used within a list of values
Fixes microsoft#44
1 parent f6672eb commit 00bdcca

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

e2e/tests/errors.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,5 +227,60 @@ describe('Errors', () => {
227227
assert.strictEqual(errorResponse.body.length, 0);
228228
});
229229
});
230+
231+
it('should not return an error for a placeholder that spans multiple lines (#44)', () => {
232+
const server = createServer();
233+
openMockFile(server, mockFileName, `let css: any = {}; const q = css.a\`
234+
color:
235+
$\{'transparent'};
236+
border-bottom: 1px;
237+
&:hover {
238+
color: inherit;
239+
text-decoration: none;
240+
}
241+
}
242+
\``)
243+
server.send({ command: 'semanticDiagnosticsSync', arguments: { file: mockFileName } });
244+
245+
return server.close().then(() => {
246+
const errorResponse = getFirstResponseOfType('semanticDiagnosticsSync', server);
247+
assert.isTrue(errorResponse.success);
248+
assert.strictEqual(errorResponse.body.length, 0);
249+
});
250+
});
251+
252+
253+
it('should not return an error for complicated style (#44)', () => {
254+
const server = createServer();
255+
openMockFile(server, mockFileName, `let css: any = {}; const q = css.a\`
256+
display: flex;
257+
width: 6rem;
258+
height: 5rem;
259+
margin-right: -3px;
260+
border-right: 3px solid
261+
$\{({ active, theme: { colors } }) =>
262+
active ? colors.yellow : 'transparent'};
263+
border-bottom: 1px solid rgba(255, 255, 255, 0.5);
264+
font-weight: bold;
265+
font-size: 0.875rem;
266+
color: white;
267+
cursor: pointer;
268+
&:not([href]):not([tabindex]) {
269+
color: white;
270+
}
271+
&:hover {
272+
color: inherit;
273+
text-decoration: none;
274+
}
275+
\``)
276+
server.send({ command: 'semanticDiagnosticsSync', arguments: { file: mockFileName } });
277+
278+
return server.close().then(() => {
279+
const errorResponse = getFirstResponseOfType('semanticDiagnosticsSync', server);
280+
assert.isTrue(errorResponse.success);
281+
assert.strictEqual(errorResponse.body.length, 0);
282+
});
283+
});
284+
230285
});
231286

src/index.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,29 @@ export = (mod: { typescript: typeof ts }) => {
3232
// if in-property, replace with "xxxxxx"
3333
// if a mixin, replace with " "
3434
const pre = templateString.slice(0, start);
35-
36-
const replacementChar = pre.match(/(^|\n)\s*$/g) && !templateString.slice(end).match(/^\s*\{/) /* ${'button'} */ ? ' ' : 'x';
35+
const post = templateString.slice(end);
36+
const replacementChar = pre.match(/(^|\n)\s*$/g) && !post.match(/^\s*\{/) /* ${'button'} */ ? ' ' : 'x';
3737

3838
const result = placeholder.replace(/./gm, c => c === '\n' ? '\n' : replacementChar);
3939

40-
// check if it's a mixin and if followed by a semicolon
41-
// if so, replace with a dummy variable declaration, so scss server doesn't complain about rogue semicolon
42-
if (replacementChar === ' ' && templateString.slice(end).match(/^\s*;/)) {
43-
return '$a:0' + result.slice(4);
40+
// If followed by a semicolon, we may have to eat the semi colon using a false property
41+
if (replacementChar === ' ' && post.match(/^\s*;/)) {
42+
// Handle case where we need to eat the semi colon:
43+
//
44+
// styled.x`
45+
// ${'color: red'};
46+
// `
47+
//
48+
// vs. the other case where we do not:
49+
//
50+
// styled.x`
51+
// color: ${'red'};
52+
// `
53+
if (pre.match(/(;|^|\})[\s|\n]*$$/)) {
54+
// Mixin, replace with a dummy variable declaration, so scss server doesn't complain about rogue semicolon
55+
return '$a:0' + result.slice(4); // replace(/./gm, c => c === '\n' ? '\n' : ' ');
56+
}
57+
return placeholder.replace(/./gm, c => c === '\n' ? '\n' : 'x');
4458
}
4559

4660
return result;

0 commit comments

Comments
 (0)