Как собрать большую карту в Kotlin для JVM или мультиплатформенных? - PullRequest
0 голосов
/ 14 января 2019

Мне нужен доступ к общему списку суффиксов в моем многоплатформенном коде 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 есть какое-то решение, о котором я не знаю.

...