UNPKG

2.36 kBJavaScriptView Raw
1"use strict";
2
3const parse = require("./parser");
4const memoize = require("mem");
5
6const reHasPragma = /@prettier|@format/;
7
8const getPageLevelDocBlock = memoize((text) => {
9 const parsed = parse(text);
10
11 const [firstChild] = parsed.children;
12 const [firstDocBlock] = parsed.comments.filter(
13 (el) => el.kind === "commentblock"
14 );
15
16 if (
17 firstChild &&
18 firstDocBlock &&
19 firstDocBlock.loc.start.line < firstChild.loc.start.line
20 ) {
21 return firstDocBlock;
22 }
23});
24
25function guessLineEnding(text) {
26 const index = text.indexOf("\n");
27
28 if (index >= 0 && text.charAt(index - 1) === "\r") {
29 return "\r\n";
30 }
31
32 return "\n";
33}
34
35function hasPragma(text) {
36 // fast path optimization - check if the pragma shows up in the file at all
37 if (!reHasPragma.test(text)) {
38 return false;
39 }
40
41 const pageLevelDocBlock = getPageLevelDocBlock(text);
42
43 if (pageLevelDocBlock) {
44 const { value } = pageLevelDocBlock;
45
46 return reHasPragma.test(value);
47 }
48
49 return false;
50}
51
52function injectPragma(docblock, text) {
53 let lines = docblock.split(/\r?\n/g);
54
55 if (lines.length === 1) {
56 // normalize to multiline for simplicity
57 const [, line] = /\/*\*\*(.*)\*\//.exec(lines[0]);
58
59 lines = ["/**", ` * ${line.trim()}`, " */"];
60 }
61
62 // find the first @pragma
63 // if there happens to be one on the opening line, just put it on the next line.
64 const pragmaIndex = lines.findIndex((line) => /@\S/.test(line)) || 1;
65
66 // not found => index == -1, which conveniently will splice 1 from the end.
67 lines.splice(pragmaIndex, 0, " * @format");
68
69 return lines.join(guessLineEnding(text));
70}
71
72function insertPragma(text) {
73 const pageLevelDocBlock = getPageLevelDocBlock(text);
74
75 if (pageLevelDocBlock) {
76 const {
77 start: { offset: startOffset },
78 end: { offset: endOffset },
79 } = pageLevelDocBlock.loc;
80 const before = text.substring(0, startOffset);
81 const after = text.substring(endOffset);
82
83 return `${before}${injectPragma(pageLevelDocBlock.value, text)}${after}`;
84 }
85
86 const openTag = "<?php";
87
88 if (!text.startsWith(openTag)) {
89 // bail out
90 return text;
91 }
92
93 const splitAt = openTag.length;
94 const phpTag = text.substring(0, splitAt);
95 const after = text.substring(splitAt);
96
97 return `${phpTag}
98/**
99 * @format
100 */
101${after}`;
102}
103
104module.exports = {
105 hasPragma,
106 insertPragma,
107};