Compare commits
33 commits
main
...
vue-plugin
Author | SHA1 | Date | |
---|---|---|---|
cb8d74ac2f | |||
c04cb33a28 | |||
ff5f5d1cca | |||
df6c1cc961 | |||
e362b0023a | |||
0472839b8f | |||
5fc16ced20 | |||
d1c2d862b9 | |||
cda045ce80 | |||
ab1fc019d5 | |||
ac03583a07 | |||
881884a6e2 | |||
51408f0a0d | |||
7def921610 | |||
5f2443a26c | |||
6cf7194082 | |||
2693d3fec1 | |||
b65c45994a | |||
ad12198188 | |||
fd19e54090 | |||
62c686aacb | |||
779a3930a4 | |||
bf0227a967 | |||
c87a647add | |||
7f91c780c1 | |||
29e461f3a4 | |||
b6a4bbf4dc | |||
27869b53c8 | |||
8100a16176 | |||
0a3738d8a7 | |||
79addfd5c7 | |||
0610d5fb51 | |||
9316f14e1d |
|
@ -785,6 +785,71 @@ namespace Harness.LanguageService {
|
|||
}),
|
||||
error: undefined
|
||||
};
|
||||
case "mock-vue":
|
||||
return {
|
||||
module: () => ({
|
||||
create(info: ts.server.PluginCreateInfo) {
|
||||
const clssf = ts.createLanguageServiceSourceFile;
|
||||
const ulssf = ts.updateLanguageServiceSourceFile;
|
||||
ts.overrideCreateupdateLanguageServiceSourceFile(
|
||||
(fileName, scriptSnapshot, scriptTarget, version, setNodeParents, scriptKind?) => {
|
||||
if (interested(fileName)) {
|
||||
const wrapped = scriptSnapshot;
|
||||
scriptSnapshot = {
|
||||
getChangeRange: old => wrapped.getChangeRange(old),
|
||||
getLength: () => wrapped.getLength(),
|
||||
getText: (start, end) => parse(wrapped.getText(0, wrapped.getLength())).slice(start, end),
|
||||
};
|
||||
}
|
||||
var sourceFile = clssf(fileName, scriptSnapshot, scriptTarget, version, setNodeParents, scriptKind);
|
||||
return sourceFile;
|
||||
},
|
||||
(sourceFile, scriptSnapshot, version, textChangeRange, aggressiveChecks?) => {
|
||||
if (interested(sourceFile.fileName)) {
|
||||
const wrapped = scriptSnapshot;
|
||||
scriptSnapshot = {
|
||||
getChangeRange: old => wrapped.getChangeRange(old),
|
||||
getLength: () => wrapped.getLength(),
|
||||
getText: (start, end) => parse(wrapped.getText(0, wrapped.getLength())).slice(start, end),
|
||||
};
|
||||
}
|
||||
var sourceFile = ulssf(sourceFile, scriptSnapshot, version, textChangeRange, aggressiveChecks);
|
||||
return sourceFile;
|
||||
});
|
||||
return makeDefaultProxy(info);
|
||||
|
||||
function interested(filename: string) {
|
||||
return filename.length;
|
||||
}
|
||||
function parse(text: string) {
|
||||
const start = text.indexOf("<script>") + "<script>".length;
|
||||
const end = text.indexOf("</script>");
|
||||
return text.slice(0, start).replace(/./g, ' ') + text.slice(start, end) + text.slice(end).replace(/./g, ' ');
|
||||
}
|
||||
},
|
||||
resolveModules() {
|
||||
return (rmn: any) =>
|
||||
(moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache?: ts.ModuleResolutionCache) => {
|
||||
if (importInterested(moduleName)) {
|
||||
return {
|
||||
resolvedModule: {
|
||||
extension: ts.Extension.Ts,
|
||||
isExternalLibraryImport: true,
|
||||
resolvedFileName: containingFile.slice(0, containingFile.lastIndexOf("/")) + "/" + moduleName,
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return rmn(moduleName, containingFile, compilerOptions, host, cache);
|
||||
}
|
||||
};
|
||||
function importInterested(filename: string) {
|
||||
return filename.charAt(0) === "." && filename.slice(-4) === ".vue";
|
||||
}
|
||||
}
|
||||
}),
|
||||
error: undefined
|
||||
};
|
||||
|
||||
default:
|
||||
return {
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace ts.server {
|
|||
|
||||
private filesWithChangedSetOfUnresolvedImports: Path[];
|
||||
|
||||
private readonly resolveModuleName: typeof resolveModuleName;
|
||||
private resolveModuleName: typeof resolveModuleName;
|
||||
readonly trace: (s: string) => void;
|
||||
readonly realpath?: (path: string) => string;
|
||||
|
||||
|
@ -46,6 +46,11 @@ namespace ts.server {
|
|||
}
|
||||
}
|
||||
|
||||
public overrideResolveModuleName(plugin: PluginResolveModules) {
|
||||
const prevResolveModuleName = this.resolveModuleName;
|
||||
this.resolveModuleName = plugin(prevResolveModuleName);
|
||||
}
|
||||
|
||||
public startRecordingFilesWithChangedResolutions() {
|
||||
this.filesWithChangedSetOfUnresolvedImports = [];
|
||||
}
|
||||
|
@ -237,4 +242,4 @@ namespace ts.server {
|
|||
this.compilationSettings = opt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,6 +102,13 @@ namespace ts.server {
|
|||
export interface PluginModule {
|
||||
create(createInfo: PluginCreateInfo): LanguageService;
|
||||
getExternalFiles?(proj: Project): string[];
|
||||
resolveModules?(createInfo: PluginCreateInfo): PluginResolveModules;
|
||||
}
|
||||
|
||||
export type ModuleResolver = (moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache) => ResolvedModuleWithFailedLookupLocations;
|
||||
|
||||
export type PluginResolveModules = {
|
||||
(plugin: ModuleResolver): ModuleResolver;
|
||||
}
|
||||
|
||||
export interface PluginModuleFactory {
|
||||
|
@ -904,6 +911,9 @@ namespace ts.server {
|
|||
|
||||
const pluginModule = pluginModuleFactory({ typescript: ts });
|
||||
this.languageService = pluginModule.create(info);
|
||||
if (pluginModule.resolveModules) {
|
||||
this.lsHost.overrideResolveModuleName(pluginModule.resolveModules(info));
|
||||
}
|
||||
this.plugins.push(pluginModule);
|
||||
}
|
||||
catch (e) {
|
||||
|
@ -1083,4 +1093,4 @@ namespace ts.server {
|
|||
this.typeAcquisition = newTypeAcquisition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -891,6 +891,13 @@ namespace ts {
|
|||
sourceFile.scriptSnapshot = scriptSnapshot;
|
||||
}
|
||||
|
||||
export function overrideCreateupdateLanguageServiceSourceFile(
|
||||
create: (fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean, scriptKind?: ScriptKind, cheat?: string) => SourceFile,
|
||||
update: (sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean, cheat?: string) => SourceFile) {
|
||||
ts.createLanguageServiceSourceFile = create;
|
||||
ts.updateLanguageServiceSourceFile = update;
|
||||
}
|
||||
|
||||
export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile {
|
||||
const text = scriptSnapshot.getText(0, scriptSnapshot.getLength());
|
||||
const sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents, scriptKind);
|
||||
|
|
44
tests/cases/fourslash/server/vueProxy1.ts
Normal file
44
tests/cases/fourslash/server/vueProxy1.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
/// <reference path="../fourslash.ts"/>
|
||||
|
||||
// @Filename: tsconfig.json
|
||||
//// {
|
||||
//// "compilerOptions": {
|
||||
//// "allowNonTsExtensions": true,
|
||||
//// "plugins": [
|
||||
//// { "name": "mock-vue" }
|
||||
//// ]
|
||||
//// },
|
||||
//// "files": ["a.vue"]
|
||||
//// }
|
||||
|
||||
// Note: This test does *not* implement the correct vue transformation.
|
||||
// So it's other.data.property, not other.property or other.$data.property
|
||||
// @Filename: other.vue
|
||||
////<template>
|
||||
////</template>
|
||||
////<script>
|
||||
////export default {
|
||||
//// data: { property: "Example" }
|
||||
////}
|
||||
////</script>
|
||||
////<style>
|
||||
////</style>
|
||||
|
||||
|
||||
// @Filename: a.vue
|
||||
////<template>
|
||||
////</template>
|
||||
////<script>
|
||||
////import other from './other.vue'
|
||||
//// other.data.property/**/
|
||||
////export default {
|
||||
//// data: { greeting: "Hello" }
|
||||
////}
|
||||
////</script>
|
||||
////<style>
|
||||
////</style>
|
||||
|
||||
// LS shouldn't crash/fail if a plugin fails to init correctly
|
||||
goTo.marker();
|
||||
verify.quickInfoIs('(property) property: string');
|
||||
verify.numberOfErrorsInCurrentFile(0);
|
Loading…
Reference in a new issue