Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import slangPrint from './slangPrinter.js';
import { isBlockComment, isComment } from './slang-utils/is-comment.js';
import { locEnd, locStart } from './slang-utils/loc.js';
import { hasPrettierIgnore } from './slang-utils/has-prettier-ignore.js';
import { getVisitorKeys } from './slang-utils/get-visitor-keys.js';

import type {
AstPath,
Expand Down Expand Up @@ -57,10 +58,9 @@ const parsers = {

const antlrCanAttachComment = ({ type }: { type: string }): boolean =>
typeof type === 'string' && type !== 'BlockComment' && type !== 'LineComment';
const canAttachComment = (node: PrintableNode | undefined): boolean =>
node !== undefined &&
node.kind && // Make sure it's not Location
!isComment(node);
const canAttachComment = (node: PrintableNode): boolean =>
// Make sure it's not Location
node.kind && !isComment(node);

// https://prettier.io/docs/en/plugins.html#printers
const antlrPrinter = {
Expand All @@ -75,18 +75,19 @@ const antlrPrinter = {
print: antlrPrint,
printComment: comments.printComment
};
const slangPrinter: Printer<PrintableNode | undefined> = {
const slangPrinter: Printer<PrintableNode> = {
canAttachComment,
handleComments,
isBlockComment,
massageAstNode,
print: slangPrint as (
path: AstPath<PrintableNode | undefined>,
options: ParserOptions<PrintableNode | undefined>,
print: (path: AstPath<PrintableNode | undefined>) => Doc,
path: AstPath<PrintableNode>,
options: ParserOptions<PrintableNode>,
print: (path: AstPath<PrintableNode>) => Doc,
args?: unknown
) => Doc,
hasPrettierIgnore,
getVisitorKeys,
printComment
};

Expand Down
4 changes: 1 addition & 3 deletions src/slang-comments/printer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import { isComment } from '../slang-utils/is-comment.js';
import type { AstPath, Doc } from 'prettier';
import type { PrintableNode } from '../slang-nodes/types.d.ts';

export function printComment({
node: comment
}: AstPath<PrintableNode | undefined>): Doc {
export function printComment({ node: comment }: AstPath<PrintableNode>): Doc {
if (isComment(comment)) {
return comment.print();
}
Expand Down
36 changes: 18 additions & 18 deletions src/slang-printers/print-comments.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { doc, util } from 'prettier';
import { printComment } from '../slang-comments/printer.js';
import { joinExisting } from '../slang-utils/join-existing.js';
import { locEnd } from '../slang-utils/loc.js';

import type { AstPath, Doc, ParserOptions } from 'prettier';
import type { Comment, PrintableNode } from '../slang-nodes/types.d.ts';

const { hardline, line } = doc.builders;
const { hardline } = doc.builders;

function isPrintable(comment: Comment): boolean {
return !comment.trailing && !comment.leading && !comment.printed;
Expand All @@ -21,20 +20,21 @@ export function printComments(
if (lastPrintableIndex === -1) {
return [];
}
return joinExisting(
line,
path.map(({ node: comment }, index) => {
if (!isPrintable(comment)) {
return '';
}
comment.printed = true;
return [
printComment(path),
index !== lastPrintableIndex &&
util.isNextLineEmpty(options.originalText, locEnd(comment))
? hardline
: ''
];
}, 'comments')
);
return path.map(({ node: comment }, index) => {
if (!isPrintable(comment)) {
return '';
}
comment.printed = true;
return [
printComment(path),
index !== lastPrintableIndex
? [
hardline,
util.isNextLineEmpty(options.originalText, locEnd(comment))
? hardline
: ''
]
: ''
];
}, 'comments');
}
21 changes: 21 additions & 0 deletions src/slang-utils/get-visitor-keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { PrintableNode } from '../slang-nodes/types.js';

const ignoredKeys = new Set([
'kind',
'loc',
'comments',
'print',
'isEmpty',
'updateMetadata',
'cleanModifierInvocationArguments',
'getSingleExpression'
]);

export function getVisitorKeys(
node: PrintableNode,
nonTraversableKeys: Set<string>
): string[] {
return Object.keys(node).filter(
(key) => !nonTraversableKeys.has(key) && !ignoredKeys.has(key)
);
}
6 changes: 2 additions & 4 deletions src/slang-utils/has-prettier-ignore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import { isBlockComment, isComment } from './is-comment.js';
import type { AstPath } from 'prettier';
import type { PrintableNode } from '../slang-nodes/types.js';

export function hasPrettierIgnore({
node
}: AstPath<PrintableNode | undefined>): boolean {
if (node === undefined || isComment(node)) return false;
export function hasPrettierIgnore({ node }: AstPath<PrintableNode>): boolean {
if (isComment(node)) return false;

// Prettier sets SourceUnit's comments to undefined after assigning comments
// to each node.
Expand Down
6 changes: 2 additions & 4 deletions src/slang-utils/is-comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ import type {
export const isBlockComment = createKindCheckFunction([
TerminalKind.MultiLineComment,
TerminalKind.MultiLineNatSpecComment
]) as (
node: PrintableNode | Comment | Node | undefined
) => node is BlockComment;
]) as (node: PrintableNode | Comment | Node) => node is BlockComment;

export const isComment = createKindCheckFunction([
TerminalKind.MultiLineComment,
TerminalKind.MultiLineNatSpecComment,
TerminalKind.SingleLineComment,
TerminalKind.SingleLineNatSpecComment
]) as (node: PrintableNode | Comment | Node | undefined) => node is Comment;
]) as (node: PrintableNode | Comment | Node) => node is Comment;
8 changes: 4 additions & 4 deletions src/slangSolidityParser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// https://prettier.io/docs/en/plugins.html#parsers
import { SourceUnit as SlangSourceUnit } from '@nomicfoundation/slang/ast';
import { createParser } from './slang-utils/create-parser.js';
import { locStart } from './slang-utils/loc.js';
import { SourceUnit } from './slang-nodes/SourceUnit.js';

import type { ParserOptions } from 'prettier';
Expand All @@ -12,7 +13,7 @@ export default function parse(
): PrintableNode {
const { parser, parseOutput } = createParser(text, options);

// We update the compiler version by the inferred one.
// We update the compiler version with the inferred one.
options.compiler = parser.languageVersion;
const comments: Comment[] = [];
const parsed = new SourceUnit(
Expand All @@ -21,8 +22,7 @@ export default function parse(
options
);

// Because of comments being extracted like a Russian doll, the order needs
// to be fixed at the end.
parsed.comments = comments.sort((a, b) => a.loc.start - b.loc.start);
// Comments are extracted in nested order; sort them by location.
parsed.comments = comments.sort((a, b) => locStart(a) - locStart(b));
return parsed;
}
6 changes: 1 addition & 5 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@ interface AstLocation extends Location {
}

type PrintFunction = (
selector?:
| string
| number
| (string | number)[]
| AstPath<PrintableNode | undefined>
selector?: string | number | (string | number)[] | AstPath<PrintableNode>
) => Doc;

// This the union of all the types in the namespace `ast`.
Expand Down