extractMethodResponseTypeWithField function
Extracts the type of the 'data' field from a method's response type.
Implementation
Future<Map<String, dynamic>> extractMethodResponseTypeWithField(
String filePath,
String methodName,
dynamic searchFields, [
bool returnRawType = true,
bool stripFutureType = true,
]) async {
searchFields =
searchFields.replaceAll(RegExp(r'\s+'), "").split(",") as List<String>;
if (searchFields == null ||
searchFields is List<String> && searchFields.isEmpty) {
searchFields = ["data", "body"];
}
// }
// printInfo("search declaration for field '$searchFields'");
final initialUnit = parseFileByPath(filePath);
if (initialUnit == null) {
throw Exception('File not found or failed to parse: $filePath');
}
final methodVisitor = _MethodVisitor(methodName);
initialUnit.accept(methodVisitor);
final returnType = methodVisitor.returnType;
if (returnType == null) {
throw Exception(
'Method "$methodName" not found or has no return type in $filePath',
);
}
if (returnRawType) {
// print(" raw return type: $returnType");
if (stripFutureType) {
return {"responseDataType": unwrapFuture(returnType.toString())};
}
return {"responseDataType": returnType.toString()};
}
final innerType = getInnerTypeByPosition(returnType, at: 0);
if (innerType == "void") {
return {"responseDataType": innerType};
}
final filesToSearch = <String>{filePath};
// final fileDir = p.dirname(filePath);
final partOfDirective = initialUnit.directives
.whereType<PartOfDirective>()
.firstOrNull;
if (partOfDirective != null && partOfDirective.libraryName != null) {
final libraryName = partOfDirective.libraryName!.name;
final projectRoot = getProjectRootPath(scriptPath: filePath);
// Search for the library file within the project root.
final libraryFilePath = findLibraryFile(projectRoot!, libraryName);
if (libraryFilePath != null) {
final libraryDir = p.dirname(libraryFilePath);
filesToSearch.add(libraryFilePath);
final libraryUnit = parseFileByPath(libraryFilePath);
if (libraryUnit != null) {
for (final directive
in libraryUnit.directives.whereType<PartDirective>()) {
final partUri = directive.uri.stringValue;
if (partUri != null) {
final partPath = p.normalize(p.join(libraryDir, partUri));
filesToSearch.add(partPath);
}
}
}
}
}
// print({filesToSearch.toList().join("\n")});
ClassDeclaration? classNode;
String? classDeclarationPath;
for (final path in filesToSearch) {
classNode = findClassInFile(path, innerType);
if (classNode != null) {
classDeclarationPath = path;
printInfo("found by findClassInFile ($classDeclarationPath}");
break;
}
}
// TODO: bellow maybe never reach
if (classNode == null) {
final projectRoot = getProjectRootPath(scriptPath: filePath);
if (projectRoot != null) {
final result = findClassInProjectWithFilePath(projectRoot, innerType);
if (result != null) {
classNode = result.classNode;
classDeclarationPath = result.filePath;
printInfo(
"found in getProjectRootPath+findClassInProjectWithFilePath ($classDeclarationPath)",
);
}
}
}
// END TODO
bool foundBy_findClassDeclarationWithHttpResponse = false;
if (classNode == null) {
try {
classNode = await findClassDeclarationWithHttpResponse(
codePath: filePath,
);
if (classNode != null) {
foundBy_findClassDeclarationWithHttpResponse = true;
// printSuccess("found by findClassDeclarationWithHttpResponse");
}
} catch (e) {}
}
if (classNode == null) {
throw Exception(
'ClassType "$innerType" not found in the library, its parts, its direct imports, or the project.',
);
}
// print(classNode);
String? responseDataType;
TypeAnnotation? dataTypeNode;
for (final field in searchFields) {
final fieldVisitor = FieldVisitor(fieldName: field);
classNode.accept(fieldVisitor);
responseDataType = fieldVisitor.dataType;
dataTypeNode = fieldVisitor.dataTypeNode;
if (responseDataType != null && dataTypeNode != null) {
break;
}
}
// print("$innerType");
if (responseDataType == null || dataTypeNode == null) {
throw Exception('Field "$searchFields" not found in class "$innerType"');
}
String? importUri;
if (classDeclarationPath != null) {
importUri = importClauseToPath(classDeclarationPath);
}
// printInfo("↓↓↓ result ↓↓↓");
return {
"searchFields": searchFields,
"hitClass": innerType,
"hitField": foundBy_findClassDeclarationWithHttpResponse ? "body" : "data",
"responseDataType": responseDataType,
"importUri": foundBy_findClassDeclarationWithHttpResponse
? "import 'package:http/src/response.dart';"
: importUri,
"classDeclarationPath": classDeclarationPath,
};
}