Skip to content

Commit

Permalink
fix: Resolved issue where using a function type as self can cause tha…
Browse files Browse the repository at this point in the history
…t function's params to be added to the current function
  • Loading branch information
adam-coster committed Aug 2, 2023
1 parent 267e62b commit d1eec5c
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 45 deletions.
24 changes: 8 additions & 16 deletions packages/parser/src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,29 +483,21 @@ export class Project {
}
// Second pass
// TODO: Find a better way than brute-forcing to resolve cross-file references
logger.info('Second pass...');
const reloads: Promise<any>[] = [];
for (const asset of assets) {
// asset.updateGlobals();
// asset.updateAllSymbols();
for (const file of asset.gmlFilesArray) {
reloads.push(file.reload(file.content));
for (const pass of [1]) {
logger.info(`Re-processing pass ${pass}...`);
const reloads: Promise<any>[] = [];
for (const asset of assets) {
for (const file of asset.gmlFilesArray) {
reloads.push(file.reload(file.content));
}
}
await Promise.all(reloads);
}
await Promise.all(reloads);
// logger.info('Third pass...');
// for (const asset of assets) {
// asset.updateGlobals();
// asset.updateAllSymbols();
// }

// But for now, that's what we'll do!
logger.info('Updating diagnostics...');
for (const asset of assets) {
asset.updateDiagnostics();
// for (const file of asset.gmlFilesArray) {
// await file.reload(file._content);
// }
}
}

Expand Down
10 changes: 8 additions & 2 deletions packages/parser/src/types.feather.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,17 @@ export function typeFromParsedJsdocs(
addMissing,
);
} else if (jsdoc.kind === 'self') {
return typeFromFeatherString(
// The self-type could be a function, in which case
// we want to use its "self" as the type instead of
// the function itself.
const matchingType = typeFromFeatherString(
jsdoc.self?.content || 'Any',
knownTypes,
addMissing,
);
)
.map((t) => (t.kind === 'Function' ? t.self : t))
.filter((x) => !!x) as Type[];
return matchingType;
} else if (jsdoc.kind === 'function') {
const type = new Type('Function').describe(jsdoc.description);
let i = 0;
Expand Down
5 changes: 0 additions & 5 deletions packages/parser/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ export class Type<T extends PrimitiveName = PrimitiveName> {
): Signifier | undefined {
// If this is a Id.Instance or Asset.GMObject type, then we want to add
// the member to the parent Struct instead.

if (this.kind === 'Id.Instance' || this.kind === 'Asset.GMObject') {
return this.extends?.addMember(newMember, options);
}
Expand All @@ -356,10 +355,6 @@ export class Type<T extends PrimitiveName = PrimitiveName> {
'Cannot replace existing member with new member',
);
const existingOnThis = this.getMember(name, true);
// assert(
// !existingOnThis || !existingOnThis.override,
// 'Cannot override already-overridden member',
// );

let member: Signifier | undefined;
if (signifierArg?.override) {
Expand Down
5 changes: 1 addition & 4 deletions packages/parser/src/visitor.functionExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export function visitFunctionExpression(
children: FunctionExpressionCstChildren,
ctx: VisitorContext,
): Type<'Function'> | undefined {
const functionName: string | undefined = children.Identifier?.[0]?.image;
const docs = ctx.docs || this.PROCESSOR.consumeJsdoc();
ctx.docs = undefined;
const assignedTo = ctx.signifier;
Expand All @@ -32,7 +33,6 @@ export function visitFunctionExpression(

// Compute useful properties of this function to help figure out
// how to define its symbol, type, scope, etc.
const functionName: string | undefined = children.Identifier?.[0]?.image;
const nameLocation = functionName
? this.PROCESSOR.range(children.Identifier![0])
: undefined;
Expand Down Expand Up @@ -222,9 +222,6 @@ export function visitFunctionExpression(

// Also add to the function's local scope.
const localVar = functionType.local.getMember(param.name);
// if (localVar && localVar !== param) {
// debugger;
// }
if (!localVar) {
functionType.local.addMember(param);
} else if (localVar !== param) {
Expand Down
14 changes: 0 additions & 14 deletions packages/parser/src/visitor.identifierAccessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,25 +240,11 @@ export function visitIdentifierAccessor(
}
break;
case 'functionArguments':
// if (
// this.PROCESSOR.file.asset.name === 'o_world_element' &&
// this.PROCESSOR.file.name === 'Create_0' &&
// name === 'z_setup'
// ) {
// debugger;
// }
const functionType = getTypeOfKind(accessing.type, 'Function');

// If this is a mixin call, then we need to ensure that the context
// includes the variables created by the mixin function.
if (functionType?.signifier?.mixin && functionType.self) {
// if (
// this.PROCESSOR.file.asset.name === 'o_world_element' &&
// this.PROCESSOR.file.name === 'Create_0' &&
// name === 'z_setup'
// ) {
// debugger;
// }
const variables = functionType.self;
for (const member of variables.listMembers()) {
if (!member.def) continue;
Expand Down
11 changes: 7 additions & 4 deletions packages/parser/src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -465,12 +465,15 @@ export class GmlSignifierVisitor extends GmlVisitorBase {
.children;

if (assignedToFunction || assignedToStructLiteral) {
ctx.signifier = signifier;
ctx.docs = docs;
const newCtx = {
...ctx,
signifier,
docs,
};
if (assignedToFunction) {
this.functionExpression(assignedToFunction, ctx);
this.functionExpression(assignedToFunction, newCtx);
} else if (assignedToStructLiteral) {
this.structLiteral(assignedToStructLiteral, ctx);
this.structLiteral(assignedToStructLiteral, newCtx);
}
} else {
const inferredType = normalizeType(
Expand Down

0 comments on commit d1eec5c

Please sign in to comment.