JavaScript: fix edge cases in type cast comment detection regex (#5793)
Fix edge cases involving {...} ([record @type](http://usejsdoc.org/tags-type.html)) and newlines in prettier's detection code for type cast comments
This commit is contained in:
1 parent
847a78e8e9
commit
47da0804a9
4 files changed
+122
-1
No files matched your search
@@ -67,3 +67,20 @@ Examples:
|
||||
<!-- Output (Prettier master) -->
|
||||
Prix·:·32·€
|
||||
```
|
||||
|
||||
- JavaScript: fix record type cast comment detection ([#5793] by [@yangsu])
|
||||
|
||||
Previously, type cast comments with record types were ignored and prettier
|
||||
stripped the subsequent parens. Prettier master handles these cases correctly.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```js
|
||||
// Input
|
||||
const v = /** @type {{key: number}} */ (value);
|
||||
|
||||
// Output (Prettier stable)
|
||||
const v = /** @type {{key: number}} */ value;
|
||||
|
||||
// Output (Prettier master)
|
||||
const v = /** @type {{key: number}} */ (value);
|
||||
```
|
||||
@@ -34,11 +34,37 @@ function hasClosureCompilerTypeCastComment(text, path, locStart, locEnd) {
|
||||
comment =>
|
||||
comment.leading &&
|
||||
comments.isBlockComment(comment) &&
|
||||
comment.value.match(/^\*\s*@type\s*{[^}]+}\s*$/) &&
|
||||
isTypeCastComment(comment.value) &&
|
||||
util.getNextNonSpaceNonCommentCharacter(text, comment, locEnd) === "("
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function isTypeCastComment(comment) {
|
||||
const trimmed = comment.trim();
|
||||
if (!/^\*\s*@type\s*\{[^]+\}$/.test(trimmed)) {
|
||||
return false;
|
||||
}
|
||||
let isCompletelyClosed = false;
|
||||
let unpairedBracketCount = 0;
|
||||
for (const char of trimmed) {
|
||||
if (char === "{") {
|
||||
if (isCompletelyClosed) {
|
||||
return false;
|
||||
}
|
||||
unpairedBracketCount++;
|
||||
} else if (char === "}") {
|
||||
if (unpairedBracketCount === 0) {
|
||||
return false;
|
||||
}
|
||||
unpairedBracketCount--;
|
||||
if (unpairedBracketCount === 0) {
|
||||
isCompletelyClosed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return unpairedBracketCount === 0;
|
||||
}
|
||||
}
|
||||
|
||||
function needsParens(path, options) {
|
||||
|
||||
@@ -350,6 +350,32 @@ var newArray = /** @type {array} */ (numberOrString).map(x => x);
|
||||
var newArray = /** @type {array} */ ((numberOrString)).map(x => x);
|
||||
var newArray = /** @type {array} */ ((numberOrString).map(x => x));
|
||||
|
||||
|
||||
const data = functionCall(
|
||||
arg1,
|
||||
arg2,
|
||||
/** @type {{height: number, width: number}} */ (arg3));
|
||||
|
||||
// Invalid type casts
|
||||
const v = /** @type {} */ (value);
|
||||
const v = /** @type {}} */ (value);
|
||||
const v = /** @type } */ (value);
|
||||
const v = /** @type { */ (value);
|
||||
const v = /** @type {{} */ (value);
|
||||
|
||||
const style = /** @type {{
|
||||
width: number,
|
||||
height: number,
|
||||
marginTop: number,
|
||||
marginLeft: number,
|
||||
marginRight: number,
|
||||
marginBottom: number,
|
||||
}} */ ({
|
||||
width,
|
||||
height,
|
||||
...margins,
|
||||
});
|
||||
|
||||
=====================================output=====================================
|
||||
// test to make sure comments are attached correctly
|
||||
let inlineComment = /* some comment */ someReallyLongFunctionCall(
|
||||
@@ -374,6 +400,32 @@ var newArray = /** @type {array} */ (numberOrString).map(x => x);
|
||||
var newArray = /** @type {array} */ (numberOrString).map(x => x);
|
||||
var newArray = /** @type {array} */ (numberOrString.map(x => x));
|
||||
|
||||
const data = functionCall(
|
||||
arg1,
|
||||
arg2,
|
||||
/** @type {{height: number, width: number}} */ (arg3)
|
||||
);
|
||||
|
||||
// Invalid type casts
|
||||
const v = /** @type {} */ value;
|
||||
const v = /** @type {}} */ value;
|
||||
const v = /** @type } */ value;
|
||||
const v = /** @type { */ value;
|
||||
const v = /** @type {{} */ value;
|
||||
|
||||
const style = /** @type {{
|
||||
width: number,
|
||||
height: number,
|
||||
marginTop: number,
|
||||
marginLeft: number,
|
||||
marginRight: number,
|
||||
marginBottom: number,
|
||||
}} */ ({
|
||||
width,
|
||||
height,
|
||||
...margins
|
||||
});
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
|
||||
@@ -18,3 +18,29 @@ function returnValue() {
|
||||
var newArray = /** @type {array} */ (numberOrString).map(x => x);
|
||||
var newArray = /** @type {array} */ ((numberOrString)).map(x => x);
|
||||
var newArray = /** @type {array} */ ((numberOrString).map(x => x));
|
||||
|
||||
|
||||
const data = functionCall(
|
||||
arg1,
|
||||
arg2,
|
||||
/** @type {{height: number, width: number}} */ (arg3));
|
||||
|
||||
// Invalid type casts
|
||||
const v = /** @type {} */ (value);
|
||||
const v = /** @type {}} */ (value);
|
||||
const v = /** @type } */ (value);
|
||||
const v = /** @type { */ (value);
|
||||
const v = /** @type {{} */ (value);
|
||||
|
||||
const style = /** @type {{
|
||||
width: number,
|
||||
height: number,
|
||||
marginTop: number,
|
||||
marginLeft: number,
|
||||
marginRight: number,
|
||||
marginBottom: number,
|
||||
}} */ ({
|
||||
width,
|
||||
height,
|
||||
...margins,
|
||||
});
|
||||
Reference in new issue
Block a user