Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/giant-eyes-play.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphprotocol/graph-cli': minor
---

`graph codegen`: handle events with fields with reserved names #1896
23 changes: 23 additions & 0 deletions packages/cli/src/codegen/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ describe('Schema code generator', { concurrent: true }, () => {
count: Int!
isActive: Boolean

# reserved word
yield: Int!

# derivedFrom
wallets: [Wallet!] @derivedFrom(field: "account")

Expand Down Expand Up @@ -248,6 +251,26 @@ describe('Schema code generator', { concurrent: true }, () => {
this.set('count', Value.fromI32(value))
`,
},
{
name: 'get yield_',
params: [],
returnType: new NamedType('i32'),
body: `let value = this.get('yield')
if (!value || value.kind == ValueKind.NULL) {
return 0
} else {
return value.toI32()
}
`,
},
{
name: 'set yield_',
params: [new Param('value', new NamedType('i32'))],
returnType: undefined,
body: `
this.set('yield', Value.fromI32(value))
`,
},
{
name: 'get isActive',
params: [],
Expand Down
14 changes: 10 additions & 4 deletions packages/cli/src/codegen/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import debug from '../debug.js';
import Schema from '../schema.js';
import * as typesCodegen from './types/index.js';
import * as tsCodegen from './typescript.js';
import * as util from './util.js';

class IdField {
static BYTES = Symbol('Bytes');
Expand Down Expand Up @@ -308,6 +309,7 @@ export default class SchemaCodeGenerator {
_generateEntityFieldGetter(_entityDef: ObjectTypeDefinitionNode, fieldDef: FieldDefinitionNode) {
const isDerivedField = this._isDerivedField(fieldDef);
const name = fieldDef.name.value;
const safeName = util.handleReservedWord(name);

if (isDerivedField) {
schemaCodeGeneratorDebug.extend('_generateEntityFieldGetter')(
Expand Down Expand Up @@ -339,7 +341,7 @@ export default class SchemaCodeGenerator {
}`;

return tsCodegen.method(
`get ${name}`,
`get ${safeName}`,
[],
returnType,
`
Expand All @@ -351,6 +353,8 @@ export default class SchemaCodeGenerator {
_generateDerivedFieldGetter(entityDef: ObjectTypeDefinitionNode, fieldDef: FieldDefinitionNode) {
const entityName = entityDef.name.value;
const name = fieldDef.name.value;
const safeName = util.handleReservedWord(name);

schemaCodeGeneratorDebug.extend('_generateDerivedFieldGetter')(
`Generating derived field '${name}' getter for Entity '${entityName}'`,
);
Expand Down Expand Up @@ -390,7 +394,7 @@ export default class SchemaCodeGenerator {
const toValueString = idIsBytes ? '.toBytes().toHexString()' : '.toString()';

return tsCodegen.method(
`get ${name}`,
`get ${safeName}`,
[],
returnType,
`
Expand All @@ -415,6 +419,7 @@ export default class SchemaCodeGenerator {
fieldDef: FieldDefinitionNode,
) {
const name = fieldDef.name.value;
const safeName = util.handleReservedWord(name);
const gqlType = fieldDef.type;
const fieldValueType = this._valueTypeFromGraphQl(gqlType);
const returnType = this._typeFromGraphQl(gqlType);
Expand All @@ -428,7 +433,7 @@ export default class SchemaCodeGenerator {
}`;

return tsCodegen.method(
`get ${name}`,
`get ${safeName}`,
[],
returnType,
`
Expand All @@ -439,6 +444,7 @@ export default class SchemaCodeGenerator {
}
_generateEntityFieldSetter(_entityDef: ObjectTypeDefinitionNode, fieldDef: FieldDefinitionNode) {
const name = fieldDef.name.value;
const safeName = util.handleReservedWord(name);
const isDerivedField = !!fieldDef.directives?.find(
directive => directive.name.value === 'derivedFrom',
);
Expand Down Expand Up @@ -477,7 +483,7 @@ Suggestion: add an '!' to the member type of the List, change from '[${baseType}
`;

return tsCodegen.method(
`set ${name}`,
`set ${safeName}`,
[tsCodegen.param('value', paramType)],
undefined,
isNullable ? setNullable : setNonNullable,
Expand Down
50 changes: 49 additions & 1 deletion packages/cli/src/codegen/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function disambiguateNames<T>({
}) {
const collisionCounter = new Map();
return values.map((value, index) => {
const name = getName(value, index);
const name = handleReservedWord(getName(value, index));
const counter = collisionCounter.get(name);
if (counter === undefined) {
collisionCounter.set(name, 1);
Expand All @@ -20,6 +20,54 @@ export function disambiguateNames<T>({
});
}

const RESERVED_WORDS = new Set([
'await',
'break',
'case',
'catch',
'class',
'const',
'continue',
'debugger',
'delete',
'do',
'else',
'enum',
'export',
'extends',
'false',
'finally',
'function',
'if',
'implements',
'import',
'in',
'interface',
'let',
'new',
'package',
'private',
'protected',
'public',
'return',
'super',
'switch',
'static',
'this',
'throw',
'true',
'try',
'typeof',
'var',
'while',
'with',
'yield',
]);

export function handleReservedWord(name: string): string {
return RESERVED_WORDS.has(name) ? `${name}_` : name;
}

export function isTupleType(t: string) {
return t === 'tuple';
}
Expand Down
7 changes: 5 additions & 2 deletions packages/cli/src/scaffold/mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export const generateFieldAssignment = (
value: string[],
type: string,
): { assignment: string; imports: string[] } => {
let rightSide = `event.params.${value.join('.')}`;
const safeKey = key.map(k => util.handleReservedWord(k));
const safeValue = value.map(v => util.handleReservedWord(v));

let rightSide = `event.params.${safeValue.join('.')}`;
const imports = [];

if (type in VALUE_TYPECAST_MAP) {
Expand All @@ -23,7 +26,7 @@ export const generateFieldAssignment = (
}

return {
assignment: `entity.${key.join('_')} = ${rightSide}`,
assignment: `entity.${safeKey.join('_')} = ${rightSide}`,
imports,
};
};
Expand Down
Loading