You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

776 lines
30 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. let isTesting = false;
  4. const ILCommentPrefix = "@@comments";
  5. const ILQuotesPrefix = "@@quotes";
  6. const ILSingleQuotesPrefix = "@@singlequotes";
  7. var FormatMode;
  8. (function (FormatMode) {
  9. FormatMode[FormatMode["Default"] = 0] = "Default";
  10. FormatMode[FormatMode["EndsWithSemicolon"] = 1] = "EndsWithSemicolon";
  11. FormatMode[FormatMode["CaseWhen"] = 2] = "CaseWhen";
  12. FormatMode[FormatMode["IfElse"] = 3] = "IfElse";
  13. FormatMode[FormatMode["PortGeneric"] = 4] = "PortGeneric";
  14. })(FormatMode || (FormatMode = {}));
  15. let Mode = FormatMode.Default;
  16. class NewLineSettings {
  17. constructor() {
  18. this.newLineAfter = [];
  19. this.noNewLineAfter = [];
  20. }
  21. newLineAfterPush(keyword) {
  22. this.newLineAfter.push(keyword);
  23. }
  24. noNewLineAfterPush(keyword) {
  25. this.noNewLineAfter.push(keyword);
  26. }
  27. push(keyword, addNewLine) {
  28. let str = addNewLine.toLowerCase();
  29. if (str == "none") {
  30. return;
  31. }
  32. else if (!str.startsWith("no")) {
  33. this.newLineAfterPush(keyword);
  34. }
  35. else {
  36. this.noNewLineAfterPush(keyword);
  37. }
  38. }
  39. }
  40. exports.NewLineSettings = NewLineSettings;
  41. function ConstructNewLineSettings(dict) {
  42. let settings = new NewLineSettings();
  43. for (let key in dict) {
  44. settings.push(key, dict[key]);
  45. }
  46. return settings;
  47. }
  48. String.prototype.regexCount = function (pattern) {
  49. if (pattern.flags.indexOf("g") < 0) {
  50. pattern = new RegExp(pattern.source, pattern.flags + "g");
  51. }
  52. return (this.match(pattern) || []).length;
  53. };
  54. String.prototype.count = function (text) {
  55. return this.split(text).length - 1;
  56. };
  57. String.prototype.regexStartsWith = function (pattern) {
  58. var searchResult = this.search(pattern);
  59. return searchResult == 0;
  60. };
  61. String.prototype.regexIndexOf = function (pattern, startIndex) {
  62. startIndex = startIndex || 0;
  63. var searchResult = this.substr(startIndex).search(pattern);
  64. return (-1 === searchResult) ? -1 : searchResult + startIndex;
  65. };
  66. String.prototype.regexLastIndexOf = function (pattern, startIndex) {
  67. startIndex = startIndex === undefined ? this.length : startIndex;
  68. var searchResult = this.substr(0, startIndex).reverse().regexIndexOf(pattern, 0);
  69. return (-1 === searchResult) ? -1 : this.length - ++searchResult;
  70. };
  71. String.prototype.reverse = function () {
  72. return this.split('').reverse().join('');
  73. };
  74. String.prototype.convertToRegexBlockWords = function () {
  75. let result = new RegExp("(" + this + ")([^\\w]|$)");
  76. return result;
  77. };
  78. Array.prototype.convertToRegexBlockWords = function () {
  79. let wordsStr = this.join("|");
  80. let result = new RegExp("(" + wordsStr + ")([^\\w]|$)");
  81. return result;
  82. };
  83. function wordWrap() {
  84. var d = document.getElementById("result");
  85. if (d.className == "") {
  86. d.className = "wordwrap";
  87. }
  88. else {
  89. d.className = "";
  90. }
  91. }
  92. function getHTMLInputElement(id) {
  93. return document.getElementById(id);
  94. }
  95. function noFormat() {
  96. let elements = [
  97. "remove_comments",
  98. "remove_lines",
  99. "remove_report",
  100. "check_alias",
  101. "sign_align_in",
  102. "sign_align_port",
  103. "sign_align_generic",
  104. "sign_align_function",
  105. "sign_align_procedure",
  106. "sign_align_all",
  107. "new_line_after",
  108. "use_space",
  109. "customise_indentation",
  110. "compress",
  111. "mix_letter"
  112. ];
  113. var isDisabled = getHTMLInputElement("no_format").checked;
  114. elements.forEach(element => {
  115. var htmlElement = getHTMLInputElement(element + "_div");
  116. try {
  117. getHTMLInputElement(element).disabled = isDisabled;
  118. }
  119. catch (_a) { }
  120. if (isDisabled) {
  121. htmlElement.className += " disabled";
  122. }
  123. else {
  124. htmlElement.className = htmlElement.className.replace(/\bdisabled\b/g, "");
  125. }
  126. });
  127. let radioButtons = document.getElementsByTagName("input");
  128. for (let i = 0; i < radioButtons.length; i++) {
  129. if (radioButtons[i].type == "radio") {
  130. radioButtons[i].disabled = isDisabled;
  131. }
  132. }
  133. getHTMLInputElement("cust_indent").disabled = isDisabled;
  134. }
  135. function Compress(input) {
  136. input = input.replace(/\r\n/g, '');
  137. input = input.replace(/[\t ]+/g, ' ');
  138. input = input.replace(/[ ]?([&=:\-<>\+|])[ ]?/g, '$1');
  139. return input;
  140. }
  141. function MixLetters(input) {
  142. let arr = input.split("");
  143. for (var k = 0; k < arr.length; k++) {
  144. if (arr[k] === arr[k].toUpperCase() && Math.random() > 0.5) {
  145. arr[k] = arr[k].toLowerCase();
  146. }
  147. else if (Math.random() > 0.5) {
  148. arr[k] = arr[k].toUpperCase();
  149. }
  150. }
  151. return arr.join("");
  152. }
  153. function EscapeComments(arr, comments, commentIndex) {
  154. for (var i = 0; i < arr.length; i++) {
  155. let line = arr[i];
  156. var commentStartIndex = line.indexOf("--");
  157. if (commentStartIndex >= 0) {
  158. comments.push(line.substr(commentStartIndex));
  159. arr[i] = line.substr(0, commentStartIndex) + ILCommentPrefix + commentIndex;
  160. commentIndex++;
  161. }
  162. }
  163. return commentIndex;
  164. }
  165. function ToLowerCases(arr) {
  166. for (var i = 0; i < arr.length; i++) {
  167. arr[i] = arr[i].toLowerCase();
  168. }
  169. }
  170. function ToUpperCases(arr) {
  171. for (var i = 0; i < arr.length; i++) {
  172. arr[i] = arr[i].toUpperCase();
  173. }
  174. }
  175. function ToCamelCases(arr) {
  176. for (var i = 0; i < arr.length; i++) {
  177. arr[i] = arr[i].charAt(0) + arr[i].slice(1).toLowerCase();
  178. }
  179. }
  180. function ReplaceKeyWords(text, keywords) {
  181. for (var k = 0; k < keywords.length; k++) {
  182. text = text.replace(new RegExp("([^a-zA-Z0-9_@]|^)" + keywords[k] + "([^a-zA-Z0-9_]|$)", 'gi'), "$1" + keywords[k] + "$2");
  183. }
  184. return text;
  185. }
  186. function SetKeywordCase(input, keywordcase, keywords, typenames) {
  187. let inputcase = keywordcase.toLowerCase();
  188. switch (keywordcase.toLowerCase()) {
  189. case "lowercase":
  190. ToLowerCases(keywords);
  191. ToLowerCases(typenames);
  192. break;
  193. case "defaultcase":
  194. ToCamelCases(keywords);
  195. ToCamelCases(typenames);
  196. break;
  197. case "uppercase":
  198. ToUpperCases(keywords);
  199. ToUpperCases(typenames);
  200. }
  201. input = ReplaceKeyWords(input, keywords);
  202. input = ReplaceKeyWords(input, typenames);
  203. return input;
  204. }
  205. function SetNewLinesAfterSymbols(text, newLineSettings) {
  206. if (newLineSettings == null) {
  207. return text;
  208. }
  209. if (newLineSettings.newLineAfter != null) {
  210. newLineSettings.newLineAfter.forEach(symbol => {
  211. let regex = new RegExp("(" + symbol.toUpperCase() + ")[ ]?([^ \r\n@])", "g");
  212. text = text.replace(regex, '$1\r\n$2');
  213. if (symbol.toUpperCase() == "PORT") {
  214. text = text.replace(/PORT\s+MAP/, "PORT MAP");
  215. }
  216. });
  217. }
  218. if (newLineSettings.noNewLineAfter != null) {
  219. newLineSettings.noNewLineAfter.forEach(symbol => {
  220. let regex = new RegExp("(" + symbol.toUpperCase() + ")[ \r\n]+([^@])", "g");
  221. text = text.replace(regex, '$1 $2');
  222. });
  223. }
  224. return text;
  225. }
  226. exports.SetNewLinesAfterSymbols = SetNewLinesAfterSymbols;
  227. class BeautifierSettings {
  228. constructor(removeComments, removeReport, checkAlias, signAlign, signAlignAll, keywordCase, indentation, newLineSettings) {
  229. this.RemoveComments = removeComments;
  230. this.RemoveAsserts = removeReport;
  231. this.CheckAlias = checkAlias;
  232. this.SignAlignRegional = signAlign;
  233. this.SignAlignAll = signAlignAll;
  234. this.KeywordCase = keywordCase;
  235. this.Indentation = indentation;
  236. this.NewLineSettings = newLineSettings;
  237. }
  238. }
  239. exports.BeautifierSettings = BeautifierSettings;
  240. let KeyWords = ["ABS", "ACCESS", "AFTER", "ALIAS", "ALL", "AND", "ARCHITECTURE", "ARRAY", "ASSERT", "ATTRIBUTE", "BEGIN", "BLOCK", "BODY", "BUFFER", "BUS", "CASE", "COMPONENT", "CONFIGURATION", "CONSTANT", "CONTEXT", "COVER", "DISCONNECT", "DOWNTO", "DEFAULT", "ELSE", "ELSIF", "END", "ENTITY", "EXIT", "FAIRNESS", "FILE", "FOR", "FORCE", "FUNCTION", "GENERATE", "GENERIC", "GROUP", "GUARDED", "IF", "IMPURE", "IN", "INERTIAL", "INOUT", "IS", "LABEL", "LIBRARY", "LINKAGE", "LITERAL", "LOOP", "MAP", "MOD", "NAND", "NEW", "NEXT", "NOR", "NOT", "NULL", "OF", "ON", "OPEN", "OR", "OTHERS", "OUT", "PACKAGE", "PORT", "POSTPONED", "PROCEDURE", "PROCESS", "PROPERTY", "PROTECTED", "PURE", "RANGE", "RECORD", "REGISTER", "REJECT", "RELEASE", "REM", "REPORT", "RESTRICT", "RESTRICT_GUARANTEE", "RETURN", "ROL", "ROR", "SELECT", "SEQUENCE", "SEVERITY", "SHARED", "SIGNAL", "SLA", "SLL", "SRA", "SRL", "STRONG", "SUBTYPE", "THEN", "TO", "TRANSPORT", "TYPE", "UNAFFECTED", "UNITS", "UNTIL", "USE", "VARIABLE", "VMODE", "VPROP", "VUNIT", "WAIT", "WHEN", "WHILE", "WITH", "XNOR", "XOR"];
  241. let TypeNames = ["BOOLEAN", "BIT", "CHARACTER", "INTEGER", "TIME", "NATURAL", "POSITIVE", "STRING"];
  242. function beautify(input, settings) {
  243. input = input.replace(/\r\n/g, "\n");
  244. input = input.replace(/\n/g, "\r\n");
  245. var arr = input.split("\r\n");
  246. var comments = [], commentsIndex = 0;
  247. commentsIndex = EscapeComments(arr, comments, commentsIndex);
  248. RemoveLeadingWhitespaces(arr);
  249. input = arr.join("\r\n");
  250. if (settings.RemoveComments) {
  251. input = input.replace(/\r\n[ \t]*@@comments[0-9]+[ \t]*\r\n/g, '\r\n');
  252. input = input.replace(/@@comments[0-9]+/g, '');
  253. commentsIndex = 0;
  254. }
  255. input = RemoveExtraNewLines(input);
  256. input = input.replace(/[\t ]+/g, ' ');
  257. input = input.replace(/\([\t ]+/g, '\(');
  258. input = input.replace(/[ ]+;/g, ';');
  259. input = input.replace(/:[ ]*(PROCESS|ENTITY)/gi, ':$1');
  260. arr = input.split("\r\n");
  261. let quotes = EscapeQuotes(arr);
  262. let singleQuotes = EscapeSingleQuotes(arr);
  263. input = arr.join("\r\n");
  264. input = SetKeywordCase(input, "uppercase", KeyWords, TypeNames);
  265. arr = input.split("\r\n");
  266. if (settings.RemoveAsserts) {
  267. RemoveAsserts(arr); //RemoveAsserts must be after EscapeQuotes
  268. }
  269. ReserveSemicolonInKeywords(arr);
  270. input = arr.join("\r\n");
  271. input = input.replace(/(PORT|GENERIC)\s+MAP/g, '$1 MAP');
  272. input = input.replace(/(PORT|PROCESS|GENERIC)[\s]*\(/g, '$1 (');
  273. input = SetNewLinesAfterSymbols(input, settings.NewLineSettings);
  274. arr = input.split("\r\n");
  275. ApplyNoNewLineAfter(arr, settings.NewLineSettings.noNewLineAfter);
  276. input = arr.join("\r\n");
  277. //new
  278. input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end');
  279. input = input.replace(/[ ]?([&=:\-<>\+|\*])[ ]?/g, ' $1 ');
  280. input = input.replace(/[ ]?([,])[ ]?/g, '$1 ');
  281. input = input.replace(/[ ]?(['"])(THEN)/g, '$1 $2');
  282. input = input.replace(/[ ]?(\?)?[ ]?(<|:|>|\/)?[ ]+(=)?[ ]?/g, ' $1$2$3 ');
  283. input = input.replace(/(IF)[ ]?([\(\)])/g, '$1 $2');
  284. input = input.replace(/([\(\)])[ ]?(THEN)/gi, '$1 $2');
  285. input = input.replace(/(^|[\(\)])[ ]?(AND|OR|XOR|XNOR)[ ]*([\(])/g, '$1 $2 $3');
  286. input = input.replace(/ ([\-\*\/=+<>])[ ]*([\-\*\/=+<>]) /g, " $1$2 ");
  287. //input = input.replace(/\r\n[ \t]+--\r\n/g, "\r\n");
  288. input = input.replace(/[ ]+/g, ' ');
  289. input = input.replace(/[ \t]+\r\n/g, "\r\n");
  290. input = input.replace(/\r\n\r\n\r\n/g, '\r\n');
  291. input = input.replace(/[\r\n\s]+$/g, '');
  292. input = input.replace(/[ \t]+\)/g, ')');
  293. input = input.replace(/\s*\)\s+RETURN\s+([\w]+;)/g, '\r\n) RETURN $1'); //function(..\r\n)return type; -> function(..\r\n)return type;
  294. arr = input.split("\r\n");
  295. let result = [];
  296. beautify3(arr, result, settings, 0, 0);
  297. if (settings.SignAlignAll) {
  298. AlignSigns(result, 0, result.length - 1);
  299. }
  300. arr = FormattedLineToString(result, settings.Indentation);
  301. input = arr.join("\r\n");
  302. input = SetKeywordCase(input, settings.KeywordCase, KeyWords, TypeNames);
  303. for (var k = 0; k < quotes.length; k++) {
  304. input = input.replace(ILQuotesPrefix + k, quotes[k]);
  305. }
  306. for (var k = 0; k < singleQuotes.length; k++) {
  307. input = input.replace(ILSingleQuotesPrefix + k, singleQuotes[k]);
  308. }
  309. for (var k = 0; k < commentsIndex; k++) {
  310. input = input.replace(ILCommentPrefix + k, comments[k]);
  311. }
  312. input = input.replace(/@@semicolon/g, ";");
  313. input = input.replace(/@@[a-z]+/g, "");
  314. return input;
  315. }
  316. exports.beautify = beautify;
  317. function RemoveLeadingWhitespaces(arr) {
  318. for (var i = 0; i < arr.length; i++) {
  319. arr[i] = arr[i].replace(/^\s+/, "");
  320. }
  321. }
  322. class FormattedLine {
  323. constructor(line, indent) {
  324. this.Line = line;
  325. this.Indent = indent;
  326. }
  327. }
  328. exports.FormattedLine = FormattedLine;
  329. function FormattedLineToString(arr, indentation) {
  330. let result = [];
  331. if (arr == null) {
  332. return result;
  333. }
  334. arr.forEach(i => {
  335. if (i instanceof FormattedLine) {
  336. if (i.Line.length > 0) {
  337. result.push((Array(i.Indent + 1).join(indentation)) + i.Line);
  338. }
  339. else {
  340. result.push("");
  341. }
  342. }
  343. else {
  344. result = result.concat(FormattedLineToString(i, indentation));
  345. }
  346. });
  347. return result;
  348. }
  349. exports.FormattedLineToString = FormattedLineToString;
  350. function GetCloseparentheseEndIndex(inputs, startIndex) {
  351. let openParentheseCount = 0;
  352. let closeParentheseCount = 0;
  353. for (let i = startIndex; i < inputs.length; i++) {
  354. let input = inputs[i];
  355. openParentheseCount += input.count("(");
  356. closeParentheseCount += input.count(")");
  357. if (openParentheseCount > 0
  358. && openParentheseCount <= closeParentheseCount) {
  359. return i;
  360. }
  361. }
  362. return startIndex;
  363. }
  364. function beautifyPortGenericBlock(inputs, result, settings, startIndex, parentEndIndex, indent, mode) {
  365. let firstLine = inputs[startIndex];
  366. let regex = new RegExp("[\\w\\s:]*(" + mode + ")([\\s]|$)");
  367. if (!firstLine.regexStartsWith(regex)) {
  368. return [startIndex, parentEndIndex];
  369. }
  370. let firstLineHasParenthese = firstLine.indexOf("(") >= 0;
  371. let hasParenthese = firstLineHasParenthese;
  372. let blockBodyStartIndex = startIndex;
  373. let secondLineHasParenthese = startIndex + 1 < inputs.length && inputs[startIndex + 1].startsWith("(");
  374. if (secondLineHasParenthese) {
  375. hasParenthese = true;
  376. blockBodyStartIndex++;
  377. }
  378. let endIndex = hasParenthese ? GetCloseparentheseEndIndex(inputs, startIndex) : startIndex;
  379. if (endIndex != startIndex && firstLineHasParenthese) {
  380. inputs[startIndex] = inputs[startIndex].replace(/(PORT|GENERIC|PROCEDURE)([\w ]+)\(([\w\(\) ]+)/, '$1$2(\r\n$3');
  381. let newInputs = inputs[startIndex].split("\r\n");
  382. if (newInputs.length == 2) {
  383. inputs[startIndex] = newInputs[0];
  384. inputs.splice(startIndex + 1, 0, newInputs[1]);
  385. endIndex++;
  386. parentEndIndex++;
  387. }
  388. }
  389. else if (endIndex > startIndex + 1 && secondLineHasParenthese) {
  390. inputs[startIndex + 1] = inputs[startIndex + 1].replace(/\(([\w\(\) ]+)/, '(\r\n$1');
  391. let newInputs = inputs[startIndex + 1].split("\r\n");
  392. if (newInputs.length == 2) {
  393. inputs[startIndex + 1] = newInputs[0];
  394. inputs.splice(startIndex + 2, 0, newInputs[1]);
  395. endIndex++;
  396. parentEndIndex++;
  397. }
  398. }
  399. if (firstLineHasParenthese && inputs[startIndex].indexOf("MAP") > 0) {
  400. inputs[startIndex] = inputs[startIndex].replace(/([^\w])(MAP)\s+\(/g, '$1$2(');
  401. }
  402. result.push(new FormattedLine(inputs[startIndex], indent));
  403. if (secondLineHasParenthese) {
  404. let secondLineIndent = indent;
  405. if (endIndex == startIndex + 1) {
  406. secondLineIndent++;
  407. }
  408. result.push(new FormattedLine(inputs[startIndex + 1], secondLineIndent));
  409. }
  410. let blockBodyEndIndex = endIndex;
  411. let i = beautify3(inputs, result, settings, blockBodyStartIndex + 1, indent + 1, endIndex);
  412. if (inputs[i].startsWith(")")) {
  413. result[i].Indent--;
  414. blockBodyEndIndex--;
  415. }
  416. if (settings.SignAlignRegional && !settings.SignAlignAll
  417. && settings.SignAlignKeyWords != null
  418. && settings.SignAlignKeyWords.indexOf(mode) >= 0) {
  419. blockBodyStartIndex++;
  420. AlignSigns(result, blockBodyStartIndex, blockBodyEndIndex);
  421. }
  422. return [i, parentEndIndex];
  423. }
  424. exports.beautifyPortGenericBlock = beautifyPortGenericBlock;
  425. function AlignSigns(result, startIndex, endIndex) {
  426. AlignSign_(result, startIndex, endIndex, ":");
  427. AlignSign_(result, startIndex, endIndex, ":=");
  428. AlignSign_(result, startIndex, endIndex, "=>");
  429. AlignSign_(result, startIndex, endIndex, "<=");
  430. }
  431. exports.AlignSigns = AlignSigns;
  432. function AlignSign_(result, startIndex, endIndex, symbol) {
  433. let maxSymbolIndex = -1;
  434. let symbolIndices = {};
  435. let startLine = startIndex;
  436. let labelAndKeywords = [
  437. "([\\w\\s]*:(\\s)*PROCESS)",
  438. "([\\w\\s]*:(\\s)*POSTPONED PROCESS)",
  439. "([\\w\\s]*:\\s*$)",
  440. "([\\w\\s]*:.*\\s+GENERATE)"
  441. ];
  442. let labelAndKeywordsStr = labelAndKeywords.join("|");
  443. let labelAndKeywordsRegex = new RegExp("(" + labelAndKeywordsStr + ")([^\\w]|$)");
  444. for (let i = startIndex; i <= endIndex; i++) {
  445. let line = result[i].Line;
  446. if (symbol == ":" && line.regexStartsWith(labelAndKeywordsRegex)) {
  447. continue;
  448. }
  449. let regex = new RegExp("([\\s\\w\\\\]|^)" + symbol + "([\\s\\w\\\\]|$)");
  450. if (line.regexCount(regex) > 1) {
  451. continue;
  452. }
  453. let colonIndex = line.regexIndexOf(regex);
  454. if (colonIndex > 0) {
  455. maxSymbolIndex = Math.max(maxSymbolIndex, colonIndex);
  456. symbolIndices[i] = colonIndex;
  457. }
  458. else if (!line.startsWith(ILCommentPrefix) && line.length != 0) {
  459. if (startLine < i - 1) // if cannot find the symbol, a block of symbols ends
  460. {
  461. AlignSign(result, startLine, i - 1, symbol, maxSymbolIndex, symbolIndices);
  462. }
  463. maxSymbolIndex = -1;
  464. symbolIndices = {};
  465. startLine = i;
  466. }
  467. }
  468. if (startLine < endIndex) // if cannot find the symbol, a block of symbols ends
  469. {
  470. AlignSign(result, startLine, endIndex, symbol, maxSymbolIndex, symbolIndices);
  471. }
  472. }
  473. function AlignSign(result, startIndex, endIndex, symbol, maxSymbolIndex = -1, symbolIndices = {}) {
  474. if (maxSymbolIndex < 0) {
  475. return;
  476. }
  477. for (let lineIndex in symbolIndices) {
  478. let symbolIndex = symbolIndices[lineIndex];
  479. if (symbolIndex == maxSymbolIndex) {
  480. continue;
  481. }
  482. let line = result[lineIndex].Line;
  483. result[lineIndex].Line = line.substring(0, symbolIndex)
  484. + (Array(maxSymbolIndex - symbolIndex + 1).join(" "))
  485. + line.substring(symbolIndex);
  486. }
  487. }
  488. exports.AlignSign = AlignSign;
  489. function beautifyCaseBlock(inputs, result, settings, startIndex, indent) {
  490. if (!inputs[startIndex].regexStartsWith(/(.+:\s*)?(CASE)([\s]|$)/)) {
  491. return startIndex;
  492. }
  493. result.push(new FormattedLine(inputs[startIndex], indent));
  494. let i = beautify3(inputs, result, settings, startIndex + 1, indent + 2);
  495. result[i].Indent = indent;
  496. return i;
  497. }
  498. exports.beautifyCaseBlock = beautifyCaseBlock;
  499. function getSemicolonBlockEndIndex(inputs, settings, startIndex, parentEndIndex) {
  500. let endIndex = 0;
  501. let openBracketsCount = 0;
  502. let closeBracketsCount = 0;
  503. for (let i = startIndex; i < inputs.length; i++) {
  504. let input = inputs[i];
  505. let indexOfSemicolon = input.indexOf(";");
  506. let splitIndex = indexOfSemicolon < 0 ? input.length : indexOfSemicolon + 1;
  507. let stringBeforeSemicolon = input.substring(0, splitIndex);
  508. let stringAfterSemicolon = input.substring(splitIndex);
  509. stringAfterSemicolon = stringAfterSemicolon.replace(new RegExp(ILCommentPrefix + "[0-9]+"), "");
  510. openBracketsCount += stringBeforeSemicolon.count("(");
  511. closeBracketsCount += stringBeforeSemicolon.count(")");
  512. if (indexOfSemicolon < 0) {
  513. continue;
  514. }
  515. if (openBracketsCount == closeBracketsCount) {
  516. endIndex = i;
  517. if (stringAfterSemicolon.trim().length > 0 && settings.NewLineSettings.newLineAfter.indexOf(";") >= 0) {
  518. inputs[i] = stringBeforeSemicolon;
  519. inputs.splice(i, 0, stringAfterSemicolon);
  520. parentEndIndex++;
  521. }
  522. break;
  523. }
  524. }
  525. return [endIndex, parentEndIndex];
  526. }
  527. function beautifyComponentBlock(inputs, result, settings, startIndex, parentEndIndex, indent) {
  528. let endIndex = startIndex;
  529. for (let i = startIndex; i < inputs.length; i++) {
  530. if (inputs[i].regexStartsWith(/END(\s|$)/)) {
  531. endIndex = i;
  532. break;
  533. }
  534. }
  535. result.push(new FormattedLine(inputs[startIndex], indent));
  536. if (endIndex != startIndex) {
  537. let actualEndIndex = beautify3(inputs, result, settings, startIndex + 1, indent + 1, endIndex);
  538. let incremental = actualEndIndex - endIndex;
  539. endIndex += incremental;
  540. parentEndIndex += incremental;
  541. }
  542. return [endIndex, parentEndIndex];
  543. }
  544. exports.beautifyComponentBlock = beautifyComponentBlock;
  545. function beautifySemicolonBlock(inputs, result, settings, startIndex, parentEndIndex, indent) {
  546. let endIndex = startIndex;
  547. [endIndex, parentEndIndex] = getSemicolonBlockEndIndex(inputs, settings, startIndex, parentEndIndex);
  548. result.push(new FormattedLine(inputs[startIndex], indent));
  549. if (endIndex != startIndex) {
  550. let i = beautify3(inputs, result, settings, startIndex + 1, indent + 1, endIndex);
  551. }
  552. return [endIndex, parentEndIndex];
  553. }
  554. exports.beautifySemicolonBlock = beautifySemicolonBlock;
  555. function beautify3(inputs, result, settings, startIndex, indent, endIndex) {
  556. let i;
  557. let regexOneLineBlockKeyWords = new RegExp(/(PROCEDURE)[^\w](?!.+[^\w]IS([^\w]|$))/); //match PROCEDURE..; but not PROCEDURE .. IS;
  558. let regexFunctionMultiLineBlockKeyWords = new RegExp(/(FUNCTION|IMPURE FUNCTION)[^\w](?=.+[^\w]IS([^\w]|$))/); //match FUNCTION .. IS; but not FUNCTION
  559. let blockMidKeyWords = ["BEGIN"];
  560. let blockStartsKeyWords = [
  561. "IF",
  562. "CASE",
  563. "ARCHITECTURE",
  564. "PROCEDURE",
  565. "PACKAGE",
  566. "(([\\w\\s]*:)?(\\s)*PROCESS)",
  567. "(([\\w\\s]*:)?(\\s)*POSTPONED PROCESS)",
  568. "(.*\\s*PROTECTED)",
  569. "(COMPONENT)",
  570. "(ENTITY(?!.+;))",
  571. "FOR",
  572. "WHILE",
  573. "LOOP",
  574. "(.*\\s*GENERATE)",
  575. "(CONTEXT[\\w\\s\\\\]+IS)",
  576. "(CONFIGURATION(?!.+;))",
  577. "BLOCK",
  578. "UNITS",
  579. "\\w+\\s+\\w+\\s+IS\\s+RECORD"
  580. ];
  581. let blockEndsKeyWords = ["END", ".*\\)\\s*RETURN\\s+[\\w]+;"];
  582. let blockEndsWithSemicolon = [
  583. "(WITH\\s+[\\w\\s\\\\]+SELECT)",
  584. "([\\w\\\\]+[\\s]*<=)",
  585. "([\\w\\\\]+[\\s]*:=)",
  586. "FOR\\s+[\\w\\s,]+:\\s*\\w+\\s+USE",
  587. "REPORT"
  588. ];
  589. let newLineAfterKeyWordsStr = blockStartsKeyWords.join("|");
  590. let regexBlockMidKeyWords = blockMidKeyWords.convertToRegexBlockWords();
  591. let regexBlockStartsKeywords = new RegExp("([\\w]+\\s*:\\s*)?(" + newLineAfterKeyWordsStr + ")([^\\w]|$)");
  592. let regexBlockEndsKeyWords = blockEndsKeyWords.convertToRegexBlockWords();
  593. let regexblockEndsWithSemicolon = blockEndsWithSemicolon.convertToRegexBlockWords();
  594. let regexMidKeyWhen = "WHEN".convertToRegexBlockWords();
  595. let regexMidKeyElse = "ELSE|ELSIF".convertToRegexBlockWords();
  596. if (endIndex == null) {
  597. endIndex = inputs.length - 1;
  598. }
  599. for (i = startIndex; i <= endIndex; i++) {
  600. if (indent < 0) {
  601. indent = 0;
  602. }
  603. let input = inputs[i].trim();
  604. if (input.regexStartsWith(/COMPONENT\s/)) {
  605. let modeCache = Mode;
  606. Mode = FormatMode.EndsWithSemicolon;
  607. [i, endIndex] = beautifyComponentBlock(inputs, result, settings, i, endIndex, indent);
  608. Mode = modeCache;
  609. continue;
  610. }
  611. if (input.regexStartsWith(/\w+\s*:\s*ENTITY/)) {
  612. let modeCache = Mode;
  613. Mode = FormatMode.EndsWithSemicolon;
  614. [i, endIndex] = beautifySemicolonBlock(inputs, result, settings, i, endIndex, indent);
  615. Mode = modeCache;
  616. continue;
  617. }
  618. if (Mode != FormatMode.EndsWithSemicolon && input.regexStartsWith(regexblockEndsWithSemicolon)) {
  619. let modeCache = Mode;
  620. Mode = FormatMode.EndsWithSemicolon;
  621. [i, endIndex] = beautifySemicolonBlock(inputs, result, settings, i, endIndex, indent);
  622. Mode = modeCache;
  623. continue;
  624. }
  625. if (input.regexStartsWith(/(.+:\s*)?(CASE)([\s]|$)/)) {
  626. let modeCache = Mode;
  627. Mode = FormatMode.CaseWhen;
  628. i = beautifyCaseBlock(inputs, result, settings, i, indent);
  629. Mode = modeCache;
  630. continue;
  631. }
  632. if (input.regexStartsWith(/[\w\s:]*PORT([\s]|$)/)) {
  633. [i, endIndex] = beautifyPortGenericBlock(inputs, result, settings, i, endIndex, indent, "PORT");
  634. continue;
  635. }
  636. if (input.regexStartsWith(/TYPE\s+\w+\s+IS\s+\(/)) {
  637. [i, endIndex] = beautifyPortGenericBlock(inputs, result, settings, i, endIndex, indent, "IS");
  638. continue;
  639. }
  640. if (input.regexStartsWith(/[\w\s:]*GENERIC([\s]|$)/)) {
  641. [i, endIndex] = beautifyPortGenericBlock(inputs, result, settings, i, endIndex, indent, "GENERIC");
  642. continue;
  643. }
  644. if (input.regexStartsWith(/[\w\s:]*PROCEDURE[\s\w]+\($/)) {
  645. [i, endIndex] = beautifyPortGenericBlock(inputs, result, settings, i, endIndex, indent, "PROCEDURE");
  646. if (inputs[i].regexStartsWith(/.*\)[\s]*IS/)) {
  647. i = beautify3(inputs, result, settings, i + 1, indent + 1);
  648. }
  649. continue;
  650. }
  651. if (input.regexStartsWith(/FUNCTION[^\w]/)
  652. && input.regexIndexOf(/[^\w]RETURN[^\w]/) < 0) {
  653. [i, endIndex] = beautifyPortGenericBlock(inputs, result, settings, i, endIndex, indent, "FUNCTION");
  654. if (!inputs[i].regexStartsWith(regexBlockEndsKeyWords)) {
  655. i = beautify3(inputs, result, settings, i + 1, indent + 1);
  656. }
  657. else {
  658. result[i].Indent++;
  659. }
  660. continue;
  661. }
  662. if (input.regexStartsWith(/IMPURE FUNCTION[^\w]/)
  663. && input.regexIndexOf(/[^\w]RETURN[^\w]/) < 0) {
  664. [i, endIndex] = beautifyPortGenericBlock(inputs, result, settings, i, endIndex, indent, "IMPURE FUNCTION");
  665. if (!inputs[i].regexStartsWith(regexBlockEndsKeyWords)) {
  666. i = beautify3(inputs, result, settings, i + 1, indent + 1);
  667. }
  668. else {
  669. result[i].Indent++;
  670. }
  671. continue;
  672. }
  673. result.push(new FormattedLine(input, indent));
  674. if (startIndex != 0
  675. && (input.regexStartsWith(regexBlockMidKeyWords)
  676. || (Mode != FormatMode.EndsWithSemicolon && input.regexStartsWith(regexMidKeyElse))
  677. || (Mode == FormatMode.CaseWhen && input.regexStartsWith(regexMidKeyWhen)))) {
  678. result[i].Indent--;
  679. }
  680. else if (startIndex != 0
  681. && (input.regexStartsWith(regexBlockEndsKeyWords))) {
  682. result[i].Indent--;
  683. return i;
  684. }
  685. if (input.regexStartsWith(regexOneLineBlockKeyWords)) {
  686. continue;
  687. }
  688. if (input.regexStartsWith(regexFunctionMultiLineBlockKeyWords)
  689. || input.regexStartsWith(regexBlockStartsKeywords)) {
  690. i = beautify3(inputs, result, settings, i + 1, indent + 1);
  691. }
  692. }
  693. i--;
  694. return i;
  695. }
  696. exports.beautify3 = beautify3;
  697. function ReserveSemicolonInKeywords(arr) {
  698. for (let i = 0; i < arr.length; i++) {
  699. if (arr[i].match(/FUNCTION|PROCEDURE/) != null) {
  700. arr[i] = arr[i].replace(/;/g, '@@semicolon');
  701. }
  702. }
  703. }
  704. function ApplyNoNewLineAfter(arr, noNewLineAfter) {
  705. if (noNewLineAfter == null) {
  706. return;
  707. }
  708. for (let i = 0; i < arr.length; i++) {
  709. noNewLineAfter.forEach(n => {
  710. let regex = new RegExp("(" + n.toUpperCase + ")[ a-z0-9]+[a-z0-9]+");
  711. if (arr[i].regexIndexOf(regex) >= 0) {
  712. arr[i] += "@@singleline";
  713. }
  714. });
  715. }
  716. }
  717. exports.ApplyNoNewLineAfter = ApplyNoNewLineAfter;
  718. function RemoveAsserts(arr) {
  719. let need_semi = false;
  720. let inAssert = false;
  721. let n = 0;
  722. for (let i = 0; i < arr.length; i++) {
  723. let has_semi = arr[i].indexOf(";") >= 0;
  724. if (need_semi) {
  725. arr[i] = '';
  726. }
  727. n = arr[i].indexOf("ASSERT ");
  728. if (n >= 0) {
  729. inAssert = true;
  730. arr[i] = '';
  731. }
  732. if (!has_semi) {
  733. if (inAssert) {
  734. need_semi = true;
  735. }
  736. }
  737. else {
  738. need_semi = false;
  739. }
  740. }
  741. }
  742. exports.RemoveAsserts = RemoveAsserts;
  743. function EscapeQuotes(arr) {
  744. let quotes = [];
  745. let quotesIndex = 0;
  746. for (let i = 0; i < arr.length; i++) {
  747. let quote = arr[i].match(/"([^"]+)"/g);
  748. if (quote != null) {
  749. for (var j = 0; j < quote.length; j++) {
  750. arr[i] = arr[i].replace(quote[j], ILQuotesPrefix + quotesIndex);
  751. quotes[quotesIndex++] = quote[j];
  752. }
  753. }
  754. }
  755. return quotes;
  756. }
  757. function EscapeSingleQuotes(arr) {
  758. let quotes = [];
  759. let quotesIndex = 0;
  760. for (let i = 0; i < arr.length; i++) {
  761. let quote = arr[i].match(/'[^']'/g);
  762. if (quote != null) {
  763. for (var j = 0; j < quote.length; j++) {
  764. arr[i] = arr[i].replace(quote[j], ILSingleQuotesPrefix + quotesIndex);
  765. quotes[quotesIndex++] = quote[j];
  766. }
  767. }
  768. }
  769. return quotes;
  770. }
  771. function RemoveExtraNewLines(input) {
  772. input = input.replace(/(?:\r\n|\r|\n)/g, '\r\n');
  773. input = input.replace(/ \r\n/g, '\r\n');
  774. input = input.replace(/\r\n\r\n\r\n/g, '\r\n');
  775. return input;
  776. }
  777. //# sourceMappingURL=VHDLFormatter.js.map