Skip to content

Commit 15f4595

Browse files
committed
Extract getSubstitution to own file
1 parent fe083be commit 15f4595

File tree

2 files changed

+67
-49
lines changed

2 files changed

+67
-49
lines changed

src/index.ts

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as ts from 'typescript/lib/tsserverlibrary';
88
import { loadConfiguration } from './configuration';
99
import { LanguageServiceLogger } from './logger';
1010
import StyledTemplateLanguageService from './styled-template-language-service';
11+
import { getSubstitution } from './substituter';
1112

1213
export = (mod: { typescript: typeof ts }) => {
1314
return {
@@ -25,57 +26,9 @@ export = (mod: { typescript: typeof ts }) => {
2526
start: number,
2627
end: number
2728
): string {
28-
const placeholder = templateString.slice(start, end);
29-
30-
// check to see if it's an in-property interplation, or a mixin,
31-
// and determine which character to use in either case
32-
// if in-property, replace with "xxxxxx"
33-
// if a mixin, replace with " "
34-
const pre = templateString.slice(0, start);
35-
const post = templateString.slice(end);
36-
const replacementChar = getReplacementCharacter(pre, post, logger);
37-
const result = placeholder.replace(/./gm, c => c === '\n' ? '\n' : replacementChar);
38-
39-
// If followed by a semicolon, we may have to eat the semi colon using a false property
40-
if (replacementChar === ' ' && post.match(/^\s*;/)) {
41-
// Handle case where we need to eat the semi colon:
42-
//
43-
// styled.x`
44-
// ${'color: red'};
45-
// `
46-
//
47-
// vs. the other case where we do not:
48-
//
49-
// styled.x`
50-
// color: ${'red'};
51-
// `
52-
if (pre.match(/(;|^|\})[\s|\n]*$/)) {
53-
// Mixin, replace with a dummy variable declaration, so scss server doesn't complain about rogue semicolon
54-
return '$a:0' + result.slice(4); // replace(/./gm, c => c === '\n' ? '\n' : ' ');
55-
}
56-
return placeholder.replace(/./gm, c => c === '\n' ? '\n' : 'x');
57-
}
58-
59-
return result;
29+
return getSubstitution(templateString, start, end, logger);
6030
},
6131
}, { logger });
6232
},
6333
};
6434
};
65-
66-
function getReplacementCharacter(pre: string, post: string, logger: LanguageServiceLogger) {
67-
if (pre.match(/(^|\n)\s*$/g)) {
68-
if (!post.match(/^\s*\{/)) { // ${'button'} {
69-
return ' ';
70-
}
71-
}
72-
73-
// If the placeholder looks like a unit that would not work when replaced with an identifier,
74-
// try replaceing with a number.
75-
if (post.match(/^(%)/)) {
76-
return '0';
77-
}
78-
79-
// Otherwise replace with an identifier
80-
return 'x';
81-
}

src/substituter.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
import { LanguageServiceLogger } from './logger';
5+
6+
export function getSubstitution(
7+
templateString: string,
8+
start: number,
9+
end: number,
10+
logger: LanguageServiceLogger
11+
): string {
12+
const placeholder = templateString.slice(start, end);
13+
14+
// check to see if it's an in-property interplation, or a mixin,
15+
// and determine which character to use in either case
16+
// if in-property, replace with "xxxxxx"
17+
// if a mixin, replace with " "
18+
const pre = templateString.slice(0, start);
19+
const post = templateString.slice(end);
20+
const replacementChar = getReplacementCharacter(pre, post, logger);
21+
const result = placeholder.replace(/./gm, c => c === '\n' ? '\n' : replacementChar);
22+
23+
// If followed by a semicolon, we may have to eat the semi colon using a false property
24+
if (replacementChar === ' ' && post.match(/^\s*;/)) {
25+
// Handle case where we need to eat the semi colon:
26+
//
27+
// styled.x`
28+
// ${'color: red'};
29+
// `
30+
//
31+
// vs. the other case where we do not:
32+
//
33+
// styled.x`
34+
// color: ${'red'};
35+
// `
36+
if (pre.match(/(;|^|\})[\s|\n]*$/)) {
37+
// Mixin, replace with a dummy variable declaration, so scss server doesn't complain about rogue semicolon
38+
return '$a:0' + result.slice(4); // replace(/./gm, c => c === '\n' ? '\n' : ' ');
39+
}
40+
return placeholder.replace(/./gm, c => c === '\n' ? '\n' : 'x');
41+
}
42+
43+
return result;
44+
}
45+
46+
function getReplacementCharacter(
47+
pre: string,
48+
post: string,
49+
logger: LanguageServiceLogger
50+
) {
51+
if (pre.match(/(^|\n)\s*$/g)) {
52+
if (!post.match(/^\s*[\{\:]/)) { // ${'button'} {
53+
return ' ';
54+
}
55+
}
56+
57+
// If the placeholder looks like a unit that would not work when replaced with an identifier,
58+
// try replaceing with a number.
59+
if (post.match(/^%/)) {
60+
return '0';
61+
}
62+
63+
// Otherwise replace with an identifier
64+
return 'x';
65+
}

0 commit comments

Comments
 (0)