Skip to content

Commit

Permalink
feat(customcompiler) allow the user to use a custom `typescriptServic…
Browse files Browse the repository at this point in the history
  • Loading branch information
angelestelar5z authored and basarat committed Apr 25, 2015
1 parent 875e3b0 commit 300239f
Show file tree
Hide file tree
Showing 14 changed files with 103 additions and 41 deletions.
32 changes: 24 additions & 8 deletions dist/main/atom/atomConfig.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// Documentation https://atom.io/docs/api/v0.177.0/Config and http://json-schema.org/examples.html
// To add a new setting you need to add to
// schema
// getter/setter
var utils_1 = require("../lang/utils");
var packageName = 'atom-typescript';
function getConfig(name) {
return atom.config.get(packageName + '.' + name);
function getConfig(nameLambda) {
return atom.config.get(packageName + '.' + utils_1.getName(nameLambda));
}
var Config = (function () {
function Config() {
Expand All @@ -19,15 +16,34 @@ var Config = (function () {
type: 'string',
default: 'none'
},
typescriptServices: {
title: 'Full path to a custom `typescriptServices.js`',
type: 'string',
default: ''
},
};
}
Object.defineProperty(Config.prototype, "debugAtomTs", {
get: function () { return getConfig('debugAtomTs'); },
get: function () {
var _this = this;
return getConfig(function () { return _this.schema.debugAtomTs; });
},
enumerable: true,
configurable: true
});
Object.defineProperty(Config.prototype, "preferredQuoteCharacter", {
get: function () { return getConfig('preferredQuoteCharacter'); },
get: function () {
var _this = this;
return getConfig(function () { return _this.schema.preferredQuoteCharacter; });
},
enumerable: true,
configurable: true
});
Object.defineProperty(Config.prototype, "typescriptServices", {
get: function () {
var _this = this;
return getConfig(function () { return _this.schema.typescriptServices; });
},
enumerable: true,
configurable: true
});
Expand Down
4 changes: 2 additions & 2 deletions dist/main/atomts.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var atomConfig = require('./atom/atomConfig');
var makeTypeScriptGlobal_1 = require("../typescript/makeTypeScriptGlobal");
makeTypeScriptGlobal_1.makeTsGlobal();
makeTypeScriptGlobal_1.makeTsGlobal(atomConfig.typescriptServices);
var path = require('path');
var fs = require('fs');
var apd = require('atom-package-dependencies');
Expand All @@ -20,7 +21,6 @@ var statusBarMessage;
var editorWatch;
var autoCompleteWatch;
var parent = require('../worker/parent');
var atomConfig = require('./atom/atomConfig');
exports.config = atomConfig.schema;
var utils_1 = require("./lang/utils");
var hideIfNotActiveOnStart = utils_1.debounce(function () {
Expand Down
9 changes: 9 additions & 0 deletions dist/main/lang/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,12 @@ exports.debounce = debounce;
;
var punctuations = createMap([';', '{', '}', '(', ')', '.', ':', '<', '>', "'", '"']);
exports.prefixEndsInPunctuation = function (prefix) { return prefix.length && prefix.trim().length && punctuations[prefix.trim()[prefix.trim().length - 1]]; };
var nameExtractor = new RegExp("return (.*);");
function getName(nameLambda) {
var m = nameExtractor.exec(nameLambda + "");
if (m == null)
throw new Error("The function does not contain a statement matching 'return variableName;'");
var access = m[1].split('.');
return access[access.length - 1];
}
exports.getName = getName;
13 changes: 9 additions & 4 deletions dist/typescript/makeTypeScriptGlobal.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,21 @@ var path = require('path');
global.stack = function () {
console.error((new Error()).stack);
};
function makeTsGlobal() {
function makeTsGlobal(typescriptServices) {
var sandbox = {
ts: {},
console: console,
stack: global.stack
};
vm.createContext(sandbox);
files.forEach(function (f) {
vm.runInContext(fs.readFileSync(path.resolve(__dirname, f)).toString(), sandbox);
});
if (typescriptServices) {
vm.runInContext(fs.readFileSync(typescriptServices).toString(), sandbox);
}
else {
files.forEach(function (f) {
vm.runInContext(fs.readFileSync(path.resolve(__dirname, f)).toString(), sandbox);
});
}
global.ts = sandbox.ts;
}
exports.makeTsGlobal = makeTsGlobal;
6 changes: 5 additions & 1 deletion dist/worker/child.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
var typescriptServices = '';
if (process.argv.length > 2) {
typescriptServices = process.argv[2];
}
var makeTypeScriptGlobal_1 = require("../typescript/makeTypeScriptGlobal");
makeTypeScriptGlobal_1.makeTsGlobal();
makeTypeScriptGlobal_1.makeTsGlobal(typescriptServices);
var workerLib = require('./lib/workerLib');
var child = new workerLib.Child();
var projectCache = require("../main/lang/projectCache");
Expand Down
8 changes: 4 additions & 4 deletions dist/worker/lib/workerLib.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ var Parent = (function (_super) {
this.getProcess = function () { return _this.child; };
this.stopped = false;
}
Parent.prototype.startWorker = function (childJsPath, terminalError) {
Parent.prototype.startWorker = function (childJsPath, terminalError, customArguments) {
var _this = this;
try {
this.child = spawn(this.node, [
childJsPath
], { cwd: path.dirname(childJsPath), env: { ATOM_SHELL_INTERNAL_RUN_AS_NODE: '1' }, stdio: ['ipc'] });
].concat(customArguments), { cwd: path.dirname(childJsPath), env: { ATOM_SHELL_INTERNAL_RUN_AS_NODE: '1' }, stdio: ['ipc'] });
this.child.on('error', function (err) {
if (err.code === "ENOENT" && err.path === _this.node) {
_this.gotENOENTonSpawnNode = true;
Expand All @@ -152,14 +152,14 @@ var Parent = (function (_super) {
console.log('ts worker exited with code:', code);
if (code === orphanExitCode) {
console.log('ts worker restarting');
_this.startWorker(childJsPath, terminalError);
_this.startWorker(childJsPath, terminalError, customArguments);
}
else if (_this.gotENOENTonSpawnNode) {
terminalError(new Error('gotENOENTonSpawnNode'));
}
else {
console.log('ts worker restarting');
_this.startWorker(childJsPath, terminalError);
_this.startWorker(childJsPath, terminalError, customArguments);
}
});
}
Expand Down
3 changes: 2 additions & 1 deletion dist/worker/parent.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ var childprocess = require('child_process');
var exec = childprocess.exec;
var spawn = childprocess.spawn;
var workerLib = require('./lib/workerLib');
var atomConfig = require("../main/atom/atomConfig");
var parent = new workerLib.Parent();
var mainPanel = require("../main/atom/views/mainPanelView");
parent.pendingRequestsChanged = function (pending) {
Expand All @@ -14,7 +15,7 @@ if (debug_1.debug) {
parent.sendToIpc = function (x) { return x; };
}
function startWorker() {
parent.startWorker(__dirname + '/child.js', showError);
parent.startWorker(__dirname + '/child.js', showError, atomConfig.typescriptServices ? [atomConfig.typescriptServices] : []);
console.log('AtomTS worker started');
}
exports.startWorker = startWorker;
Expand Down
16 changes: 11 additions & 5 deletions lib/main/atom/atomConfig.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

import {getName} from "../lang/utils";

// Documentation https://atom.io/docs/api/v0.177.0/Config and http://json-schema.org/examples.html
// To add a new setting you need to add to
// schema
// getter/setter

var packageName = 'atom-typescript';
function getConfig<T>(name: string): T {
return atom.config.get(packageName + '.' + name);
function getConfig<T>(nameLambda: () => any): T {
return atom.config.get(packageName + '.' + getName(nameLambda));
}

class Config {
Expand All @@ -22,9 +22,15 @@ class Config {
type: 'string',
default: 'none'
},
typescriptServices: {
title: 'Full path to a custom `typescriptServices.js`',
type: 'string',
default: ''
},
}
get debugAtomTs() { return getConfig<boolean>('debugAtomTs') }
get preferredQuoteCharacter() { return getConfig<string>('preferredQuoteCharacter') }
get debugAtomTs() { return getConfig<boolean>(() => this.schema.debugAtomTs) }
get preferredQuoteCharacter() { return getConfig<string>(() => this.schema.preferredQuoteCharacter) }
get typescriptServices() { return getConfig<string>(() => this.schema.typescriptServices) }
}
var config = new Config();
export = config;
6 changes: 3 additions & 3 deletions lib/main/atomts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import atomConfig = require('./atom/atomConfig');
import {makeTsGlobal} from "../typescript/makeTypeScriptGlobal";
makeTsGlobal();
makeTsGlobal(atomConfig.typescriptServices);

import path = require('path');
import fs = require('fs');
Expand Down Expand Up @@ -44,7 +45,6 @@ export interface PackageState {
import parent = require('../worker/parent');

// Export config
import atomConfig = require('./atom/atomConfig');
export var config = atomConfig.schema;
import {debounce} from "./lang/utils";

Expand All @@ -59,7 +59,7 @@ var hideIfNotActiveOnStart = debounce(() => {

/** only called once we have our dependencies */
function readyToActivate() {

// Add the documentation view
documentationView.attach();

Expand Down
10 changes: 10 additions & 0 deletions lib/main/lang/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,13 @@ export function debounce<T extends Function>(func: T, milliseconds: number, imme

var punctuations = createMap([';', '{', '}', '(', ')', '.', ':', '<', '>', "'", '"']);
export var prefixEndsInPunctuation = (prefix) => prefix.length && prefix.trim().length && punctuations[prefix.trim()[prefix.trim().length - 1]];

var nameExtractor = new RegExp("return (.*);");
/** Get the name using a lambda so that you don't have magic strings */
export function getName(nameLambda: () => any) {
var m = nameExtractor.exec(nameLambda + "");
if (m == null)
throw new Error("The function does not contain a statement matching 'return variableName;'");
var access = m[1].split('.');
return access[access.length - 1];
}
16 changes: 11 additions & 5 deletions lib/typescript/makeTypeScriptGlobal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ import vm = require('vm');
import fs = require('fs');
import path = require('path');

global.stack = function(){
global.stack = function() {
console.error((<any>new Error()).stack);
}

export function makeTsGlobal() {
/** Makes the bundled typescript services global or (if passed in) a custom typescriptServices file */
export function makeTsGlobal(typescriptServices?: string) {
var sandbox = {
// This is going to gather the ts module exports
ts: {},
Expand All @@ -59,9 +60,14 @@ export function makeTsGlobal() {
};
vm.createContext(sandbox);

files.forEach(f=> {
vm.runInContext(fs.readFileSync(path.resolve(__dirname,f)).toString(), sandbox);
});
if (typescriptServices) {
vm.runInContext(fs.readFileSync(typescriptServices).toString(), sandbox);
}
else {
files.forEach(f=> {
vm.runInContext(fs.readFileSync(path.resolve(__dirname, f)).toString(), sandbox);
});
}

// Finally export ts to the local global namespace
global.ts = sandbox.ts;
Expand Down
6 changes: 5 additions & 1 deletion lib/worker/child.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
var typescriptServices = '';
if (process.argv.length > 2) {
typescriptServices = process.argv[2];
}
// setup typescript
import {makeTsGlobal} from "../typescript/makeTypeScriptGlobal";
makeTsGlobal();
makeTsGlobal(typescriptServices);

import workerLib = require('./lib/workerLib');

Expand Down
12 changes: 6 additions & 6 deletions lib/worker/lib/workerLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class RequesterResponder {
private currentListeners: { [messages: string]: { [id: string]: PromiseDeferred<any> } } = {};
/** TODO: Display this in the UI */
private pendingRequests: string[] = [];
public pendingRequestsChanged = (pending:string[]) => null;
public pendingRequestsChanged = (pending: string[]) => null;

/** process a message from the child */
protected processResponse(m: any) {
Expand All @@ -69,7 +69,7 @@ class RequesterResponder {
if (parsed.error) {
this.currentListeners[parsed.message][parsed.id].reject(parsed.error);
console.log(parsed.error);
console.log(parsed.error.stack);
console.log(parsed.error.stack);
}
else {
this.currentListeners[parsed.message][parsed.id].resolve(parsed.data);
Expand Down Expand Up @@ -174,12 +174,12 @@ export class Parent extends RequesterResponder {
private stopped = false;

/** start worker */
startWorker(childJsPath: string, terminalError: (e: Error) => any) {
startWorker(childJsPath: string, terminalError: (e: Error) => any, customArguments: string[]) {
try {
this.child = spawn(this.node, [
// '--debug', // Uncomment if you want to debug the child process
childJsPath
], { cwd: path.dirname(childJsPath), env: { ATOM_SHELL_INTERNAL_RUN_AS_NODE: '1' }, stdio: ['ipc'] });
].concat(customArguments), { cwd: path.dirname(childJsPath), env: { ATOM_SHELL_INTERNAL_RUN_AS_NODE: '1' }, stdio: ['ipc'] });

this.child.on('error', (err) => {
if (err.code === "ENOENT" && err.path === this.node) {
Expand Down Expand Up @@ -213,7 +213,7 @@ export class Parent extends RequesterResponder {
// If orphaned then Definitely restart
if (code === orphanExitCode) {
console.log('ts worker restarting');
this.startWorker(childJsPath, terminalError);
this.startWorker(childJsPath, terminalError, customArguments);
}
// If we got ENOENT. Restarting will not help.
else if (this.gotENOENTonSpawnNode) {
Expand All @@ -222,7 +222,7 @@ export class Parent extends RequesterResponder {
// We haven't found a reson to not start worker yet
else {
console.log('ts worker restarting');
this.startWorker(childJsPath, terminalError);
this.startWorker(childJsPath, terminalError, customArguments);
}
});
} catch (err) {
Expand Down
3 changes: 2 additions & 1 deletion lib/worker/parent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var spawn = childprocess.spawn;

import workerLib = require('./lib/workerLib');
import tsconfig = require('../main/tsconfig/tsconfig');
import * as atomConfig from "../main/atom/atomConfig";

var parent = new workerLib.Parent();
import * as mainPanel from "../main/atom/views/mainPanelView";
Expand All @@ -22,7 +23,7 @@ if (debug) {
}

export function startWorker() {
parent.startWorker(__dirname + '/child.js', showError);
parent.startWorker(__dirname + '/child.js', showError, atomConfig.typescriptServices ? [atomConfig.typescriptServices] : []);
console.log('AtomTS worker started')
}

Expand Down

0 comments on commit 300239f

Please sign in to comment.