openapi-processor / openapi-processor/openapi-processor-spring

Support complex generic type response mapping procesing

未关闭
#150 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

enhancement
主要语言
Kotlin
星标
56
派生
11
平均合并
2 天 4 小时
30 天内合并 PR
8

描述

Hi @hauner!

Processing response mapping of generic types with depth 1 works fine:

FooToBar => java.util.Map<java.lang.String, java.lang.String>
FooToBar => java.util.Map<java.lang.String,  java.lang.List>

But it doesn't work with a complex generic types such as:

FooToBar => java.util.Map<java.lang.String, java.lang.List<java.lang.String>>

The output of processing:

line 1:64 no viable alternative at input 'java.util.Map<java.lang.String,java.lang.List<'
processing failed!
io.openapiprocessor.core.processor.mapping.v2.parser.antlr.MappingException: failed to parse mapping: FooToBar => java.util.Map<java.lang.String, java.lang.List<java.lang.String>>
	at io.openapiprocessor.core.processor.mapping.v2.parser.antlr.ParserKt.parseMapping(Parser.kt:27)
	at io.openapiprocessor.core.processor.mapping.v2.MappingConverter.convertType(MappingConverter.kt:91)
	at io.openapiprocessor.core.processor.mapping.v2.MappingConverter.convert(MappingConverter.kt:44)
	at io.openapiprocessor.core.processor.MappingConverter.convert(MappingConverter.kt:29)
	at io.openapiprocessor.core.converter.OptionsConverter.readMapping(OptionsConverter.kt:69)
	at io.openapiprocessor.core.converter.OptionsConverter.convertOptions(OptionsConverter.kt:34)
	at io.openapiprocessor.spring.processor.SpringProcessor.convertOptions(SpringProcessor.kt:116)
	at io.openapiprocessor.spring.processor.SpringProcessor.run(SpringProcessor.kt:45)
	at io.openapiprocessor.gradle.OpenApiProcessorWorker.run(OpenApiProcessorWorker.java:36)
	at io.openapiprocessor.gradle.OpenApiProcessorWorker.execute(OpenApiProcessorWorker.java:25)
	at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
	at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:49)
	at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:43)
	at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)
	at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:43)
	at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:49)
	at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:30)
	at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.lambda$execute$0(IsolatedClassloaderWorkerFactory.java:57)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
	at org.gradle.workers.internal.IsolatedClassloaderWorkerFactory$1.execute(IsolatedClassloaderWorkerFactory.java:49)
	at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$2(DefaultWorkerExecutor.java:205)
	at java.base@18.0.1.1/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:187)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:120)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:162)
	at org.gradle.internal.Factories$1.create(Factories.java:31)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:270)
	at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:119)
	at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:124)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:157)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:126)
	at java.base@18.0.1.1/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base@18.0.1.1/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.base@18.0.1.1/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base@18.0.1.1/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base@18.0.1.1/java.lang.Thread.run(Thread.java:833)
Caused by: io.openapiprocessor.core.processor.mapping.v2.parser.antlr.MappingParserException: no viable alternative at input 'java.util.Map<java.lang.String,java.lang.List<'
	at io.openapiprocessor.core.processor.mapping.v2.parser.antlr.MappingErrorListener.syntaxError(MappingErrorListener.kt:22)
	at org.antlr.v4.runtime.ProxyErrorListener.syntaxError(ProxyErrorListener.java:41)
	at org.antlr.v4.runtime.Parser.notifyErrorListeners(Parser.java:544)
	at org.antlr.v4.runtime.DefaultErrorStrategy.reportNoViableAlternative(DefaultErrorStrategy.java:310)
	at org.antlr.v4.runtime.DefaultErrorStrategy.reportError(DefaultErrorStrategy.java:136)
	at io.openapiprocessor.core.processor.mapping.v2.parser.antlr.MappingParser.targetType(MappingParser.java:524)
	at io.openapiprocessor.core.processor.mapping.v2.parser.antlr.MappingParser.map(MappingParser.java:276)
	at io.openapiprocessor.core.processor.mapping.v2.parser.antlr.MappingParser.mapping(MappingParser.java:154)
	at io.openapiprocessor.core.processor.mapping.v2.parser.antlr.ParserKt.parseMapping(Parser.kt:22)
	... 47 more
Caused by: org.antlr.v4.runtime.NoViableAltException
	at org.antlr.v4.runtime.atn.ParserATNSimulator.noViableAlt(ParserATNSimulator.java:2031)
	at org.antlr.v4.runtime.atn.ParserATNSimulator.execATN(ParserATNSimulator.java:470)
	at org.antlr.v4.runtime.atn.ParserATNSimulator.adaptivePredict(ParserATNSimulator.java:396)
	at io.openapiprocessor.core.processor.mapping.v2.parser.antlr.MappingParser.targetType(MappingParser.java:510)
	... 50 more
Caused by: io.openapiprocessor.core.processor.mapping.v2.parser.antlr.MappingParserException: no viable alternative at input 'java.util.Map<java.lang.String,java.lang.List<'

Caused by: org.antlr.v4.runtime.NoViableAltException


Execution failed for task '...:processSpring'.
> A failure occurred while executing io.openapiprocessor.gradle.OpenApiProcessorWorker
   > failed to parse mapping: FooToBar => java.util.Map<java.lang.String, java.lang.List<java.lang.String>>

It would be useful to add complex generic types support.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 Parser.kt 和 MappingParser.targetType 中报告的映射解析器开始,然后检查 MappingConverter.kt 和 MappingErrorListener.kt。复现 Map<String, List> 的文档映射,并追踪解析器失败的原因。当嵌套泛型映射能够成功解析且不再出现所报告的处理错误时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
java, kotlin, spring-boot
领域
tooling
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
42/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。