Мне нужен доступ к общему списку суффиксов в моем многоплатформенном коде Kotlin. Я жестко закодировал его как карту, он имеет примерно 6220 строку и выглядит следующим образом:
val publicSuffixes = hashMapOf(
"0.bg" to 1,
"0emm.com" to 2,
"1.bg" to 1,
"12hp.at" to 1,
"12hp.ch" to 1,
...
При компиляции исходного кода для JVM (тесты) с компилятором Kotlin 1.3 выдает ошибку:
Cause: Error generating class file (truncated)/PublicSuffixListKt.class (compiled from [(truncated)/PublicSuffixList.kt]): Method code too large!
File being compiled at position: file:///Users/(truncated)/PublicSuffixList.kt
The root cause was thrown at: ClassFileFactory.java:308
at org.jetbrains.kotlin.codegen.CompilationErrorHandler.lambda$static$0(CompilationErrorHandler.java:24)
at org.jetbrains.kotlin.codegen.PackageCodegenImpl.generate(PackageCodegenImpl.java:74)
at org.jetbrains.kotlin.codegen.DefaultCodegenFactory.generatePackage(CodegenFactory.kt:97)
at org.jetbrains.kotlin.codegen.DefaultCodegenFactory.generateModule(CodegenFactory.kt:68)
at org.jetbrains.kotlin.codegen.KotlinCodegenFacade.doGenerateFiles(KotlinCodegenFacade.java:47)
at org.jetbrains.kotlin.codegen.KotlinCodegenFacade.compileCorrectFiles(KotlinCodegenFacade.java:39)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.generate(KotlinToJVMBytecodeCompiler.kt:446)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:142)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:161)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:57)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:96)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:52)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:93)
at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:362)
at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:102)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileIncrementally(IncrementalCompilerRunner.kt:225)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:100)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.execIncrementalCompiler(CompileServiceImpl.kt:606)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.access$execIncrementalCompiler(CompileServiceImpl.kt:102)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:455)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:102)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:1029)
at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:102)
at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:1071)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:1028)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:454)
at sun.reflect.GeneratedMethodAccessor99.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: Error generating class file (truncated)/PublicSuffixListKt.class (compiled from [/Users/(truncated)/PublicSuffixList.kt]): Method code too large!
at org.jetbrains.kotlin.codegen.ClassFileFactory$OutputClassFile.asByteArray(ClassFileFactory.java:308)
at org.jetbrains.kotlin.cli.common.output.OutputUtilsKt.writeAll(outputUtils.kt:32)
at org.jetbrains.kotlin.cli.common.output.OutputUtilsKt.writeAll(outputUtils.kt:42)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.writeOutput(KotlinToJVMBytecodeCompiler.kt:87)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.access$writeOutput(KotlinToJVMBytecodeCompiler.kt:67)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$createOutputFilesFlushingCallbackIfPossible$1.invoke(KotlinToJVMBytecodeCompiler.kt:96)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$createOutputFilesFlushingCallbackIfPossible$1.invoke(KotlinToJVMBytecodeCompiler.kt:67)
at org.jetbrains.kotlin.codegen.state.GenerationStateKt$GenerationStateEventCallback$1.invoke(GenerationState.kt:325)
at org.jetbrains.kotlin.codegen.state.GenerationStateKt$GenerationStateEventCallback$1.invoke(GenerationState.kt:324)
at org.jetbrains.kotlin.codegen.state.GenerationState.afterIndependentPart(GenerationState.kt:281)
at org.jetbrains.kotlin.codegen.PackageCodegenImpl.generate(PackageCodegenImpl.java:67)
... 41 more
Caused by: java.lang.RuntimeException: Method code too large!
at org.jetbrains.org.objectweb.asm.MethodWriter.getSize(MethodWriter.java:2059)
at org.jetbrains.org.objectweb.asm.ClassWriter.toByteArray(ClassWriter.java:861)
at org.jetbrains.kotlin.codegen.ClassBuilderFactories$2.asBytes(ClassBuilderFactories.java:119)
at org.jetbrains.kotlin.codegen.DelegatingClassBuilderFactory.asBytes(DelegatingClassBuilderFactory.kt:36)
at org.jetbrains.kotlin.codegen.DelegatingClassBuilderFactory.asBytes(DelegatingClassBuilderFactory.kt:36)
at org.jetbrains.kotlin.codegen.DelegatingClassBuilderFactory.asBytes(DelegatingClassBuilderFactory.kt:36)
at org.jetbrains.kotlin.codegen.ClassFileFactory$ClassBuilderAndSourceFileList.asBytes(ClassFileFactory.java:340)
at org.jetbrains.kotlin.codegen.ClassFileFactory$OutputClassFile.asByteArray(ClassFileFactory.java:305)
... 51 more
Что здесь можно сделать? У меня есть несколько вариантов:
- хранить карту в файле ресурсов (нежелательно, потому что проект является мультиплатформенным, и мне придется использовать подход загрузки ресурсов для конкретной платформы и иметь
expect
/ actual
с. На Android (хотя это на самом деле kotlin-jvm) будет даже другой подход [android-default] для загрузки ресурсов).
- изменить структуру данных с
HashMap
на Trie
, например
Есть предложения?
PS. Я знаю, что наличие таких огромных файлов исходного кода - это действительно плохой дизайн в целом, но он используется только для POC и первое впечатление от перехода на Kotlin (из JS), так что я чувствую себя хорошо для этого конкретного случая.
PPS. Это не дублирует вопрос Java, так как он гораздо шире и подход к загрузке ресурсов различен для каждой платформы. Если у kotlin multiplatform есть какое-то решение, о котором я не знаю.