|
1 | 1 | function template = fillClass(name, namespace, processed, classprops, inherited) |
2 | | -%name is the name of the scheme |
3 | | -%namespace is the namespace context for this class |
| 2 | + %name is the name of the scheme |
| 3 | + %namespace is the namespace context for this class |
4 | 4 |
|
5 | | -%% PROCESSING |
6 | | -class = processed(1); |
| 5 | + %% PROCESSING |
| 6 | + class = processed(1); |
7 | 7 |
|
8 | | -allprops = keys(classprops); |
9 | | -required = {}; |
10 | | -optional = {}; |
11 | | -readonly = {}; |
12 | | -defaults = {}; |
13 | | -dependent = {}; |
14 | | -%separate into readonly, required, and optional properties |
15 | | -for i=1:length(allprops) |
16 | | - pnm = allprops{i}; |
17 | | - prop = classprops(pnm); |
| 8 | + allProperties = keys(classprops); |
| 9 | + required = {}; |
| 10 | + optional = {}; |
| 11 | + readonly = {}; |
| 12 | + defaults = {}; |
| 13 | + dependent = {}; |
| 14 | + hidden = {}; % special hidden properties for hard-coded workarounds |
| 15 | + %separate into readonly, required, and optional properties |
| 16 | + for iGroup = 1:length(allProperties) |
| 17 | + propertyName = allProperties{iGroup}; |
| 18 | + prop = classprops(propertyName); |
18 | 19 |
|
19 | | - isRequired = ischar(prop) || isa(prop, 'containers.Map') || isstruct(prop); |
20 | | - iIsPropertyRequired = false; |
21 | | - if isa(prop, 'file.interface.HasProps') |
22 | | - iIsPropertyRequired = false(size(prop)); |
23 | | - for iProp = 1:length(prop) |
24 | | - p = prop(iProp); |
25 | | - iIsPropertyRequired(iProp) = p.required; |
26 | | - end |
27 | | - end |
28 | | - |
29 | | - if isRequired || all(iIsPropertyRequired) |
30 | | - required = [required {pnm}]; |
31 | | - else |
32 | | - optional = [optional {pnm}]; |
33 | | - end |
34 | | - |
35 | | - if isa(prop, 'file.Attribute') |
36 | | - if prop.readonly |
37 | | - readonly = [readonly {pnm}]; |
| 20 | + isRequired = ischar(prop) || isa(prop, 'containers.Map') || isstruct(prop); |
| 21 | + isPropertyRequired = false; |
| 22 | + if isa(prop, 'file.interface.HasProps') |
| 23 | + isPropertyRequired = false(size(prop)); |
| 24 | + for iProp = 1:length(prop) |
| 25 | + p = prop(iProp); |
| 26 | + isPropertyRequired(iProp) = p.required; |
| 27 | + end |
38 | 28 | end |
39 | | - |
40 | | - if ~isempty(prop.value) |
41 | | - defaults = [defaults {pnm}]; |
| 29 | + |
| 30 | + if isRequired || all(isPropertyRequired) |
| 31 | + required = [required {propertyName}]; |
| 32 | + else |
| 33 | + optional = [optional {propertyName}]; |
42 | 34 | end |
43 | | - |
44 | | - if ~isempty(prop.dependent) |
45 | | - %extract prefix |
46 | | - parentName = strrep(pnm, ['_' prop.name], ''); |
47 | | - parent = classprops(parentName); |
48 | | - if ~parent.required |
49 | | - dependent = [dependent {pnm}]; |
| 35 | + |
| 36 | + if isa(prop, 'file.Attribute') |
| 37 | + if prop.readonly |
| 38 | + readonly = [readonly {propertyName}]; |
| 39 | + end |
| 40 | + |
| 41 | + if ~isempty(prop.value) |
| 42 | + defaults = [defaults {propertyName}]; |
| 43 | + end |
| 44 | + |
| 45 | + if ~isempty(prop.dependent) |
| 46 | + %extract prefix |
| 47 | + parentName = strrep(propertyName, ['_' prop.name], ''); |
| 48 | + parent = classprops(parentName); |
| 49 | + if ~parent.required |
| 50 | + dependent = [dependent {propertyName}]; |
| 51 | + end |
| 52 | + end |
| 53 | + |
| 54 | + if strcmp(namespace.name, 'hdmf_common') ... |
| 55 | + && strcmp(name, 'VectorData') ... |
| 56 | + && any(strcmp(prop.name, {'unit', 'sampling_rate', 'resolution'})) |
| 57 | + hidden{end+1} = propertyName; |
50 | 58 | end |
51 | 59 | end |
52 | 60 | end |
53 | | -end |
54 | | -nonInherited = setdiff(allprops, inherited); |
55 | | -readonly = intersect(readonly, nonInherited); |
56 | | -required = intersect(required, nonInherited); |
57 | | -optional = intersect(optional, nonInherited); |
| 61 | + nonInherited = setdiff(allProperties, inherited); |
| 62 | + readonly = intersect(readonly, nonInherited); |
| 63 | + exclusivePropertyGroups = union(readonly, hidden); |
| 64 | + required = setdiff(intersect(required, nonInherited), exclusivePropertyGroups); |
| 65 | + optional = setdiff(intersect(optional, nonInherited), exclusivePropertyGroups); |
58 | 66 |
|
59 | | -%% CLASSDEF |
60 | | -if length(processed) <= 1 |
61 | | - depnm = 'types.untyped.MetaClass'; %WRITE |
62 | | -else |
63 | | - parentName = processed(2).type; %WRITE |
64 | | - depnm = namespace.getFullClassName(parentName); |
65 | | -end |
| 67 | + %% CLASSDEF |
| 68 | + if length(processed) <= 1 |
| 69 | + depnm = 'types.untyped.MetaClass'; %WRITE |
| 70 | + else |
| 71 | + parentName = processed(2).type; %WRITE |
| 72 | + depnm = namespace.getFullClassName(parentName); |
| 73 | + end |
66 | 74 |
|
67 | | -if isa(processed, 'file.Group') |
68 | | - classTag = 'types.untyped.GroupClass'; |
69 | | -else |
70 | | - classTag = 'types.untyped.DatasetClass'; |
71 | | -end |
| 75 | + if isa(processed, 'file.Group') |
| 76 | + classTag = 'types.untyped.GroupClass'; |
| 77 | + else |
| 78 | + classTag = 'types.untyped.DatasetClass'; |
| 79 | + end |
72 | 80 |
|
73 | | -%% return classfile string |
74 | | -classDef = [... |
75 | | - 'classdef ' name ' < ' depnm ' & ' classTag newline... %header, dependencies |
76 | | - '% ' upper(name) ' ' class.doc]; %name, docstr |
77 | | -propgroups = {... |
78 | | - @()file.fillProps(classprops, readonly, 'PropertyAttributes', 'SetAccess=protected')... |
79 | | - @()file.fillProps(classprops, setdiff(required, readonly), 'IsRequired', true)... |
80 | | - @()file.fillProps(classprops, setdiff(optional, readonly))... |
81 | | - }; |
82 | | -docsep = {... |
83 | | - '% READONLY PROPERTIES'... |
84 | | - '% REQUIRED PROPERTIES'... |
85 | | - '% OPTIONAL PROPERTIES'... |
86 | | - }; |
87 | | -propsDef = ''; |
88 | | -for i=1:length(propgroups) |
89 | | - pg = propgroups{i}; |
90 | | - pdef = pg(); |
91 | | - if ~isempty(pdef) |
92 | | - propsDef = strjoin({propsDef docsep{i} pdef}, newline); |
| 81 | + %% return classfile string |
| 82 | + classDefinitionHeader = [... |
| 83 | + 'classdef ' name ' < ' depnm ' & ' classTag newline... %header, dependencies |
| 84 | + '% ' upper(name) ' ' class.doc]; %name, docstr |
| 85 | + hiddenAndReadonly = intersect(hidden, readonly); |
| 86 | + hidden = setdiff(hidden, hiddenAndReadonly); |
| 87 | + readonly = setdiff(readonly, hiddenAndReadonly); |
| 88 | + PropertyGroups = struct(... |
| 89 | + 'Function', {... |
| 90 | + @()file.fillProps(classprops, hiddenAndReadonly, 'PropertyAttributes', 'Hidden, SetAccess = protected') ... |
| 91 | + , @()file.fillProps(classprops, hidden, 'PropertyAttributes', 'Hidden') ... |
| 92 | + , @()file.fillProps(classprops, readonly, 'PropertyAttributes', 'SetAccess = protected') ... |
| 93 | + , @()file.fillProps(classprops, required, 'IsRequired', true) ... |
| 94 | + , @()file.fillProps(classprops, optional)... |
| 95 | + } ... |
| 96 | + , 'Separator', { ... |
| 97 | + '% HIDDEN READONLY PROPERTIES' ... |
| 98 | + , '% HIDDEN PROPERTIES' ... |
| 99 | + , '% READONLY PROPERTIES' ... |
| 100 | + , '% REQUIRED PROPERTIES' ... |
| 101 | + , '% OPTIONAL PROPERTIES' ... |
| 102 | + } ... |
| 103 | + ); |
| 104 | + fullPropertyDefinition = ''; |
| 105 | + for iGroup = 1:length(PropertyGroups) |
| 106 | + Group = PropertyGroups(iGroup); |
| 107 | + propertyDefinitionBody = Group.Function(); |
| 108 | + if isempty(propertyDefinitionBody) |
| 109 | + continue; |
| 110 | + end |
| 111 | + fullPropertyDefinition = strjoin({... |
| 112 | + fullPropertyDefinition ... |
| 113 | + , Group.Separator ... |
| 114 | + , propertyDefinitionBody ... |
| 115 | + }, newline); |
93 | 116 | end |
94 | | -end |
95 | 117 |
|
96 | | -constructorBody = file.fillConstructor(... |
97 | | - name,... |
98 | | - depnm,... |
99 | | - defaults,... %all defaults, regardless of inheritance |
100 | | - classprops,... |
101 | | - namespace); |
102 | | -setterFcns = file.fillSetters(setdiff(nonInherited, readonly)); |
103 | | -validatorFcns = file.fillValidators(allprops, classprops, namespace); |
104 | | -exporterFcns = file.fillExport(nonInherited, class, depnm); |
105 | | -methodBody = strjoin({constructorBody... |
106 | | - '%% SETTERS' setterFcns... |
107 | | - '%% VALIDATORS' validatorFcns... |
108 | | - '%% EXPORT' exporterFcns}, newline); |
| 118 | + constructorBody = file.fillConstructor(... |
| 119 | + name,... |
| 120 | + depnm,... |
| 121 | + defaults,... %all defaults, regardless of inheritance |
| 122 | + classprops,... |
| 123 | + namespace); |
| 124 | + setterFcns = file.fillSetters(setdiff(nonInherited, union(readonly, hiddenAndReadonly))); |
| 125 | + validatorFcns = file.fillValidators(allProperties, classprops, namespace); |
| 126 | + exporterFcns = file.fillExport(nonInherited, class, depnm); |
| 127 | + methodBody = strjoin({constructorBody... |
| 128 | + '%% SETTERS' setterFcns... |
| 129 | + '%% VALIDATORS' validatorFcns... |
| 130 | + '%% EXPORT' exporterFcns}, newline); |
109 | 131 |
|
110 | | -if strcmp(name, 'DynamicTable') |
111 | | - methodBody = strjoin({methodBody, '%% TABLE METHODS', file.fillDynamicTableMethods()}, newline); |
112 | | -end |
| 132 | + if strcmp(name, 'DynamicTable') |
| 133 | + methodBody = strjoin({methodBody, '%% TABLE METHODS', file.fillDynamicTableMethods()}, newline); |
| 134 | + end |
113 | 135 |
|
114 | | -fullMethodBody = strjoin({'methods' ... |
115 | | - file.addSpaces(methodBody, 4) 'end'}, newline); |
116 | | -template = strjoin({classDef propsDef fullMethodBody 'end'}, ... |
117 | | - [newline newline]); |
| 136 | + fullMethodBody = strjoin({'methods' ... |
| 137 | + file.addSpaces(methodBody, 4) 'end'}, newline); |
| 138 | + template = strjoin({classDefinitionHeader fullPropertyDefinition fullMethodBody 'end'}, ... |
| 139 | + [newline newline]); |
118 | 140 | end |
119 | 141 |
|
0 commit comments