code-block-writer
Advanced tools
Comparing version 10.0.0 to 10.1.0
@@ -5,2 +5,17 @@ # Change Log | ||
<a name="10.1.0"></a> | ||
# [10.1.0](https://github.com/dsherret/code-block-writer/compare/v10.0.0...v10.1.0) (2019-11-23) | ||
### Features | ||
* Add `iterateLastCharCodes` which is slightly more efficient than `iterateLastChars`. ([5e27b85](https://github.com/dsherret/code-block-writer/commit/5e27b85)) | ||
### Performance Improvements | ||
* Use `charCodeAt` instead of indexing into the string (to avoid an allocation). ([48b4e3e](https://github.com/dsherret/code-block-writer/commit/48b4e3e)) | ||
<a name="10.0.0"></a> | ||
@@ -7,0 +22,0 @@ # [10.0.0](https://github.com/dsherret/code-block-writer/compare/v9.4.1...v10.0.0) (2019-09-02) |
@@ -263,2 +263,11 @@ /** | ||
/** | ||
* Iterates over the writer character char codes in reverse order. The iteration stops when a non-null or | ||
* undefined value is returned from the action. The returned value is then returned by the method. | ||
* | ||
* @remarks It is much more efficient to use this method rather than `#toString()` since `#toString()` | ||
* will combine the internal array into a string. Additionally, this is slightly more efficient that | ||
* `iterateLastChars` as this won't allocate a string per character. | ||
*/ | ||
iterateLastCharCodes<T>(action: (charCode: number, index: number) => T | undefined): T | undefined; | ||
/** | ||
* Gets the writer's text. | ||
@@ -265,0 +274,0 @@ */ |
@@ -5,2 +5,16 @@ "use strict"; | ||
const CommentChar_1 = require("./CommentChar"); | ||
const isCharToHandle = new Set(["/", "\\", "\n", "\r", "*", "\"", "'", "`", "{", "}"].map(c => c.charCodeAt(0))); | ||
const CHARS = { | ||
BACK_SLASH: "\\".charCodeAt(0), | ||
FORWARD_SLASH: "/".charCodeAt(0), | ||
NEW_LINE: "\n".charCodeAt(0), | ||
CARRIAGE_RETURN: "\r".charCodeAt(0), | ||
ASTERISK: "*".charCodeAt(0), | ||
DOUBLE_QUOTE: "\"".charCodeAt(0), | ||
SINGLE_QUOTE: "'".charCodeAt(0), | ||
BACK_TICK: "`".charCodeAt(0), | ||
OPEN_BRACE: "{".charCodeAt(0), | ||
CLOSE_BRACE: "}".charCodeAt(0), | ||
DOLLAR_SIGN: "$".charCodeAt(0) | ||
}; | ||
/** | ||
@@ -375,3 +389,3 @@ * Code writer that assists with formatting and visualizing blocks of JavaScript or TypeScript code. | ||
isInString() { | ||
return this._stringCharStack.length > 0 && this._stringCharStack[this._stringCharStack.length - 1] !== "{"; | ||
return this._stringCharStack.length > 0 && this._stringCharStack[this._stringCharStack.length - 1] !== CHARS.OPEN_BRACE; | ||
} | ||
@@ -395,4 +409,4 @@ /** | ||
for (let j = currentText.length - 1; j >= 0; j--) { | ||
const currentChar = currentText[j]; | ||
if (currentChar === "\n") { | ||
const currentChar = currentText.charCodeAt(j); | ||
if (currentChar === CHARS.NEW_LINE) { | ||
foundCount++; | ||
@@ -402,3 +416,3 @@ if (foundCount === 2) | ||
} | ||
else if (currentChar !== "\r") { | ||
else if (currentChar !== CHARS.CARRIAGE_RETURN) { | ||
return false; | ||
@@ -426,3 +440,4 @@ } | ||
getLastChar() { | ||
return this._getLastCharWithOffset(0); | ||
const charCode = this._getLastCharCodeWithOffset(0); | ||
return charCode == null ? undefined : String.fromCharCode(charCode); | ||
} | ||
@@ -435,6 +450,6 @@ /** | ||
const length = this._length; | ||
return this.iterateLastChars((char, index) => { | ||
return this.iterateLastCharCodes((charCode, index) => { | ||
const offset = length - index; | ||
const textIndex = text.length - offset; | ||
if (text[textIndex] !== char) | ||
if (text.charCodeAt(textIndex) !== charCode) | ||
return false; | ||
@@ -452,2 +467,13 @@ return textIndex === 0 ? true : undefined; | ||
iterateLastChars(action) { | ||
return this.iterateLastCharCodes((charCode, index) => action(String.fromCharCode(charCode), index)); | ||
} | ||
/** | ||
* Iterates over the writer character char codes in reverse order. The iteration stops when a non-null or | ||
* undefined value is returned from the action. The returned value is then returned by the method. | ||
* | ||
* @remarks It is much more efficient to use this method rather than `#toString()` since `#toString()` | ||
* will combine the internal array into a string. Additionally, this is slightly more efficient that | ||
* `iterateLastChars` as this won't allocate a string per character. | ||
*/ | ||
iterateLastCharCodes(action) { | ||
let index = this._length; | ||
@@ -458,3 +484,3 @@ for (let i = this._texts.length - 1; i >= 0; i--) { | ||
index--; | ||
const result = action(currentText[j], index); | ||
const result = action(currentText.charCodeAt(j), index); | ||
if (result != null) | ||
@@ -507,3 +533,3 @@ return result; | ||
const lastStringCharOnStack = this._stringCharStack[this._stringCharStack.length - 1]; | ||
if ((lastStringCharOnStack === "\"" || lastStringCharOnStack === "'") && this.getLastChar() !== "\\") | ||
if ((lastStringCharOnStack === CHARS.DOUBLE_QUOTE || lastStringCharOnStack === CHARS.SINGLE_QUOTE) && this._getLastCharCodeWithOffset(0) !== CHARS.BACK_SLASH) | ||
this._stringCharStack.pop(); | ||
@@ -528,5 +554,5 @@ this._internalWrite(this._newLine); | ||
let foundNewLine = false; | ||
return writer.iterateLastChars(char => { | ||
switch (char) { | ||
case "\n": | ||
return writer.iterateLastCharCodes(charCode => { | ||
switch (charCode) { | ||
case CHARS.NEW_LINE: | ||
if (foundNewLine) | ||
@@ -537,5 +563,5 @@ return false; | ||
break; | ||
case "\r": | ||
case CHARS.CARRIAGE_RETURN: | ||
return undefined; | ||
case "{": | ||
case CHARS.OPEN_BRACE: | ||
return true; | ||
@@ -551,13 +577,13 @@ default: | ||
for (let i = 0; i < str.length; i++) { | ||
const currentChar = str[i]; | ||
const currentChar = str.charCodeAt(i); | ||
// This is a performance optimization to short circuit all the checks below. If the current char | ||
// is not in this set then it won't change any internal state so no need to continue and do | ||
// so many other checks (this made it 3x faster in one scenario I tested). | ||
if (!CodeBlockWriter._isCharToHandle.has(currentChar)) | ||
if (!isCharToHandle.has(currentChar)) | ||
continue; | ||
const pastChar = i === 0 ? this.getLastChar() : str[i - 1]; | ||
const pastPastChar = i === 0 ? this._getLastCharWithOffset(1) : i === 1 ? this.getLastChar() : str[i - 2]; | ||
const pastChar = i === 0 ? this._getLastCharCodeWithOffset(0) : str.charCodeAt(i - 1); | ||
const pastPastChar = i === 0 ? this._getLastCharCodeWithOffset(1) : i === 1 ? this._getLastCharCodeWithOffset(0) : str.charCodeAt(i - 2); | ||
// handle regex | ||
if (this._isInRegEx) { | ||
if (pastChar === "/" && pastPastChar !== "\\" || pastChar === "\n") | ||
if (pastChar === CHARS.FORWARD_SLASH && pastPastChar !== CHARS.BACK_SLASH || pastChar === CHARS.NEW_LINE) | ||
this._isInRegEx = false; | ||
@@ -572,7 +598,7 @@ else | ||
// handle comments | ||
if (this._currentCommentChar == null && pastChar === "/" && currentChar === "/") | ||
if (this._currentCommentChar == null && pastChar === CHARS.FORWARD_SLASH && currentChar === CHARS.FORWARD_SLASH) | ||
this._currentCommentChar = CommentChar_1.CommentChar.Line; | ||
else if (this._currentCommentChar == null && pastChar === "/" && currentChar === "*") | ||
else if (this._currentCommentChar == null && pastChar === CHARS.FORWARD_SLASH && currentChar === CHARS.ASTERISK) | ||
this._currentCommentChar = CommentChar_1.CommentChar.Star; | ||
else if (this._currentCommentChar === CommentChar_1.CommentChar.Star && pastChar === "*" && currentChar === "/") | ||
else if (this._currentCommentChar === CommentChar_1.CommentChar.Star && pastChar === CHARS.ASTERISK && currentChar === CHARS.FORWARD_SLASH) | ||
this._currentCommentChar = undefined; | ||
@@ -583,11 +609,11 @@ if (this.isInComment()) | ||
const lastStringCharOnStack = this._stringCharStack.length === 0 ? undefined : this._stringCharStack[this._stringCharStack.length - 1]; | ||
if (pastChar !== "\\" && (currentChar === "\"" || currentChar === "'" || currentChar === "`")) { | ||
if (pastChar !== CHARS.BACK_SLASH && (currentChar === CHARS.DOUBLE_QUOTE || currentChar === CHARS.SINGLE_QUOTE || currentChar === CHARS.BACK_TICK)) { | ||
if (lastStringCharOnStack === currentChar) | ||
this._stringCharStack.pop(); | ||
else if (lastStringCharOnStack === "{" || lastStringCharOnStack === undefined) | ||
else if (lastStringCharOnStack === CHARS.OPEN_BRACE || lastStringCharOnStack === undefined) | ||
this._stringCharStack.push(currentChar); | ||
} | ||
else if (pastPastChar !== "\\" && pastChar === "$" && currentChar === "{" && lastStringCharOnStack === "`") | ||
else if (pastPastChar !== CHARS.BACK_SLASH && pastChar === CHARS.DOLLAR_SIGN && currentChar === CHARS.OPEN_BRACE && lastStringCharOnStack === CHARS.BACK_TICK) | ||
this._stringCharStack.push(currentChar); | ||
else if (currentChar === "}" && lastStringCharOnStack === "{") | ||
else if (currentChar === CHARS.CLOSE_BRACE && lastStringCharOnStack === CHARS.OPEN_BRACE) | ||
this._stringCharStack.pop(); | ||
@@ -597,3 +623,3 @@ } | ||
/** @internal - This is private, but exposed for testing. */ | ||
_getLastCharWithOffset(offset) { | ||
_getLastCharCodeWithOffset(offset) { | ||
if (offset >= this._length || offset < 0) | ||
@@ -606,3 +632,3 @@ return undefined; | ||
else | ||
return currentText[currentText.length - 1 - offset]; | ||
return currentText.charCodeAt(currentText.length - 1 - offset); | ||
} | ||
@@ -675,15 +701,13 @@ return undefined; | ||
} | ||
exports.default = CodeBlockWriter; | ||
/** @internal */ | ||
CodeBlockWriter._newLineRegEx = /\r?\n/; | ||
/** @internal */ | ||
CodeBlockWriter._isCharToHandle = new Set(["/", "\\", "\n", "\r", "*", "\"", "'", "`", "{", "}"]); | ||
/** @internal */ | ||
CodeBlockWriter._spacesOrTabsRegEx = /^[ \t]*$/; | ||
exports.default = CodeBlockWriter; | ||
function isRegExStart(currentChar, pastChar, pastPastChar) { | ||
return pastChar === "/" | ||
&& currentChar !== "/" | ||
&& currentChar !== "*" | ||
&& pastPastChar !== "*" | ||
&& pastPastChar !== "/"; | ||
return pastChar === CHARS.FORWARD_SLASH | ||
&& currentChar !== CHARS.FORWARD_SLASH | ||
&& currentChar !== CHARS.ASTERISK | ||
&& pastPastChar !== CHARS.ASTERISK | ||
&& pastPastChar !== CHARS.FORWARD_SLASH; | ||
} | ||
@@ -690,0 +714,0 @@ function getIndentationText(useTabs, numberSpaces) { |
{ | ||
"name": "code-block-writer", | ||
"version": "10.0.0", | ||
"version": "10.1.0", | ||
"description": "A simple code writer that assists with formatting and visualizing blocks of code.", | ||
@@ -11,3 +11,3 @@ "main": "dist/code-block-writer.js", | ||
"build": "rimraf dist && tsc", | ||
"format": "dprint \"**/*{.ts|.json}\"", | ||
"format": "dprint", | ||
"dopublish": "npm run build && echo \"Run: npm publish --otp\"" | ||
@@ -46,15 +46,17 @@ }, | ||
"devDependencies": { | ||
"@types/chai": "^4.1.7", | ||
"@types/chai": "^4.2.5", | ||
"@types/mocha": "^5.2.7", | ||
"@types/node": "^12.6.8", | ||
"@types/node": "^12.12.12", | ||
"chai": "^4.2.0", | ||
"coveralls": "^3.0.5", | ||
"cross-env": "^5.2.1", | ||
"dprint": "^0.2.0", | ||
"mocha": "^6.2.0", | ||
"coveralls": "^3.0.8", | ||
"cross-env": "^6.0.3", | ||
"dprint": "^0.7.3", | ||
"dprint-plugin-jsonc": "^0.2.4", | ||
"dprint-plugin-typescript": "^0.10.0", | ||
"mocha": "^6.2.2", | ||
"nyc": "^14.1.1", | ||
"source-map-support": "^0.5.12", | ||
"ts-node": "^8.3.0", | ||
"typescript": "^3.5.3" | ||
"source-map-support": "^0.5.16", | ||
"ts-node": "^8.5.2", | ||
"typescript": "^3.7.2" | ||
} | ||
} |
@@ -97,2 +97,3 @@ code-block-writer | ||
* `iterateLastChars<T>(action: (char: string, index: number) => T | undefined): T | undefined` - Iterates over the writer's characters in reverse order, stopping once a non-null or undefined value is returned and returns that value. | ||
* `iterateLastCharCodes<T>(action: (charCode: number, index: number) => T | undefined): T | undefined` - A slightly faster version of `iterateLastChars` that doesn't allocate a string per character. | ||
* `getOptions()` - Gets the writer options. | ||
@@ -99,0 +100,0 @@ * `toString()` - Gets the string. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
137583
1022
109
14
10