typir
Version:
General purpose type checking library
64 lines • 2.93 kB
JavaScript
/******************************************************************************
* Copyright 2024 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { isFunctionType } from './function-type.js';
/**
* Predefined validation to produce errors for those (overloaded) functions which cannot be distinguished when calling them.
* By default, only the name and the types of the input parameters are used to distinguish functions.
*/
export class UniqueFunctionValidation {
constructor(services, isRelevant) {
this.foundDeclarations = new Map();
this.services = services;
this.isRelevant = isRelevant;
}
beforeValidation(_languageRoot, _accept, _typir) {
this.foundDeclarations.clear();
}
validation(languageNode, _accept, _typir) {
if (this.isRelevant === undefined || this.isRelevant(languageNode)) { // improves performance, since type inference need to be done only for relevant language nodes
const type = this.services.Inference.inferType(languageNode);
if (isFunctionType(type)) {
// register language nodes which have FunctionTypes with a key for their uniqueness
const key = this.calculateFunctionKey(type);
let entries = this.foundDeclarations.get(key);
if (!entries) {
entries = [];
this.foundDeclarations.set(key, entries);
}
entries.push(languageNode);
}
}
}
/**
* Calculates a key for a function which encodes its unique properties, i.e. duplicate functions have the same key.
* This key is used to identify duplicated functions.
* Override this method to change the properties which make a function unique.
* By default, only the name and the types of the input parameters are relevant.
* @param func the current function type
* @returns a string key
*/
calculateFunctionKey(func) {
return `${func.functionName}(${func.getInputs().map(param => param.type.getIdentifier())})`;
}
afterValidation(_languageRoot, accept, _typir) {
for (const [key, functions] of this.foundDeclarations.entries()) {
if (functions.length >= 2) {
for (const func of functions) {
this.reportNonUniqueFunction(func, key, accept);
}
}
}
this.foundDeclarations.clear();
}
reportNonUniqueFunction(func, key, accept) {
accept({
languageNode: func,
severity: 'error',
message: `Declared functions need to be unique (${key}).`,
});
}
}
//# sourceMappingURL=function-validation-unique.js.map