Is there a way to programmatically generate function signature jsons file?

19 views (last 30 days)
Hello. I managed to generate function signatures json files using the MATLAB Production Service Compiler GUI through my IDE. However, I was wondering if there was a way to generate signature jsons through MATLAB code directly?

Accepted Answer

Adam Danz
Adam Danz on 16 May 2024
> I was wondering if there was a way to generate signature jsons through MATLAB code
No, MATLAB does not offer such a function. I haven't checked the File Exchange but you could look there for a 3rd party solution.
That being said, MATLAB is able to provide code completions and suggestions for functions with arguments blocks based on the information contained in the arguments block. This information is available without requiring a functionSignatures.json file. However, custom code suggestions and completions are not supported in MATLAB Online.

More Answers (1)

Chandler
Chandler on 17 May 2024
Edited: Chandler on 17 May 2024
I've acutally spent the time to create a generate_function_signature_json function that handles that for me to be used like so:
generate_function_signature_json(@print_hello_world, output_dir=pwd)
Where its output is the fully qualified file path of the json file.
function output_file = generate_function_signature_json(function_handle, options)
% Generate a function signature JSON file for a given MATLAB function.
%
% Args:
% function_handle (function call signal): Function handle call of the MATLAB function to introspect.
% ouptions.output_dir (char): The output directory where the JSON signature file is to be save at.
arguments
function_handle {isFunctionCallSignal}
options.output_dir = tempdir
end
function_name = func2str(function_handle);
% Ensure the function is on the MATLAB path
if exist(function_name, 'file') ~= 2
error('Function %s does not exist or is not on the MATLAB path.', function_name);
end
if ~isfolder(options.output_dir)
error('Output %s dirctory does not exists.', options.output_dir);
end
% Get function information
function_info = functions(function_handle);
function_file = function_info.file;
% Use the MATLAB introspection to get function signature
function_signature = get_function_signature(function_file);
% Convert the function signature to JSON
json_struct = struct( ...
'schema_version', '1.0.0', ...
function_name, function_signature);
json_text = jsonencode(json_struct, 'PrettyPrint', true);
% Replace otherwise invalid struct prop for schema value
json_text = strrep(json_text, 'schema_version', '_schemaVersion');
% Save to JSON file
output_file_name = [function_name '_signature.json'];
output_file = fullfile(options.output_dir, output_file_name);
fid = fopen(output_file, 'w');
fwrite(fid, json_text, 'char');
fclose(fid);
% validateFunctionSignaturesJSON(output_file);
end
function function_signature = get_function_signature(function_file)
% Read the function file and extract the signature
%
% Args:
% function_file (char): Path to the function file.
%
% Returns:
% function_signature (struct): Structure representing the function signature.
fid = fopen(function_file, 'r');
if fid == -1
error('Could not open function file %s.', function_file);
end
function_signature = struct( ...
'inputs', [], ...
'outputs', [], ...
'purpose', '');
while ~feof(fid)
line = fgetl(fid);
if startsWith(strtrim(line), 'function')
signature = parse_function_signature(line);
function_signature.inputs = build_argument_struct(signature.Inputs);
function_signature.outputs = build_argument_struct(signature.Outputs);
break;
end
end
fclose(fid);
end
function signature = parse_function_signature(line)
% Parse the function signature from the function definition line
%
% Args:
% line (char): Function definition line.
%
% Returns:
% signature (struct): Parsed function signature structure.
% Remove 'function' keyword and split into parts
line = strtrim(strrep(line, 'function', ''));
parts = strsplit(line, '=');
% Parse outputs
if numel(parts) > 1
outputs_part = strtrim(parts{1});
outputs_part = strrep(outputs_part, '[', '');
outputs_part = strrep(outputs_part, ']', '');
outputs_part = strrep(outputs_part, ' ', '');
outputs = strsplit(outputs_part, ',');
else
outputs = {};
end
% Parse function name and inputs
func_name_part = strtrim(parts{end});
func_name_parts = strsplit(func_name_part, '(');
func_name = strtrim(func_name_parts{1});
inputs_part = strtrim(func_name_parts{2});
inputs_part = strrep(inputs_part, ')', '');
inputs_part = strrep(inputs_part, ' ', '');
inputs = strsplit(inputs_part, ',');
% Build the signature structure
signature.Name = func_name;
signature.Description = '';
signature.Inputs = inputs;
signature.Outputs = outputs;
signature.Attributes = struct('Inline', false, 'Extrinsic', false);
end
function arg_structs = build_argument_struct(args)
% Build argument structures from argument names
%
% Args:
% args (cell): Cell array of argument names.
%
% Returns:
% arg_structs (cell): Array of argument structures.
arg_structs = {};
if ~isempty(args{:})
for i = 1:numel(args)
arg_struct = {};
arg_struct.name = args{i};
arg_struct.type = {}; % Type introspection can be added
arg_struct.purpose = ''; % Purpose introspection can be added
arg_structs{end+1} = arg_struct; %#ok<AGROW>
end
end
end
  1 Comment
Adam Danz
Adam Danz on 17 May 2024
+1 I haven't tried it out but thanks for sharing! Someone may stumble upon this thread and this might be exactly what they are looking for!

Sign in to comment.

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!