Skip to content

Commit

Permalink
fix: 🐛 unexpected indent on raw php comment block
Browse files Browse the repository at this point in the history
  • Loading branch information
shufo committed Dec 18, 2022
1 parent 7369fcb commit f896cc8
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 6 deletions.
167 changes: 167 additions & 0 deletions __tests__/formatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4824,4 +4824,171 @@ describe('formatter', () => {
endOfLine: 'CRLF',
});
});

test('fix shufo/prettier-plugin-blade#166', async () => {
const content = [
`@php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
`@endphp`,
`<span>{{ $post->title }} by {{ $user->name }}</span>`,
].join('\n');

const expected = [
`@php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
`@endphp`,
`<span>{{ $post->title }} by {{ $user->name }}</span>`,
``,
].join('\n');

await util.doubleFormatCheck(content, expected);
});

test('raw php comment block', async () => {
const content = [
`<div>`,
` <?php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` ?>`,
` <?php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */ echo 1;`,
` ?>`,
` <?php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` ?>`,
` <?php`,
` /**`,
` \App\Models\User $user`,
` \App\Models\Post $post`,
` */`,
` ?>`,
`</div>`,
].join('\n');

const expected = [
`<div>`,
` <?php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` ?>`,
` <?php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */ echo 1;`,
` ?>`,
` <?php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` ?>`,
` <?php`,
` /**`,
` \App\Models\User $user`,
` \App\Models\Post $post`,
` */`,
` ?>`,
`</div>`,
``,
].join('\n');

await util.doubleFormatCheck(content, expected);
});

test('php directive comment block', async () => {
const content = [
`<div>`,
` @php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` @endphp`,
` @php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */ echo 1;`,
` @endphp`,
` @php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` @endphp`,
` @php`,
` /**`,
` \App\Models\User $user`,
` \App\Models\Post $post`,
` */`,
` @endphp`,
`</div>`,
].join('\n');

const expected = [
`<div>`,
` @php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` @endphp`,
` @php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */ echo 1;`,
` @endphp`,
` @php`,
` /**`,
` * @var \App\Models\User $user`,
` * @var \App\Models\Post $post`,
` */`,
` @endphp`,
` @php`,
` /**`,
` \App\Models\User $user`,
` \App\Models\Post $post`,
` */`,
` @endphp`,
`</div>`,
``,
].join('\n');

await util.doubleFormatCheck(content, expected);
});
});
54 changes: 54 additions & 0 deletions src/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Formats php comment
*
* @param comment
* @returns string
*/
export function formatPhpComment(comment: string): string {
const lines = splitByLines(comment);

if (!isMultiline(lines)) {
return comment;
}

let nonCommentLineExists = false;

const mapped = lines.map((line: string, row: number) => {
if (row === 0) {
return line;
}

if (nonCommentLineExists) {
return line;
}

if (!isCommentedLine(line)) {
nonCommentLineExists = true;
return line;
}

const trimmedLine = line.trim();

return addPrefixToLine(trimmedLine);
});

return mapped.join('\n');
}

function splitByLines(content: string): Array<string> {
return content.split('\n');
}

function isCommentedLine(line: string): boolean {
return line.trim().startsWith('*');
}

function isMultiline(lines: Array<string>): boolean {
return lines.length > 1;
}

function addPrefixToLine(line: string): string {
const prefix = ' ';

return `${prefix}${line}`;
}
62 changes: 56 additions & 6 deletions src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
} from './indent';
import { nestedParenthesisRegex } from './regex';
import { SortHtmlAttributes } from './runtimeConfig';
import { formatPhpComment } from './comment';

export default class Formatter {
argumentCheck: any;
Expand Down Expand Up @@ -717,7 +718,9 @@ export default class Formatter {
}

preservePhpComment(content: string) {
return _.replace(content, /\/\*+([^\*]*?)\*\//gi, (match: string) => this.storePhpComment(match));
return _.replace(content, /\/\*(?:[^*]|[\r\n]|(?:\*+(?:[^*\/]|[\r\n])))*\*+\//gi, (match: string) =>
this.storePhpComment(match),
);
}

async preserveBladeBrace(content: any) {
Expand Down Expand Up @@ -1212,8 +1215,10 @@ export default class Formatter {
return `@php${q2}@endphp`;
}

const preserved = this.preserveStringLiteralInPhp(q2);
const indented = this.indentRawBlock(indent, preserved);
let preserved = this.preserveStringLiteralInPhp(q2);
preserved = this.preservePhpComment(preserved);
let indented = this.indentRawBlock(indent, preserved);
indented = this.restorePhpComment(indented);
const restored = this.restoreStringLiteralInPhp(indented);

return `@php${restored}@endphp`;
Expand Down Expand Up @@ -1268,7 +1273,8 @@ export default class Formatter {

return prefix + line;
})
.join('\n');
.join('\n')
.value();
}

indentBladeDirectiveBlock(indent: detectIndent.Indent, content: any) {
Expand Down Expand Up @@ -1397,6 +1403,43 @@ export default class Formatter {
.join('\n');
}

indentPhpComment(indent: detectIndent.Indent, content: string) {
if (_.isEmpty(indent.indent)) {
return content;
}

if (this.isInline(content)) {
return `${content}`;
}

const leftIndentAmount = indent.amount;
const indentLevel = leftIndentAmount / this.indentSize;
const prefixSpaces = this.indentCharacter.repeat(indentLevel < 0 ? 0 : indentLevel * this.indentSize);

const lines = content.split('\n');
let withoutCommentLine = false;

return _.chain(lines)
.map((line: string, index: number) => {
if (index === 0) {
return line.trim();
}

if (!line.trim().startsWith('*')) {
withoutCommentLine = true;
return line;
}

if (line.trim().endsWith('*/') && withoutCommentLine) {
return line;
}

return prefixSpaces + line;
})
.join('\n')
.value();
}

restoreBladeDirectivesInScripts(content: any) {
const regex = new RegExp(`${this.getBladeDirectivePlaceholder('(\\d+)')}`, 'gm');

Expand Down Expand Up @@ -1522,8 +1565,15 @@ export default class Formatter {
restorePhpComment(content: string) {
return _.replace(
content,
new RegExp(`${this.getPhpCommentPlaceholder('(\\d+)')}`, 'gms'),
(_match: string, p1: number) => this.phpComments[p1],
new RegExp(`${this.getPhpCommentPlaceholder('(\\d+)')};{0,1}`, 'gms'),
(_match: string, p1: number) => {
const placeholder = this.getPhpCommentPlaceholder(p1.toString());
const matchedLine = content.match(new RegExp(`^(.*?)${placeholder}`, 'gmi')) ?? [''];
const indent = detectIndent(matchedLine[0]);
const formatted = formatPhpComment(this.phpComments[p1]);

return this.indentPhpComment(indent, formatted);
},
);
}

Expand Down

0 comments on commit f896cc8

Please sign in to comment.