Browse Source

support more

master
g2384 6 years ago
parent
commit
4035e7c471
5 changed files with 282 additions and 48 deletions
  1. +63
    -18
      VHDLFormatter.html
  2. +40
    -5
      VHDLFormatter.js
  3. +40
    -7
      VHDLFormatter.ts
  4. +66
    -8
      VHDLFormatterUnitTests.js
  5. +73
    -10
      VHDLFormatterUnitTests.ts

+ 63
- 18
VHDLFormatter.html View File

@ -66,6 +66,12 @@
margin-bottom: 0px; margin-bottom: 0px;
} }
form span {
width: 170px;
display: inline-block;
text-align: right;
}
a { a {
color: #4b9aff; color: #4b9aff;
text-decoration: none; text-decoration: none;
@ -75,7 +81,7 @@
text-decoration: underline; text-decoration: underline;
} }
</style> </style>
<link href="highlight.css" />
<link href="highlight.css" rel="stylesheet" />
<script src="highlight.js"></script> <script src="highlight.js"></script>
<script> <script>
function selectText(element) { function selectText(element) {
@ -122,16 +128,52 @@
<label> <label>
<input type="checkbox" id="no_format" onclick="noFormat()">Only highlight, don't format</label> <input type="checkbox" id="no_format" onclick="noFormat()">Only highlight, don't format</label>
<br> New line after <br> New line after
<label>
<input type="checkbox" checked="checked" id="new_line_after_then">THEN</label>,
<label>
<input type="checkbox" checked="checked" id="new_line_after_semicolon">semicolon ";"</label>,
<label>
<input type="checkbox" id="new_line_after_else">ELSE</label>,
<label>
<input type="checkbox" id="new_line_after_port">PORT or PORT MAP</label>,
<label>
<input type="checkbox" id="new_line_after_generic">GENERIC</label>
<br>
<form id="new_line_after_then">
<span>THEN</span>
<label>
<input type="radio" name="new_line_after_thencase" value="NewLine" checked="checked">New Line</label>
<label>
<input type="radio" name="new_line_after_thencase" value="NoNewLine">No New Line</label>
<label>
<input type="radio" name="new_line_after_thencase" value="None">None</label>
</form>
<form id="new_line_after_semicolon">
<span>semicolon ";"</span>
<label>
<input type="radio" name="new_line_after_semicoloncase" value="NewLine" checked="checked">New Line</label>
<label>
<input type="radio" name="new_line_after_semicoloncase" value="NoNewLine">No New Line</label>
<label>
<input type="radio" name="new_line_after_semicoloncase" value="None">None</label>
</form>
<form id="new_line_after_else">
<span>ELSE</span>
<label>
<input type="radio" name="new_line_after_elsecase" value="NewLine" checked="checked">New Line</label>
<label>
<input type="radio" name="new_line_after_elsecase" value="NoNewLine">No New Line</label>
<label>
<input type="radio" name="new_line_after_elsecase" value="None">None</label>
</form>
<form id="new_line_after_port">
<span>PORT or PORT MAP</span>
<label>
<input type="radio" name="new_line_after_portcase" value="NewLine">New Line</label>
<label>
<input type="radio" name="new_line_after_portcase" value="NoNewLine">No New Line</label>
<label>
<input type="radio" name="new_line_after_portcase" value="None" checked="checked">None</label>
</form>
<form id="new_line_after_generic">
<span>GENERIC</span>
<label>
<input type="radio" name="new_line_after_genericcase" value="NewLine">New Line</label>
<label>
<input type="radio" name="new_line_after_genericcase" value="NoNewLine">No New Line</label>
<label>
<input type="radio" name="new_line_after_genericcase" value="None" checked="checked">None</label>
</form>
<br> <br>
<label> <label>
<input type="checkbox" id="remove_comments">Remove commments</label> <input type="checkbox" id="remove_comments">Remove commments</label>
@ -220,9 +262,10 @@
<span class="hljs-keyword">END</span> <span class="hljs-keyword">PROCESS</span>; <span class="hljs-keyword">END</span> <span class="hljs-keyword">PROCESS</span>;
<span class="hljs-keyword">END</span> EXA;</code></pre> <span class="hljs-keyword">END</span> EXA;</code></pre>
<script> var exports = {}; </script>
<script>
var exports = {};
</script>
<script src="VHDLFormatter.js"></script> <script src="VHDLFormatter.js"></script>
<script src="VHDLFormatterUnitTests.js"></script>
<script> <script>
let lastModifiedDate = fetchHeader(location.href, 'Last-Modified'); let lastModifiedDate = fetchHeader(location.href, 'Last-Modified');
if (lastModifiedDate != "") { if (lastModifiedDate != "") {
@ -244,10 +287,11 @@
var check_alias = document.getElementById("check_alias").checked; var check_alias = document.getElementById("check_alias").checked;
var sign_align = document.getElementById("sign_align").checked; var sign_align = document.getElementById("sign_align").checked;
var sign_align_all = document.getElementById("sign_align_all").checked; var sign_align_all = document.getElementById("sign_align_all").checked;
var new_line_after_port = document.getElementById("new_line_after_port").checked;
var new_line_after_then = document.getElementById("new_line_after_then").checked;
var new_line_after_semicolon = document.getElementById("new_line_after_semicolon").checked;
var new_line_after_generic = document.getElementById("new_line_after_generic").checked;
var new_line_after_port = document.getElementById("new_line_after_port").elements.namedItem("new_line_after_portcase").value;
var new_line_after_then = document.getElementById("new_line_after_then").elements.namedItem("new_line_after_thencase").value;
var new_line_after_semicolon = document.getElementById("new_line_after_semicolon").elements.namedItem("new_line_after_semicoloncase").value;
var new_line_after_else = document.getElementById("new_line_after_else").elements.namedItem("new_line_after_elsecase").value;
var new_line_after_generic = document.getElementById("new_line_after_generic").elements.namedItem("new_line_after_genericcase").value;
var use_space = document.getElementById("use_space").checked; var use_space = document.getElementById("use_space").checked;
var compress = document.getElementById("compress").checked; var compress = document.getElementById("compress").checked;
var cust_indent = document.getElementById("cust_indent").value; var cust_indent = document.getElementById("cust_indent").value;
@ -271,7 +315,8 @@
newLineSettingsDict["else"] = new_line_after_else; newLineSettingsDict["else"] = new_line_after_else;
newLineSettings = ConstructNewLineSettings(newLineSettingsDict); newLineSettings = ConstructNewLineSettings(newLineSettingsDict);
beautifierSettings = BeautifierSettings(remove_comments, remove_report, check_alias, sign_align, sign_align_all,
beautifierSettings = new BeautifierSettings(remove_comments, remove_report, check_alias, sign_align,
sign_align_all,
keywordcase, indentation, newLineSettings); keywordcase, indentation, newLineSettings);
input = beautify(input, beautifierSettings); input = beautify(input, beautifierSettings);


+ 40
- 5
VHDLFormatter.js View File

@ -15,7 +15,11 @@ class NewLineSettings {
this.noNewLineAfter.push(keyword); this.noNewLineAfter.push(keyword);
} }
push(keyword, addNewLine) { push(keyword, addNewLine) {
if (addNewLine) {
let str = addNewLine.toLowerCase();
if (str.indexOf("none") >= 0) {
return;
}
else if (str.indexOf("no") < 0) {
this.newLineAfterPush(keyword); this.newLineAfterPush(keyword);
} }
else { else {
@ -245,14 +249,17 @@ exports.BeautifierSettings = BeautifierSettings;
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"]; 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"];
let TypeNames = ["BOOLEAN", "BIT", "CHARACTER", "INTEGER", "TIME", "NATURAL", "POSITIVE", "STRING"]; let TypeNames = ["BOOLEAN", "BIT", "CHARACTER", "INTEGER", "TIME", "NATURAL", "POSITIVE", "STRING"];
function beautify(input, settings) { function beautify(input, settings) {
input = input.replace("\r\n", "\n");
input = input.replace("\n", "\r\n");
var arr = input.split("\r\n"); var arr = input.split("\r\n");
var comments = [], commentsIndex = 0; var comments = [], commentsIndex = 0;
commentsIndex = EscapeComments(arr, comments, commentsIndex); commentsIndex = EscapeComments(arr, comments, commentsIndex);
input = arr.join("\r\n");
if (settings.RemoveComments) { if (settings.RemoveComments) {
input = input.replace(/\r\n[ \t]*@@comments[0-9]+[ \t]*\r\n/g, '\r\n');
input = input.replace(/@@comments[0-9]+/g, ''); input = input.replace(/@@comments[0-9]+/g, '');
commentsIndex = 0; commentsIndex = 0;
} }
input = arr.join("\r\n");
input = RemoveExtraNewLines(input); input = RemoveExtraNewLines(input);
input = input.replace(/[\t ]+/g, ' '); input = input.replace(/[\t ]+/g, ' ');
input = input.replace(/\([\t ]+/g, '\('); input = input.replace(/\([\t ]+/g, '\(');
@ -267,6 +274,20 @@ function beautify(input, settings) {
input = SetNewLinesAfterSymbols(input, settings.NewLineSettings); input = SetNewLinesAfterSymbols(input, settings.NewLineSettings);
//input = beautify2(input, settings); //input = beautify2(input, settings);
//new //new
input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end');
input = input.replace(/[ ]?([&=:\-<>\+|\*])[ ]?/g, ' $1 ');
input = input.replace(/[ ]?([,])[ ]?/g, '$1 ');
input = input.replace(/[ ]?(['"])(THEN)/g, '$1 $2');
input = input.replace(/[ ]?(\?)?[ ]?(<|:|>|\/)?[ ]+(=)?[ ]?/g, ' $1$2$3 ');
input = input.replace(/(IF)[ ]?([\(\)])/g, '$1 $2');
input = input.replace(/([\(\)])[ ]?(THEN)/gi, '$1 $2');
input = input.replace(/(^|[\(\)])[ ]?(AND|OR|XOR|XNOR)[ ]*([\(])/g, '$1 $2 $3');
input = input.replace(/ ([\-\*\/=+<>])[ ]*([\-\*\/=+<>]) /g, " $1$2 ");
input = input.replace(/\r\n[ \t]+--\r\n/g, "\r\n");
input = input.replace(/[ ]+/g, ' ');
input = input.replace(/\r\n\r\n\r\n/g, '\r\n');
input = input.replace(/[\r\n\s]+$/g, '');
input = input.replace(/[ \t]+\)/g, ')');
arr = input.split("\r\n"); arr = input.split("\r\n");
let result = []; let result = [];
beautify3(arr, result, settings, 0, 0); beautify3(arr, result, settings, 0, 0);
@ -294,7 +315,7 @@ function FormattedLineToString(arr, indentation) {
} }
arr.forEach(i => { arr.forEach(i => {
if (i instanceof FormattedLine) { if (i instanceof FormattedLine) {
result.push((Array(i.Indent).join(indentation)) + i.Line);
result.push((Array(i.Indent + 1).join(indentation)) + i.Line);
} }
else { else {
result = result.concat(FormattedLineToString(i, indentation)); result = result.concat(FormattedLineToString(i, indentation));
@ -302,6 +323,7 @@ function FormattedLineToString(arr, indentation) {
}); });
return result; return result;
} }
exports.FormattedLineToString = FormattedLineToString;
function beautifyCaseBlock(inputs, result, settings, startIndex, indent, isFirstKeyWord) { function beautifyCaseBlock(inputs, result, settings, startIndex, indent, isFirstKeyWord) {
if (!inputs[startIndex].regexStartsWith(/(CASE)([\s]|$)/)) { if (!inputs[startIndex].regexStartsWith(/(CASE)([\s]|$)/)) {
return startIndex; return startIndex;
@ -316,7 +338,20 @@ function beautify3(inputs, result, settings, startIndex, indent, isFirstKeyWord)
let i; let i;
let regexOneLineBlockKeyWords = new RegExp(/(PROCEDURE|FUNCTION|IMPURE FUNCTION)[^\w_](?!.+[^\w_]IS([^\w_]|$))/); //match PROCEDURE..; but not PROCEDURE .. IS; let regexOneLineBlockKeyWords = new RegExp(/(PROCEDURE|FUNCTION|IMPURE FUNCTION)[^\w_](?!.+[^\w_]IS([^\w_]|$))/); //match PROCEDURE..; but not PROCEDURE .. IS;
let blockMidKeyWords = ["ELSE", "ELSIF", "WHEN", "BEGIN"]; let blockMidKeyWords = ["ELSE", "ELSIF", "WHEN", "BEGIN"];
let blockStartsKeyWords = ["IF", "CASE", "ARCHITECTURE", "PROCEDURE", "PACKAGE", "PROCESS", "POSTPONED PROCESS", "(\\w+:\\s+PROCESS)", "FUNCTION", "IMPURE FUNCTION", "TYPE\\s.+\\sPROTECTED"];
let blockStartsKeyWords = [
"IF",
"CASE",
"ARCHITECTURE",
"PROCEDURE",
"PACKAGE",
"PROCESS",
"POSTPONED PROCESS",
"(\\w+:\\s+PROCESS)",
"FUNCTION",
"IMPURE FUNCTION",
"(.+\\sPROTECTED)",
"COMPONENT"
];
let blockEndsKeyWords = ["END"]; let blockEndsKeyWords = ["END"];
let newLineAfterKeyWordsStr = blockStartsKeyWords.join("|"); let newLineAfterKeyWordsStr = blockStartsKeyWords.join("|");
let blockEndKeyWordsStr = blockEndsKeyWords.join("|"); let blockEndKeyWordsStr = blockEndsKeyWords.join("|");
@ -325,7 +360,7 @@ function beautify3(inputs, result, settings, startIndex, indent, isFirstKeyWord)
let regexBlockStartsKeywords = new RegExp("(" + newLineAfterKeyWordsStr + ")([^\\w_]|$)"); let regexBlockStartsKeywords = new RegExp("(" + newLineAfterKeyWordsStr + ")([^\\w_]|$)");
let regexBlockEndsKeyWords = new RegExp("(" + blockEndKeyWordsStr + ")([^\\w_]|$)"); let regexBlockEndsKeyWords = new RegExp("(" + blockEndKeyWordsStr + ")([^\\w_]|$)");
for (i = startIndex; i < inputs.length; i++) { for (i = startIndex; i < inputs.length; i++) {
let input = inputs[i];
let input = inputs[i].trim();
if (input.regexStartsWith(/(CASE)([\s]|$)/)) { if (input.regexStartsWith(/(CASE)([\s]|$)/)) {
i = beautifyCaseBlock(inputs, result, settings, i, indent); i = beautifyCaseBlock(inputs, result, settings, i, indent);
continue; continue;


+ 40
- 7
VHDLFormatter.ts View File

@ -18,8 +18,12 @@ export class NewLineSettings {
this.noNewLineAfter.push(keyword); this.noNewLineAfter.push(keyword);
} }
push(keyword: string, addNewLine: boolean) {
if (addNewLine) {
push(keyword: string, addNewLine: string) {
let str = addNewLine.toLowerCase();
if (str.indexOf("none") >= 0) {
return;
}
else if (str.indexOf("no") < 0) {
this.newLineAfterPush(keyword); this.newLineAfterPush(keyword);
} }
else { else {
@ -277,17 +281,20 @@ let KeyWords: Array<string> = ["ABS", "ACCESS", "AFTER", "ALIAS", "ALL", "AND",
let TypeNames: Array<string> = ["BOOLEAN", "BIT", "CHARACTER", "INTEGER", "TIME", "NATURAL", "POSITIVE", "STRING"]; let TypeNames: Array<string> = ["BOOLEAN", "BIT", "CHARACTER", "INTEGER", "TIME", "NATURAL", "POSITIVE", "STRING"];
export function beautify(input: string, settings: BeautifierSettings) { export function beautify(input: string, settings: BeautifierSettings) {
input = input.replace("\r\n", "\n");
input = input.replace("\n", "\r\n");
var arr = input.split("\r\n"); var arr = input.split("\r\n");
var comments = [], var comments = [],
commentsIndex = 0; commentsIndex = 0;
commentsIndex = EscapeComments(arr, comments, commentsIndex); commentsIndex = EscapeComments(arr, comments, commentsIndex);
input = arr.join("\r\n");
if (settings.RemoveComments) { if (settings.RemoveComments) {
input = input.replace(/\r\n[ \t]*@@comments[0-9]+[ \t]*\r\n/g, '\r\n');
input = input.replace(/@@comments[0-9]+/g, ''); input = input.replace(/@@comments[0-9]+/g, '');
commentsIndex = 0; commentsIndex = 0;
} }
input = arr.join("\r\n");
input = RemoveExtraNewLines(input); input = RemoveExtraNewLines(input);
input = input.replace(/[\t ]+/g, ' '); input = input.replace(/[\t ]+/g, ' ');
input = input.replace(/\([\t ]+/g, '\('); input = input.replace(/\([\t ]+/g, '\(');
@ -305,6 +312,20 @@ export function beautify(input: string, settings: BeautifierSettings) {
//input = beautify2(input, settings); //input = beautify2(input, settings);
//new //new
input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end');
input = input.replace(/[ ]?([&=:\-<>\+|\*])[ ]?/g, ' $1 ');
input = input.replace(/[ ]?([,])[ ]?/g, '$1 ');
input = input.replace(/[ ]?(['"])(THEN)/g, '$1 $2');
input = input.replace(/[ ]?(\?)?[ ]?(<|:|>|\/)?[ ]+(=)?[ ]?/g, ' $1$2$3 ');
input = input.replace(/(IF)[ ]?([\(\)])/g, '$1 $2');
input = input.replace(/([\(\)])[ ]?(THEN)/gi, '$1 $2');
input = input.replace(/(^|[\(\)])[ ]?(AND|OR|XOR|XNOR)[ ]*([\(])/g, '$1 $2 $3');
input = input.replace(/ ([\-\*\/=+<>])[ ]*([\-\*\/=+<>]) /g, " $1$2 ");
input = input.replace(/\r\n[ \t]+--\r\n/g, "\r\n");
input = input.replace(/[ ]+/g, ' ');
input = input.replace(/\r\n\r\n\r\n/g, '\r\n');
input = input.replace(/[\r\n\s]+$/g, '');
input = input.replace(/[ \t]+\)/g, ')');
arr = input.split("\r\n"); arr = input.split("\r\n");
let result: (FormattedLine | FormattedLine[])[] = []; let result: (FormattedLine | FormattedLine[])[] = [];
beautify3(arr, result, settings, 0, 0); beautify3(arr, result, settings, 0, 0);
@ -329,14 +350,14 @@ export class FormattedLine {
} }
} }
function FormattedLineToString(arr: (FormattedLine | FormattedLine[])[], indentation: string): Array<string> {
export function FormattedLineToString(arr: (FormattedLine | FormattedLine[])[], indentation: string): Array<string> {
let result: Array<string> = []; let result: Array<string> = [];
if (arr == null) { if (arr == null) {
return result; return result;
} }
arr.forEach(i => { arr.forEach(i => {
if (i instanceof FormattedLine) { if (i instanceof FormattedLine) {
result.push((Array(i.Indent).join(indentation)) + i.Line);
result.push((Array(i.Indent + 1).join(indentation)) + i.Line);
} }
else { else {
result = result.concat(FormattedLineToString(i, indentation)); result = result.concat(FormattedLineToString(i, indentation));
@ -360,7 +381,19 @@ export function beautify3(inputs: Array<string>, result: (FormattedLine | Format
let i: number; let i: number;
let regexOneLineBlockKeyWords: RegExp = new RegExp(/(PROCEDURE|FUNCTION|IMPURE FUNCTION)[^\w_](?!.+[^\w_]IS([^\w_]|$))/);//match PROCEDURE..; but not PROCEDURE .. IS; let regexOneLineBlockKeyWords: RegExp = new RegExp(/(PROCEDURE|FUNCTION|IMPURE FUNCTION)[^\w_](?!.+[^\w_]IS([^\w_]|$))/);//match PROCEDURE..; but not PROCEDURE .. IS;
let blockMidKeyWords: Array<string> = ["ELSE", "ELSIF", "WHEN", "BEGIN"]; let blockMidKeyWords: Array<string> = ["ELSE", "ELSIF", "WHEN", "BEGIN"];
let blockStartsKeyWords: Array<string> = ["IF", "CASE", "ARCHITECTURE", "PROCEDURE", "PACKAGE", "PROCESS", "POSTPONED PROCESS","(\\w+:\\s+PROCESS)","FUNCTION","IMPURE FUNCTION","TYPE\\s.+\\sPROTECTED"];
let blockStartsKeyWords: Array<string> = [
"IF",
"CASE",
"ARCHITECTURE",
"PROCEDURE",
"PACKAGE",
"PROCESS",
"POSTPONED PROCESS",
"(\\w+:\\s+PROCESS)",
"FUNCTION",
"IMPURE FUNCTION",
"(.+\\sPROTECTED)",
"COMPONENT"];
let blockEndsKeyWords: Array<string> = ["END"]; let blockEndsKeyWords: Array<string> = ["END"];
let newLineAfterKeyWordsStr: string = blockStartsKeyWords.join("|"); let newLineAfterKeyWordsStr: string = blockStartsKeyWords.join("|");
@ -370,7 +403,7 @@ export function beautify3(inputs: Array<string>, result: (FormattedLine | Format
let regexBlockStartsKeywords: RegExp = new RegExp("(" + newLineAfterKeyWordsStr + ")([^\\w_]|$)") let regexBlockStartsKeywords: RegExp = new RegExp("(" + newLineAfterKeyWordsStr + ")([^\\w_]|$)")
let regexBlockEndsKeyWords: RegExp = new RegExp("(" + blockEndKeyWordsStr + ")([^\\w_]|$)") let regexBlockEndsKeyWords: RegExp = new RegExp("(" + blockEndKeyWordsStr + ")([^\\w_]|$)")
for (i = startIndex; i < inputs.length; i++) { for (i = startIndex; i < inputs.length; i++) {
let input: string = inputs[i];
let input: string = inputs[i].trim();
if (input.regexStartsWith(/(CASE)([\s]|$)/)) { if (input.regexStartsWith(/(CASE)([\s]|$)/)) {
i = beautifyCaseBlock(inputs, result, settings, i, indent); i = beautifyCaseBlock(inputs, result, settings, i, indent);
continue; continue;


+ 66
- 8
VHDLFormatterUnitTests.js View File

@ -9,18 +9,41 @@ const VHDLFormatter_6 = require("./VHDLFormatter");
const VHDLFormatter_7 = require("./VHDLFormatter"); const VHDLFormatter_7 = require("./VHDLFormatter");
const VHDLFormatter_8 = require("./VHDLFormatter"); const VHDLFormatter_8 = require("./VHDLFormatter");
const VHDLFormatter_9 = require("./VHDLFormatter"); const VHDLFormatter_9 = require("./VHDLFormatter");
const VHDLFormatter_10 = require("./VHDLFormatter");
let testCount = 0; let testCount = 0;
var showUnitTests = true; //window.location.href.indexOf("http") < 0; var showUnitTests = true; //window.location.href.indexOf("http") < 0;
if (showUnitTests) { if (showUnitTests) {
testCount = 0; testCount = 0;
//UnitTest();
UnitTest();
UnitTestIndentDecode(); UnitTestIndentDecode();
UnitTestRemoveAsserts(); UnitTestRemoveAsserts();
UnitTestApplyNoNewLineAfter(); UnitTestApplyNoNewLineAfter();
UnitTestSetNewLinesAfterSymbols(); UnitTestSetNewLinesAfterSymbols();
UnitTestFormattedLineToString();
UnitTestbeautify3(); UnitTestbeautify3();
console.log("total tests: " + testCount); console.log("total tests: " + testCount);
} }
function UnitTestFormattedLineToString() {
console.log("=== FormattedLineToString ===");
FormattedLineToStringCase1();
FormattedLineToStringCase2();
}
function FormattedLineToStringCase1() {
let inputs = [
new VHDLFormatter_9.FormattedLine("a;", 0),
new VHDLFormatter_9.FormattedLine("b;", 0)
];
let expected = ["a;", "b;"];
UnitTest7(VHDLFormatter_10.FormattedLineToString, "General", " ", inputs, expected);
}
function FormattedLineToStringCase2() {
let inputs = [
new VHDLFormatter_9.FormattedLine("a;", 1),
new VHDLFormatter_9.FormattedLine("b;", 2)
];
let expected = [" a;", " b;"];
UnitTest7(VHDLFormatter_10.FormattedLineToString, "General", " ", inputs, expected);
}
function UnitTestbeautify3() { function UnitTestbeautify3() {
console.log("=== beautify3 ==="); console.log("=== beautify3 ===");
Beautify3Case1(); Beautify3Case1();
@ -36,6 +59,7 @@ function UnitTestbeautify3() {
Beautify3Case11(); Beautify3Case11();
Beautify3Case12(); Beautify3Case12();
Beautify3Case13(); Beautify3Case13();
Beautify3Case14();
} }
function Beautify3Case1() { function Beautify3Case1() {
let new_line_after_symbols = new VHDLFormatter_3.NewLineSettings(); let new_line_after_symbols = new VHDLFormatter_3.NewLineSettings();
@ -362,7 +386,30 @@ function Beautify3Case13() {
new VHDLFormatter_9.FormattedLine("IMPURE FUNCTION value RETURN INTEGER;", 1), new VHDLFormatter_9.FormattedLine("IMPURE FUNCTION value RETURN INTEGER;", 1),
new VHDLFormatter_9.FormattedLine("END PROTECTED SharedCounter;", 0) new VHDLFormatter_9.FormattedLine("END PROTECTED SharedCounter;", 0)
]; ];
UnitTest6(VHDLFormatter_8.beautify3, "package", settings, inputs, expected, 0, expected.length - 1, 0);
UnitTest6(VHDLFormatter_8.beautify3, "type projected", settings, inputs, expected, 0, expected.length - 1, 0);
}
function Beautify3Case14() {
let new_line_after_symbols = new VHDLFormatter_3.NewLineSettings();
new_line_after_symbols.newLineAfter = ["then", ";"];
new_line_after_symbols.noNewLineAfter = ["port", "generic"];
let settings = new VHDLFormatter_4.BeautifierSettings(false, false, false, false, false, "uppercase", " ", new_line_after_symbols);
let inputs = [
"PACKAGE p IS",
"TYPE SharedCounter IS PROTECTED",
"PROCEDURE increment (N : INTEGER := 1);",
"IMPURE FUNCTION value RETURN INTEGER;",
"END PROTECTED SharedCounter;",
"TYPE SharedCounter IS PROTECTED BODY"
];
let expected = [
new VHDLFormatter_9.FormattedLine("PACKAGE p IS", 0),
new VHDLFormatter_9.FormattedLine("TYPE SharedCounter IS PROTECTED", 1),
new VHDLFormatter_9.FormattedLine("PROCEDURE increment (N : INTEGER := 1);", 2),
new VHDLFormatter_9.FormattedLine("IMPURE FUNCTION value RETURN INTEGER;", 2),
new VHDLFormatter_9.FormattedLine("END PROTECTED SharedCounter;", 1),
new VHDLFormatter_9.FormattedLine("TYPE SharedCounter IS PROTECTED BODY", 1)
];
UnitTest6(VHDLFormatter_8.beautify3, "type projected", settings, inputs, expected, 0, expected.length - 1, 0);
} }
function UnitTestSetNewLinesAfterSymbols() { function UnitTestSetNewLinesAfterSymbols() {
console.log("=== SetNewLinesAfterSymbols ==="); console.log("=== SetNewLinesAfterSymbols ===");
@ -483,6 +530,10 @@ function assertArray(testName, expected, actual, message) {
} }
testCount++; testCount++;
} }
function UnitTest7(func, testName, indentation, inputs, expected) {
let actual = func(inputs, indentation);
assertArray(testName, expected, actual);
}
function UnitTest6(func, testName, parameters, inputs, expected, startIndex, expectedEndIndex, indent) { function UnitTest6(func, testName, parameters, inputs, expected, startIndex, expectedEndIndex, indent) {
let actual = []; let actual = [];
let endIndex = func(inputs, actual, parameters, startIndex, indent); let endIndex = func(inputs, actual, parameters, startIndex, indent);
@ -521,15 +572,11 @@ function UnitTest() {
let expected = "ARCHITECTURE TB OF TB_CPU IS\r\n COMPONENT CPU_IF\r\n PORT -- port list\r\n END COMPONENT;\r\n SIGNAL CPU_DATA_VALID : std_ulogic;\r\n SIGNAL CLK, RESET : std_ulogic := '0';\r\n CONSTANT PERIOD : TIME := 10 ns;\r\n CONSTANT MAX_SIM : TIME := 50 * PERIOD;\r\nBEGIN\r\n -- concurrent statements\r\nEND TB;"; let expected = "ARCHITECTURE TB OF TB_CPU IS\r\n COMPONENT CPU_IF\r\n PORT -- port list\r\n END COMPONENT;\r\n SIGNAL CPU_DATA_VALID : std_ulogic;\r\n SIGNAL CLK, RESET : std_ulogic := '0';\r\n CONSTANT PERIOD : TIME := 10 ns;\r\n CONSTANT MAX_SIM : TIME := 50 * PERIOD;\r\nBEGIN\r\n -- concurrent statements\r\nEND TB;";
let actual = VHDLFormatter_1.beautify(input, settings); let actual = VHDLFormatter_1.beautify(input, settings);
assert("General", expected, actual); assert("General", expected, actual);
let newSettings = deepCopy(settings);
newSettings.RemoveComments = true;
expected = "ARCHITECTURE TB OF TB_CPU IS\r\n COMPONENT CPU_IF\r\n PORT \r\n END COMPONENT;\r\n SIGNAL CPU_DATA_VALID : std_ulogic;\r\n SIGNAL CLK, RESET : std_ulogic := '0';\r\n CONSTANT PERIOD : TIME := 10 ns;\r\n CONSTANT MAX_SIM : TIME := 50 * PERIOD;\r\nBEGIN\r\nEND TB;";
actual = VHDLFormatter_1.beautify(input, newSettings);
assert("Remove comments", expected, actual);
IntegrationTest2();
let new_line_after_symbols_2 = new VHDLFormatter_3.NewLineSettings(); let new_line_after_symbols_2 = new VHDLFormatter_3.NewLineSettings();
new_line_after_symbols_2.newLineAfter = []; new_line_after_symbols_2.newLineAfter = [];
new_line_after_symbols_2.noNewLineAfter = ["then", ";", "generic", "port"]; new_line_after_symbols_2.noNewLineAfter = ["then", ";", "generic", "port"];
newSettings = deepCopy(settings);
let newSettings = deepCopy(settings);
newSettings.NewLineSettings = new_line_after_symbols_2; newSettings.NewLineSettings = new_line_after_symbols_2;
expected = "a; b; c;"; expected = "a; b; c;";
input = "a; \r\nb;\r\n c;"; input = "a; \r\nb;\r\n c;";
@ -610,6 +657,17 @@ function UnitTest() {
actual = VHDLFormatter_1.beautify(input, newSettings); actual = VHDLFormatter_1.beautify(input, newSettings);
assert("Indent after Begin", expected, actual); assert("Indent after Begin", expected, actual);
} }
function IntegrationTest2() {
let new_line_after_symbols = new VHDLFormatter_3.NewLineSettings();
new_line_after_symbols.newLineAfter = ["then", ";"];
new_line_after_symbols.noNewLineAfter = ["generic"];
let settings = new VHDLFormatter_4.BeautifierSettings(false, false, false, false, false, "uppercase", " ", new_line_after_symbols);
settings.RemoveComments = true;
let input = "architecture TB of TB_CPU is\r\n component CPU_IF\r\n port -- port list\r\n end component;\r\n signal CPU_DATA_VALID: std_ulogic;\r\n signal CLK, RESET: std_ulogic := '0';\r\n constant PERIOD : time := 10 ns;\r\n constant MAX_SIM: time := 50 * PERIOD;\r\n begin\r\n -- concurrent statements\r\n end TB;";
let expected = "ARCHITECTURE TB OF TB_CPU IS\r\n COMPONENT CPU_IF\r\n PORT \r\n END COMPONENT;\r\n SIGNAL CPU_DATA_VALID : std_ulogic;\r\n SIGNAL CLK, RESET : std_ulogic := '0';\r\n CONSTANT PERIOD : TIME := 10 ns;\r\n CONSTANT MAX_SIM : TIME := 50 * PERIOD;\r\nBEGIN\r\nEND TB;";
let actual = VHDLFormatter_1.beautify(input, settings);
assert("Remove comments", expected, actual);
}
function CompareString(actual, expected) { function CompareString(actual, expected) {
var l = Math.min(actual.length, expected.length); var l = Math.min(actual.length, expected.length);
for (var i = 0; i < l; i++) { for (var i = 0; i < l; i++) {


+ 73
- 10
VHDLFormatterUnitTests.ts View File

@ -7,19 +7,20 @@ import { ApplyNoNewLineAfter } from "./VHDLFormatter";
import { SetNewLinesAfterSymbols } from "./VHDLFormatter"; import { SetNewLinesAfterSymbols } from "./VHDLFormatter";
import { beautify3 } from "./VHDLFormatter"; import { beautify3 } from "./VHDLFormatter";
import { FormattedLine } from "./VHDLFormatter"; import { FormattedLine } from "./VHDLFormatter";
import { FormattedLineToString } from "./VHDLFormatter";
let testCount: number = 0; let testCount: number = 0;
var showUnitTests = true;//window.location.href.indexOf("http") < 0; var showUnitTests = true;//window.location.href.indexOf("http") < 0;
if (showUnitTests) { if (showUnitTests) {
testCount = 0; testCount = 0;
//UnitTest();
UnitTest();
UnitTestIndentDecode(); UnitTestIndentDecode();
UnitTestRemoveAsserts(); UnitTestRemoveAsserts();
UnitTestApplyNoNewLineAfter(); UnitTestApplyNoNewLineAfter();
UnitTestSetNewLinesAfterSymbols(); UnitTestSetNewLinesAfterSymbols();
UnitTestFormattedLineToString();
UnitTestbeautify3(); UnitTestbeautify3();
console.log("total tests: " + testCount); console.log("total tests: " + testCount);
} }
@ -28,6 +29,28 @@ interface Function {
readonly name: string; readonly name: string;
} }
function UnitTestFormattedLineToString() {
console.log("=== FormattedLineToString ===");
FormattedLineToStringCase1();
FormattedLineToStringCase2();
}
function FormattedLineToStringCase1() {
let inputs: (FormattedLine | FormattedLine[])[] = [
new FormattedLine("a;", 0),
new FormattedLine("b;", 0)];
let expected: Array<string> = ["a;", "b;"];
UnitTest7(FormattedLineToString, "General", " ", inputs, expected);
}
function FormattedLineToStringCase2() {
let inputs: (FormattedLine | FormattedLine[])[] = [
new FormattedLine("a;", 1),
new FormattedLine("b;", 2)];
let expected: Array<string> = [" a;", " b;"];
UnitTest7(FormattedLineToString, "General", " ", inputs, expected);
}
function UnitTestbeautify3() { function UnitTestbeautify3() {
console.log("=== beautify3 ==="); console.log("=== beautify3 ===");
Beautify3Case1(); Beautify3Case1();
@ -43,6 +66,7 @@ function UnitTestbeautify3() {
Beautify3Case11(); Beautify3Case11();
Beautify3Case12(); Beautify3Case12();
Beautify3Case13(); Beautify3Case13();
Beautify3Case14();
} }
function Beautify3Case1() { function Beautify3Case1() {
@ -381,7 +405,31 @@ function Beautify3Case13() {
new FormattedLine("IMPURE FUNCTION value RETURN INTEGER;", 1), new FormattedLine("IMPURE FUNCTION value RETURN INTEGER;", 1),
new FormattedLine("END PROTECTED SharedCounter;", 0) new FormattedLine("END PROTECTED SharedCounter;", 0)
]; ];
UnitTest6(beautify3, "package", settings, inputs, expected, 0, expected.length - 1, 0);
UnitTest6(beautify3, "type projected", settings, inputs, expected, 0, expected.length - 1, 0);
}
function Beautify3Case14() {
let new_line_after_symbols: NewLineSettings = new NewLineSettings();
new_line_after_symbols.newLineAfter = ["then", ";"];
new_line_after_symbols.noNewLineAfter = ["port", "generic"];
let settings: BeautifierSettings = new BeautifierSettings(false, false, false, false, false, "uppercase", " ", new_line_after_symbols);
let inputs: Array<string> = [
"PACKAGE p IS",
"TYPE SharedCounter IS PROTECTED",
"PROCEDURE increment (N : INTEGER := 1);",
"IMPURE FUNCTION value RETURN INTEGER;",
"END PROTECTED SharedCounter;",
"TYPE SharedCounter IS PROTECTED BODY"
];
let expected: (FormattedLine | FormattedLine[])[] = [
new FormattedLine("PACKAGE p IS", 0),
new FormattedLine("TYPE SharedCounter IS PROTECTED", 1),
new FormattedLine("PROCEDURE increment (N : INTEGER := 1);", 2),
new FormattedLine("IMPURE FUNCTION value RETURN INTEGER;", 2),
new FormattedLine("END PROTECTED SharedCounter;", 1),
new FormattedLine("TYPE SharedCounter IS PROTECTED BODY", 1)
];
UnitTest6(beautify3, "type projected", settings, inputs, expected, 0, expected.length - 1, 0);
} }
function UnitTestSetNewLinesAfterSymbols() { function UnitTestSetNewLinesAfterSymbols() {
@ -493,7 +541,7 @@ function compareFormattedLine(expected: FormattedLine, actual: FormattedLine, me
return result; return result;
} }
function assert(testName, expected, actual, message?) {
function assert(testName, expected: string, actual: string, message?) {
var result = CompareString(actual, expected); var result = CompareString(actual, expected);
if (result != true) { if (result != true) {
console.log(testName + " failed: " + result); console.log(testName + " failed: " + result);
@ -525,6 +573,13 @@ type String2Callback = (text: string, parameters: NewLineSettings) => string;
type BeautifyCallback = (inputs: Array<string>, result: (FormattedLine | FormattedLine[])[], settings: BeautifierSettings, startIndex: number, indent: number) => number; type BeautifyCallback = (inputs: Array<string>, result: (FormattedLine | FormattedLine[])[], settings: BeautifierSettings, startIndex: number, indent: number) => number;
type FormattedLinesCallback = (inputs: (FormattedLine | FormattedLine[])[], indentation: string) => Array<string>;
function UnitTest7(func: FormattedLinesCallback, testName: string, indentation: string, inputs: (FormattedLine | FormattedLine[])[], expected: Array<string>) {
let actual = func(inputs, indentation);
assertArray(testName, expected, actual);
}
function UnitTest6(func: BeautifyCallback, testName: string, parameters: BeautifierSettings, inputs: Array<string>, expected: (FormattedLine | FormattedLine[])[], startIndex: number, expectedEndIndex: number, indent: number) { function UnitTest6(func: BeautifyCallback, testName: string, parameters: BeautifierSettings, inputs: Array<string>, expected: (FormattedLine | FormattedLine[])[], startIndex: number, expectedEndIndex: number, indent: number) {
let actual: (FormattedLine | FormattedLine[])[] = [] let actual: (FormattedLine | FormattedLine[])[] = []
let endIndex: number = func(inputs, actual, parameters, startIndex, indent); let endIndex: number = func(inputs, actual, parameters, startIndex, indent);
@ -570,16 +625,12 @@ function UnitTest() {
let actual = beautify(input, settings); let actual = beautify(input, settings);
assert("General", expected, actual); assert("General", expected, actual);
let newSettings = deepCopy(settings);
newSettings.RemoveComments = true;
expected = "ARCHITECTURE TB OF TB_CPU IS\r\n COMPONENT CPU_IF\r\n PORT \r\n END COMPONENT;\r\n SIGNAL CPU_DATA_VALID : std_ulogic;\r\n SIGNAL CLK, RESET : std_ulogic := '0';\r\n CONSTANT PERIOD : TIME := 10 ns;\r\n CONSTANT MAX_SIM : TIME := 50 * PERIOD;\r\nBEGIN\r\nEND TB;";
actual = beautify(input, newSettings);
assert("Remove comments", expected, actual);
IntegrationTest2();
let new_line_after_symbols_2: NewLineSettings = new NewLineSettings(); let new_line_after_symbols_2: NewLineSettings = new NewLineSettings();
new_line_after_symbols_2.newLineAfter = []; new_line_after_symbols_2.newLineAfter = [];
new_line_after_symbols_2.noNewLineAfter = ["then", ";", "generic", "port"]; new_line_after_symbols_2.noNewLineAfter = ["then", ";", "generic", "port"];
newSettings = deepCopy(settings);
let newSettings = deepCopy(settings);
newSettings.NewLineSettings = new_line_after_symbols_2; newSettings.NewLineSettings = new_line_after_symbols_2;
expected = "a; b; c;"; expected = "a; b; c;";
input = "a; \r\nb;\r\n c;" input = "a; \r\nb;\r\n c;"
@ -677,6 +728,18 @@ function UnitTest() {
assert("Indent after Begin", expected, actual); assert("Indent after Begin", expected, actual);
} }
function IntegrationTest2() {
let new_line_after_symbols: NewLineSettings = new NewLineSettings();
new_line_after_symbols.newLineAfter = ["then", ";"];
new_line_after_symbols.noNewLineAfter = ["generic"];
let settings: BeautifierSettings = new BeautifierSettings(false, false, false, false, false, "uppercase", " ", new_line_after_symbols);
settings.RemoveComments = true;
let input = "architecture TB of TB_CPU is\r\n component CPU_IF\r\n port -- port list\r\n end component;\r\n signal CPU_DATA_VALID: std_ulogic;\r\n signal CLK, RESET: std_ulogic := '0';\r\n constant PERIOD : time := 10 ns;\r\n constant MAX_SIM: time := 50 * PERIOD;\r\n begin\r\n -- concurrent statements\r\n end TB;"
let expected = "ARCHITECTURE TB OF TB_CPU IS\r\n COMPONENT CPU_IF\r\n PORT \r\n END COMPONENT;\r\n SIGNAL CPU_DATA_VALID : std_ulogic;\r\n SIGNAL CLK, RESET : std_ulogic := '0';\r\n CONSTANT PERIOD : TIME := 10 ns;\r\n CONSTANT MAX_SIM : TIME := 50 * PERIOD;\r\nBEGIN\r\nEND TB;";
let actual = beautify(input, settings);
assert("Remove comments", expected, actual);
}
function CompareString(actual: string, expected: string) { function CompareString(actual: string, expected: string) {
var l = Math.min(actual.length, expected.length); var l = Math.min(actual.length, expected.length);
for (var i = 0; i < l; i++) { for (var i = 0; i < l; i++) {


Loading…
Cancel
Save