diff --git a/src/extensions/default/JavaScriptCodeHints/HintUtils.js b/src/extensions/default/JavaScriptCodeHints/HintUtils.js index 6de4c8314e0..2b0959cac7c 100644 --- a/src/extensions/default/JavaScriptCodeHints/HintUtils.js +++ b/src/extensions/default/JavaScriptCodeHints/HintUtils.js @@ -103,21 +103,6 @@ define(function (require, exports, module) { function hintableKey(key) { return (key === null || key === "." || maybeIdentifier(key)); } - - /** - * Divide a path into directory and filename parts - * - * @param {string} path - a URI with directories separated by / - * @return {{dir: string, file: string}} - a pair of strings that - * correspond to the directory and filename of the given path. - */ - function splitPath(path) { - var index = path.lastIndexOf("/"), - dir = (index === -1) ? "" : path.substring(0, index), - file = path.substring(index + 1, path.length); - - return {dir: dir, file: file }; - } /* * Get a JS-hints-specific event name. Used to prevent event namespace @@ -203,7 +188,6 @@ define(function (require, exports, module) { exports.hintable = hintable; exports.hintableKey = hintableKey; exports.maybeIdentifier = maybeIdentifier; - exports.splitPath = splitPath; exports.eventName = eventName; exports.annotateLiterals = annotateLiterals; exports.isSupportedLanguage = isSupportedLanguage; diff --git a/src/extensions/default/JavaScriptCodeHints/ScopeManager.js b/src/extensions/default/JavaScriptCodeHints/ScopeManager.js index b4f615a531d..cb7d66a2418 100644 --- a/src/extensions/default/JavaScriptCodeHints/ScopeManager.js +++ b/src/extensions/default/JavaScriptCodeHints/ScopeManager.js @@ -175,65 +175,6 @@ define(function (require, exports, module) { } } - /** - * For each file in a directory get a callback with the path of the javascript - * file or directory. - * - * dotfiles are ignored. - * - * @param {string} dir - directory in which to list the files. - * @param {function()} doneCallback - called after all of the files have - * been listed. - * @param {function(string)} fileCallback - callback for javascript files. - * The function is passed the full path name of the file. - * @param {!function(string)=} directoryCallback - callback for directory - * files. The function is passed the full path name of the file (optional). - * @param {!function(string)=} errorCallback - Callback for errors (optional). - */ - function forEachFileInDirectory(dir, doneCallback, fileCallback, directoryCallback, errorCallback) { - var files = []; - - FileSystem.resolve(dir, function (err, directory) { - if (!err && directory.isDirectory) { - directory.getContents(function (err, contents) { - if (!err) { - contents.slice(0, preferences.getMaxFileCount()).forEach(function (entry) { - var path = entry.fullPath, - split = HintUtils.splitPath(path), - file = split.file; - - if (fileCallback && entry.isFile) { - - if (file.indexOf(".") > 0) { // ignore .dotfiles - var languageID = LanguageManager.getLanguageForPath(path).getId(); - if (languageID === HintUtils.LANGUAGE_ID) { - fileCallback(path); - } - } - } else if (directoryCallback && entry.isDirectory) { - var dirName = HintUtils.splitPath(split.dir).file; - if (dirName.indexOf(".") !== 0) { // ignore .dotfiles - directoryCallback(entry.fullPath); - } - } - }); - doneCallback(); - } else { - if (errorCallback) { - errorCallback(err); - } - console.log("Unable to refresh directory: ", err); - } - }); - } else { - if (errorCallback) { - errorCallback(err); - } - console.log("Directory \"%s\" does not exist", dir); - } - }); - } - /** * Test if the directory should be excluded from analysis. * @@ -256,52 +197,17 @@ define(function (require, exports, module) { /** * Test if the file should be excluded from analysis. * - * @param {!string} path - full directory path. + * @param {!File} file - file to test for exclusion. * @return {boolean} true if excluded, false otherwise. */ - function isFileExcluded(path) { + function isFileExcluded(file) { var excludes = preferences.getExcludedFiles(); if (!excludes) { return false; } - var file = HintUtils.splitPath(path).file; - - return excludes.test(file); - } - - /** - * Get a list of javascript files in a given directory. - * - * @param {string} dir - directory to list the files of. - * @param {function(Array.)} successCallback - callback with - * array of file path names. - * @param {function(Array.)} errorCallback - callback for - * when an error occurs. - */ - function getFilesInDirectory(dir, successCallback, errorCallback) { - var files = []; // file names without paths. - - /** - * Call the success callback with all of the found files. - */ - function doneCallback() { - successCallback(files); - } - - /** - * Add files to global list. - * - * @param path - full path of file. - */ - function fileCallback(path) { - if (!isFileExcluded(path)) { - files.push(path); - } - } - - forEachFileInDirectory(dir, doneCallback, fileCallback, null, errorCallback); + return excludes.test(file.name); } /** @@ -870,7 +776,7 @@ define(function (require, exports, module) { */ function findNameInProject() { // check for any files in project that end with the right path. - var fileName = HintUtils.splitPath(name).file; + var fileName = name.substring(name.lastIndexOf("/")); function _fileFilter(entry) { return entry.name === fileName; @@ -986,74 +892,32 @@ define(function (require, exports, module) { * added to tern. */ function addAllFilesAndSubdirectories(dir, doneCallback) { - - var numDirectoriesLeft = 1; // number of directories to process - - /** - * Add the files in the directory and subdirectories of a given directory - * to tern, excluding the rootTernDir). - * - * @param {string} dir - the root directory to add. - * @param {function()} successCallback - callback when - * done processing files. - */ - function addAllFilesRecursively(dir, successCallback) { - - var files = [], - dirs = []; - - function doneCallback() { - numDirectoriesLeft--; - - if (!stopAddingFiles && files.length > 0 && - (dir + "/") !== rootTernDir) { - addFilesToTern(files); - } - - if (!stopAddingFiles) { - dirs.forEach(function (path) { - var dir = HintUtils.splitPath(path).dir; - if (!stopAddingFiles) { - numDirectoriesLeft++; - addAllFilesRecursively(dir, successCallback); + FileSystem.resolve(dir, function (err, directory) { + function visitor(entry) { + if (entry.isFile) { + if (!isFileExcluded(entry) && entry.name.indexOf(".") !== 0) { // ignore .dotfiles + var languageID = LanguageManager.getLanguageForPath(entry.fullPath).getId(); + if (languageID === HintUtils.LANGUAGE_ID) { + addFilesToTern([entry.fullPath]); } - }); - } - - if (numDirectoriesLeft === 0) { - successCallback(); + } + } else { + return !isDirectoryExcluded(entry.fullPath) && + entry.name.indexOf(".") !== 0 && + !stopAddingFiles; } } - - /** - * Add files to global list. - * - * @param path - full path of file. - */ - function fileCallback(path) { - if (!isFileExcluded(path)) { - files.push(path); - } + + if (err) { + return; } - - /** - * For each directory, add all the files in its subdirectory. - * - * @param path - */ - function directoryCallback(path) { - if (!isDirectoryExcluded(path) && - path !== rootTernDir) { - dirs.push(path); - } + + if (dir === FileSystem.getDirectoryForPath(rootTernDir)) { + doneCallback(); + return; } - - dir = FileUtils.stripTrailingSlash(dir); - forEachFileInDirectory(dir, doneCallback, fileCallback, directoryCallback); - } - - addAllFilesRecursively(dir, function () { - doneCallback(); + + directory.visit(visitor, doneCallback); }); } @@ -1156,11 +1020,10 @@ define(function (require, exports, module) { * @param {Document} previousDocument - the document the editor has changed from */ function doEditorChange(session, document, previousDocument) { - var path = document.file.fullPath, - split = HintUtils.splitPath(path), - dir = split.dir, + var file = document.file, + path = file.fullPath, + dir = file.parentPath, files = [], - file = split.file, pr; var addFilesDeferred = $.Deferred(); @@ -1193,40 +1056,58 @@ define(function (require, exports, module) { ensurePreferences(); deferredPreferences.done(function () { - getFilesInDirectory(dir, function (files) { - initTernServer(dir, files); - - var hintsPromise = primePump(path); - hintsPromise.done(function () { - if (!usingModules()) { - // Read the subdirectories of the new file's directory. - // Read them first in case there are too many files to - // read in the project. - addAllFilesAndSubdirectories(dir, function () { - // If the file is in the project root, then read - // all the files under the project root. - var currentDir = (dir + "/"); - if (projectRoot && currentDir !== projectRoot && - currentDir.indexOf(projectRoot) === 0) { - addAllFilesAndSubdirectories(projectRoot, function () { - // prime the pump again but this time don't wait - // for completion. - primePump(path); - - addFilesDeferred.resolveWith(null, [_ternWorker]); - }); - } else { - addFilesDeferred.resolveWith(null, [_ternWorker]); - } - }); - } else { - addFilesDeferred.resolveWith(null, [_ternWorker]); + FileSystem.resolve(dir, function (err, directory) { + if (err) { + addFilesDeferred.resolveWith(null); + return; + } + + directory.getContents(function (err, contents) { + if (err) { + addFilesDeferred.resolveWith(null); + return; } + + var files = contents + .filter(function (entry) { + return entry.isFile && !isFileExcluded(entry); + }) + .map(function (entry) { + return entry.fullPath; + }); + + initTernServer(dir, files); + + var hintsPromise = primePump(path); + hintsPromise.done(function () { + if (!usingModules()) { + // Read the subdirectories of the new file's directory. + // Read them first in case there are too many files to + // read in the project. + addAllFilesAndSubdirectories(dir, function () { + // If the file is in the project root, then read + // all the files under the project root. + var currentDir = (dir + "/"); + if (projectRoot && currentDir !== projectRoot && + currentDir.indexOf(projectRoot) === 0) { + addAllFilesAndSubdirectories(projectRoot, function () { + // prime the pump again but this time don't wait + // for completion. + primePump(path); + + addFilesDeferred.resolveWith(null, [_ternWorker]); + }); + } else { + addFilesDeferred.resolveWith(null, [_ternWorker]); + } + }); + } else { + addFilesDeferred.resolveWith(null, [_ternWorker]); + } + }); }); - }, function () { - addFilesDeferred.resolveWith(null); }); - }).fail(function () {}); + }); } /**