Do no take runtime dependency on TypeScript

This commit is contained in:
Matt Bierner 2017-11-09 16:46:56 -08:00
Родитель b9f62050c6
Коммит 5641a8dd12
7 изменённых файлов: 249 добавлений и 83 удалений

14
.vscode/tasks.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,14 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch:compile",
"problemMatcher": [
"$tsc-watch"
]
}
]
}

Просмотреть файл

@ -1,5 +1,8 @@
# Changelog
# 0.2.0 November 9, 2017
- Do not take runtime dependecy on TypeScript.
# 0.1.2 — October 24, 2017
- Fix bug that could cause errors not to be reported when on the last line of a block.

193
package-lock.json сгенерированный
Просмотреть файл

@ -2,6 +2,7 @@
"name": "typescript-styled-plugin",
"version": "0.1.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/node": {
"version": "7.0.46",
@ -32,12 +33,24 @@
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
"dev": true,
"requires": {
"chalk": "1.1.3",
"esutils": "2.0.2",
"js-tokens": "3.0.2"
},
"dependencies": {
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true
"dev": true,
"requires": {
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
"has-ansi": "2.0.0",
"strip-ansi": "3.0.1",
"supports-color": "2.0.0"
}
},
"supports-color": {
"version": "2.0.0",
@ -57,7 +70,11 @@
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
"dev": true
"dev": true,
"requires": {
"balanced-match": "1.0.0",
"concat-map": "0.0.1"
}
},
"browser-stdout": {
"version": "1.3.0",
@ -75,19 +92,35 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz",
"integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=",
"dev": true
"dev": true,
"requires": {
"assertion-error": "1.0.2",
"check-error": "1.0.2",
"deep-eql": "3.0.1",
"get-func-name": "2.0.0",
"pathval": "1.1.0",
"type-detect": "4.0.3"
}
},
"chalk": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
"integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
"dev": true,
"requires": {
"ansi-styles": "3.2.0",
"escape-string-regexp": "1.0.5",
"supports-color": "4.5.0"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
"integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
"dev": true
"dev": true,
"requires": {
"color-convert": "1.9.0"
}
},
"has-flag": {
"version": "2.0.0",
@ -99,7 +132,10 @@
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
"integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
"dev": true
"dev": true,
"requires": {
"has-flag": "2.0.0"
}
}
}
},
@ -113,7 +149,10 @@
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
"integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
"dev": true
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
@ -125,7 +164,10 @@
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
"integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
"dev": true
"dev": true,
"requires": {
"graceful-readlink": "1.0.1"
}
},
"concat-map": {
"version": "0.0.1",
@ -137,13 +179,19 @@
"version": "2.6.8",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
"dev": true
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"deep-eql": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
"integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
"dev": true
"dev": true,
"requires": {
"type-detect": "4.0.3"
}
},
"diff": {
"version": "3.2.0",
@ -179,7 +227,15 @@
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true
"dev": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"graceful-readlink": {
"version": "1.0.1",
@ -197,7 +253,10 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"dev": true
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"has-flag": {
"version": "1.0.0",
@ -215,7 +274,11 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true
"dev": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
}
},
"inherits": {
"version": "2.0.3",
@ -239,7 +302,11 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
"integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
"dev": true
"dev": true,
"requires": {
"lodash._basecopy": "3.0.1",
"lodash.keys": "3.1.2"
}
},
"lodash._basecopy": {
"version": "3.0.1",
@ -269,7 +336,12 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz",
"integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=",
"dev": true
"dev": true,
"requires": {
"lodash._baseassign": "3.2.0",
"lodash._basecreate": "3.0.3",
"lodash._isiterateecall": "3.0.9"
}
},
"lodash.isarguments": {
"version": "3.1.0",
@ -287,13 +359,21 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
"integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
"dev": true
"dev": true,
"requires": {
"lodash._getnative": "3.9.1",
"lodash.isarguments": "3.1.0",
"lodash.isarray": "3.0.4"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true
"dev": true,
"requires": {
"brace-expansion": "1.1.8"
}
},
"minimist": {
"version": "0.0.8",
@ -305,19 +385,44 @@
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true
"dev": true,
"requires": {
"minimist": "0.0.8"
}
},
"mocha": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz",
"integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==",
"dev": true,
"requires": {
"browser-stdout": "1.3.0",
"commander": "2.9.0",
"debug": "2.6.8",
"diff": "3.2.0",
"escape-string-regexp": "1.0.5",
"glob": "7.1.1",
"growl": "1.9.2",
"he": "1.1.1",
"json3": "3.3.2",
"lodash.create": "3.1.1",
"mkdirp": "0.5.1",
"supports-color": "3.1.2"
},
"dependencies": {
"glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
"integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
"dev": true
"dev": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
}
}
},
@ -331,7 +436,10 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true
"dev": true,
"requires": {
"wrappy": "1.0.2"
}
},
"path-is-absolute": {
"version": "1.0.1",
@ -355,7 +463,10 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz",
"integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==",
"dev": true
"dev": true,
"requires": {
"path-parse": "1.0.5"
}
},
"semver": {
"version": "5.4.1",
@ -367,13 +478,19 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"supports-color": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
"integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=",
"dev": true
"dev": true,
"requires": {
"has-flag": "1.0.0"
}
},
"tslib": {
"version": "1.8.0",
@ -385,13 +502,29 @@
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz",
"integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=",
"dev": true
"dev": true,
"requires": {
"babel-code-frame": "6.26.0",
"builtin-modules": "1.1.1",
"chalk": "2.3.0",
"commander": "2.9.0",
"diff": "3.2.0",
"glob": "7.1.2",
"minimatch": "3.0.4",
"resolve": "1.4.0",
"semver": "5.4.1",
"tslib": "1.8.0",
"tsutils": "2.12.1"
}
},
"tsutils": {
"version": "2.12.1",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.12.1.tgz",
"integrity": "sha1-9Nlc4zkciXHkblTEzw7bCiHdWyQ=",
"dev": true
"dev": true,
"requires": {
"tslib": "1.8.0"
}
},
"type-detect": {
"version": "4.0.3",
@ -406,14 +539,18 @@
"dev": true
},
"typescript-template-language-service-decorator": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/typescript-template-language-service-decorator/-/typescript-template-language-service-decorator-0.1.2.tgz",
"integrity": "sha512-SNUJcS7gjrutE8TIGbYcFyehsgapvU/koDDd0cKn1Xr8GROjhmKukVQrad1lUZoc5iJ2h4AFl5kojpLy7gnmuQ=="
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typescript-template-language-service-decorator/-/typescript-template-language-service-decorator-1.0.0.tgz",
"integrity": "sha512-M7aQaxBjfH+amI/m+lo58b11UUj4HWlqM+bgL8rmFMrm2044S2end3f98GHRWdUfEyiEt1SIqKPwiju0CTKi0w=="
},
"vscode-css-languageservice": {
"version": "2.1.10",
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.1.10.tgz",
"integrity": "sha1-Rlyg3dw8U/SYuzU2dHVTKbFqXm4="
"integrity": "sha1-Rlyg3dw8U/SYuzU2dHVTKbFqXm4=",
"requires": {
"vscode-languageserver-types": "3.4.0",
"vscode-nls": "2.0.2"
}
},
"vscode-languageserver-types": {
"version": "3.4.0",

Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "typescript-styled-plugin",
"version": "0.1.2",
"version": "0.2.0",
"description": "TypeScript language service plugin that adds IntelliSense for styled components",
"keywords": [
"TypeScript",
@ -20,7 +20,7 @@
"url": "https://github.com/Microsoft/typescript-styled-plugin/issues"
},
"dependencies": {
"typescript-template-language-service-decorator": "0.1.2",
"typescript-template-language-service-decorator": "^1.0.0",
"vscode-css-languageservice": "^2.1.10",
"vscode-languageserver-types": "^3.4.0"
},

Просмотреть файл

@ -19,28 +19,28 @@ class LanguageServiceLogger implements Logger {
}
}
function create(info: ts.server.PluginCreateInfo): ts.LanguageService {
const logger = new LanguageServiceLogger(info);
const config = loadConfiguration(info.config);
logger.log('config: ' + JSON.stringify(config));
return decorateWithTemplateLanguageService(info.languageService, new StyledTemplateLanguageService(config), {
tags: config.tags,
enableForStringWithSubstitutions: true,
getSubstitution(
templateString: string,
start: number,
end: number
): string {
const placeholder = templateString.slice(start, end);
const pre = templateString.slice(0, start);
const replacementChar = pre.match(/(^|\n)\s*$/g) ? ' ' : 'x';
return placeholder.replace(/./gm, c => c === '\n' ? '\n' : replacementChar);
},
}, { logger });
}
export = (mod: { typescript: typeof ts }) => {
return { create };
return {
create(info: ts.server.PluginCreateInfo): ts.LanguageService {
const logger = new LanguageServiceLogger(info);
const config = loadConfiguration(info.config);
logger.log('config: ' + JSON.stringify(config));
return decorateWithTemplateLanguageService(mod.typescript, info.languageService, new StyledTemplateLanguageService(mod.typescript, config), {
tags: config.tags,
enableForStringWithSubstitutions: true,
getSubstitution(
templateString: string,
start: number,
end: number
): string {
const placeholder = templateString.slice(start, end);
const pre = templateString.slice(0, start);
const replacementChar = pre.match(/(^|\n)\s*$/g) ? ' ' : 'x';
return placeholder.replace(/./gm, c => c === '\n' ? '\n' : replacementChar);
},
}, { logger });
},
};
};

Просмотреть файл

@ -18,6 +18,7 @@ export default class StyledTemplateLanguageService implements TemplateLanguageSe
private _scssLanguageService?: LanguageService;
constructor(
private readonly typescript: typeof ts,
private readonly configuration: TsStyledPluginConfiguration
) { }
@ -44,7 +45,7 @@ export default class StyledTemplateLanguageService implements TemplateLanguageSe
const doc = this.createVirtualDocument(context);
const stylesheet = this.cssLanguageService.parseStylesheet(doc);
const items = this.cssLanguageService.doComplete(doc, this.toVirtualDocPosition(position), stylesheet);
return translateCompletionItems(items);
return translateCompletionItems(this.typescript, items);
}
public getQuickInfoAtPosition(
@ -120,7 +121,7 @@ export default class StyledTemplateLanguageService implements TemplateLanguageSe
doc: vscode.TextDocument,
context: TemplateContext,
content: string
) {
) {
const sourceFile = context.node.getSourceFile();
return diagnostics.map(diag =>
this.translateDiagnostic(diag, sourceFile, doc, context, content));
@ -132,7 +133,7 @@ export default class StyledTemplateLanguageService implements TemplateLanguageSe
doc: vscode.TextDocument,
context: TemplateContext,
content: string
): ts.Diagnostic | undefined {
): ts.Diagnostic | undefined {
// Make sure returned error is within the real document
if (diagnostic.range.start.line === 0
|| diagnostic.range.start.line > doc.lineCount
@ -147,7 +148,7 @@ export default class StyledTemplateLanguageService implements TemplateLanguageSe
return {
code,
messageText: diagnostic.message,
category: translateSeverity(diagnostic.severity),
category: translateSeverity(this.typescript, diagnostic.severity),
file,
start,
length,
@ -173,7 +174,7 @@ export default class StyledTemplateLanguageService implements TemplateLanguageSe
convertPart(hover.contents);
const start = context.toOffset(this.fromVirtualDocPosition(hover.range ? hover.range.start : position));
return {
kind: ts.ScriptElementKind.unknown,
kind: this.typescript.ScriptElementKind.unknown,
kindModifiers: '',
textSpan: {
start,
@ -186,74 +187,86 @@ export default class StyledTemplateLanguageService implements TemplateLanguageSe
}
}
function translateCompletionItems(items: vscode.CompletionList): ts.CompletionInfo {
function translateCompletionItems(
typescript: typeof ts,
items: vscode.CompletionList
): ts.CompletionInfo {
return {
isGlobalCompletion: false,
isMemberCompletion: false,
isNewIdentifierLocation: false,
entries: items.items.map(translateCompetionEntry),
entries: items.items.map(x => translateCompetionEntry(typescript, x)),
};
}
function translateCompetionEntry(item: vscode.CompletionItem): ts.CompletionEntry {
function translateCompetionEntry(
typescript: typeof ts,
item: vscode.CompletionItem
): ts.CompletionEntry {
return {
name: item.label,
kindModifiers: 'declare',
kind: item.kind ? translateionCompletionItemKind(item.kind) : ts.ScriptElementKind.unknown,
kind: item.kind ? translateionCompletionItemKind(typescript, item.kind) : typescript.ScriptElementKind.unknown,
sortText: '0',
};
}
function translateionCompletionItemKind(kind: vscode.CompletionItemKind): ts.ScriptElementKind {
function translateionCompletionItemKind(
typescript: typeof ts,
kind: vscode.CompletionItemKind
): ts.ScriptElementKind {
switch (kind) {
case vscode.CompletionItemKind.Method:
return ts.ScriptElementKind.memberFunctionElement;
return typescript.ScriptElementKind.memberFunctionElement;
case vscode.CompletionItemKind.Function:
return ts.ScriptElementKind.functionElement;
return typescript.ScriptElementKind.functionElement;
case vscode.CompletionItemKind.Constructor:
return ts.ScriptElementKind.constructorImplementationElement;
return typescript.ScriptElementKind.constructorImplementationElement;
case vscode.CompletionItemKind.Field:
case vscode.CompletionItemKind.Variable:
return ts.ScriptElementKind.variableElement;
return typescript.ScriptElementKind.variableElement;
case vscode.CompletionItemKind.Class:
return ts.ScriptElementKind.classElement;
return typescript.ScriptElementKind.classElement;
case vscode.CompletionItemKind.Interface:
return ts.ScriptElementKind.interfaceElement;
return typescript.ScriptElementKind.interfaceElement;
case vscode.CompletionItemKind.Module:
return ts.ScriptElementKind.moduleElement;
return typescript.ScriptElementKind.moduleElement;
case vscode.CompletionItemKind.Property:
return ts.ScriptElementKind.memberVariableElement;
return typescript.ScriptElementKind.memberVariableElement;
case vscode.CompletionItemKind.Unit:
case vscode.CompletionItemKind.Value:
return ts.ScriptElementKind.constElement;
return typescript.ScriptElementKind.constElement;
case vscode.CompletionItemKind.Enum:
return ts.ScriptElementKind.enumElement;
return typescript.ScriptElementKind.enumElement;
case vscode.CompletionItemKind.Keyword:
return ts.ScriptElementKind.keyword;
return typescript.ScriptElementKind.keyword;
case vscode.CompletionItemKind.Color:
return ts.ScriptElementKind.constElement;
return typescript.ScriptElementKind.constElement;
case vscode.CompletionItemKind.Reference:
return ts.ScriptElementKind.alias;
return typescript.ScriptElementKind.alias;
case vscode.CompletionItemKind.File:
return ts.ScriptElementKind.moduleElement;
return typescript.ScriptElementKind.moduleElement;
case vscode.CompletionItemKind.Snippet:
case vscode.CompletionItemKind.Text:
default:
return ts.ScriptElementKind.unknown;
return typescript.ScriptElementKind.unknown;
}
}
function translateSeverity(severity: vscode.DiagnosticSeverity | undefined): ts.DiagnosticCategory {
function translateSeverity(
typescript: typeof ts,
severity: vscode.DiagnosticSeverity | undefined
): ts.DiagnosticCategory {
switch (severity) {
case vscode.DiagnosticSeverity.Information:
case vscode.DiagnosticSeverity.Hint:
return ts.DiagnosticCategory.Message;
return typescript.DiagnosticCategory.Message;
case vscode.DiagnosticSeverity.Warning:
return ts.DiagnosticCategory.Warning;
return typescript.DiagnosticCategory.Warning;
case vscode.DiagnosticSeverity.Error:
default:
return ts.DiagnosticCategory.Error;
return typescript.DiagnosticCategory.Error;
}
}

Просмотреть файл

@ -2,7 +2,6 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true,
"outDir": "lib",
"rootDir": "src",
"strict": true,