"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Languages = void 0; const languages_json_1 = __importDefault(require("language-map/languages.json")); const utils_1 = require("./utils"); /** * The extension map can contain multiple languages with the same extension, * but we only want a single one. For the moment, these clashes are resolved * by the simple heuristic below listing high-priority languages. We may want * to consider smarter heuristics to correctly identify languages in cases * where the extension is ambiguous. The ordering of the list matters and * languages earlier on will get a higher priority when resolving clashes. */ const importantLanguages = [ 'javascript', 'typescript', 'ruby', 'python', 'java', 'c', 'c++', 'c#', 'rust', 'scala', 'perl', 'go', ]; const ALL_REGEXES = { c: { // matches when // are the first two characters of a line singleLineComment: /^\/\//, // matches when /* exists in a line multiLineCommentOpen: /\/\*/, // matches when /* starts a line multiLineCommentOpenStart: /^\/\*/, // matches when */ exists a line multiLineCommentClose: /\*\//, // matches when */ ends a line multiLineCommentCloseEnd: /\*\/$/, // matches /* ... */ multiLineCommentOpenAndClose: /\/\*.*\*\//, }, python: { // matches when # the first character of a line singleLineComment: /^#/, }, ruby: { // matches when # the first character of a line singleLineComment: /^#/, // For ruby multiline comments, =begin and =end must be // on their own lines // matches when =begin starts a line multiLineCommentOpen: /^=begin/, // matches when "begin starts a line multiLineCommentOpenStart: /^=begin/, // matches when "end ends a line multiLineCommentClose: /^=end/, // matches when "end ends a line multiLineCommentCloseEnd: /^=end$/, // not possible in ruby multiLineCommentOpenAndClose: /^\0$/, }, html: { // There is no single line comment singleLineComment: /^\0$/, // matches when =begin starts a line multiLineCommentOpen: //, // matches when "end ends a line multiLineCommentCloseEnd: /-->$/, // matches multiLineCommentOpenAndClose: //, }, }; /** * detecte program language through file extension * * @export * @class LanguageDetector */ class Languages { /** * Creates an instance of Detector. */ constructor() { Object.defineProperty(this, "extensionMap", { enumerable: true, configurable: true, writable: true, value: {} }); /** * load language before detecting */ Object.defineProperty(this, "loadExtensionMap", { enumerable: true, configurable: true, writable: true, value: () => { const extensions = {}; Object.keys(languages_json_1.default).forEach((language) => { const languageMode = languages_json_1.default[language]; const languageExtensions = (languageMode && languageMode.extensions) || []; languageExtensions.forEach((extension) => { const lowerCaseExtension = extension.toLowerCase(); const lowerCaseLanguage = language.toLowerCase(); if (!extensions[lowerCaseExtension]) { extensions[lowerCaseExtension] = lowerCaseLanguage; } else { const currentLanguagePriority = importantLanguages.indexOf(extensions[lowerCaseExtension]); if (currentLanguagePriority === -1) { extensions[lowerCaseExtension] = lowerCaseLanguage; } else { const otherPriority = importantLanguages.indexOf(lowerCaseLanguage); if (otherPriority !== -1 && otherPriority < currentLanguagePriority) extensions[lowerCaseExtension] = lowerCaseLanguage; } } }); }); return { ...extensions, ...utils_1.ExtensionJustify }; } }); this.extensionMap = this.loadExtensionMap(); } /** * Retrieve the regular expressions for a given language. * This is incomplete, but covers most of the languages we * see in the wild. * * @param language the language to retrieve regexes for */ getRegexes(language) { switch (language) { case 'html': case 'xml': return ALL_REGEXES.html; case 'ruby': return ALL_REGEXES.ruby; case 'python': return ALL_REGEXES.python; default: // not exact, but likely the best guess for any other unspecified language. return ALL_REGEXES.c; } } /** * return extension map */ getExtensionMap() { return this.extensionMap; } /** * get file type through a path */ getType(path) { const fileExtension = `.${path.split('.').pop()}`; return this.extensionMap[fileExtension] || ''; } } exports.Languages = Languages; //# sourceMappingURL=languages.js.map