-
Notifications
You must be signed in to change notification settings - Fork 0
Feat/#12 WispRegistry 코드 생성 기능 구현 #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
f1d30c9
b4dd159
3309ab9
1d2227d
4b9ce90
7a7e464
488f8bc
c49a493
efd128e
384ba55
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.angrypodo.wisp | ||
|
|
||
| import com.squareup.kotlinpoet.ClassName | ||
|
|
||
| internal object WispClassName { | ||
| private const val RUNTIME_PACKAGE = "com.angrypodo.wisp.runtime" | ||
| const val GENERATED_PACKAGE = "com.angrypodo.wisp.generated" | ||
|
|
||
| val ROUTE_FACTORY = ClassName(RUNTIME_PACKAGE, "RouteFactory") | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| package com.angrypodo.wisp.generator | ||
|
|
||
| import com.angrypodo.wisp.WispClassName.ROUTE_FACTORY | ||
| import com.angrypodo.wisp.model.ClassRouteInfo | ||
| import com.angrypodo.wisp.model.ObjectRouteInfo | ||
| import com.angrypodo.wisp.model.ParameterInfo | ||
|
|
@@ -25,7 +26,6 @@ internal class RouteFactoryGenerator( | |
| private val logger: KSPLogger | ||
| ) { | ||
|
|
||
| private val routeFactoryInterface = ClassName("com.angrypodo.wisp.runtime", "RouteFactory") | ||
| private val missingParameterError = ClassName( | ||
| "com.angrypodo.wisp.runtime", | ||
| "WispError", | ||
|
|
@@ -47,7 +47,7 @@ internal class RouteFactoryGenerator( | |
|
|
||
| val factoryObject = TypeSpec.objectBuilder(routeInfo.factoryClassName) | ||
| .addModifiers(KModifier.INTERNAL) | ||
| .addSuperinterface(routeFactoryInterface) | ||
| .addSuperinterface(ROUTE_FACTORY) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 아주 좋네요👍🏻
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 바로 수정하겠습니다! |
||
| .addFunction(createFun) | ||
| .build() | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package com.angrypodo.wisp.generator | ||
|
|
||
| import com.angrypodo.wisp.WispClassName.GENERATED_PACKAGE | ||
| import com.angrypodo.wisp.WispClassName.ROUTE_FACTORY | ||
| import com.angrypodo.wisp.model.RouteInfo | ||
| import com.squareup.kotlinpoet.CodeBlock | ||
| import com.squareup.kotlinpoet.FileSpec | ||
| import com.squareup.kotlinpoet.KModifier | ||
| import com.squareup.kotlinpoet.MAP | ||
| import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy | ||
| import com.squareup.kotlinpoet.PropertySpec | ||
| import com.squareup.kotlinpoet.STRING | ||
| import com.squareup.kotlinpoet.TypeSpec | ||
|
|
||
| internal object WispRegistryGenerator { | ||
| private const val REGISTRY_NAME = "WispRegistry" | ||
|
|
||
| fun generate(routes: List<RouteInfo>): FileSpec { | ||
| val mapType = MAP.parameterizedBy(STRING, ROUTE_FACTORY) | ||
|
|
||
| val initializerBlock = CodeBlock.builder() | ||
| .add("mapOf(\n") | ||
| .indent() | ||
|
|
||
| routes.forEach { route -> | ||
| initializerBlock.add("%S to %T,\n", route.wispPath, route.factoryClassName) | ||
| } | ||
|
|
||
| initializerBlock.unindent().add(")") | ||
|
|
||
| val factoriesProperty = PropertySpec.builder("factories", mapType) | ||
| .addModifiers(KModifier.INTERNAL) | ||
| .initializer(initializerBlock.build()) | ||
| .build() | ||
|
||
|
|
||
| val registryObject = TypeSpec.objectBuilder(REGISTRY_NAME) | ||
| .addModifiers(KModifier.INTERNAL) | ||
| .addProperty(factoriesProperty) | ||
| .build() | ||
|
|
||
| return FileSpec.builder(GENERATED_PACKAGE, REGISTRY_NAME) | ||
| .addType(registryObject) | ||
| .build() | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package com.angrypodo.wisp.generator | ||
|
|
||
| import com.angrypodo.wisp.model.ClassRouteInfo | ||
| import com.angrypodo.wisp.model.ObjectRouteInfo | ||
| import com.squareup.kotlinpoet.ClassName | ||
| import org.junit.jupiter.api.Assertions.assertTrue | ||
| import org.junit.jupiter.api.DisplayName | ||
| import org.junit.jupiter.api.Test | ||
|
|
||
| internal class RegistryGeneratorTest { | ||
|
|
||
| @Test | ||
| @DisplayName("RouteInfo를 받아 WispRegistry 오브젝트와 맵을 생성한다") | ||
| fun `generate_registry_with_multiple_routes`() { | ||
| // Given: RouteInfo 데이터 2개 | ||
| val homeRoute = ObjectRouteInfo( | ||
| routeClassName = ClassName("com.example", "Home"), | ||
| factoryClassName = ClassName("com.example", "HomeRouteFactory"), | ||
| wispPath = "home" | ||
| ) | ||
|
|
||
| val profileRoute = ClassRouteInfo( | ||
| routeClassName = ClassName("com.example", "Profile"), | ||
| factoryClassName = ClassName("com.example", "ProfileRouteFactory"), | ||
| wispPath = "profile/{id}", | ||
| parameters = emptyList() | ||
| ) | ||
|
|
||
| val routes = listOf(homeRoute, profileRoute) | ||
|
|
||
| // When: 코드 생성 실행 | ||
| val fileSpec = WispRegistryGenerator.generate(routes) | ||
| val generatedCode = fileSpec.toString() | ||
|
|
||
| println(generatedCode) | ||
|
|
||
| // Then: 생성된 WispRegistry 객체를 반환 | ||
| assertTrue(generatedCode.contains("object WispRegistry")) | ||
| assertTrue(generatedCode.contains("val factories: Map<String, RouteFactory> = mapOf(")) | ||
|
|
||
| assertTrue(generatedCode.contains("import com.example.HomeRouteFactory")) | ||
| assertTrue(generatedCode.contains("\"home\" to HomeRouteFactory")) | ||
|
|
||
| assertTrue(generatedCode.contains("import com.example.ProfileRouteFactory")) | ||
| assertTrue(generatedCode.contains("\"profile/{id}\" to ProfileRouteFactory")) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분도 구조적인 측면에서 제안이 있어요😊
이 검증 함수를
WispValidator클래스로 옮기는 건 어떻게 생각하시나요?저는
WispProcessor는 심볼을 찾고 생성기를 호출하는 흐름을 담당하고Wispvalidator는 모든 종류의 유효성 검사를 책임지는 구조가 될것 같아요🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋은 제안입니다! 😊 작성할 때 기존에 있던
validateSerializable때문에 검증 로직을 어디에 두는 게 맞을지 저도 살짝 고민했었거든요. ㅎㅎ 제안해주신 대로WispValidator객체에서 유효성 검사를 할 수 있도록 리팩토링 진행하겠습니다!