From 00866f5c9e55591e9afebe655bb98e1dd64b7075 Mon Sep 17 00:00:00 2001 From: aleembhd Date: Fri, 13 Mar 2026 11:31:22 +0530 Subject: [PATCH] feat(slicing): emit HttpStatus enum constants as usage slice entries Extract HttpStatus.XXX static field accesses (e.g., BAD_REQUEST, UNAUTHORIZED) from method bodies and emit them as additional ObjectUsageSlice entries. This enables downstream tools to infer multiple HTTP response codes per endpoint for OpenAPI generation. --- .../appthreat/atom/slicing/UsageSlicing.scala | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/main/scala/io/appthreat/atom/slicing/UsageSlicing.scala b/src/main/scala/io/appthreat/atom/slicing/UsageSlicing.scala index cd4de40..6c4930c 100644 --- a/src/main/scala/io/appthreat/atom/slicing/UsageSlicing.scala +++ b/src/main/scala/io/appthreat/atom/slicing/UsageSlicing.scala @@ -70,7 +70,17 @@ object UsageSlicing: case param: MethodParameterIn if !param.name.matches("(this|self)") => param }.flatMap(param => paramAnnotationSlices(param, typeMap)) - (mainSlices ++ annotationSlices) + val httpStatusMethods = filteredDecls.flatMap { + case p: MethodParameterIn => Some(p.method) + case l: Local => l.method.headOption + case m: Method => Some(m) + case _ => None + }.toSet + + val statusSlices = + httpStatusMethods.toList.flatMap(m => httpStatusFieldAccessSlices(m, typeMap)) + + (mainSlices ++ annotationSlices ++ statusSlices) .groupBy { case (method, _) => method } .view .filterKeys(m => !isExcludedMethod(m)) @@ -143,6 +153,33 @@ object UsageSlicing: }.toList end paramAnnotationSlices + private def httpStatusFieldAccessSlices( + method: Method, + typeMap: Map[String, String] + ): List[(Method, ObjectUsageSlice)] = + method.call + .nameExact(Operators.fieldAccess) + .methodFullName(".*HttpStatus.*") + .flatMap { call => + call.argument.collectFirst { case fi: FieldIdentifier => + val statusDef = CallDef( + fi.canonicalName, + "org.springframework.http.HttpStatus", + Option(s"org.springframework.http.HttpStatus.${fi.canonicalName}"), + Some(true), + call.lineNumber.map(_.intValue()), + call.columnNumber.map(_.intValue()) + ) + method -> ObjectUsageSlice( + targetObj = statusDef, + definedBy = Some(statusDef), + invokedCalls = List.empty, + argToCalls = List.empty + ) + } + }.toList + end httpStatusFieldAccessSlices + private def createMethodObjectUsageSlice( m: Method, invokedCalls: List[ObservedCall],