Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed Nov 28, 2024
1 parent 84689d1 commit d492cb1
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 64 deletions.
2 changes: 1 addition & 1 deletion benchmark/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ function maxBy(array, fn) {

// Prepare all revisions and run benchmarks matching a pattern against them.
async function runBenchmarks(benchmarks, benchmarkProjects) {
for (const benchmark of benchmarks.filter(x => x.includes('visit-') || x.includes('printer-'))) {
for (const benchmark of benchmarks) {
const results = [];
for (let i = 0; i < benchmarkProjects.length; ++i) {
const { revision, projectPath } = benchmarkProjects[i];
Expand Down
4 changes: 2 additions & 2 deletions benchmark/printer-benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

const { parse } = require('graphql/language/parser.js');
const { print } = require('graphql/language/printer.js');

Check failure on line 4 in benchmark/printer-benchmark.js

View workflow job for this annotation

GitHub Actions / ci / Lint source files

There should be at least one empty line between import groups

Check failure on line 4 in benchmark/printer-benchmark.js

View workflow job for this annotation

GitHub Actions / ci / Lint source files

There should be at least one empty line between import groups
const { bigDocument } = require('./fixtures')
const { bigDocument } = require('./fixtures');

Check failure on line 5 in benchmark/printer-benchmark.js

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Missing file extension "js" for "./fixtures"

Check failure on line 5 in benchmark/printer-benchmark.js

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Missing file extension "js" for "./fixtures"

const document = parse(bigDocument)
const document = parse(bigDocument);

module.exports = {
name: 'Print ktichen-sink query',
Expand Down
129 changes: 69 additions & 60 deletions src/language/printer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,17 @@ const printDocASTReducer: ASTReducer<string> = {
// Document

Document: {
leave: (node) => truthyJoin(node.definitions, '\n\n'),
leave: (node) => join(node.definitions, '\n\n'),
},

OperationDefinition: {
leave(node) {
const varDefs = wrap('(', truthyJoin(node.variableDefinitions, ', '), ')');
const prefix = join(
const varDefs = wrap('(', join(node.variableDefinitions, ', '), ')');
const prefix = maybeJoin(
[
node.operation,
// TODO: optimize
join([node.name, varDefs]),
truthyJoin(node.directives, ' '),
maybeJoin([node.name, varDefs]),
join(node.directives, ' '),
],
' ',
);
Expand All @@ -51,20 +50,20 @@ const printDocASTReducer: ASTReducer<string> = {
': ' +
type +
wrap(' = ', defaultValue) +
wrap(' ', truthyJoin(directives, ' ')),
wrap(' ', join(directives, ' ')),
},
SelectionSet: { leave: ({ selections }) => block(selections) },

Field: {
leave({ alias, name, arguments: args, directives, selectionSet }) {
const prefix = wrap('', alias, ': ') + name;
let argsLine = prefix + wrap('(', truthyJoin(args, ', '), ')');
let argsLine = prefix + wrap('(', join(args, ', '), ')');

if (argsLine.length > MAX_LINE_LENGTH) {
argsLine = prefix + wrap('(\n', indent(truthyJoin(args, '\n')), '\n)');
argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
}

return join([argsLine, truthyJoin(directives, ' '), selectionSet], ' ');
return maybeJoin([argsLine, join(directives, ' '), selectionSet], ' ');
},
},

Expand All @@ -74,16 +73,16 @@ const printDocASTReducer: ASTReducer<string> = {

FragmentSpread: {
leave: ({ name, directives }) =>
'...' + name + wrap(' ', truthyJoin(directives, ' ')),
'...' + name + wrap(' ', join(directives, ' ')),
},

InlineFragment: {
leave: ({ typeCondition, directives, selectionSet }) =>
join(
maybeJoin(
[
'...',
wrap('on ', typeCondition),
truthyJoin(directives, ' '),
join(directives, ' '),
selectionSet,
],
' ',
Expand All @@ -100,8 +99,8 @@ const printDocASTReducer: ASTReducer<string> = {
}) =>
// Note: fragment variable definitions are experimental and may be changed
// or removed in the future.
`fragment ${name}${wrap('(', truthyJoin(variableDefinitions, ', '), ')')} ` +
`on ${typeCondition} ${wrap('', truthyJoin(directives, ' '), ' ')}` +
`fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` +
`on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` +
selectionSet,
},

Expand All @@ -116,15 +115,15 @@ const printDocASTReducer: ASTReducer<string> = {
BooleanValue: { leave: ({ value }) => (value ? 'true' : 'false') },
NullValue: { leave: () => 'null' },
EnumValue: { leave: ({ value }) => value },
ListValue: { leave: ({ values }) => '[' + truthyJoin(values, ', ') + ']' },
ObjectValue: { leave: ({ fields }) => '{' + truthyJoin(fields, ', ') + '}' },
ListValue: { leave: ({ values }) => '[' + join(values, ', ') + ']' },
ObjectValue: { leave: ({ fields }) => '{' + join(fields, ', ') + '}' },
ObjectField: { leave: ({ name, value }) => name + ': ' + value },

// Directive

Directive: {
leave: ({ name, arguments: args }) =>
'@' + name + wrap('(', truthyJoin(args, ', '), ')'),
'@' + name + wrap('(', join(args, ', '), ')'),
},

// Type
Expand All @@ -138,7 +137,10 @@ const printDocASTReducer: ASTReducer<string> = {
SchemaDefinition: {
leave: ({ description, directives, operationTypes }) =>
wrap('', description, '\n') +
join(['schema', join(directives, ' '), block(operationTypes)], ' '),
maybeJoin(
['schema', maybeJoin(directives, ' '), block(operationTypes)],
' ',
),
},

OperationTypeDefinition: {
Expand All @@ -148,18 +150,18 @@ const printDocASTReducer: ASTReducer<string> = {
ScalarTypeDefinition: {
leave: ({ description, name, directives }) =>
wrap('', description, '\n') +
join(['scalar', name, truthyJoin(directives, ' ')], ' '),
maybeJoin(['scalar', name, join(directives, ' ')], ' '),
},

ObjectTypeDefinition: {
leave: ({ description, name, interfaces, directives, fields }) =>
wrap('', description, '\n') +
join(
maybeJoin(
[
'type',
name,
wrap('implements ', truthyJoin(interfaces, ' & ')),
truthyJoin(directives, ' '),
wrap('implements ', join(interfaces, ' & ')),
join(directives, ' '),
block(fields),
],
' ',
Expand All @@ -171,31 +173,31 @@ const printDocASTReducer: ASTReducer<string> = {
wrap('', description, '\n') +
name +
(hasMultilineItems(args)
? wrap('(\n', indent(truthyJoin(args, '\n')), '\n)')
: wrap('(', truthyJoin(args, ', '), ')')) +
? wrap('(\n', indent(join(args, '\n')), '\n)')
: wrap('(', join(args, ', '), ')')) +
': ' +
type +
wrap(' ', truthyJoin(directives, ' ')),
wrap(' ', join(directives, ' ')),
},

InputValueDefinition: {
leave: ({ description, name, type, defaultValue, directives }) =>
wrap('', description, '\n') +
join(
[name + ': ' + type, wrap('= ', defaultValue), truthyJoin(directives, ' ')],
maybeJoin(
[name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')],
' ',
),
},

InterfaceTypeDefinition: {
leave: ({ description, name, interfaces, directives, fields }) =>
wrap('', description, '\n') +
join(
maybeJoin(
[
'interface',
name,
wrap('implements ', truthyJoin(interfaces, ' & ')),
truthyJoin(directives, ' '),
wrap('implements ', join(interfaces, ' & ')),
join(directives, ' '),
block(fields),
],
' ',
Expand All @@ -205,27 +207,28 @@ const printDocASTReducer: ASTReducer<string> = {
UnionTypeDefinition: {
leave: ({ description, name, directives, types }) =>
wrap('', description, '\n') +
join(
['union', name, truthyJoin(directives, ' '), wrap('= ', truthyJoin(types, ' | '))],
maybeJoin(
['union', name, join(directives, ' '), wrap('= ', join(types, ' | '))],
' ',
),
},

EnumTypeDefinition: {
leave: ({ description, name, directives, values }) =>
wrap('', description, '\n') +
join(['enum', name, truthyJoin(directives, ' '), block(values)], ' '),
maybeJoin(['enum', name, join(directives, ' '), block(values)], ' '),
},

EnumValueDefinition: {
leave: ({ description, name, directives }) =>
wrap('', description, '\n') + join([name, truthyJoin(directives, ' ')], ' '),
wrap('', description, '\n') +
maybeJoin([name, join(directives, ' ')], ' '),
},

InputObjectTypeDefinition: {
leave: ({ description, name, directives, fields }) =>
wrap('', description, '\n') +
join(['input', name, truthyJoin(directives, ' '), block(fields)], ' '),
maybeJoin(['input', name, join(directives, ' '), block(fields)], ' '),
},

DirectiveDefinition: {
Expand All @@ -234,34 +237,34 @@ const printDocASTReducer: ASTReducer<string> = {
'directive @' +
name +
(hasMultilineItems(args)
? wrap('(\n', indent(truthyJoin(args, '\n')), '\n)')
: wrap('(', truthyJoin(args, ', '), ')')) +
? wrap('(\n', indent(join(args, '\n')), '\n)')
: wrap('(', join(args, ', '), ')')) +
(repeatable ? ' repeatable' : '') +
' on ' +
truthyJoin(locations, ' | '),
join(locations, ' | '),
},

SchemaExtension: {
leave: ({ directives, operationTypes }) =>
join(
['extend schema', truthyJoin(directives, ' '), block(operationTypes)],
maybeJoin(
['extend schema', join(directives, ' '), block(operationTypes)],
' ',
),
},

ScalarTypeExtension: {
leave: ({ name, directives }) =>
join(['extend scalar', name, truthyJoin(directives, ' ')], ' '),
maybeJoin(['extend scalar', name, join(directives, ' ')], ' '),
},

ObjectTypeExtension: {
leave: ({ name, interfaces, directives, fields }) =>
join(
maybeJoin(
[
'extend type',
name,
wrap('implements ', truthyJoin(interfaces, ' & ')),
truthyJoin(directives, ' '),
wrap('implements ', join(interfaces, ' & ')),
join(directives, ' '),
block(fields),
],
' ',
Expand All @@ -270,12 +273,12 @@ const printDocASTReducer: ASTReducer<string> = {

InterfaceTypeExtension: {
leave: ({ name, interfaces, directives, fields }) =>
join(
maybeJoin(
[
'extend interface',
name,
wrap('implements ', truthyJoin(interfaces, ' & ')),
truthyJoin(directives, ' '),
wrap('implements ', join(interfaces, ' & ')),
join(directives, ' '),
block(fields),
],
' ',
Expand All @@ -284,37 +287,43 @@ const printDocASTReducer: ASTReducer<string> = {

UnionTypeExtension: {
leave: ({ name, directives, types }) =>
join(
maybeJoin(
[
'extend union',
name,
truthyJoin(directives, ' '),
wrap('= ', truthyJoin(types, ' | ')),
join(directives, ' '),
wrap('= ', join(types, ' | ')),
],
' ',
),
},

EnumTypeExtension: {
leave: ({ name, directives, values }) =>
join(['extend enum', name, truthyJoin(directives, ' '), block(values)], ' '),
maybeJoin(
['extend enum', name, join(directives, ' '), block(values)],
' ',
),
},

InputObjectTypeExtension: {
leave: ({ name, directives, fields }) =>
join(['extend input', name, truthyJoin(directives, ' '), block(fields)], ' '),
maybeJoin(
['extend input', name, join(directives, ' '), block(fields)],
' ',
),
},
};

/**
* Given maybeArray, print an empty string if it is null or empty, otherwise
* print all items together separated by separator if provided
*/
function join(
function maybeJoin(
maybeArray: Maybe<ReadonlyArray<string | undefined>>,
separator = '',
): string {
if (!maybeArray) return ''
if (!maybeArray) return '';

Check failure on line 326 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'if' condition

Check failure on line 326 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'if' condition

const list = maybeArray.filter((x) => x);
const listLength = list.length;
Expand All @@ -323,27 +332,27 @@ function join(
if (i === listLength - 1) return result + list[i];

Check failure on line 332 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'if' condition

Check failure on line 332 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'if' condition
else result += list[i] + separator;

Check failure on line 333 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'else'

Check failure on line 333 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Unnecessary 'else' after 'return'

Check failure on line 333 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'else'

Check failure on line 333 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Unnecessary 'else' after 'return'
}
return result
return result;
}

function truthyJoin(
function join(
list: ReadonlyArray<string> | undefined,
separator: string,
): string {
if (!list) return ''
if (!list) return '';

Check failure on line 342 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'if' condition

Check failure on line 342 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'if' condition
const listLength = list.length;
let result = '';
for (let i = 0; i < listLength; i++) {
if (i === listLength - 1) return result + list[i];

Check failure on line 346 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'if' condition

Check failure on line 346 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'if' condition
else result += list[i] + separator;

Check failure on line 347 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'else'

Check failure on line 347 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Unnecessary 'else' after 'return'

Check failure on line 347 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected { after 'else'

Check failure on line 347 in src/language/printer.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Unnecessary 'else' after 'return'
}
return result
return result;
}

/**
* Given array, print each item on its own line, wrapped in an indented `{ }` block.
*/
function block(array: Maybe<ReadonlyArray<string | undefined>>): string {
function block(array: ReadonlyArray<string> | undefined): string {
return wrap('{\n', indent(join(array, '\n')), '\n}');
}

Expand Down
5 changes: 4 additions & 1 deletion src/language/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,10 @@ export function visit(
}
}
} else {
node = { ...node }
node = Object.defineProperties(
{},
Object.getOwnPropertyDescriptors(node),
);
for (let i = 0; i < edits.length; i++) {
node[edits[i][0]] = edits[i][1];
}
Expand Down

0 comments on commit d492cb1

Please sign in to comment.