Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions VHDLFormatter.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 35 additions & 25 deletions VHDLFormatter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
let isTesting = false;
const ILEscape = "@@";
const ILEscape = "@__@";
const ILCommentPrefix = ILEscape + "comments";
const ILIndentedReturnPrefix = ILEscape;
const ILQuote = "⨵";
const ILSingleQuote = "⦼";
const ILBackslash = "⨸";
const ILSemicolon = "⨴";
const ILContinuation = "➥";

enum FormatMode {
Default,
Expand Down Expand Up @@ -306,9 +307,10 @@ export class BeautifierSettings {
NewLineSettings: NewLineSettings;
EndOfLine: string;
AddNewLine: boolean;
MoveLeadingCommasToPrevLine: boolean;
constructor(removeComments: boolean, removeReport: boolean, checkAlias: boolean,
signAlignSettings: signAlignSettings, keywordCase: string, typeNameCase: string, indentation: string,
newLineSettings: NewLineSettings, endOfLine: string, addNewLine: boolean) {
newLineSettings: NewLineSettings, endOfLine: string, addNewLine: boolean, MoveLeadingCommasToPrevLine = false) {
this.RemoveComments = removeComments;
this.RemoveAsserts = removeReport;
this.CheckAlias = checkAlias;
Expand All @@ -319,6 +321,7 @@ export class BeautifierSettings {
this.NewLineSettings = newLineSettings;
this.EndOfLine = endOfLine;
this.AddNewLine = addNewLine;
this.MoveLeadingCommasToPrevLine = MoveLeadingCommasToPrevLine;
}
}

Expand All @@ -337,8 +340,8 @@ export function beautify(input: string, settings: BeautifierSettings) {

input = arr.join("\r\n");
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(/\r\n[ \t]*@__@comments[0-9]+[ \t]*\r\n/g, '\r\n');
input = input.replace(/@__@comments[0-9]+/g, '');
comments = [];
}

Expand All @@ -350,6 +353,10 @@ export function beautify(input: string, settings: BeautifierSettings) {
input = input.replace(/[ ]+;/g, ';');
input = input.replace(/:[ ]*(PROCESS|ENTITY)/gi, ':$1');

if (settings.MoveLeadingCommasToPrevLine) {
input = input.replace(/(\s*(@__@comments[0-9]+)?)\r\n(\s*),/g, ',$1\r\n$3');
}

arr = input.split("\r\n");
if (settings.RemoveAsserts) {
RemoveAsserts(arr);//RemoveAsserts must be after EscapeQuotes
Expand All @@ -366,7 +373,7 @@ export function beautify(input: string, settings: BeautifierSettings) {
input = arr.join("\r\n");
}

input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end');
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(/(\d+e) +([+\-]) +(\d+)/g, '$1$2$3');// fix exponential notation format broken by previous step
input = input.replace(/[ ]?([,])[ ]?/g, '$1 ');
Expand All @@ -383,7 +390,7 @@ export function beautify(input: string, settings: BeautifierSettings) {
input = input.replace(/[\r\n\s]+$/g, '');
input = input.replace(/[ \t]+\)/g, ')');
input = input.replace(/\s*\)\s+RETURN\s+([\w]+;)/g, '\r\n) RETURN $1');//function(..)\r\nreturn type; -> function(..\r\n)return type;
input = input.replace(/\)\s*(@@\w+)\r\n\s*RETURN\s+([\w]+;)/g, ') $1\r\n' + ILIndentedReturnPrefix + 'RETURN $2');//function(..)\r\nreturn type; -> function(..\r\n)return type;
input = input.replace(/\)\s*(@__@\w+)\r\n\s*RETURN\s+([\w]+;)/g, ') $1\r\n' + ILIndentedReturnPrefix + 'RETURN $2');//function(..)\r\nreturn type; -> function(..\r\n)return type;
let keywordAndSignRegex = new RegExp("(\\b" + KeyWords.join("\\b|\\b") + "\\b) +([\\-+]) +(\\w)", "g");
input = input.replace(keywordAndSignRegex, "$1 $2$3");// `WHEN - 2` -> `WHEN -2`
input = input.replace(/([,|]) +([+\-]) +(\w)/g, '$1 $2$3');// `1, - 2)` -> `1, -2)`
Expand All @@ -399,7 +406,7 @@ export function beautify(input: string, settings: BeautifierSettings) {

arr = FormattedLineToString(result, settings.Indentation);
input = arr.join("\r\n");
input = input.replace(/@@RETURN/g, "RETURN");
input = input.replace(/@__@RETURN/g, "RETURN");
input = SetKeywordCase(input, settings.KeywordCase, KeyWords);
input = SetKeywordCase(input, settings.TypeNameCase, TypeNames);

Expand All @@ -408,7 +415,7 @@ export function beautify(input: string, settings: BeautifierSettings) {
input = replaceEscapedComments(input, comments, ILCommentPrefix);
input = replaceEscapedWords(input, backslashes, ILBackslash);
input = input.replace(new RegExp(ILSemicolon, "g"), ";");
input = input.replace(/@@[a-z]+/g, "");
input = input.replace(/@__@[a-z]+/g, "");
var escapedTexts = new RegExp("[" + ILBackslash + ILQuote + ILSingleQuote + "]", "g");
input = input.replace(escapedTexts, "");
input = input.replace(/\r\n/g, settings.EndOfLine);
Expand Down Expand Up @@ -499,7 +506,7 @@ export function FormattedLineToString(arr: (FormattedLine | FormattedLine[])[],
arr.forEach(i => {
if (i instanceof FormattedLine) {
if (i.Line.length > 0) {
result.push((Array(i.Indent + 1).join(indentation)) + i.Line);
result.push(indentation.repeat(i.Indent) + i.Line.replace(ILContinuation, " "));
}
else {
result.push("");
Expand Down Expand Up @@ -596,7 +603,7 @@ export function AlignSigns(result: (FormattedLine | FormattedLine[])[], startInd
AlignSign_(result, startIndex, endIndex, "=>", mode);
AlignSign_(result, startIndex, endIndex, "direction", mode);
if (alignComments) {
AlignSign_(result, startIndex, endIndex, "@@comments", mode);
AlignSign_(result, startIndex, endIndex, "@__@comments", mode);
}
}

Expand Down Expand Up @@ -629,22 +636,24 @@ function AlignSign_(result: (FormattedLine | FormattedLine[])[], startIndex: num
if (symbol == ":" && line.regexStartsWith(labelAndKeywordsRegex)) {
continue;
}

let regex: RegExp;
let groupIndex: number;
if (symbol == "direction") {
regex = new RegExp("(:\\s*)(IN|OUT|INOUT|BUFFER)(\\s+)(\\w)");
groupIndex = 4;
}
else {
regex = new RegExp("([\\s\\w\\\\]|^)" + symbol + "([\\s\\w\\\\]|$)");
regex = new RegExp("([\\s\\w\\\\]|^)(" + symbol + ")([\\s\\w\\\\]|$)");
groupIndex = 2;
}
if (line.regexCount(regex) > 1) {
continue;
}
let colonIndex: number;
if (symbol == "direction") {
colonIndex = indexOfGroup(regex, line, 4);
}
else {
colonIndex = line.regexIndexOf(regex);

let colonIndex = indexOfGroup(regex, line, groupIndex);
if (colonIndex < 0) {
colonIndex = line.indexOf(ILContinuation);
}
if (colonIndex > 0) {
maxSymbolIndex = Math.max(maxSymbolIndex, colonIndex);
Expand Down Expand Up @@ -679,7 +688,7 @@ export function AlignSign(result: (FormattedLine | FormattedLine[])[], startInde
}
let line = (<FormattedLine>result[lineIndex]).Line;
(<FormattedLine>result[lineIndex]).Line = line.substring(0, symbolIndex)
+ (Array(maxSymbolIndex - symbolIndex + 1).join(" "))
+ " ".repeat(maxSymbolIndex - symbolIndex)
+ line.substring(symbolIndex);
}
}
Expand Down Expand Up @@ -772,14 +781,15 @@ export function beautifySemicolonBlock(block: CodeBlock, result: (FormattedLine

function alignSignalAssignmentBlock(settings: BeautifierSettings, inputs: string[], startIndex: number, endIndex: number, result: (FormattedLine | FormattedLine[])[]) {
if (settings.Indentation.replace(/ +/g, "").length == 0) {
let reg: RegExp = new RegExp("^([\\w\\\\]+[\\s]*<=\\s*)");
let reg: RegExp = new RegExp("^([\\w\\\\]+(\\([\\w\\s]+\\))?[\\s]*([<:]=\\s*))");
let match = reg.exec(inputs[startIndex]);
if (match != null) {
let length = match[0].length;
let prefixLength = length - settings.Indentation.length;
let prefix = new Array(prefixLength + 1).join(" ");
let prefixLength = match[0].length;
let suffixLength = match[3].length;
let prefix = " ".repeat(prefixLength - suffixLength) + ILContinuation + " ".repeat(suffixLength - 1);
for (let i = startIndex + 1; i <= endIndex; i++) {
let fl = (result[i] as FormattedLine);
fl.Indent--;
fl.Line = prefix + fl.Line;
}
}
Expand Down Expand Up @@ -814,8 +824,8 @@ export function beautify3(block: CodeBlock, result: (FormattedLine | FormattedLi
let indentedEndsKeyWords: Array<string> = [ILIndentedReturnPrefix + "RETURN\\s+\\w+;"];
let blockEndsWithSemicolon: Array<string> = [
"(WITH\\s+[\\w\\s\\\\]+SELECT)",
"([\\w\\\\]+[\\s]*<=)",
"([\\w\\\\]+[\\s]*:=)",
"([\\w\\\\]+(\\([\\w\\s]+\\))?[\\s]*<=)",
"([\\w\\\\]+(\\([\\w\\s]+\\))?[\\s]*:=)",
"FOR\\s+[\\w\\s,]+:\\s*\\w+\\s+USE",
"REPORT"
];
Expand Down Expand Up @@ -984,7 +994,7 @@ export function ApplyNoNewLineAfter(arr: Array<string>, noNewLineAfter: Array<st
noNewLineAfter.forEach(n => {
let regex = new RegExp("(" + n.toUpperCase + ")[ a-z0-9]+[a-z0-9]+");
if (arr[i].regexIndexOf(regex) >= 0) {
arr[i] += "@@singleline";
arr[i] += "@__@singleline";
}
});
}
Expand Down
Loading