Browse Source

fix: get rid of CRLF (#5494)

master
Ika 4 years ago
committed by GitHub
parent
commit
952bc0cc03
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .gitattributes
  2. 3
      azure-pipelines.yml
  3. 10
      jest.config.js
  4. 4
      package.json
  5. 12
      src/common/util.js
  6. 6
      src/language-css/printer-postcss.js
  7. 1
      src/language-html/parser-html.js
  8. 34
      src/language-html/printer-html.js
  9. 21
      src/language-html/utils.js
  10. 5
      src/language-js/printer-estree.js
  11. 2
      src/language-markdown/embed.js
  12. 2
      src/language-markdown/pragma.js
  13. 33
      src/language-markdown/printer-markdown.js
  14. 2
      src/language-markdown/utils.js
  15. 6
      src/language-yaml/parser-yaml.js
  16. 12
      src/language-yaml/printer-yaml.js
  17. 4
      src/language-yaml/utils.js
  18. 138
      src/main/core.js
  19. 56
      tests/comments_jsx_same_line/jsx_same_line.js
  20. 72
      tests/decorators/mobx.js
  21. 2
      tests/directives/escaped.js
  22. 129
      tests/end_of_line/__snapshots__/jsfmt.spec.js.snap
  23. 0
      tests/end_of_line/example.js
  24. 1
      tests/end_of_line/jsfmt.spec.js
  25. 3
      tests/end_of_line/usingCrlf.js
  26. 137
      tests/end_of_line_in_css/__snapshots__/jsfmt.spec.js.snap
  27. 4
      tests/end_of_line_in_css/jsfmt.spec.js
  28. 3
      tests/end_of_line_in_css/usingCrlf.css
  29. 3
      tests/end_of_line_in_css/usingLf.css
  30. 137
      tests/end_of_line_in_markdown/__snapshots__/jsfmt.spec.js.snap
  31. 4
      tests/end_of_line_in_markdown/jsfmt.spec.js
  32. 3
      tests/end_of_line_in_markdown/usingCrlf.md
  33. 3
      tests/end_of_line_in_markdown/usingLf.md
  34. 12
      tests/flow/malformed_code/text.js
  35. 132
      tests/interface/break.js
  36. 4
      tests/jsx-newlines/windows.js
  37. 262
      tests/jsx/expression.js
  38. 10
      tests/line/windows.js
  39. 20
      tests/multiparser_vue/lang-ts.vue
  40. 14
      tests/multiparser_vue/lang-tsx.vue
  41. 2
      tests/quotes/strings.js
  42. 8
      tests/typescript/compiler/ClassDeclaration22.ts
  43. 16
      tests/typescript/compiler/castOfAwait.ts
  44. 22
      tests/typescript/compiler/castParentheses.ts
  45. 60
      tests/typescript/compiler/castTest.ts
  46. 32
      tests/typescript/compiler/checkInfiniteExpansionTermination.ts
  47. 8
      tests/typescript/compiler/commentInNamespaceDeclarationWithIdentifierPathName.ts
  48. 8
      tests/typescript/compiler/contextualSignatureInstantiation2.ts
  49. 20
      tests/typescript/compiler/declareDottedModuleName.ts
  50. 74
      tests/typescript/compiler/decrementAndIncrementOperators.ts
  51. 6
      tests/typescript/compiler/errorOnInitializerInInterfaceProperty.ts
  52. 32
      tests/typescript/compiler/es5ExportDefaultClassDeclaration4.ts
  53. 22
      tests/typescript/compiler/functionOverloadsOnGenericArity1.ts
  54. 30
      tests/typescript/compiler/globalIsContextualKeyword.ts
  55. 14
      tests/typescript/compiler/indexSignatureWithInitializer.ts
  56. 36
      tests/typescript/compiler/mappedTypeWithCombinedTypeMappers.ts
  57. 4
      tests/typescript/compiler/modifiersOnInterfaceIndexSignature1.ts
  58. 304
      tests/typescript/compiler/privacyGloImport.ts
  59. 52
      tests/typescript/conformance/ambient/ambientDeclarations.ts
  60. 14
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAccessor.ts
  61. 8
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAsIdentifier.ts
  62. 10
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAssignabilityConstructorFunction.ts
  63. 24
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractClinterfaceAssignability.ts
  64. 26
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts
  65. 16
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractCrashedOnce.ts
  66. 30
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractExtends.ts
  67. 32
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts
  68. 48
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts
  69. 14
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts
  70. 12
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInAModule.ts
  71. 40
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts
  72. 38
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts
  73. 98
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts
  74. 12
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMethodInNonAbstractClass.ts
  75. 4
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMethodWithImplementation.ts
  76. 28
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMixedWithModifiers.ts
  77. 46
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverloads.ts
  78. 44
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverrideWithAbstract.ts
  79. 24
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts
  80. 22
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts
  81. 50
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSuperCalls.ts
  82. 32
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethod1.ts
  83. 52
      tests/typescript/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethods2.ts
  84. 14
      tests/typescript/conformance/classes/classDeclarations/classHeritageSpecification/classAppearsToHaveMembersOfObject.ts
  85. 60
      tests/typescript/conformance/classes/classDeclarations/classHeritageSpecification/classExtendingClass.ts
  86. 20
      tests/typescript/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts
  87. 14
      tests/typescript/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts
  88. 4
      tests/typescript/conformance/classes/classDeclarations/classInsideBlock.ts
  89. 20
      tests/typescript/conformance/classes/classExpression.ts
  90. 20
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/constructorDefaultValuesReferencingThis.ts
  91. 38
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/constructorImplementationWithDefaultValues.ts
  92. 38
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/constructorImplementationWithDefaultValues2.ts
  93. 24
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/constructorOverloadsWithDefaultValues.ts
  94. 24
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/constructorOverloadsWithOptionalParameters.ts
  95. 40
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/constructorParameterProperties.ts
  96. 62
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/constructorParameterProperties2.ts
  97. 8
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/declarationEmitReadonly.ts
  98. 76
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/readonlyConstructorAssignment.ts
  99. 24
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/readonlyInConstructorParameters.ts
  100. 6
      tests/typescript/conformance/classes/constructorDeclarations/constructorParameters/readonlyReadonly.ts

5
.gitattributes

@ -1,4 +1 @@
# Make sure baseline files have consistent line endings
*.txt text eol=lf
*.snap text eol=lf
*.debug-check text eol=lf
* text=auto eol=lf

3
azure-pipelines.yml

@ -1,6 +1,6 @@
trigger:
- master
- releases-*
- release-*
variables:
AST_COMPARE: true
@ -31,6 +31,7 @@ jobs:
vmImage: vs2017-win2016
variables:
node_version: 10
TEST_CRLF: true
steps:
- template: .azure-pipelines/dev.yml

10
jest.config.js

@ -17,13 +17,9 @@ module.exports = {
"jest-snapshot-serializer-ansi"
],
testRegex: "jsfmt\\.spec\\.js$|__tests__/.*\\.js$",
testPathIgnorePatterns: ["tests/new_react", "tests/more_react"]
.concat(isOldNode ? requiresPrettierInternals : [])
.concat(
require("os").EOL == "\n"
? ["tests_integration/__tests__/eol-crlf.js"]
: ["tests_integration/__tests__/eol-lf.js"]
),
testPathIgnorePatterns: ["tests/new_react", "tests/more_react"].concat(
isOldNode ? requiresPrettierInternals : []
),
collectCoverage: ENABLE_COVERAGE,
collectCoverageFrom: ["src/**/*.js", "index.js", "!<rootDir>/node_modules/"],
coveragePathIgnorePatterns: [

4
package.json

@ -71,8 +71,8 @@
"unicode-regex": "2.0.0",
"unified": "6.1.6",
"vnopts": "1.0.2",
"yaml": "1.0.0-rc.8",
"yaml-unist-parser": "1.0.0-rc.4"
"yaml": "1.0.2",
"yaml-unist-parser": "1.0.0"
},
"devDependencies": {
"@babel/cli": "7.1.5",

12
src/common/util.js

@ -675,7 +675,19 @@ function isWithinParentArrayProperty(path, propertyName) {
return parent[propertyName][key] === node;
}
function replaceEndOfLineWith(text, replacement) {
const parts = [];
for (const part of text.split("\n")) {
if (parts.length !== 0) {
parts.push(replacement);
}
parts.push(part);
}
return parts;
}
module.exports = {
replaceEndOfLineWith,
getStringWidth,
getMaxContinuousCount,
getPrecedence,

6
src/language-css/printer-postcss.js

@ -110,11 +110,7 @@ function genericPrint(path, options, print) {
}
case "css-comment": {
if (node.raws.content) {
return (
node.raws.content
// there's a bug in the less parser that trailing `\r`s are included in inline comments
.replace(/^(\/\/[^]+)\r+$/, "$1")
);
return node.raws.content;
}
const text = options.originalText.slice(
options.locStart(node),

1
src/language-html/parser-html.js

@ -265,7 +265,6 @@ function createParser({
allowHtmComponentClosingTags = false
} = {}) {
return {
preprocess: text => text.replace(/\r\n?/g, "\n"),
parse: (text, parsers, options) =>
_parse(text, options, {
recognizeSelfClosing,

34
src/language-html/printer-html.js

@ -34,12 +34,11 @@ const {
isTextLikeNode,
normalizeParts,
preferHardlineAsLeadingSpaces,
replaceDocNewlines,
replaceNewlines,
shouldNotPrintClosingTag,
shouldPreserveContent,
unescapeQuoteEntities
} = require("./utils");
const { replaceEndOfLineWith } = require("../common/util");
const preprocess = require("./preprocess");
const assert = require("assert");
const { insertPragma } = require("./pragma");
@ -147,10 +146,7 @@ function embed(path, print, textToDoc, options) {
hardline,
node.value.trim().length === 0
? ""
: replaceDocNewlines(
textToDoc(node.value, { parser: "yaml" }),
literalline
),
: textToDoc(node.value, { parser: "yaml" }),
"---"
])
);
@ -287,7 +283,7 @@ function genericPrint(path, options, print) {
? node.value.replace(trailingNewlineRegex, "")
: node.value;
return concat([
concat(replaceNewlines(value, literalline)),
concat(replaceEndOfLineWith(value, literalline)),
hasTrailingNewline ? hardline : ""
]);
}
@ -316,7 +312,7 @@ function genericPrint(path, options, print) {
return concat([
printOpeningTagPrefix(node, options),
concat(
replaceNewlines(
replaceEndOfLineWith(
options.originalText.slice(
options.locStart(node),
options.locEnd(node)
@ -341,7 +337,7 @@ function genericPrint(path, options, print) {
"=",
quote,
concat(
replaceNewlines(
replaceEndOfLineWith(
quote === '"'
? value.replace(/"/g, "&quot;")
: value.replace(/'/g, "&apos;"),
@ -354,7 +350,7 @@ function genericPrint(path, options, print) {
}
case "yaml":
case "toml":
return node.raw;
return concat(replaceEndOfLineWith(node.raw, literalline));
default:
throw new Error(`Unexpected node type ${node.type}`);
}
@ -473,7 +469,7 @@ function printChildren(path, options, print) {
return concat(
[].concat(
printOpeningTagPrefix(child, options),
replaceNewlines(
replaceEndOfLineWith(
options.originalText.slice(
options.locStart(child) +
(child.prev &&
@ -497,7 +493,7 @@ function printChildren(path, options, print) {
[].concat(
printOpeningTagPrefix(child, options),
group(printOpeningTag(childPath, options, print)),
replaceNewlines(
replaceEndOfLineWith(
options.originalText.slice(
child.startSourceSpan.end.offset +
(child.firstChild &&
@ -620,7 +616,7 @@ function printOpeningTag(path, options, print) {
const attr = attrPath.getValue();
return hasPrettierIgnoreAttribute(attr)
? concat(
replaceNewlines(
replaceEndOfLineWith(
options.originalText.slice(
options.locStart(attr),
options.locEnd(attr)
@ -894,8 +890,8 @@ function printClosingTagEndMarker(node, options) {
function getTextValueParts(node, value = node.value) {
return node.parent.isWhitespaceSensitive
? node.parent.isIndentationSensitive
? replaceNewlines(value, literalline)
: replaceNewlines(
? replaceEndOfLineWith(value, literalline)
: replaceEndOfLineWith(
dedentString(value.replace(/^\s*?\n|\n\s*?$/g, "")),
hardline
)
@ -1037,7 +1033,7 @@ function printEmbeddedAttributeValue(node, originalTextToDoc, options) {
const parts = [];
value.split(interpolationRegex).forEach((part, index) => {
if (index % 2 === 0) {
parts.push(concat(replaceNewlines(part, literalline)));
parts.push(concat(replaceEndOfLineWith(part, literalline)));
} else {
try {
parts.push(
@ -1056,7 +1052,11 @@ function printEmbeddedAttributeValue(node, originalTextToDoc, options) {
)
);
} catch (e) {
parts.push("{{", concat(replaceNewlines(part, literalline)), "}}");
parts.push(
"{{",
concat(replaceEndOfLineWith(part, literalline)),
"}}"
);
}
}
});

21
src/language-html/utils.js

@ -1,10 +1,5 @@
"use strict";
const {
builders: { concat },
utils: { mapDoc }
} = require("../doc");
const {
CSS_DISPLAY_TAGS,
CSS_DISPLAY_DEFAULT,
@ -263,20 +258,6 @@ function isDanglingSpaceSensitiveNode(node) {
);
}
function replaceNewlines(text, replacement) {
return text
.split(/(\n)/g)
.map((data, index) => (index % 2 === 1 ? replacement : data));
}
function replaceDocNewlines(doc, replacement) {
return mapDoc(doc, currentDoc =>
typeof currentDoc === "string" && currentDoc.includes("\n")
? concat(replaceNewlines(currentDoc, replacement))
: currentDoc
);
}
function forceNextEmptyLine(node) {
return (
isFrontMatterNode(node) ||
@ -645,8 +626,6 @@ module.exports = {
normalizeParts,
preferHardlineAsLeadingSpaces,
preferHardlineAsTrailingSpaces,
replaceDocNewlines,
replaceNewlines,
shouldNotPrintClosingTag,
shouldPreserveContent,
unescapeQuoteEntities

5
src/language-js/printer-estree.js

@ -2395,7 +2395,10 @@ function printPathNoParens(path, options, print, args) {
"${" +
printDocToString(
doc,
Object.assign({}, options, { printWidth: Infinity })
Object.assign({}, options, {
printWidth: Infinity,
endOfLine: "lf"
})
).formatted +
"}"
);

2
src/language-markdown/embed.js

@ -42,7 +42,7 @@ function embed(path, print, textToDoc, options) {
concat([
"---",
hardline,
node.value.trim()
node.value && node.value.trim()
? replaceNewlinesWithLiterallines(
textToDoc(node.value, { parser: "yaml" })
)

2
src/language-markdown/pragma.js

@ -9,7 +9,7 @@ function startWithPragma(text) {
const regex = new RegExp(
[
`<!--\\s*${pragma}\\s*-->`,
`<!--.*\n[\\s\\S]*(^|\n)[^\\S\n]*${pragma}[^\\S\n]*($|\n)[\\s\\S]*\n.*-->`
`<!--.*\r?\n[\\s\\S]*(^|\n)[^\\S\n]*${pragma}[^\\S\n]*($|\n)[\\s\\S]*\n.*-->`
].join("|"),
"m"
);

33
src/language-markdown/printer-markdown.js

@ -27,6 +27,7 @@ const {
splitText,
punctuationPattern
} = require("./utils");
const { replaceEndOfLineWith } = require("../common/util");
const TRAILING_HARDLINE_NODES = ["importExport"];
@ -209,7 +210,10 @@ function genericPrint(path, options, print) {
const alignment = " ".repeat(4);
return align(
alignment,
concat([alignment, replaceNewlinesWith(node.value, hardline)])
concat([
alignment,
concat(replaceEndOfLineWith(node.value, hardline))
])
);
}
@ -225,9 +229,11 @@ function genericPrint(path, options, print) {
style,
node.lang || "",
hardline,
replaceNewlinesWith(
getFencedCodeBlockValue(node, options.originalText),
hardline
concat(
replaceEndOfLineWith(
getFencedCodeBlockValue(node, options.originalText),
hardline
)
),
hardline,
style
@ -247,9 +253,11 @@ function genericPrint(path, options, print) {
? node.value.trimRight()
: node.value;
const isHtmlComment = /^<!--[\s\S]*-->$/.test(value);
return replaceNewlinesWith(
value,
isHtmlComment ? hardline : markAsRoot(literalline)
return concat(
replaceEndOfLineWith(
value,
isHtmlComment ? hardline : markAsRoot(literalline)
)
);
}
case "list": {
@ -394,7 +402,7 @@ function genericPrint(path, options, print) {
? concat([" ", markAsRoot(literalline)])
: concat(["\\", hardline]);
case "liquidNode":
return replaceNewlinesWith(node.value, hardline);
return concat(replaceEndOfLineWith(node.value, hardline));
// MDX
case "importExport":
case "jsx":
@ -404,7 +412,10 @@ function genericPrint(path, options, print) {
"$$",
hardline,
node.value
? concat([replaceNewlinesWith(node.value, hardline), hardline])
? concat([
concat(replaceEndOfLineWith(node.value, hardline)),
hardline
])
: "",
"$$"
]);
@ -467,10 +478,6 @@ function getNthListSiblingIndex(node, parentNode) {
);
}
function replaceNewlinesWith(str, doc) {
return join(doc, str.replace(/\r\n?/g, "\n").split("\n"));
}
function getNthSiblingIndex(node, parentNode, condition) {
condition = condition || (() => true);

2
src/language-markdown/utils.js

@ -148,7 +148,7 @@ function getFencedCodeBlockValue(node, originalText) {
const leadingSpaceCount = text.match(/^\s*/)[0].length;
const replaceRegex = new RegExp(`^\\s{0,${leadingSpaceCount}}`);
const lineContents = text.replace(/\r\n?/g, "\n").split("\n");
const lineContents = text.split("\n");
const markerStyle = text[leadingSpaceCount]; // ` or ~
const marker = text

6
src/language-yaml/parser-yaml.js

@ -29,11 +29,7 @@ const parser = {
parse,
hasPragma,
locStart: node => node.position.start.offset,
locEnd: node => node.position.end.offset,
// workaround for https://github.com/eemeli/yaml/issues/20
preprocess: text =>
text.indexOf("\r") === -1 ? text : text.replace(/\r\n?/g, "\n")
locEnd: node => node.position.end.offset
};
module.exports = {

12
src/language-yaml/printer-yaml.js

@ -38,6 +38,7 @@ const {
markAsRoot,
softline
} = docBuilders;
const { replaceEndOfLineWith } = require("../common/util");
function preprocess(ast) {
return mapNode(ast, defineShortcuts);
@ -104,9 +105,14 @@ function genericPrint(path, options, print) {
])
: "",
hasPrettierIgnore(path)
? options.originalText.slice(
node.position.start.offset,
node.position.end.offset
? concat(
replaceEndOfLineWith(
options.originalText.slice(
node.position.start.offset,
node.position.end.offset
),
literalline
)
)
: group(_print(node, parentNode, path, options, print)),
hasTrailingComment(node) && !isNode(node, ["document", "documentHead"])

4
src/language-yaml/utils.js

@ -1,8 +1,6 @@
"use strict";
function getLast(array) {
return array[array.length - 1];
}
const { getLast } = require("../common/util");
function getAncestorCount(path, filter) {
let counter = 0;

138
src/main/core.js

@ -14,6 +14,7 @@ const {
const rangeUtil = require("./range-util");
const privateUtil = require("../common/util");
const {
utils: { mapDoc },
printer: { printDocToString },
debug: { printDocToDebug }
} = require("../doc");
@ -21,6 +22,11 @@ const {
const UTF8BOM = 0xfeff;
const CURSOR = Symbol("cursor");
const PLACEHOLDERS = {
cursorOffset: "<<<PRETTIER_CURSOR>>>",
rangeStart: "<<<PRETTIER_RANGE_START>>>",
rangeEnd: "<<<PRETTIER_RANGE_END>>>"
};
function ensureAllCommentsPrinted(astComments) {
if (!astComments) {
@ -67,8 +73,6 @@ function coreFormat(text, opts, addAlignmentSize) {
const parsed = parser.parse(text, opts);
const ast = parsed.ast;
const originalText = text;
text = parsed.text;
if (opts.cursorOffset >= 0) {
@ -80,11 +84,18 @@ function coreFormat(text, opts, addAlignmentSize) {
const astComments = attachComments(text, ast, opts);
const doc = printAstToDoc(ast, opts, addAlignmentSize);
if (opts.endOfLine === "auto") {
opts.endOfLine = guessEndOfLine(originalText);
}
const result = printDocToString(doc, opts);
const eol = convertEndOfLineToChars(opts.endOfLine);
const result = printDocToString(
opts.endOfLine === "lf"
? doc
: mapDoc(doc, currentDoc =>
typeof currentDoc === "string" && currentDoc.indexOf("\n") !== -1
? currentDoc.replace(/\n/g, eol)
: currentDoc
),
opts
);
ensureAllCommentsPrinted(astComments);
// Remove extra leading indentation as well as the added indentation after last newline
@ -212,8 +223,8 @@ function formatRange(text, opts) {
// Since the range contracts to avoid trailing whitespace,
// we need to remove the newline that was inserted by the `format` call.
const rangeTrimmed = rangeResult.formatted.trimRight();
const formatted =
text.slice(0, rangeStart) + rangeTrimmed + text.slice(rangeEnd);
const rangeLeft = text.slice(0, rangeStart);
const rangeRight = text.slice(rangeEnd);
let cursorOffset = opts.cursorOffset;
if (opts.cursorOffset >= rangeEnd) {
@ -226,6 +237,44 @@ function formatRange(text, opts) {
}
// keep the cursor as it was if it was before the start of the range
let formatted;
if (opts.endOfLine === "lf") {
formatted = rangeLeft + rangeTrimmed + rangeRight;
} else {
const eol = convertEndOfLineToChars(opts.endOfLine);
if (cursorOffset >= 0) {
const parts = [rangeLeft, rangeTrimmed, rangeRight];
let partIndex = 0;
let partOffset = cursorOffset;
while (partIndex < parts.length) {
const part = parts[partIndex];
if (partOffset < part.length) {
parts[partIndex] =
parts[partIndex].slice(0, partOffset) +
PLACEHOLDERS.cursorOffset +
parts[partIndex].slice(partOffset);
break;
}
partIndex++;
partOffset -= part.length;
}
const [newRangeLeft, newRangeTrimmed, newRangeRight] = parts;
formatted = (
newRangeLeft.replace(/\n/g, eol) +
newRangeTrimmed +
newRangeRight.replace(/\n/g, eol)
).replace(PLACEHOLDERS.cursorOffset, (_, index) => {
cursorOffset = index;
return "";
});
} else {
formatted =
rangeLeft.replace(/\n/g, eol) +
rangeTrimmed +
rangeRight.replace(/\n/g, eol);
}
}
return { formatted, cursorOffset };
}
@ -236,23 +285,83 @@ function format(text, opts) {
return { formatted: text };
}
if (opts.rangeStart > 0 || opts.rangeEnd < text.length) {
return formatRange(text, opts);
if (opts.endOfLine === "auto") {
opts.endOfLine = guessEndOfLine(text);
}
const hasCursor = opts.cursorOffset >= 0;
const hasRangeStart = opts.rangeStart > 0;
const hasRangeEnd = opts.rangeEnd < text.length;
// get rid of CR/CRLF parsing
if (text.indexOf("\r") !== -1) {
const offsetKeys = [
hasCursor && "cursorOffset",
hasRangeStart && "rangeStart",
hasRangeEnd && "rangeEnd"
]
.filter(Boolean)
.sort((aKey, bKey) => opts[aKey] - opts[bKey]);
for (let i = offsetKeys.length - 1; i >= 0; i--) {
const key = offsetKeys[i];
text =
text.slice(0, opts[key]) + PLACEHOLDERS[key] + text.slice(opts[key]);
}
text = text.replace(/\r\n?/g, "\n");
for (let i = 0; i < offsetKeys.length; i++) {
const key = offsetKeys[i];
text = text.replace(PLACEHOLDERS[key], (_, index) => {
opts[key] = index;
return "";
});
}
}
const hasUnicodeBOM = text.charCodeAt(0) === UTF8BOM;
if (hasUnicodeBOM) {
text = text.substring(1);
if (hasCursor) {
opts.cursorOffset++;
}
if (hasRangeStart) {
opts.rangeStart++;
}
if (hasRangeEnd) {
opts.rangeEnd++;
}
}
if (opts.insertPragma && opts.printer.insertPragma && !hasPragma) {
text = opts.printer.insertPragma(text);
if (!hasCursor) {
opts.cursorOffset = -1;
}
if (opts.rangeStart < 0) {
opts.rangeStart = 0;
}
if (opts.rangeEnd > text.length) {
opts.rangeEnd = text.length;
}
const result = coreFormat(text, opts);
const result =
hasRangeStart || hasRangeEnd
? formatRange(text, opts)
: coreFormat(
opts.insertPragma && opts.printer.insertPragma && !hasPragma
? opts.printer.insertPragma(text)
: text,
opts
);
if (hasUnicodeBOM) {
result.formatted = String.fromCharCode(UTF8BOM) + result.formatted;
if (hasCursor) {
result.cursorOffset++;
}
}
return result;
}
@ -264,6 +373,9 @@ module.exports = {
parse(text, opts, massage) {
opts = normalizeOptions(opts);
if (text.indexOf("\r") !== -1) {
text = text.replace(/\r\n?/g, "\n");
}
const parsed = parser.parse(text, opts);
if (massage) {
parsed.ast = massageAST(parsed.ast, opts);

56
tests/comments_jsx_same_line/jsx_same_line.js

@ -1,28 +1,28 @@
<div
// comment
>
{foo}
</div>;
<div
// comment
attr="foo"
>
{foo}
</div>;
<div
attr="foo" // comment
>
{foo}
</div>;
<div
attr="foo"
// comment
>
{foo}
</div>;
<br // comment
/>;
<div
// comment
>
{foo}
</div>;
<div
// comment
attr="foo"
>
{foo}
</div>;
<div
attr="foo" // comment
>
{foo}
</div>;
<div
attr="foo"
// comment
>
{foo}
</div>;
<br // comment
/>;

72
tests/decorators/mobx.js

@ -1,36 +1,36 @@
import {observable} from "mobx";
@observer class OrderLine {
@observable price:number = 0;
@observable amount:number = 1;
constructor(price) {
this.price = price;
}
@computed get total() {
return this.price * this.amount;
}
@action.bound setPrice(price) {
this.price = price;
}
@computed
get total() {
return this.price * this.amount;
}
@action.bound
setPrice(price) {
this.price = price;
}
@computed @computed @computed @computed @computed @computed @computed get total() {
return this.price * this.amount;
}
@action handleDecrease = (event: React.ChangeEvent<HTMLInputElement>) => this.count--;
@action handleSomething = (event: React.ChangeEvent<HTMLInputElement>) => doSomething();
}
import {observable} from "mobx";
@observer class OrderLine {
@observable price:number = 0;
@observable amount:number = 1;
constructor(price) {
this.price = price;
}
@computed get total() {
return this.price * this.amount;
}
@action.bound setPrice(price) {
this.price = price;
}
@computed
get total() {
return this.price * this.amount;
}
@action.bound
setPrice(price) {
this.price = price;
}
@computed @computed @computed @computed @computed @computed @computed get total() {
return this.price * this.amount;
}
@action handleDecrease = (event: React.ChangeEvent<HTMLInputElement>) => this.count--;
@action handleSomething = (event: React.ChangeEvent<HTMLInputElement>) => doSomething();
}

2
tests/directives/escaped.js

@ -29,7 +29,7 @@
'meaningfully escaped alphabetical characters \n \r \v \t \b \f \u2713 \x61'
'escaped newline \
'
'escaped carriage return \
'escaped carriage return \
'
'escaped \u2028 \
'
'escaped \u2029 \
'

129
tests/end_of_line/__snapshots__/jsfmt.spec.js.snap

@ -1,145 +1,58 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`usingCrlf.js 1`] = `
====================================options=====================================
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
=====================================output=====================================
function f() {
console.log("testing line endings");
}
================================================================================
`;
exports[`usingCrlf.js 2`] = `
exports[`example.js 1`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
=====================================output=====================================
function f() {/*CR*/ console.log("testing line endings");/*CR*/}/*CR*/
================================================================================
`;
exports[`usingCrlf.js 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
=====================================output=====================================
function f() {/*CR*/
console.log("testing line endings");/*CR*/
}/*CR*/
================================================================================
`;
exports[`usingCrlf.js 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
=====================================output=====================================
function f() {
console.log("testing line endings");
}
================================================================================
`;
exports[`usingLf.js 1`] = `
====================================options=====================================
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
function f() {<LF>
console.log("testing line endings");<LF>
}<LF>
=====================================output=====================================
function f() {
console.log("testing line endings");
}
================================================================================
`;
exports[`usingLf.js 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
function f() {<CR>
console.log("testing line endings");<CR>
}<CR>
=====================================output=====================================
function f() {/*CR*/ console.log("testing line endings");/*CR*/}/*CR*/
================================================================================
`;
exports[`usingLf.js 3`] = `
exports[`example.js 2`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
function f() {<LF>
console.log("testing line endings");<LF>
}<LF>
=====================================output=====================================
function f() {/*CR*/
console.log("testing line endings");/*CR*/
}/*CR*/
function f() {<CRLF>
console.log("testing line endings");<CRLF>
}<CRLF>
================================================================================
`;
exports[`usingLf.js 4`] = `
exports[`example.js 3`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["babylon"]
printWidth: 80
| printWidth
=====================================input======================================
function f() {
console.log("testing line endings");
}
function f() {<LF>
console.log("testing line endings");<LF>
}<LF>
=====================================output=====================================
function f() {
console.log("testing line endings");
}
function f() {<LF>
console.log("testing line endings");<LF>
}<LF>
================================================================================
`;

0
tests/end_of_line/usingLf.js → tests/end_of_line/example.js

1
tests/end_of_line/jsfmt.spec.js

@ -1,4 +1,3 @@
run_spec(__dirname, ["babylon"]);
run_spec(__dirname, ["babylon"], { endOfLine: "cr" });
run_spec(__dirname, ["babylon"], { endOfLine: "crlf" });
run_spec(__dirname, ["babylon"], { endOfLine: "lf" });

3
tests/end_of_line/usingCrlf.js

@ -1,3 +0,0 @@
function f() {
console.log("testing line endings");
}

137
tests/end_of_line_in_css/__snapshots__/jsfmt.spec.js.snap

@ -1,137 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`usingCrlf.css 1`] = `
====================================options=====================================
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {
margin: 42px;
}
================================================================================
`;
exports[`usingCrlf.css 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {/*CR*/ margin: 42px;/*CR*/}/*CR*/
================================================================================
`;
exports[`usingCrlf.css 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {/*CR*/
margin: 42px;/*CR*/
}/*CR*/
================================================================================
`;
exports[`usingCrlf.css 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {
margin: 42px;
}
================================================================================
`;
exports[`usingLf.css 1`] = `
====================================options=====================================
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {
margin: 42px;
}
================================================================================
`;
exports[`usingLf.css 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {/*CR*/ margin: 42px;/*CR*/}/*CR*/
================================================================================
`;
exports[`usingLf.css 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {/*CR*/
margin: 42px;/*CR*/
}/*CR*/
================================================================================
`;
exports[`usingLf.css 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["css"]
printWidth: 80
| printWidth
=====================================input======================================
.foo {
margin: 42px;
}
=====================================output=====================================
.foo {
margin: 42px;
}
================================================================================
`;

4
tests/end_of_line_in_css/jsfmt.spec.js

@ -1,4 +0,0 @@
run_spec(__dirname, ["css"]);
run_spec(__dirname, ["css"], { endOfLine: "cr" });
run_spec(__dirname, ["css"], { endOfLine: "crlf" });
run_spec(__dirname, ["css"], { endOfLine: "lf" });

3
tests/end_of_line_in_css/usingCrlf.css

@ -1,3 +0,0 @@
.foo {
margin: 42px;
}

3
tests/end_of_line_in_css/usingLf.css

@ -1,3 +0,0 @@
.foo {
margin: 42px;
}

137
tests/end_of_line_in_markdown/__snapshots__/jsfmt.spec.js.snap

@ -1,137 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`usingCrlf.md 1`] = `
====================================options=====================================
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file
testing line endings
================================================================================
`;
exports[`usingCrlf.md 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file/*CR*//*CR*/testing line endings/*CR*/
================================================================================
`;
exports[`usingCrlf.md 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file/*CR*/
/*CR*/
testing line endings/*CR*/
================================================================================
`;
exports[`usingCrlf.md 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file
testing line endings
================================================================================
`;
exports[`usingLf.md 1`] = `
====================================options=====================================
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file
testing line endings
================================================================================
`;
exports[`usingLf.md 2`] = `
====================================options=====================================
endOfLine: "cr"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file/*CR*//*CR*/testing line endings/*CR*/
================================================================================
`;
exports[`usingLf.md 3`] = `
====================================options=====================================
endOfLine: "crlf"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file/*CR*/
/*CR*/
testing line endings/*CR*/
================================================================================
`;
exports[`usingLf.md 4`] = `
====================================options=====================================
endOfLine: "lf"
parsers: ["markdown"]
printWidth: 80
| printWidth
=====================================input======================================
# Markdown file
testing line endings
=====================================output=====================================
# Markdown file
testing line endings
================================================================================
`;

4
tests/end_of_line_in_markdown/jsfmt.spec.js

@ -1,4 +0,0 @@
run_spec(__dirname, ["markdown"]);
run_spec(__dirname, ["markdown"], { endOfLine: "cr" });
run_spec(__dirname, ["markdown"], { endOfLine: "crlf" });
run_spec(__dirname, ["markdown"], { endOfLine: "lf" });

3
tests/end_of_line_in_markdown/usingCrlf.md

@ -1,3 +0,0 @@
# Markdown file
testing line endings

3
tests/end_of_line_in_markdown/usingLf.md

@ -1,3 +0,0 @@
# Markdown file
testing line endings

12
tests/flow/malformed_code/text.js

@ -1,6 +1,6 @@
// @flow
// Example found at
// https://github.com/sebmarkbage/art/blob/51ffce8164a555d652843241c2fdda52e186cbbd/parsers/svg/text.js#L137
const evil_regex_as_a_string = "/[\s�]*$/";
const error: string = 123; // Should be an error, but can't lex this file
// @flow
// Example found at
// https://github.com/sebmarkbage/art/blob/51ffce8164a555d652843241c2fdda52e186cbbd/parsers/svg/text.js#L137
const evil_regex_as_a_string = "/[\s�]*$/";
const error: string = 123; // Should be an error, but can't lex this file

132
tests/interface/break.js

@ -1,66 +1,66 @@
export interface Environment1 extends GenericEnvironment<
SomeType,
AnotherType,
YetAnotherType,
> {
m(): void;
};
export class Environment2 extends GenericEnvironment<
SomeType,
AnotherType,
YetAnotherType,
DifferentType1,
DifferentType2,
DifferentType3,
DifferentType4,
> {
m() {};
};
// Declare Interface Break
declare interface ExtendsOne extends ASingleInterface {
x: string;
}
declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
x: string;
}
declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
x: string;
}
// Interface declaration break
interface ExtendsOne extends ASingleInterface {
x: string;
}
interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
x: string;
}
interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
s: string;
}
// Generic Types
interface ExtendsOne extends ASingleInterface<string> {
x: string;
}
interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
x: string;
}
interface ExtendsMany
extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
x: string;
}
interface ExtendsManyWithGenerics
extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
x: string;
}
export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType, ToBreakLineToBreakLineToBreakLine> {}
export interface Environment1 extends GenericEnvironment<
SomeType,
AnotherType,
YetAnotherType,
> {
m(): void;
};
export class Environment2 extends GenericEnvironment<
SomeType,
AnotherType,
YetAnotherType,
DifferentType1,
DifferentType2,
DifferentType3,
DifferentType4,
> {
m() {};
};
// Declare Interface Break
declare interface ExtendsOne extends ASingleInterface {
x: string;
}
declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
x: string;
}
declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
x: string;
}
// Interface declaration break
interface ExtendsOne extends ASingleInterface {
x: string;
}
interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
x: string;
}
interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
s: string;
}
// Generic Types
interface ExtendsOne extends ASingleInterface<string> {
x: string;
}
interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
x: string;
}
interface ExtendsMany
extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
x: string;
}
interface ExtendsManyWithGenerics
extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
x: string;
}
export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType, ToBreakLineToBreakLineToBreakLine> {}

4
tests/jsx-newlines/windows.js

@ -1,3 +1,3 @@
<div>
Text
<div>
Text
</div>

262
tests/jsx/expression.js

@ -1,131 +1,131 @@
<View
style={
{
someVeryLongStyle1: "true",
someVeryLongStyle2: "true",
someVeryLongStyle3: "true",