Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit b12f8ed

Browse files
committed
Merge pull request #7362 from adobe/kai/fix-6661-multi-linters
Fix #6661. Configurable multiple linters.
2 parents 13f85b4 + fb0183f commit b12f8ed

3 files changed

Lines changed: 109 additions & 33 deletions

File tree

.brackets.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
"es5": true
99
},
1010
"defaultExtension": "js",
11+
"language": {
12+
"javascript": {
13+
"linting.prefer": ["JSLint", "JSHint"],
14+
"linting.usePreferredOnly": true
15+
}
16+
},
1117
"path": {
1218
"src/thirdparty/CodeMirror2/**/*.js": {
1319
"spaceUnits": 2,
@@ -20,4 +26,4 @@
2026
},
2127
"spaceUnits": 4,
2228
"useTabChar": false
23-
}
29+
}

src/language/CodeInspection.js

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ define(function (require, exports, module) {
7575
/**
7676
* Constants for the preferences defined in this file.
7777
*/
78-
var PREF_ENABLED = "enabled",
79-
PREF_COLLAPSED = "collapsed",
80-
PREF_ASYNC_TIMEOUT = "asyncTimeout";
78+
var PREF_ENABLED = "enabled",
79+
PREF_COLLAPSED = "collapsed",
80+
PREF_ASYNC_TIMEOUT = "asyncTimeout",
81+
PREF_PREFER_PROVIDERS = "prefer",
82+
PREF_PREFERRED_ONLY = "usePreferredOnly";
8183

8284
var prefs = PreferencesManager.getExtensionPrefs("linting");
8385

@@ -158,11 +160,42 @@ define(function (require, exports, module) {
158160
* Decision is made depending on the file extension.
159161
*
160162
* @param {!string} filePath
161-
* @return ?{Array.<{name:string, scanFileAsync:?function(string, string):!{$.Promise}, scanFile:?function(string, string):?{errors:!Array, aborted:boolean}}>} provider
163+
* @return {Array.<{name:string, scanFileAsync:?function(string, string):!{$.Promise}, scanFile:?function(string, string):?{errors:!Array, aborted:boolean}}>}
162164
*/
163165
function getProvidersForPath(filePath) {
164-
var providers = _providers[LanguageManager.getLanguageForPath(filePath).getId()];
165-
return (providers && providers.slice(0)) || [];
166+
var language = LanguageManager.getLanguageForPath(filePath).getId(),
167+
context = PreferencesManager._buildContext(filePath, language),
168+
installedProviders = _providers[language],
169+
preferredProviders,
170+
171+
prefPreferredProviderNames = prefs.get(PREF_PREFER_PROVIDERS, context),
172+
prefPreferredOnly = prefs.get(PREF_PREFERRED_ONLY, context),
173+
174+
providers;
175+
176+
// ensure there is an instance and that a copy is returned, always
177+
installedProviders = (installedProviders && installedProviders.slice(0)) || [];
178+
179+
if (prefPreferredProviderNames && prefPreferredProviderNames.length) {
180+
if (typeof prefPreferredProviderNames === "string") {
181+
prefPreferredProviderNames = [prefPreferredProviderNames];
182+
}
183+
preferredProviders = prefPreferredProviderNames.reduce(function (result, key) {
184+
var provider = _.find(installedProviders, {name: key});
185+
if (provider) {
186+
result.push(provider);
187+
}
188+
return result;
189+
}, []);
190+
if (prefPreferredOnly) {
191+
providers = preferredProviders;
192+
} else {
193+
providers = _.union(preferredProviders, installedProviders);
194+
}
195+
} else {
196+
providers = installedProviders;
197+
}
198+
return providers;
166199
}
167200

168201
/**
@@ -184,7 +217,7 @@ define(function (require, exports, module) {
184217
var response = new $.Deferred(),
185218
results = [];
186219

187-
providerList = (providerList || getProvidersForPath(file.fullPath)) || [];
220+
providerList = providerList || getProvidersForPath(file.fullPath);
188221

189222
if (!providerList.length) {
190223
response.resolve(null);
@@ -458,14 +491,6 @@ define(function (require, exports, module) {
458491
_providers[languageId] = [];
459492
}
460493

461-
if (languageId === "javascript") {
462-
// This is a special case to enable extension provider to replace the JSLint provider
463-
// in favor of their own implementation
464-
_.remove(_providers[languageId], function (registeredProvider) {
465-
return registeredProvider.name === "JSLint";
466-
});
467-
}
468-
469494
_providers[languageId].push(provider);
470495

471496
run(); // in case a file of this type is open currently
@@ -580,7 +605,7 @@ define(function (require, exports, module) {
580605
});
581606

582607
prefs.definePreference(PREF_ASYNC_TIMEOUT, "number", 10000);
583-
608+
584609
// Initialize items dependent on HTML DOM
585610
AppInit.htmlReady(function () {
586611
// Create bottom panel to list error details
@@ -644,6 +669,8 @@ define(function (require, exports, module) {
644669
// Testing
645670
exports._unregisterAll = _unregisterAll;
646671
exports._PREF_ASYNC_TIMEOUT = PREF_ASYNC_TIMEOUT;
672+
exports._PREF_PREFER_PROVIDERS = PREF_PREFER_PROVIDERS;
673+
exports._PREF_PREFERRED_ONLY = PREF_PREFERRED_ONLY;
647674

648675
// Public API
649676
exports.register = register;

test/spec/CodeInspection-test.js

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ define(function (require, exports, module) {
3030
var SpecRunnerUtils = require("spec/SpecRunnerUtils"),
3131
FileSystem = require("filesystem/FileSystem"),
3232
StringUtils = require("utils/StringUtils"),
33-
Strings = require("strings");
33+
Strings = require("strings"),
34+
_ = require("thirdparty/lodash");
3435

3536
describe("Code Inspection", function () {
3637
this.category = "integration";
@@ -42,8 +43,9 @@ define(function (require, exports, module) {
4243
CodeInspection,
4344
CommandManager,
4445
Commands = require("command/Commands"),
45-
DocumentManager,
4646
EditorManager,
47+
DocumentManager,
48+
PreferencesManager,
4749
prefs;
4850

4951
var toggleJSLintResults = function (visible) {
@@ -115,6 +117,7 @@ define(function (require, exports, module) {
115117
EditorManager = brackets.test.EditorManager;
116118
prefs = brackets.test.PreferencesManager.getExtensionPrefs("linting");
117119
CodeInspection = brackets.test.CodeInspection;
120+
PreferencesManager = brackets.test.PreferencesManager;
118121
CodeInspection.toggleEnabled(true);
119122
});
120123
});
@@ -300,6 +303,60 @@ define(function (require, exports, module) {
300303
});
301304
});
302305

306+
it("should use preferences for providers lookup", function () {
307+
var pm = PreferencesManager.getExtensionPrefs("linting"),
308+
codeInspector1 = createCodeInspector("html1", failLintResult),
309+
codeInspector2 = createCodeInspector("html2", successfulLintResult),
310+
codeInspector3 = createCodeInspector("html3", successfulLintResult),
311+
codeInspector4 = createCodeInspector("html4", successfulLintResult),
312+
codeInspector5 = createCodeInspector("html5", failLintResult);
313+
314+
CodeInspection.register("html", codeInspector1);
315+
CodeInspection.register("html", codeInspector2);
316+
CodeInspection.register("html", codeInspector3);
317+
CodeInspection.register("html", codeInspector4);
318+
CodeInspection.register("html", codeInspector5);
319+
320+
function setAtLocation(name, value) {
321+
pm.set(name, value, {location: {layer: "language", layerID: "html", scope: "user"}});
322+
}
323+
324+
runs(function () {
325+
var providers;
326+
327+
setAtLocation(CodeInspection._PREF_PREFER_PROVIDERS, ["html3", "html4"]);
328+
providers = CodeInspection.getProvidersForPath("my/index.html");
329+
expect(providers).toNotBe(null);
330+
expect(_.pluck(providers, "name")).toEqual(["html3", "html4", "html1", "html2", "html5"]);
331+
332+
setAtLocation(CodeInspection._PREF_PREFER_PROVIDERS, ["html5", "html6"]);
333+
providers = CodeInspection.getProvidersForPath("index.html");
334+
expect(providers).toNotBe(null);
335+
expect(_.pluck(providers, "name")).toEqual(["html5", "html1", "html2", "html3", "html4"]);
336+
337+
setAtLocation(CodeInspection._PREF_PREFER_PROVIDERS, ["html19", "html100"]);
338+
providers = CodeInspection.getProvidersForPath("index.html");
339+
expect(providers).toNotBe(null);
340+
expect(_.pluck(providers, "name")).toEqual(["html1", "html2", "html3", "html4", "html5"]);
341+
342+
setAtLocation(CodeInspection._PREF_PREFERRED_ONLY, true);
343+
providers = CodeInspection.getProvidersForPath("test.html");
344+
expect(providers).toEqual([]);
345+
346+
setAtLocation(CodeInspection._PREF_PREFER_PROVIDERS, ["html2", "html1"]);
347+
setAtLocation(CodeInspection._PREF_PREFERRED_ONLY, true);
348+
providers = CodeInspection.getProvidersForPath("c:/temp/another.html");
349+
expect(providers).toNotBe(null);
350+
expect(_.pluck(providers, "name")).toEqual(["html2", "html1"]);
351+
352+
setAtLocation(CodeInspection._PREF_PREFER_PROVIDERS, undefined);
353+
setAtLocation(CodeInspection._PREF_PREFERRED_ONLY, undefined);
354+
providers = CodeInspection.getProvidersForPath("index.html");
355+
expect(providers).toNotBe(null);
356+
expect(_.pluck(providers, "name")).toEqual(["html1", "html2", "html3", "html4", "html5"]);
357+
});
358+
});
359+
303360
it("should run asynchoronous implementation when both available in the provider", function () {
304361
var provider = createAsyncCodeInspector("javascript async linter with sync impl", failLintResult(), 200, true);
305362
CodeInspection.register("javascript", provider);
@@ -1071,20 +1128,6 @@ define(function (require, exports, module) {
10711128
CodeInspection._unregisterAll();
10721129
});
10731130

1074-
it("should unregister JSLint linter if a new javascript linter is registered", function () {
1075-
var codeInspector1 = createCodeInspector("JSLint", successfulLintResult());
1076-
CodeInspection.register("javascript", codeInspector1);
1077-
var codeInspector2 = createCodeInspector("javascript inspector", successfulLintResult());
1078-
CodeInspection.register("javascript", codeInspector2, true);
1079-
1080-
waitsForDone(SpecRunnerUtils.openProjectFiles(["no-errors.js"]), "open test file", 5000);
1081-
1082-
runs(function () {
1083-
expect(codeInspector1.scanFile).not.toHaveBeenCalled();
1084-
expect(codeInspector2.scanFile).toHaveBeenCalled();
1085-
});
1086-
});
1087-
10881131
it("should call inspector 1 and inspector 2", function () {
10891132
var codeInspector1 = createCodeInspector("javascript inspector 1", successfulLintResult());
10901133
CodeInspection.register("javascript", codeInspector1);

0 commit comments

Comments
 (0)