Support async script dependency updates for annotation based templates

Do not try to cache dependencies for every script on startup
Schedule cache updates upon request as opposed to updating them synchronously
This commit is contained in:
Pavel V. Talanov
2017-05-25 18:22:36 +03:00
parent b7fc909821
commit a2aeda7b2c
2 changed files with 76 additions and 70 deletions
@@ -123,28 +123,35 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
override fun getScriptName(script: KtScript): Name = NameUtils.getScriptNameForFile(script.containingKtFile.name)
override fun <TF: Any> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? {
fun makeScriptContents() = BasicScriptContents(file, getAnnotations = {
val classLoader = template.java.classLoader
takeUnlessError(reportError = false) {
getAnnotationEntries(file, project)
.mapNotNull { psiAnn ->
// TODO: consider advanced matching using semantic similar to actual resolving
acceptedAnnotations.find { ann ->
psiAnn.typeName.let { it == ann.simpleName || it == ann.qualifiedName }
}?.let { constructAnnotation(psiAnn, classLoader.loadClass(it.qualifiedName).kotlin as KClass<out Annotation>) }
}
}
?: emptyList()
})
return takeUnlessError(reportError = false) {
val fileDeps = resolver?.resolve(makeScriptContents(), environment, ::logScriptDefMessage, previousDependencies)
val fileDeps = resolver?.resolve(makeScriptContents(file, project), environment, ::logScriptDefMessage, previousDependencies)
// TODO: use it as a Future
fileDeps?.get()
}
}
fun <TF: Any> makeScriptContents(file: TF, project: Project) = BasicScriptContents(file, getAnnotations = {
val classLoader = template.java.classLoader
takeUnlessError(reportError = false) {
getAnnotationEntries(file, project)
.mapNotNull { psiAnn ->
// TODO: consider advanced matching using semantic similar to actual resolving
acceptedAnnotations.find { ann ->
psiAnn.typeName.let { it == ann.simpleName || it == ann.qualifiedName }
}?.let { constructAnnotation(psiAnn, classLoader.loadClass(it.qualifiedName).kotlin as KClass<out Annotation>) }
}
}
?: emptyList()
})
fun getDependenciesFor(previousDependencies: KotlinScriptExternalDependencies?, scriptContents: ScriptContents): KotlinScriptExternalDependencies? {
return takeUnlessError(reportError = false) {
// TODO: use it as a Future
resolver?.resolve(scriptContents, environment, ::logScriptDefMessage, previousDependencies)?.get()
}
}
private fun <TF: Any> getAnnotationEntries(file: TF, project: Project): Iterable<KtAnnotationEntry> = when (file) {
is PsiFile -> getAnnotationEntriesFromPsiFile(file)
is VirtualFile -> getAnnotationEntriesFromVirtualFile(file, project)