Как использовать листы Kotlin в проекте Android

Я хочу использовать листы Kotlin в моем проекте Android, чтобы добавлять черновики кода, например:

draft.ws.kts

package com.example.app

val a = 1 + 1
a

Сам рабочий лист работает:

val a: Int
2

Но создание моего приложения для Android не удается со следующим результатом:

> Task :appicals:compileDebugKotlin FAILED
e: org.jetbrains.kotlin.util.KotlinFrontEndException: Front-end Internal error: Failed to analyze declaration Draft_ws
File being compiled: (1,43) in /Users/me/secretproject/app/src/main/java/com/example/app/draft.ws.kts
The root cause org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException was thrown at: org.jetbrains.kotlin.resolve.lazy.BasicAbsentDescriptorHandler.diagnoseDescriptorNotFound(AbsentDescriptorHandler.kt:18)
    at org.jetbrains.kotlin.resolve.ExceptionWrappingKtVisitorVoid.visitDeclaration(ExceptionWrappingKtVisitorVoid.kt:43)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:453)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:21)
    at org.jetbrains.kotlin.psi.KtVisitor.visitScript(KtVisitor.java:78)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitScript(KtVisitorVoid.java:73)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitScript(KtVisitorVoid.java:519)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitScript(KtVisitorVoid.java:21)
    at org.jetbrains.kotlin.psi.KtScript.accept(KtScript.java:69)
    at org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
    at org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer$analyzeDeclarations$1.registerDeclarations(LazyTopDownAnalyzer.kt:78)
    at org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer$analyzeDeclarations$1.visitKtFile(LazyTopDownAnalyzer.kt:96)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:513)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:21)
    at org.jetbrains.kotlin.psi.KtFile.accept(KtFile.kt:242)
    at org.jetbrains.kotlin.psi.KtFile.accept(KtFile.kt:229)
    at org.jetbrains.kotlin.resolve.ExceptionWrappingKtVisitorVoid.visitElement(ExceptionWrappingKtVisitorVoid.kt:27)
    at org.jetbrains.kotlin.com.intellij.psi.PsiElementVisitor.visitFile(PsiElementVisitor.java:34)
    at org.jetbrains.kotlin.psi.KtVisitor.visitKtFile(KtVisitor.java:73)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:69)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:513)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitKtFile(KtVisitorVoid.java:21)
    at org.jetbrains.kotlin.psi.KtFile.accept(KtFile.kt:242)
    at org.jetbrains.kotlin.psi.KtFile.accept(KtFile.kt:229)
    at org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer.analyzeDeclarations(LazyTopDownAnalyzer.kt:201)
    at org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer.analyzeDeclarations$default(LazyTopDownAnalyzer.kt:60)
    at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
    at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:82)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:554)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:81)
    at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:107)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:545)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:176)
    at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:163)
    at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:51)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:85)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:43)
    at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:104)
    at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:349)
    at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:105)
    at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileIncrementally(IncrementalCompilerRunner.kt:237)
    at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.access$compileIncrementally(IncrementalCompilerRunner.kt:37)
    at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner$compile$2.invoke(IncrementalCompilerRunner.kt:79)
    at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:91)
    at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:606)
    at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:99)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1645)
    at sun.reflect.GeneratedMethodAccessor182.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:357)
    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:573)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException: Descriptor wasn't found for declaration SCRIPT
    at org.jetbrains.kotlin.resolve.lazy.BasicAbsentDescriptorHandler.diagnoseDescriptorNotFound(AbsentDescriptorHandler.kt:18)
    at org.jetbrains.kotlin.resolve.lazy.BasicAbsentDescriptorHandler.diagnoseDescriptorNotFound(AbsentDescriptorHandler.kt:17)
    at org.jetbrains.kotlin.resolve.lazy.LazyDeclarationResolver.findClassDescriptor(LazyDeclarationResolver.kt:88)
    at org.jetbrains.kotlin.resolve.lazy.LazyDeclarationResolver.getScriptDescriptor(LazyDeclarationResolver.kt:65)
    at org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer$analyzeDeclarations$1.visitScript(LazyTopDownAnalyzer.kt:89)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitScript(KtVisitorVoid.java:519)
    at org.jetbrains.kotlin.psi.KtVisitorVoid.visitScript(KtVisitorVoid.java:21)
    at org.jetbrains.kotlin.psi.KtScript.accept(KtScript.java:69)
    at org.jetbrains.kotlin.psi.KtElementImplStub.accept(KtElementImplStub.java:59)
    at org.jetbrains.kotlin.resolve.ExceptionWrappingKtVisitorVoid.visitDeclaration(ExceptionWrappingKtVisitorVoid.kt:32)
    ... 61 more

Зависимость implementation "org.jetbrains.kotlin:kotlin-script-runtime:1.3.70"

2 ответа

Не уверен, что это считается отличным ответом, поскольку он не просто полностью исправляет его, но суть в том, что ... изменить расширение файла. Просто добавьте подчеркивание в конце или что-то в этом роде.

OMFSM Я так долго пытался найти правильный способ сделать это. А потом пробовал миллион разных кладжей. И раньше у меня даже не было этой проблемы (даже не знал, что рабочие листы существуют, TBH), это просто выглядело как хорошая идея.

Есть несколько способов сделать это проще, но все равно требуется вмешательство человека, когда вы хотите построить (или вы можете просто не использовать их, пока они вам снова не понадобятся).

Лично я только что создал пару командных файлов (хотя каждая из них - только одна команда), которые переименовали все файлы .kts (а затем переименовали их обратно) и создал несколько удобных ярлыков. Я использую Windows, и создание сценариев bash определенно не входит в мои компетенции, поэтому я уверен, что это можно сделать и на * nix.

Чтобы переименовать их все, чтобы они не пытались скомпилировать:

      forfiles /S /M *.ws.kts /C "cmd /c ren @file @fname.kts_"

и превратить их обратно в действующие рабочие листы:

      forfiles /S /M *.ws.kts_ /C "cmd /c ren @file @fname.kts"

Чтобы сделать командный файл из одного из них:

  1. Открыть блокнот
  2. Скопируйте в него одну из этих строк.
  3. Идти к File > Save, перейдите в папку, в которой сохранен ваш проект, и дайте ему имя файла, заключенное в двойные кавычки (") и заканчивающееся на .bat
    • Например, «disable_worksheets.bat» и «enable_worksheets.bat», но не забудьте включить двойные кавычки .

Теперь вы можете просто найти этот файл в проводнике Windows и дважды щелкнуть по нему, чтобы отключить или включить их все сразу.

Если вы хотите, вы также можете сделать макрос для каждого способа в Android Studio, но AFAIK, который может изменять только один файл за раз (хотя вы можете установить сочетание клавиш, поэтому оно работает, если у вас не слишком много рабочие листы). Чтобы макрос отключал рабочий лист:

  1. Выберите файл рабочего листа в дереве слева
  2. В строке меню перейдите и нажмите « Начать запись макроса ».
  3. Щелкните правой кнопкой мыши свой лист в дереве и в меню выберите « Переименовать файл ... »
  4. Нажмите End на клавиатуре
  5. Введите подчеркивание _
  6. Нажмите Enter
  7. В строке меню перейдите и нажмите « Остановить запись макроса ».
  8. Дайте вашему макросу имя и нажмите ОК.

И для того, чтобы его снова включить:

  1. Выберите файл рабочего листа в дереве слева
  2. В строке меню перейдите и нажмите « Начать запись макроса ».
  3. Щелкните правой кнопкой мыши свой лист в древовидном представлении и под Refactorв меню выберите " Переименовать ..."
  4. Нажмите End на клавиатуре
  5. Нажмите Backspace
  6. Нажмите Enter
  7. В строке меню перейдите и нажмите « Остановить запись макроса ».
  8. Дайте вашему макросу имя и нажмите ОК.

Теперь вы можете просто выбрать файл в дереве, а затем в меню перейти к Edit > Macrosи щелкните по нужному. Но для удобства можно установить сочетания клавиш. Для этого:

  1. В строке меню перейдите к Fileи нажмите " Настройки ..."
  2. В меню слева нажмите « Раскладка ».
  3. На главной панели редактора щелкните значок рядом с « Макросы », чтобы развернуть этот раздел.
  4. Щелкните правой кнопкой мыши макрос, для которого хотите установить ярлык, и нажмите « Добавить сочетание клавиш ».
  5. Нажмите клавиши ярлыка, который вы хотите использовать (например, Ctrl + Comma). Он предупредит вас, если ярлык уже использует эти клавиши, поэтому вам, возможно, придется использовать несколько модификаторов (например, Ctrl + Shift + G)
    • Я обнаружил, что некоторые из них по умолчанию пусты (по крайней мере, в моей установке) и используют только Ctrl в качестве модификатора: Ctrl + запятая (,), Ctrl + точка с запятой (;) и Ctrl + обратная косая черта (\).
    • Большинство клавиш цифровой клавиатуры не используются, но, очевидно, они не так удобны.
  6. Нажмите ОК, чтобы вернуться в главное окно настроек.
  7. Если вы хотите установить ярлык для другого макроса, просто повторите шаги 4-6.
  8. Нажмите ОК внизу окна настроек.

После этого все, что вам нужно сделать, это щелкнуть имя файла в дереве слева и нажать комбинацию клавиш.

Надеюсь, все это кому-то поможет! И извините, если это было немного долго, но быть кратким - тоже не входит в мои навыки.

TL;DR: IntelliJ отлично его поддерживает. Android Studio скрывает это.

1: Создайте новый файл, щелкнув правой кнопкой мыши в дереве проекта и выбрав New ► Scratch File или нажав Ctrl+Alt+Shift+Insert и выбрав Kotlin из появившегося списка.

Он хранит их в папке конфигурации IDE, поэтому Gradle не приближается к ним, но в редакторе есть простая настройка для каждого файла, чтобы использовать путь к классам для открытого проекта. Это также означает, что они совместно используются проектами.

2: В представлении проекта слева вверху щелкните Android и выберите «Проект». Они будут находиться в папке внизу под названием Scratches and Consoles ► Scratches и откройте свои рабочие листы. Теперь вы можете вернуться к представлению Android.

3: Вините Google.


Вот длинная история:

Итак, поигравшись и проведя дополнительные исследования - что я, вероятно, должен был сделать в первую очередь - IntelliJ поддерживает эту функцию (довольно хорошо, судя по всему), но Android Studio как бы скрывает ее.

IntelliJ называет их временными файлами (звучит правильно). Они хранятся в папке настроек IDE (в моем случае %APPDATA%\Google\AndroidStudio4.1\scratches), поэтому Gradle их даже не видит. Будучи сохраненными в настройках IDE, они также являются глобальными, а не частью конкретного проекта, поэтому вы можете получить к ним доступ из любого проекта.

Чтобы создать его, щелкните правой кнопкой мыши в любом месте панели инструментов проекта слева и выберите « Создать» ► «Временный файл» или нажмите Ctrl+Alt+Shift+Insert. Это вызовет меню языков, по умолчанию для меня это Kotlin (возможно, потому, что проект, который я открыл, находится в Kotlin), с этим выбранным просто нажмите Enter. Это откроет файл в виде вкладки в редакторе, код слева, результат справа. Вверху есть опция « Использовать путь к классу модуля» с раскрывающимся списком справа, вы можете выбрать модуль в текущем открытом проекте (вы знаете, для тестирования материала с проектом).

По умолчанию файл называется скретч.kts (или, если у вас их несколько, скретч_1.ктс, скретч_2.ктс и т. д . Вы можете переименовать его, если хотите, щелкнув правой кнопкой мыши его вкладку в окнах редактора и выбрав Переименовать файл...

Вот важная часть:

В Android Studio областью по умолчанию для дерева проекта (по умолчанию панель инструментов в левой части окна) установлено значение Android. Если вы нажмете на это и выберите Project. Внизу будет папка Scratches and Consoles с подпапкой Scratches. И вуаля! Ваши рабочие файлы там. Очевидно, что в общем представлении проекта вы теряете все тонкости Android, поэтому вы можете переключиться обратно сейчас, просто помните, как туда вернуться. Если есть способ заставить их появиться, я не могу его найти (но, если вы еще не можете сказать, я не опытный программист Android, а просто умница со слишком большим количеством свободного времени).

Другие вопросы по тегам