Skip to content

Commit

Permalink
Enable strict mode in the compiler, and fix all problems (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcomorain authored and avli committed May 16, 2018
1 parent 4927e7f commit 4b091db
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 58 deletions.
13 changes: 10 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"tonsky.clojure-warrior"
],
"categories": [
"Languages",
"Programming Languages",
"Other"
],
"activationEvents": [
Expand Down Expand Up @@ -121,6 +121,7 @@
"@types/jszip": "^0.0.31",
"@types/mocha": "^2.2.32",
"@types/node": "^6.0.85",
"@types/cross-spawn": "^6.0.0",
"mocha": "^2.3.3",
"typescript": "^2.4.2",
"vscode": "^1.0.0"
Expand Down
12 changes: 8 additions & 4 deletions src/cljConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface CljConnectionInformation {
}
export interface REPLSession {
type: 'ClojureScript' | 'Clojure';
id: string;
id?: string;
}

const CONNECTION_STATE_KEY: string = 'CLJ_CONNECTION';
Expand All @@ -23,7 +23,7 @@ let cljContext: vscode.ExtensionContext;

const setCljContext = (context: vscode.ExtensionContext) => cljContext = context;

const getConnection = (): CljConnectionInformation => cljContext.workspaceState.get(CONNECTION_STATE_KEY);
const getConnection = (): CljConnectionInformation | undefined => cljContext.workspaceState.get(CONNECTION_STATE_KEY);

const isConnected = (): boolean => !!getConnection();

Expand All @@ -47,7 +47,7 @@ const saveDisconnection = (showMessage: boolean = true): void => {
vscode.window.showInformationMessage('Disconnected from nREPL.');
};

let loadingHandler: NodeJS.Timer;
let loadingHandler: NodeJS.Timer | null
const startLoadingAnimation = () => {
if (loadingHandler)
return;
Expand Down Expand Up @@ -173,7 +173,11 @@ const findClojureScriptSession = (sessions: string[]): Promise<string> => {
if (sessions.length == 0)
return Promise.reject(null);

let base_session = sessions.shift();
const base_session = sessions.shift();

if (!base_session) {
return Promise.reject("no base session");
}
return nreplClient.evaluate('(js/parseInt "42")', base_session).then(results => {
let { session, value } = results[0];
nreplClient.close(session);
Expand Down
6 changes: 3 additions & 3 deletions src/cljParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const CLJ_EXPRESSION_DELIMITERS: Map<string, string> = new Map<string, string>([
[CLJ_TEXT_DELIMITER, CLJ_TEXT_DELIMITER],
]);

const getExpressionInfo = (text: string): ExpressionInfo => {
const getExpressionInfo = (text: string): ExpressionInfo | undefined => {
text = removeCljComments(text);
const relativeExpressionInfo = getRelativeExpressionInfo(text);
if (!relativeExpressionInfo)
Expand All @@ -42,7 +42,7 @@ const getExpressionInfo = (text: string): ExpressionInfo => {
};

const removeCljComments = (text: string): string => {
const lines = text.match(/[^\r\n]+/g); // split string by line
const lines = text.match(/[^\r\n]+/g) || [] // split string by line

if (lines.length > 1) {
return lines.map(line => removeCljComments(line)).join(`\n`); // remove comments from each line and concat them again after
Expand All @@ -65,7 +65,7 @@ const removeCljComments = (text: string): string => {
return line.substring(0, uncommentedIndex);
};

const getRelativeExpressionInfo = (text: string, openChar: string = `(`): RelativeExpressionInfo => {
const getRelativeExpressionInfo = (text: string, openChar: string = `(`): RelativeExpressionInfo | undefined => {
const relativeExpressionInfo: RelativeExpressionInfo = {
startPosition: text.length - 1,
parameterPosition: -1,
Expand Down
8 changes: 4 additions & 4 deletions src/clojureConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ const keywords = [
'thread',
]

export class ClojureLanguageConfiguration implements vscode.LanguageConfiguration {
wordPattern = /[\w\-\.:<>\*][\w\d\.\\/\-\?<>\*!]+/;
indentationRules = {
decreaseIndentPattern: undefined,
export const ClojureLanguageConfiguration : vscode.LanguageConfiguration = {
wordPattern: /[\w\-\.:<>\*][\w\d\.\\/\-\?<>\*!]+/,
indentationRules: {
decreaseIndentPattern: /$^/, // line end then start - this will never match anything
increaseIndentPattern: /^\s*\(.*[^)]\s*$/
}
}
4 changes: 3 additions & 1 deletion src/clojureEval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ function evaluate(outputChannel: vscode.OutputChannel, showResults: boolean): vo
}

const editor = vscode.window.activeTextEditor;

if (!editor) return;
const selection = editor.selection;
let text = editor.document.getText();
if (!selection.isEmpty) {
Expand Down Expand Up @@ -65,7 +67,7 @@ function handleError(outputChannel: vscode.OutputChannel, selection: vscode.Sele
outputChannel.appendLine(`${stacktraceObj.class} ${stacktraceObj.message}`);
outputChannel.appendLine(` at ${stacktraceObj.file}:${errLine}:${errChar}`);

stacktraceObj.stacktrace.forEach(trace => {
stacktraceObj.stacktrace.forEach((trace: any) => {
if (trace.flags.indexOf('tooling') > -1)
outputChannel.appendLine(` ${trace.class}.${trace.method} (${trace.file}:${trace.line})`);
});
Expand Down
15 changes: 9 additions & 6 deletions src/clojureFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ function slashEscape(contents: string) {
}

function slashUnescape(contents: string) {
const replacements = { '\\\\': '\\', '\\n': '\n', '\\"': '"' };
return contents.replace(/\\(\\|n|")/g, function (match) {
return replacements[match];
const replacements : { [key: string]: string} = { '\\\\': '\\', '\\n': '\n', '\\"': '"' };
return contents.replace(/\\(\\|n|")/g, function(match) {
return replacements[match]
});
}

export const formatFile = (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit): void => {
export const formatFile = (textEditor: vscode.TextEditor, edit?: vscode.TextEditorEdit): void => {

if (!cljConnection.isConnected()) {
vscode.window.showErrorMessage("Formatting functions don't work, connect to nREPL first.");
Expand Down Expand Up @@ -70,11 +70,14 @@ export const maybeActivateFormatOnSave = () => {
return;
}
let textEditor = vscode.window.activeTextEditor;
if (!textEditor) {
return
}
let editorConfig = vscode.workspace.getConfiguration('editor');
const globalEditorFormatOnSave = editorConfig && editorConfig.has('formatOnSave') && editorConfig.get('formatOnSave') === true;
let clojureConfig = vscode.workspace.getConfiguration('clojureVSCode');
if ((clojureConfig.formatOnSave || globalEditorFormatOnSave) && textEditor.document === document) {
formatFile(textEditor, null);
formatFile(textEditor, undefined);
}
});
}
}
6 changes: 3 additions & 3 deletions src/clojureMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ export function activate(context: vscode.ExtensionContext) {
if (config.autoStartNRepl) {
cljConnection.startNRepl();
}

maybeActivateFormatOnSave();

vscode.commands.registerCommand('clojureVSCode.manuallyConnectToNRepl', cljConnection.manuallyConnect);
vscode.commands.registerCommand('clojureVSCode.stopDisconnectNRepl', cljConnection.disconnect);
vscode.commands.registerCommand('clojureVSCode.startNRepl', cljConnection.startNRepl);
Expand All @@ -39,7 +39,7 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.languages.registerSignatureHelpProvider(CLOJURE_MODE, new ClojureSignatureProvider(), ' ', '\n'));

vscode.workspace.registerTextDocumentContentProvider('jar', new JarContentProvider());
vscode.languages.setLanguageConfiguration(CLOJURE_MODE.language, new ClojureLanguageConfiguration());
vscode.languages.setLanguageConfiguration(CLOJURE_MODE.language, ClojureLanguageConfiguration);
}

export function deactivate() { }
2 changes: 1 addition & 1 deletion src/clojureMode.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import vscode = require('vscode');

export const CLOJURE_MODE: vscode.DocumentFilter = { language: 'clojure', scheme: 'file' };
export const CLOJURE_MODE = { language: 'clojure', scheme: 'file' };
4 changes: 2 additions & 2 deletions src/clojureSignature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const SPECIAL_FORM_CUSTOM_ARGLISTS: Map<string, string> = new Map<string, string

export class ClojureSignatureProvider implements vscode.SignatureHelpProvider {

provideSignatureHelp(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable<vscode.SignatureHelp> {
provideSignatureHelp(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult<vscode.SignatureHelp> {
if (!cljConnection.isConnected())
return Promise.reject('No nREPL connected.');

Expand Down Expand Up @@ -55,7 +55,7 @@ function getSpecialFormSignatureHelp(info: any, parameterPosition: number): vsco
return getSignatureHelp(signatureLabel, info.doc, arglists, parameterPosition);
}

function getFunctionSignatureHelp(info: any, parameterPosition: number): vscode.SignatureHelp {
function getFunctionSignatureHelp(info: any, parameterPosition: number): vscode.SignatureHelp | undefined {
const arglists = info['arglists-str'];
if (!arglists)
return;
Expand Down
32 changes: 19 additions & 13 deletions src/clojureSuggest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import { cljConnection } from './cljConnection';
import { cljParser } from './cljParser';
import { nreplClient } from './nreplClient';

const mappings = {
'nil': vscode.CompletionItemKind.Value,
'macro': vscode.CompletionItemKind.Value,
'class': vscode.CompletionItemKind.Class,
'keyword': vscode.CompletionItemKind.Keyword,
'namespace': vscode.CompletionItemKind.Module,
'function': vscode.CompletionItemKind.Function,
'special-form': vscode.CompletionItemKind.Keyword,
'var': vscode.CompletionItemKind.Variable,
'method': vscode.CompletionItemKind.Method,
}
const mappings: {
[key: string]: vscode.CompletionItemKind
} = {
'nil': vscode.CompletionItemKind.Value,
'macro': vscode.CompletionItemKind.Value,
'class': vscode.CompletionItemKind.Class,
'keyword': vscode.CompletionItemKind.Keyword,
'namespace': vscode.CompletionItemKind.Module,
'function': vscode.CompletionItemKind.Function,
'special-form': vscode.CompletionItemKind.Keyword,
'var': vscode.CompletionItemKind.Variable,
'method': vscode.CompletionItemKind.Method,
}

export class ClojureCompletionItemProvider implements vscode.CompletionItemProvider {

Expand All @@ -38,7 +40,7 @@ export class ClojureCompletionItemProvider implements vscode.CompletionItemProvi
if (!('completions' in completions))
return Promise.reject(undefined);

let suggestions = completions.completions.map(element => ({
let suggestions = completions.completions.map((element: any) => ({
label: element.candidate,
kind: mappings[element.type] || vscode.CompletionItemKind.Text,
insertText: buildInsertText(element.candidate)
Expand All @@ -49,7 +51,11 @@ export class ClojureCompletionItemProvider implements vscode.CompletionItemProvi
}

public resolveCompletionItem(item: vscode.CompletionItem, token: vscode.CancellationToken): Thenable<vscode.CompletionItem> {
let document = vscode.window.activeTextEditor.document;
const editor = vscode.window.activeTextEditor
if (!editor) {
return Promise.reject("No active editor");
}
let document = editor.document;
let ns = cljParser.getNamespace(document.getText());
return nreplClient.info(item.label, ns).then(info => {
item.documentation = info.doc;
Expand Down
21 changes: 12 additions & 9 deletions src/nreplClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface nREPLInfoMessage {
op: string;
symbol: string;
ns: string;
session: string;
session?: string;
}

interface nREPLEvalMessage {
Expand Down Expand Up @@ -56,28 +56,31 @@ const info = (symbol: string, ns: string, session?: string): Promise<any> => {
return send(msg).then(respObjs => respObjs[0]);
};

const evaluate = (code: string, session?: string): Promise<any[]> => clone(session).then((new_session) => {
const session_id = new_session['new-session'];
const evaluate = (code: string, session?: string): Promise<any[]> => clone(session).then((session_id) => {
const msg: nREPLSingleEvalMessage = { op: 'eval', code: code, session: session_id };
return send(msg);
});

const evaluateFile = (code: string, filepath: string, session?: string): Promise<any[]> => clone(session).then((new_session) => {
const session_id = new_session['new-session'];
const evaluateFile = (code: string, filepath: string, session?: string): Promise<any[]> => clone(session).then((session_id) => {
const msg: nREPLEvalMessage = { op: 'load-file', file: code, 'file-path': filepath, session: session_id };
return send(msg);
});

const stacktrace = (session: string): Promise<any> => send({ op: 'stacktrace', session: session });

const clone = (session?: string): Promise<any[]> => send({ op: 'clone', session: session }).then(respObjs => respObjs[0]);
const clone = (session?: string): Promise<string> => {
return send({ op: 'clone', session: session }).then(respObjs => respObjs[0]['new-session']);
}

const test = (connectionInfo: CljConnectionInformation): Promise<any[]> => {
return send({ op: 'clone' }, connectionInfo)
.then(respObjs => respObjs[0])
.then(response => {
if (!('new-session' in response))
return Promise.reject(false);
else {
return Promise.resolve([]);
}
});
};

Expand All @@ -100,21 +103,21 @@ const send = (msg: nREPLCompleteMessage | nREPLInfoMessage | nREPLEvalMessage |
return reject('No connection found.');

const client = net.createConnection(connection.port, connection.host);
Object.keys(msg).forEach(key => msg[key] === undefined && delete msg[key]);
Object.keys(msg).forEach(key => (msg as any)[key] === undefined && delete (msg as any)[key]);
client.write(bencodeUtil.encode(msg), 'binary');

client.on('error', error => {
client.end();
client.removeAllListeners();
if (error['code'] == 'ECONNREFUSED') {
if ((error as any)['code'] === 'ECONNREFUSED') {
vscode.window.showErrorMessage('Connection refused.');
cljConnection.disconnect();
}
reject(error);
});

let nreplResp = Buffer.from('');
const respObjects = [];
const respObjects: any[] = [];
client.on('data', data => {
nreplResp = Buffer.concat([nreplResp, data]);
const { decodedObjects, rest } = bencodeUtil.decodeObjects(nreplResp);
Expand Down
15 changes: 8 additions & 7 deletions src/nreplController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'process';
import * as os from 'os';
import * as vscode from 'vscode';
import { spawn } from 'cross-spawn';
import * as spawn from 'cross-spawn';
import { ChildProcess, exec } from 'child_process';

import { CljConnectionInformation } from './cljConnection';
Expand All @@ -28,7 +28,7 @@ const LEIN_ARGS: string[] = [

const R_NREPL_CONNECTION_INFO = /nrepl:\/\/(.*?:.*?(?=[\n\r]))/;

let nreplProcess: ChildProcess;
let nreplProcess: ChildProcess | null

const isStarted = () => !!nreplProcess;

Expand All @@ -40,16 +40,17 @@ const start = (): Promise<CljConnectionInformation> => {
if (isStarted())
return Promise.reject({ nreplError: 'nREPL already started.' });

nreplProcess = spawn('lein', LEIN_ARGS, {
cwd: vscode.workspace.rootPath,
detached: !(os.platform() === 'win32')
});

// Clear any output from previous nREPL sessions to help users focus
// on the current session only.
nreplChannel.clear();

return new Promise((resolve, reject) => {

nreplProcess = spawn('lein', LEIN_ARGS, {
cwd: vscode.workspace.rootPath,
detached: !(os.platform() === 'win32')
});

nreplProcess.stdout.addListener('data', data => {
const nreplConnectionMatch = data.toString().match(R_NREPL_CONNECTION_INFO);
// Send any stdout messages to the output channel
Expand Down
Loading

0 comments on commit 4b091db

Please sign in to comment.