Skip to content

Commit

Permalink
Add support for aliasing of overloaded functions
Browse files Browse the repository at this point in the history
  • Loading branch information
asmblah committed Jun 11, 2024
1 parent 75f6b8f commit 655b82c
Show file tree
Hide file tree
Showing 15 changed files with 394 additions and 31 deletions.
41 changes: 29 additions & 12 deletions src/Function/FunctionSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var _ = require('microdash'),
* @param {ReferenceFactory} referenceFactory
* @param {FutureFactory} futureFactory
* @param {Flow} flow
* @param {FunctionSpecFactory} functionSpecFactory
* @param {FunctionContextInterface} context
* @param {NamespaceScope} namespaceScope
* @param {Parameter[]} parameterList
Expand All @@ -50,6 +51,7 @@ function FunctionSpec(
referenceFactory,
futureFactory,
flow,
functionSpecFactory,
context,
namespaceScope,
parameterList,
Expand Down Expand Up @@ -94,6 +96,10 @@ function FunctionSpec(
* @type {Function}
*/
this.func = func;
/**
* @type {FunctionSpecFactory}
*/
this.functionSpecFactory = functionSpecFactory;
/**
* @type {FutureFactory}
*/
Expand Down Expand Up @@ -248,22 +254,12 @@ _.extend(FunctionSpec.prototype, {
* Creates a new function (and its FunctionSpec) for an alias of the current FunctionSpec.
*
* @param {string} aliasName
* @param {FunctionSpecFactory} functionSpecFactory
* @param {FunctionFactory} functionFactory
* @return {Function}
*/
createAliasFunction: function (aliasName, functionSpecFactory, functionFactory) {
createAliasFunction: function (aliasName, functionFactory) {
var spec = this,
aliasFunctionSpec = functionSpecFactory.createAliasFunctionSpec(
spec.namespaceScope,
aliasName,
spec.parameterList,
spec.func,
spec.returnType,
spec.returnByReference,
spec.filePath,
spec.lineNumber
);
aliasFunctionSpec = spec.createAliasFunctionSpec(aliasName);

return functionFactory.create(
spec.namespaceScope,
Expand All @@ -277,6 +273,27 @@ _.extend(FunctionSpec.prototype, {
);
},

/**
* Creates a new FunctionSpec for an alias of the current FunctionSpec.
*
* @param {string} aliasName
* @return {FunctionSpec}
*/
createAliasFunctionSpec: function (aliasName) {
var spec = this;

return spec.functionSpecFactory.createAliasFunctionSpec(
spec.namespaceScope,
aliasName,
spec.parameterList,
spec.func,
spec.returnType,
spec.returnByReference,
spec.filePath,
spec.lineNumber
);
},

/**
* Fetches the path to the file this function was defined in.
* May be null, if the function is a built-in.
Expand Down
13 changes: 11 additions & 2 deletions src/Function/FunctionSpecFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,12 @@ _.extend(FunctionSpecFactory.prototype, {
factory.referenceFactory,
factory.futureFactory,
factory.flow,
factory,
context,
namespaceScope,
parameters,
parameters.map(function (parameter) {
return parameter !== null ? parameter.createAlias(context) : null;
}),
func,
returnType,
returnByReference,
Expand Down Expand Up @@ -204,6 +207,7 @@ _.extend(FunctionSpecFactory.prototype, {
factory.referenceFactory,
factory.futureFactory,
factory.flow,
factory,
context,
namespaceScope,
parameters,
Expand Down Expand Up @@ -258,6 +262,7 @@ _.extend(FunctionSpecFactory.prototype, {
factory.referenceFactory,
factory.futureFactory,
factory.flow,
factory,
context,
namespaceScope,
parameters,
Expand Down Expand Up @@ -336,6 +341,7 @@ _.extend(FunctionSpecFactory.prototype, {
factory.referenceFactory,
factory.futureFactory,
factory.flow,
factory,
context,
namespaceScope,
parameters,
Expand All @@ -354,18 +360,21 @@ _.extend(FunctionSpecFactory.prototype, {
* @param {Array.<number, FunctionSpec>} variantFunctionSpecsByParameterCount
* @param {number} minimumParameterCount
* @param {number} maximumParameterCount
* @param {NamespaceScope} namespaceScope
* @returns {OverloadedFunctionSpec}
*/
createOverloadedFunctionSpec: function (
name,
variantFunctionSpecsByParameterCount,
minimumParameterCount,
maximumParameterCount
maximumParameterCount,
namespaceScope
) {
var factory = this;

return new factory.OverloadedFunctionSpec(
factory,
namespaceScope,
name,
variantFunctionSpecsByParameterCount,
minimumParameterCount,
Expand Down
3 changes: 2 additions & 1 deletion src/Function/Overloaded/OverloadedFunctionDefiner.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ _.extend(OverloadedFunctionDefiner.prototype, {
name,
variantFunctionSpecsByParameterCount,
minimumParameterCount,
maximumParameterCount
maximumParameterCount,
namespaceScope
);

return definer.functionFactory.create(
Expand Down
43 changes: 43 additions & 0 deletions src/Function/Overloaded/OverloadedFunctionSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var _ = require('microdash'),
* Represents an overloaded PHP function.
*
* @param {FunctionSpecFactory} functionSpecFactory
* @param {NamespaceScope} namespaceScope
* @param {string} name
* @param {Array.<number, FunctionSpec>} variantFunctionSpecsByParameterCount
* @param {number} minimumParameterCount
Expand All @@ -25,6 +26,7 @@ var _ = require('microdash'),
*/
function OverloadedFunctionSpec(
functionSpecFactory,
namespaceScope,
name,
variantFunctionSpecsByParameterCount,
minimumParameterCount,
Expand All @@ -46,13 +48,54 @@ function OverloadedFunctionSpec(
* @type {string}
*/
this.name = name;
/**
* @type {NamespaceScope}
*/
this.namespaceScope = namespaceScope;
/**
* @type {Array<number, FunctionSpec>}
*/
this.variantFunctionSpecsByParameterCount = variantFunctionSpecsByParameterCount;
}

_.extend(OverloadedFunctionSpec.prototype, {
/**
* Creates a new function (and its FunctionSpec) for an alias of the current OverloadedFunctionSpec.
*
* @param {string} aliasName
* @param {FunctionFactory} functionFactory
* @return {Function}
*/
createAliasFunction: function (aliasName, functionFactory) {
var spec = this,
aliasFunctionSpec,
aliasVariantFunctionSpecsByParameterCount = {};

_.forOwn(spec.variantFunctionSpecsByParameterCount, function (variantFunctionSpec, parameterCount) {
aliasVariantFunctionSpecsByParameterCount[parameterCount] = variantFunctionSpec.createAliasFunctionSpec(
aliasName
);
});

aliasFunctionSpec = spec.functionSpecFactory.createOverloadedFunctionSpec(
aliasName,
aliasVariantFunctionSpecsByParameterCount,
spec.minimumParameterCount,
spec.maximumParameterCount
);

return functionFactory.create(
spec.namespaceScope,
// Class will always be null for 'normal' functions
// as defining a function inside a class will define it
// inside the current namespace instead.
null,
null,
null,
aliasFunctionSpec
);
},

/**
* Fetches the fully-qualified name of the function.
*
Expand Down
29 changes: 29 additions & 0 deletions src/Function/Parameter.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ var _ = require('microdash'),
* @param {FutureFactory} futureFactory
* @param {Flow} flow
* @param {Userland} userland
* @param {ParameterFactory} parameterFactory
* @param {string} name
* @param {number} index
* @param {TypeInterface} typeObject
Expand All @@ -51,6 +52,7 @@ function Parameter(
futureFactory,
flow,
userland,
parameterFactory,
name,
index,
typeObject,
Expand All @@ -74,6 +76,10 @@ function Parameter(
* @type {Function|null}
*/
this.defaultValueProvider = defaultValueProvider;
/**
* @type {ParameterFactory}
*/
this.parameterFactory = parameterFactory;
/**
* @type {string|null}
*/
Expand Down Expand Up @@ -175,6 +181,29 @@ _.extend(Parameter.prototype, {
return value;
},

/**
* Creates an alias of this parameter, for an alias of its original function context.
*
* @param {FunctionContextInterface} aliasContext
* @returns {Parameter}
*/
createAlias: function (aliasContext) {
var parameter = this;

return parameter.parameterFactory.createParameter(
parameter.name,
parameter.index,
parameter.typeObject,
aliasContext,
parameter.namespaceScope,
parameter.passedByReference,
parameter.variadic,
parameter.defaultValueProvider,
parameter.filePath,
parameter.lineNumber
);
},

/**
* Fetches the line number this parameter was defined on, if known
*
Expand Down
1 change: 1 addition & 0 deletions src/Function/ParameterFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ _.extend(ParameterFactory.prototype, {
factory.futureFactory,
factory.flow,
factory.userland,
factory,
name,
index,
typeObject,
Expand Down
1 change: 0 additions & 1 deletion src/Namespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ module.exports = require('pauser')([

namespace.functions[aliasName.toLowerCase()] = existingFunction.functionSpec.createAliasFunction(
aliasName,
namespace.functionSpecFactory,
namespace.functionFactory
);
},
Expand Down
Loading

0 comments on commit 655b82c

Please sign in to comment.