@@ -81,118 +81,119 @@ class ComponentAstVisitor extends RecursiveAstVisitor<void> {
8181 ComponentInfo ? componentInfo;
8282 List <PropertyInfo > propertyList = [];
8383 Map <String ,PropertyInfo > fieldMap = {};
84+ // 当前正在解析的目标类名(null 表示不在目标类内)
85+ String ? _currentTargetClassName;
86+ // 当前正在解析的类是否是 abstract class(用于收集实例方法)
87+ bool _currentClassIsAbstract = false ;
88+
89+ bool get _isInTargetClass => _currentTargetClassName != null ;
90+
91+ void _resetClassState () {
92+ componentInfo = null ;
93+ propertyList = [];
94+ fieldMap = {};
95+ _currentTargetClassName = null ;
96+ _currentClassIsAbstract = false ;
97+ }
98+
99+ PropertyInfo _buildPropertyFromParameter (FormalParameter param) {
100+ final PropertyInfo item = PropertyInfo ();
101+ item.name = param.name? .lexeme.toString () ?? '' ;
102+ item.isRequired =
103+ param.isRequired || param.toSource ().toString ().startsWith ('@required' );
104+ item.isNamed = param.isNamed;
105+ item.type = extractFormalParameterType (param);
106+ item.defaultValue = formatDefaultValueForDoc (
107+ extractFormalParameterDefaultValue (param),
108+ paramName: item.name,
109+ isRequired: item.isRequired,
110+ );
111+ return item;
112+ }
113+
114+ void _mergeExtraFieldsIntoPropertyList () {
115+ for (final MapEntry <String , PropertyInfo > entry in fieldMap.entries) {
116+ if (entry.key.startsWith ('_' )) {
117+ continue ;
118+ }
119+ final bool exists =
120+ propertyList.any ((PropertyInfo element) => element.name == entry.key);
121+ if (! exists) {
122+ final PropertyInfo field = entry.value;
123+ field.name = entry.key;
124+ propertyList.add (field);
125+ }
126+ }
127+ }
128+
129+ void _fillPropertyFromFieldMap (PropertyInfo item) {
130+ final PropertyInfo ? field = fieldMap[item.name];
131+ if (field == null ) {
132+ return ;
133+ }
134+ if (item.type.isEmpty && field.type.isNotEmpty) {
135+ item.type = field.type;
136+ }
137+ if (item.introduction.isEmpty && field.introduction.isNotEmpty) {
138+ item.introduction = field.introduction;
139+ }
140+ }
84141
85142 @override
86143 void visitConstructorDeclaration (ConstructorDeclaration node) {
144+ if (! _isInTargetClass) {
145+ node.visitChildren (this );
146+ return ;
147+ }
87148 node.visitChildren (this );
88- // 无命名构造函数
89- // List childEntities = node.childEntities.toList();
90- // bool isNormalConstructor = childEntities.isNotEmpty && nameList!.contains(childEntities[0].toString());
91- // bool isConstConstructor = childEntities.length >= 2 && childEntities[0].toString() == 'const' && nameList!.contains(childEntities[1].toString());
92149 if (node.name == null ) {
93150 for (final FormalParameter param in node.parameters.parameters) {
94- List <String > strList = [];
95- strList.add ('identifier:' + (param.name? .lexeme.toString () ?? "" ));
96- strList.add ('isNamed:' + param.isNamed.toString ());
97- strList.add ('isOptional:' + param.isOptional.toString ());
98- strList.add ('isOptionalNamed:' + param.isOptionalNamed.toString ());
99- strList.add ('isOptionalPositional:' + param.isOptionalPositional.toString ());
100- strList.add ('isPositional:' + param.isPositional.toString ());
101- strList.add ('isRequired:' + param.isRequired.toString ());
102- strList.add ('isRequiredNamed:' + param.isRequiredNamed.toString ());
103- strList.add ('isRequiredPositional:' + param.isRequiredPositional.toString ());
104- strList.add ('requiredKeyword:' + param.requiredKeyword.toString ());
105- strList.add ('declaredElement:' + param.declaredElement.toString ());
106- strList.add ('parent:' + param.toSource ().toString ());
107- strList.add ('beginToken:' + param.beginToken.toString ());
108- strList.add ('endToken:' + param.endToken.toString ());
109- String tmp = '' ;
110- if (param.childEntities.isNotEmpty) {
111- tmp = param.childEntities.map ((e) => e.toString ()).toList ().join ('|' );
112- }
113- strList.add ('childEntities:' + tmp);
114- Debug .yellow ('构造参数[$folderName ]: ${strList .join (', ' )}' );
115- PropertyInfo item = PropertyInfo ();
116- item.name = param.name? .lexeme.toString () ?? "" ;
117- item.isRequired = param.isRequired || param.toSource ().toString ().startsWith ('@required' );
118- item.isNamed = param.isNamed;
119- if (param.childEntities.length == 3 ) {
120- item.defaultValue = param.childEntities.toList ().last.toString ();
121- }
122- if (tmp.startsWith ('Key' ) && param.beginToken.toString () == 'Key' ) {
123- item.type = 'Key' ;
124- }
125- propertyList.add (item);
151+ Debug .yellow ('构造参数[$folderName ]: ${param .toSource ()}' );
152+ propertyList.add (_buildPropertyFromParameter (param));
126153 }
127154 } else {
128155 // 记录工厂构造方法
129- StaticMethodInfo staticMethodInfo = new StaticMethodInfo ();
156+ final StaticMethodInfo staticMethodInfo = StaticMethodInfo ();
130157 staticMethodInfo.name = node.name.toString ();
131- staticMethodInfo.introduction = removeDocumentationComment (node.documentationComment? .tokens.join ("\n " ) ?? "" );
132- // staticMethodInfo.returnType = node.returnType.type.toString();
133- node.parameters.parameters.forEach ((element) {
134- PropertyInfo info = PropertyInfo ();
135- info.name = element.name? .lexeme.toString () ?? "Null" ;
136- // if (element is SimpleFormalParameter) {
137- // info.type = element.type.toString();
138- // } else if(element is DefaultFormalParameter && element.parameter is FieldFormalParameter){
139- // info.type = (element.parameter as FieldFormalParameter).parameters.toString();
140- // } else if(element is FieldFormalParameter) {
141- // info.name = element.toString();
142- // }
143-
144- info.isRequired =
145- element.isRequiredNamed || element.isRequiredPositional;
146- info.isNamed = element.isNamed;
147-
148- staticMethodInfo.params.add (info);
149- });
158+ staticMethodInfo.introduction = removeDocumentationComment (
159+ node.documentationComment? .tokens.join ('\n ' ) ?? '' );
160+ for (final FormalParameter element in node.parameters.parameters) {
161+ staticMethodInfo.params.add (_buildPropertyFromParameter (element));
162+ }
150163 componentInfo ?? = ComponentInfo ();
151164 componentInfo! .constructorMethodList.add (staticMethodInfo);
152165 }
153- String tmp = '' ;
154- if (node.childEntities.isNotEmpty) {
155- tmp = node.childEntities.map ((e) => e.toString ()).toList ().join ('|' );
156- }
157- List <String > strList = [];
158- strList.add (node.firstTokenAfterCommentAndMetadata.toString ());
159- strList.add (node.parameters.parameters.map ((e) => e.name? .lexeme.toString () ?? "" ).toList ().join ('|' ));
160- strList.add (node.childEntities.length.toString ());
161- strList.add (tmp);
162- strList.add (node.beginToken.toString ());
163- strList.add (node.name.toString ());
164- // strList.add(node.toSource());
165- Debug .green ('构造函数[$folderName ]: ${strList .join (', ' )}' );
166+ Debug .green (
167+ '构造函数[$folderName ]: ${node .name ?? 'default' } | ${node .parameters .parameters .map ((FormalParameter e ) => e .name ?.lexeme ).join ('|' )}' );
166168 }
167169
168170 @override
169171 void visitFieldDeclaration (FieldDeclaration node) {
170- node.visitChildren (this );
171- String tmp = '' ;
172- if (node.childEntities.isNotEmpty) {
173- tmp = node.childEntities.map ((e) => e.toString ()).toList ().join ('|' );
172+ if (! _isInTargetClass) {
173+ node.visitChildren (this );
174+ return ;
174175 }
175- List <String > strList = [];
176- strList.add (node.childEntities.length.toString ());
177- strList.add (tmp);
178- strList.add (node.beginToken.toString ());
179- strList.add (node.toSource ());
180- strList.add ('type:' + node.fields.type.toString ());
181- strList.add ('fields:' + node.fields.variables.join (',' ).toString ());
182- Debug .blue ('成员变量[$folderName ]: ${strList .join (', ' )}' );
176+ node.visitChildren (this );
183177 String fieldName = node.fields.variables.join (',' );
184- if (fieldName.contains ("=" )) {
185- fieldName = fieldName.split ("=" )[0 ].trim ();
178+ if (fieldName.contains ('=' )) {
179+ fieldName = fieldName.split ('=' )[0 ].trim ();
186180 }
187- PropertyInfo ? item = propertyList.firstWhereOrNull ((element) => element.name == fieldName);
188- if (item == null ) {
189- item = PropertyInfo ();
190- fieldMap[fieldName] = item;
181+ if (fieldName.startsWith ('_' )) {
182+ return ;
191183 }
184+ PropertyInfo ? item =
185+ propertyList.firstWhereOrNull ((PropertyInfo element) => element.name == fieldName);
186+ item ?? = PropertyInfo ()..name = fieldName;
187+ fieldMap[fieldName] = item;
192188 item.type = node.fields.type.toString ();
193- if (node.beginToken.toString ().startsWith ('///' )) {
189+ if (node.documentationComment != null ) {
190+ item.introduction = removeDocumentationComment (
191+ node.documentationComment! .tokens.join ('\n ' ),
192+ );
193+ } else if (node.beginToken.toString ().startsWith ('///' )) {
194194 item.introduction = removeDocumentationComment (node.beginToken.toString ());
195195 }
196+ Debug .blue ('成员变量[$folderName ]: $fieldName | ${item .type }' );
196197 }
197198
198199 @override
@@ -214,61 +215,70 @@ class ComponentAstVisitor extends RecursiveAstVisitor<void> {
214215
215216 @override
216217 void visitClassDeclaration (ClassDeclaration node) {
218+ final bool isTarget = nameList! .contains (node.name.toString ());
219+ final String ? previousTargetClassName = _currentTargetClassName;
220+ final bool previousClassIsAbstract = _currentClassIsAbstract;
221+ if (isTarget) {
222+ _currentTargetClassName = node.name.toString ();
223+ _currentClassIsAbstract = node.abstractKeyword != null ;
224+ }
217225 node.visitChildren (this );
218- if (nameList ! . contains (node.name. toString ()) ) {
226+ if (isTarget ) {
219227 componentInfo ?? = ComponentInfo ();
220- List <String > strList = [];
221- strList.add (node.name.toString ());
222- strList.add (node.beginToken.toString ());
223- if (node.name.toString () == 'TECheckBox' ) {
224- // strList.add(node.getField('checked')!.parent!.parent!.beginToken.toString());
225- strList.add (node.getProperty ('checked' )! .parent! .parent! .beginToken.toString ());
226- }
227- Debug .red ('类[$folderName ]: ${strList .join (', ' )}' );
228228 componentInfo! .name = node.name.toString ();
229229 if (node.documentationComment != null ) {
230230 componentInfo! .introduction = removeDocumentationComment (
231- node.documentationComment! .tokens.join ("\n " ));
231+ node.documentationComment! .tokens.join ('\n ' ));
232+ }
233+ _mergeExtraFieldsIntoPropertyList ();
234+ for (final PropertyInfo item in propertyList) {
235+ _fillPropertyFromFieldMap (item);
236+ if (item.type.isEmpty) {
237+ item.type = '-' ;
238+ }
232239 }
240+ propertyList.sort (
241+ (PropertyInfo a, PropertyInfo b) => a.name.toLowerCase ().compareTo (b.name.toLowerCase ()));
233242 if (onParsedComponentInfoInfo != null ) {
234- // 按照属性名称的首字母排序
235- propertyList.sort ((a, b) => a.name.toLowerCase ().compareTo (b.name.toLowerCase ()));
236-
237243 onParsedComponentInfoInfo !(ParsedComponentInfoInfo ()
238244 ..componentInfo = componentInfo
239245 ..propertyList = propertyList
240246 ..fieldMap = fieldMap);
241247 }
248+ _resetClassState ();
242249 }
243- componentInfo = null ;
244- propertyList = [] ;
250+ _currentTargetClassName = previousTargetClassName ;
251+ _currentClassIsAbstract = previousClassIsAbstract ;
245252 }
246253
247254 @override
248255 void visitMethodDeclaration (MethodDeclaration node) {
256+ if (! _isInTargetClass) {
257+ super .visitMethodDeclaration (node);
258+ return ;
259+ }
249260 super .visitMethodDeclaration (node);
250- if (node.isStatic && ! node.name.toString ().startsWith ("_" )){
251- StaticMethodInfo staticMethodInfo = new StaticMethodInfo ();
252- staticMethodInfo.name = node.name.toString ();
253- staticMethodInfo.introduction = removeDocumentationComment (node.documentationComment? .tokens.join ("\n " ) ?? "" );
254- staticMethodInfo.returnType = node.returnType? .type.toString ();
255- node.parameters? .parameters.forEach ((element) {
256- PropertyInfo info = PropertyInfo ();
257- info.name = element.name? .lexeme.toString () ?? "Null" ;
258- if (element is SimpleFormalParameter ) {
259- info.type = element.type.toString ();
260- } else if (element is DefaultFormalParameter && element.parameter is SimpleFormalParameter ){
261- info.type = (element.parameter as SimpleFormalParameter ).type.toString ();
262- }
261+ final String methodName = node.name.toString ();
262+ // 私有方法不收录
263+ if (methodName.startsWith ('_' )) {
264+ return ;
265+ }
263266
264- info.isRequired =
265- element.isRequiredNamed || element.isRequiredPositional;
266- info.isNamed = element.isNamed;
267+ StaticMethodInfo methodInfo = StaticMethodInfo ();
268+ methodInfo.name = methodName;
269+ methodInfo.introduction = removeDocumentationComment (
270+ node.documentationComment? .tokens.join ('\n ' ) ?? '' );
271+ methodInfo.returnType = node.returnType? .toSource ();
272+ node.parameters? .parameters.forEach ((FormalParameter element) {
273+ methodInfo.params.add (_buildPropertyFromParameter (element));
274+ });
267275
268- staticMethodInfo.params.add (info);
269- });
270- componentInfo ?? = ComponentInfo ();
271- componentInfo! .staticMethodList.add (staticMethodInfo);
276+ componentInfo ?? = ComponentInfo ();
277+ if (node.isStatic) {
278+ componentInfo! .staticMethodList.add (methodInfo);
279+ } else if (_currentClassIsAbstract) {
280+ // abstract class 的实例方法(含 abstract 方法和带默认实现的可覆写方法)
281+ componentInfo! .instanceMethodList.add (methodInfo);
272282 }
273283 }
274284}
@@ -341,16 +351,16 @@ class ComponentVisitor extends RecursiveElementVisitor<void> {
341351 }
342352
343353 String getDefaultValue (ParameterElement param) {
344- bool paramIsString = param.type.getDisplayString (withNullability: false ) == 'String' ;
354+ final bool paramIsString =
355+ param.type.getDisplayString (withNullability: false ) == 'String' ;
345356 String defaultValue = param.defaultValueCode! ;
346- // if (defaultValue == '\'\' ') {
347- // defaultValue = '"" ';
348- // }
357+ if (defaultValue == param.name || defaultValue == 'this.${ param . name } ' ) {
358+ return '- ' ;
359+ }
349360 if (defaultValue.startsWith ("'" )) {
350361 defaultValue = defaultValue.substring (1 , defaultValue.length - 1 );
351362 }
352- // print('paramIsString=$paramIsString, defaultValue=$defaultValue');
353- return paramIsString ? defaultValue : '$defaultValue ' ;
363+ return paramIsString ? defaultValue : defaultValue;
354364 }
355365
356366 String ? getDescription (String name, List <FieldElement > fields) {
0 commit comments