This repository has been archived by the owner on Aug 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #57 from AtomLinter/arcanemagus/js-rewrite
Rewrite in JS
- Loading branch information
Showing
8 changed files
with
259 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
'use babel'; | ||
|
||
// eslint-disable-next-line import/no-extraneous-dependencies, import/extensions | ||
import { CompositeDisposable } from 'atom'; | ||
|
||
// Dependencies | ||
let helpers; | ||
|
||
const loadDeps = () => { | ||
if (!helpers) { | ||
helpers = require('atom-linter'); | ||
} | ||
}; | ||
|
||
export default { | ||
activate() { | ||
this.idleCallbacks = new Set(); | ||
let depsCallbackID; | ||
const installLinterClojureDeps = () => { | ||
this.idleCallbacks.delete(depsCallbackID); | ||
if (!atom.inSpecMode()) { | ||
require('atom-package-deps').install('linter-clojure'); | ||
} | ||
loadDeps(); | ||
}; | ||
depsCallbackID = window.requestIdleCallback(installLinterClojureDeps); | ||
this.idleCallbacks.add(depsCallbackID); | ||
|
||
this.subscriptions = new CompositeDisposable(); | ||
this.subscriptions.add( | ||
atom.config.observe('linter-clojure.javaExecutablePath', (value) => { | ||
this.javaExecutablePath = value; | ||
}), | ||
atom.config.observe('linter-clojure.clojureExecutablePath', (value) => { | ||
this.clojureExecutablePath = value; | ||
}), | ||
); | ||
}, | ||
|
||
deactivate() { | ||
this.idleCallbacks.forEach(callbackID => window.cancelIdleCallback(callbackID)); | ||
this.idleCallbacks.clear(); | ||
this.subscriptions.dispose(); | ||
}, | ||
|
||
provideLinter() { | ||
return { | ||
name: 'Clojure', | ||
grammarScopes: ['source.clojure', 'source.clojurescript'], | ||
scope: 'file', | ||
lintOnFly: false, | ||
lint: async (textEditor) => { | ||
loadDeps(); | ||
|
||
if (!atom.workspace.isTextEditor(textEditor)) { | ||
// Somehow we got fed an invalid TextEditor | ||
return null; | ||
} | ||
|
||
const filePath = textEditor.getPath(); | ||
|
||
if (!filePath) { | ||
// The TextEditor had no path associated with it somehow | ||
return null; | ||
} | ||
|
||
const fileText = textEditor.getText(); | ||
|
||
const parameters = [ | ||
'-jar', this.clojureExecutablePath, | ||
'-i', filePath, | ||
]; | ||
|
||
const execOpts = { | ||
stream: 'stderr', | ||
allowEmptyStderr: true, | ||
}; | ||
|
||
const output = await helpers.exec(this.javaExecutablePath, parameters, execOpts); | ||
|
||
// Check for invalid jarfile specification | ||
const invalidJarCheck = /Error: Unable to access jarfile (.+)/.exec(output); | ||
if (invalidJarCheck !== null) { | ||
const message = 'linter-clojure: Unable to find Clojure!'; | ||
const options = { | ||
detail: `Java was unable to find the Clojure jarfile at '${invalidJarCheck[1]}'.`, | ||
}; | ||
atom.notifications.addError(message, options); | ||
return []; | ||
} | ||
|
||
if (textEditor.getText() !== fileText) { | ||
// File has changed since the lint was triggered, tell Linter not to update | ||
return null; | ||
} | ||
|
||
const toReturn = []; | ||
const regex = /RuntimeException: (.+), compiling:\((.+):(\d+):(\d+)\)/g; | ||
|
||
let match = regex.exec(output); | ||
while (match !== null) { | ||
// Reports 1 indexed positions normally, but can report 0:0. | ||
let line = Number.parseInt(match[3], 10); | ||
line = line > 0 ? line - 1 : 0; | ||
let col = Number.parseInt(match[4], 10); | ||
col = col > 0 ? col - 1 : 0; | ||
|
||
toReturn.push({ | ||
severity: 'error', | ||
excerpt: match[1], | ||
location: { | ||
file: match[2], | ||
position: helpers.generateRange(textEditor, line, col), | ||
}, | ||
}); | ||
match = regex.exec(output); | ||
} | ||
return toReturn; | ||
}, | ||
}; | ||
}, | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,66 @@ | ||
{ | ||
"name": "linter-clojure", | ||
"main": "./lib/init", | ||
"main": "./lib/index", | ||
"version": "1.1.3", | ||
"description": "Lint Clojure on the fly, using clojure-x.x.x.jar", | ||
"repository": "https://github.com/AtomLinter/linter-clojure", | ||
"license": "MIT", | ||
"engines": { | ||
"atom": ">=1.0.0 <2.0.0" | ||
"atom": ">=1.7.0 <2.0.0" | ||
}, | ||
"configSchema": { | ||
"javaExecutablePath": { | ||
"type": "string", | ||
"default": "java" | ||
}, | ||
"clojureExecutablePath": { | ||
"type": "string", | ||
"default": "clojure-x.x.x.jar" | ||
} | ||
}, | ||
"scripts": { | ||
"lint": "eslint .", | ||
"test": "apm test" | ||
}, | ||
"providedServices": { | ||
"linter": { | ||
"versions": { | ||
"1.0.0": "provideLinter" | ||
"2.0.0": "provideLinter" | ||
} | ||
} | ||
}, | ||
"dependencies": { | ||
"atom-linter": "^10.0.0", | ||
"atom-package-deps": "^4.0.1" | ||
"atom-package-deps": "^4.6.0" | ||
}, | ||
"package-deps": [ | ||
"linter" | ||
] | ||
"linter:2.0.0" | ||
], | ||
"devDependencies": { | ||
"eslint": "^4.3.0", | ||
"eslint-config-airbnb-base": "^11.3.2", | ||
"eslint-plugin-import": "^2.7.0", | ||
"jasmine-fix": "^1.3.0" | ||
}, | ||
"eslintConfig": { | ||
"extends": "airbnb-base", | ||
"rules": { | ||
"global-require": "off", | ||
"import/no-unresolved": [ | ||
"error", | ||
{ | ||
"ignore": [ | ||
"atom" | ||
] | ||
} | ||
] | ||
}, | ||
"globals": { | ||
"atom": true | ||
}, | ||
"env": { | ||
"node": true, | ||
"browser": true | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
module.exports = { | ||
env: { | ||
jasmine: true, | ||
atomtest: true, | ||
}, | ||
rules: { | ||
"import/no-extraneous-dependencies": [ | ||
"error", | ||
{ | ||
"devDependencies": true | ||
} | ||
] | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
(+ 1 2 3) | ||
xyz |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
(+ 1 2 3) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
'use babel'; | ||
|
||
import { join } from 'path'; | ||
// eslint-disable-next-line no-unused-vars | ||
import { it, fit, wait, beforeEach, afterEach } from 'jasmine-fix'; | ||
import linterClojure from '../lib'; | ||
|
||
const linterProvider = linterClojure.provideLinter(); | ||
const lint = linterProvider.lint; | ||
|
||
const fixturePath = join(__dirname, 'fixtures'); | ||
const emptyPath = join(fixturePath, 'empty.clj'); | ||
const goodPath = join(fixturePath, 'good.clj'); | ||
const badPath = join(fixturePath, 'bad.clj'); | ||
|
||
describe('The Clojure provider for Linter', () => { | ||
beforeEach(async () => { | ||
await atom.packages.activatePackage('language-clojure'); | ||
await atom.packages.activatePackage('linter-clojure'); | ||
// NOTE: You must set the environment variable `$ClojurePath` to the full path of Clojure | ||
if (Object.prototype.hasOwnProperty.call(process.env, 'CLOJURE_PATH')) { | ||
atom.config.set('linter-clojure.clojureExecutablePath', process.env.CLOJURE_PATH); | ||
} | ||
// Used to check for Clojure path failures | ||
spyOn(atom.notifications, 'addError'); | ||
}); | ||
|
||
it('should be in the packages list', () => | ||
expect(atom.packages.isPackageLoaded('linter-clojure')).toBe(true), | ||
); | ||
|
||
it('should be an active package', () => | ||
expect(atom.packages.isPackageActive('linter-clojure')).toBe(true), | ||
); | ||
|
||
it('finds nothing wrong with a good file', async () => { | ||
const editor = await atom.workspace.open(goodPath); | ||
const messages = await lint(editor); | ||
|
||
expect(atom.notifications.addError).not.toHaveBeenCalled(); | ||
expect(messages.length).toBe(0); | ||
}); | ||
|
||
it('reports invalid clojure.jar specifications', async () => { | ||
atom.config.set('linter-clojure.clojureExecutablePath', 'foobar'); | ||
const editor = await atom.workspace.open(goodPath); | ||
await lint(editor); | ||
const message = 'linter-clojure: Unable to find Clojure!'; | ||
const options = { | ||
detail: "Java was unable to find the Clojure jarfile at 'foobar'.", | ||
}; | ||
expect(atom.notifications.addError).toHaveBeenCalledWith(message, options); | ||
}); | ||
|
||
it('properly reports errors found', async () => { | ||
const editor = await atom.workspace.open(badPath); | ||
const messages = await lint(editor); | ||
|
||
expect(atom.notifications.addError).not.toHaveBeenCalled(); | ||
expect(messages[0].severity).toBe('error'); | ||
expect(messages[0].excerpt).toBe('Unable to resolve symbol: xyz in this context'); | ||
expect(messages[0].location.file).toBe(badPath); | ||
expect(messages[0].location.position).toEqual([[0, 0], [0, 4]]); | ||
}); | ||
|
||
it('finds nothing wrong with an empty file', async () => { | ||
const editor = await atom.workspace.open(emptyPath); | ||
const messages = await lint(editor); | ||
|
||
expect(atom.notifications.addError).not.toHaveBeenCalled(); | ||
expect(messages.length).toBe(0); | ||
}); | ||
}); |