Skip to content
This repository has been archived by the owner on Dec 1, 2019. It is now read-only.

Commit

Permalink
feat(checker-runtime): checker now can resolve imports too
Browse files Browse the repository at this point in the history
  • Loading branch information
Stanislav Panferov committed Nov 24, 2015
1 parent ddca715 commit 99220c1
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 11 deletions.
78 changes: 73 additions & 5 deletions src/checker-runtime.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ICompilerOptions, ICompilerInfo, IFile } from './host';
import { ICompilerOptions, ICompilerInfo, IFile, SyncResolver } from './host';
import makeResolver from './resolver';
import * as colors from 'colors';
import * as path from 'path';

require('babel-polyfill');

Expand All @@ -16,6 +18,7 @@ export interface IMessage {
export interface IInitPayload {
compilerOptions: ICompilerOptions;
compilerInfo: ICompilerInfo;
webpackOptions: any;
}

export interface ICompilePayload {
Expand All @@ -25,6 +28,7 @@ export interface ICompilePayload {

export interface IEnv {
options?: ICompilerOptions;
webpackOptions?: any;
compiler?: typeof ts;
compilerInfo?: ICompilerInfo;
host?: Host;
Expand All @@ -36,7 +40,35 @@ export interface IEnv {

let env: IEnv = {};

export class ModuleResolutionHost implements ts.ModuleResolutionHost {
servicesHost: Host;

constructor(servicesHost: Host) {
this.servicesHost = servicesHost;
}

fileExists(fileName: string) {
return this.servicesHost.getScriptSnapshot(fileName) !== undefined;
}

readFile(fileName: string): string {
let snapshot = this.servicesHost.getScriptSnapshot(fileName);
return snapshot && snapshot.getText(0, snapshot.getLength());
}
}

export class Host implements ts.LanguageServiceHost {
moduleResolutionHost: ModuleResolutionHost
resolver: SyncResolver

constructor() {
this.moduleResolutionHost = new ModuleResolutionHost(this);
this.resolver = makeResolver(env.webpackOptions);
}

normalizePath(filePath: string): string {
return path.normalize(filePath);
}

getScriptFileNames() {
return Object.keys(env.files);
Expand Down Expand Up @@ -71,9 +103,44 @@ export class Host implements ts.LanguageServiceHost {
let resolvedModules: ts.ResolvedModule[] = [];

for (let moduleName of moduleNames) {
resolvedModules.push(
env.resolutionCache[`${containingFile}::${moduleName}`]
);
let cached = env.resolutionCache[`${containingFile}::${moduleName}`];
if (cached) {
resolvedModules.push(cached);
} else {
let resolvedFileName: string;
let resolvedModule: ts.ResolvedModule;

try {
resolvedFileName = this.resolver.resolveSync(
this.normalizePath(path.dirname(containingFile)),
moduleName
);

if (!resolvedFileName.match(/\.tsx?$/)) {
resolvedFileName = null;
}
}
catch (e) {
resolvedFileName = null
}

let tsResolved = env.compiler.resolveModuleName(
resolvedFileName || moduleName,
containingFile,
env.options,
this.moduleResolutionHost
);

if (tsResolved.resolvedModule) {
resolvedModule = tsResolved.resolvedModule;
} else {
resolvedModule = {
resolvedFileName: resolvedFileName || ''
}
}

resolvedModules.push(resolvedModule);
}
}

return resolvedModules;
Expand All @@ -92,9 +159,10 @@ export class Host implements ts.LanguageServiceHost {

function processInit(payload: IInitPayload) {
env.compiler = require(payload.compilerInfo.compilerName);
env.host = new Host();
env.compilerInfo = payload.compilerInfo;
env.options = payload.compilerOptions;
env.webpackOptions = payload.webpackOptions;
env.host = new Host();
env.service = env.compiler.createLanguageService(env.host, env.compiler.createDocumentRegistry());
}

Expand Down
13 changes: 10 additions & 3 deletions src/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,29 @@ interface ChildProcess extends childProcess.ChildProcess {
inProgress?: boolean;
compilerInfo?: ICompilerInfo;
compilerOptions?: ICompilerOptions;
webpackOptions?: any;
}

export function createChecker(compilerInfo: ICompilerInfo, compilerOptions: ICompilerOptions): ChildProcess {
export function createChecker(
compilerInfo: ICompilerInfo,
compilerOptions: ICompilerOptions,
webpackOptions: any
): ChildProcess {
let checker: ChildProcess = childProcess.fork(path.join(__dirname, 'checker-runtime.js'));

checker.send({
messageType: 'init',
payload: {
compilerInfo: _.omit(compilerInfo, 'tsImpl'),
compilerOptions
compilerOptions,
webpackOptions
}
}, null);

checker.inProgress = false;
checker.compilerInfo = compilerInfo;
checker.compilerOptions = compilerOptions;
checker.webpackOptions = webpackOptions;
checker.on('message', function(msg) {
if (msg.messageType == 'progress') {
checker.inProgress = msg.payload.inProgress;
Expand All @@ -35,7 +42,7 @@ export function createChecker(compilerInfo: ICompilerInfo, compilerOptions: ICom
export function resetChecker(checker: ChildProcess) {
if (checker.inProgress) {
checker.kill('SIGKILL');
return createChecker(checker.compilerInfo, checker.compilerOptions);
return createChecker(checker.compilerInfo, checker.compilerOptions, checker.webpackOptions);
} else {
return checker;
}
Expand Down
6 changes: 4 additions & 2 deletions src/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export function ensureInstance(webpack: IWebPack, options: ICompilerOptions, ins
sourceRoot: process.cwd()
});

options = _.omit(options, 'outDir') as any;
options = _.omit(options, 'outDir', 'files', 'exclude') as any;
options.externals.push.apply(options.externals, tsFiles)

let babelImpl: any;
Expand Down Expand Up @@ -202,6 +202,8 @@ export function ensureInstance(webpack: IWebPack, options: ICompilerOptions, ins
setupAfterCompile(compiler, instanceName, forkChecker);
}

let webpackOptions = _.pick(webpack._compiler.options, 'resolve');

return getInstanceStore(webpack._compiler)[instanceName] = {
tsFlow,
tsState,
Expand All @@ -210,7 +212,7 @@ export function ensureInstance(webpack: IWebPack, options: ICompilerOptions, ins
options,
externalsInvoked: false,
checker: forkChecker
? createChecker(compilerInfo, options)
? createChecker(compilerInfo, options, webpackOptions)
: null,
cacheIdentifier
}
Expand Down
1 change: 1 addition & 0 deletions src/tsconfig-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ function buildEnumMap(tsImpl: typeof ts) {
'es3': tsImpl.ScriptTarget.ES3,
'es5': tsImpl.ScriptTarget.ES5,
'es6': tsImpl.ScriptTarget.ES6,
'es2015': tsImpl.ScriptTarget.ES2015,
'latest': tsImpl.ScriptTarget.Latest
},
module: {
Expand Down
1 change: 0 additions & 1 deletion src/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"moduleResolution": "node",
"noLib": false,
"preserveConstEnums": true,
"suppressImplicitAnyIndexErrors": true
Expand Down

0 comments on commit 99220c1

Please sign in to comment.