summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-10-01 19:23:47 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-10-01 19:23:47 +0000
commitb7f7f3c623f36428dd7ab6cb27047c1198333619 (patch)
tree96e87f85a1343603b6daf464a5160a669298ca44
parent04b7586ff0142791f8c9638114a1ad70c228c316 (diff)
parente89832de680bd0d2b76835f2f7fcca31ff6e667d (diff)
downloadkotlin-mirror-goog-studio-master-dev.tar.gz
Snap for 5038502 from e89832de680bd0d2b76835f2f7fcca31ff6e667d to studio-3.2-releasestudio-3.2.1mirror-goog-studio-master-dev
Change-Id: I28fd10cf0f090b33a73738508ef6581917af5d8c
-rw-r--r--idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt15
-rw-r--r--idea/src/org/jetbrains/kotlin/idea/actions/JavaToKotlinAction.kt.as33c418
-rw-r--r--idea/src/org/jetbrains/kotlin/idea/update/GooglePluginUpdateVerifier.kt.as33c4152
-rw-r--r--plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidLayoutXmlFileManager.kt13
4 files changed, 184 insertions, 14 deletions
diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt
index c572f65b051..f31f6cad1f7 100644
--- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt
+++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt
@@ -16,6 +16,7 @@ import com.intellij.openapi.roots.impl.libraries.LibraryEx
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.util.ModificationTracker
import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.psi.ResolveScopeEnlarger
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.CachedValueProvider
import com.intellij.util.PathUtil
@@ -57,6 +58,14 @@ interface IdeaModuleInfo : org.jetbrains.kotlin.idea.caches.resolve.IdeaModuleIn
override fun dependencies(): List<IdeaModuleInfo>
}
+private fun enlargedSearchScope(searchScope: GlobalSearchScope, moduleFile: VirtualFile?): GlobalSearchScope {
+ if (moduleFile == null) return searchScope
+ return ResolveScopeEnlarger.EP_NAME.extensions.fold(searchScope) { scope, enlarger ->
+ val extra = enlarger.getAdditionalResolveScope(moduleFile, scope.project)
+ if (extra != null) scope.union(extra) else scope
+ }
+}
+
private fun orderEntryToModuleInfo(project: Project, orderEntry: OrderEntry, forProduction: Boolean): List<IdeaModuleInfo> {
fun Module.toInfos() = correspondingModuleInfos().filter { !forProduction || it is ModuleProductionSourceInfo }
@@ -158,7 +167,7 @@ data class ModuleProductionSourceInfo internal constructor(
override val name = Name.special("<production sources for module ${module.name}>")
- override fun contentScope(): GlobalSearchScope = ModuleProductionSourceScope(module)
+ override fun contentScope(): GlobalSearchScope = enlargedSearchScope(ModuleProductionSourceScope(module), module.moduleFile)
override fun <T> createCachedValueProvider(f: () -> CachedValueProvider.Result<T>) = CachedValueProvider { f() }
}
@@ -172,7 +181,7 @@ data class ModuleTestSourceInfo internal constructor(override val module: Module
override val displayedName get() = module.name + " (test)"
- override fun contentScope(): GlobalSearchScope = ModuleTestSourceScope(module)
+ override fun contentScope(): GlobalSearchScope = enlargedSearchScope(ModuleTestSourceScope(module), module.moduleFile)
override fun modulesWhoseInternalsAreVisible() = module.cached(CachedValueProvider {
val list = SmartList<ModuleInfo>()
@@ -428,4 +437,4 @@ data class PlatformModuleInfo(
}
fun IdeaModuleInfo.projectSourceModules(): List<ModuleSourceInfo>? =
- (this as? ModuleSourceInfo)?.let(::listOf) ?: (this as? PlatformModuleInfo)?.containedModules \ No newline at end of file
+ (this as? ModuleSourceInfo)?.let(::listOf) ?: (this as? PlatformModuleInfo)?.containedModules
diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/JavaToKotlinAction.kt.as33c4 b/idea/src/org/jetbrains/kotlin/idea/actions/JavaToKotlinAction.kt.as33c4
index dc0c28f012f..5e858c12a0d 100644
--- a/idea/src/org/jetbrains/kotlin/idea/actions/JavaToKotlinAction.kt.as33c4
+++ b/idea/src/org/jetbrains/kotlin/idea/actions/JavaToKotlinAction.kt.as33c4
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.idea.actions
import com.intellij.codeInsight.navigation.NavigationUtil
-import com.intellij.ide.highlighter.JavaFileType
import com.intellij.ide.scratch.ScratchFileService
import com.intellij.ide.scratch.ScratchRootType
import com.intellij.openapi.actionSystem.AnAction
@@ -30,6 +29,7 @@ import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.ui.ex.MessagesEx
+import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileVisitor
@@ -37,8 +37,6 @@ import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiManager
-import com.intellij.psi.search.FileTypeIndex
-import com.intellij.psi.search.GlobalSearchScopesCore
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
@@ -50,10 +48,13 @@ import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.j2k.ConverterSettings
import org.jetbrains.kotlin.j2k.JavaToKotlinConverter
import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.psi.UserDataProperty
import java.io.File
import java.io.IOException
import java.util.*
+var VirtualFile.pathBeforeJ2K: String? by UserDataProperty(Key.create<String>("PATH_BEFORE_J2K_CONVERSION"))
+
class JavaToKotlinAction : AnAction() {
companion object {
private fun uniqueKotlinFileName(javaFile: VirtualFile): String {
@@ -88,6 +89,7 @@ class JavaToKotlinAction : AnAction() {
}
else {
val fileName = uniqueKotlinFileName(virtualFile)
+ virtualFile.pathBeforeJ2K = virtualFile.path
virtualFile.rename(this, fileName)
}
}
@@ -193,14 +195,10 @@ class JavaToKotlinAction : AnAction() {
}
private fun isAnyJavaFileSelected(project: Project, files: Array<VirtualFile>): Boolean {
-
- val filesScope = GlobalSearchScopesCore.directoriesScope(project, true, *files)
- val potentialJavaFiles = FileTypeIndex.getFiles(JavaFileType.INSTANCE, filesScope)
-
- if (potentialJavaFiles.isEmpty()) return false
-
val manager = PsiManager.getInstance(project)
- return potentialJavaFiles.any { manager.findFile(it) is PsiJavaFile && it.isWritable }
+
+ if (files.any { manager.findFile(it) is PsiJavaFile && it.isWritable }) return true
+ return files.any { it.isDirectory && isAnyJavaFileSelected(project, it.children) }
}
private fun selectedJavaFiles(e: AnActionEvent): Sequence<PsiJavaFile> {
diff --git a/idea/src/org/jetbrains/kotlin/idea/update/GooglePluginUpdateVerifier.kt.as33c4 b/idea/src/org/jetbrains/kotlin/idea/update/GooglePluginUpdateVerifier.kt.as33c4
new file mode 100644
index 00000000000..77f54309b20
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/update/GooglePluginUpdateVerifier.kt.as33c4
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
+ * that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.idea.update
+
+import com.intellij.ide.plugins.IdeaPluginDescriptor
+import com.intellij.ide.plugins.PluginManagerCore
+import com.intellij.ide.plugins.PluginNode
+import com.intellij.openapi.diagnostic.Logger
+import org.jetbrains.kotlin.idea.util.isDev
+import org.jetbrains.kotlin.idea.util.isEap
+import java.io.IOException
+import java.net.URL
+import java.util.*
+import javax.xml.bind.JAXBContext
+import javax.xml.bind.JAXBException
+import javax.xml.bind.annotation.*
+
+class GooglePluginUpdateVerifier : PluginUpdateVerifier() {
+ override val verifierName: String
+ get() = "Android Studio"
+
+ // Verifies if a plugin can be installed in Android Studio 3.2+.
+ // Currently used only by KotlinPluginUpdater.
+ override fun verify(pluginDescriptor: IdeaPluginDescriptor): PluginVerifyResult? {
+ if (pluginDescriptor.pluginId.idString != KOTLIN_PLUGIN_ID) {
+ return null
+ }
+
+ val version = pluginDescriptor.version
+ if (isEap(version) || isDev(version)) {
+ return PluginVerifyResult.accept()
+ }
+
+ try {
+ val url = URL(METADATA_FILE_URL)
+ val stream = url.openStream()
+ val context = JAXBContext.newInstance(PluginCompatibility::class.java)
+ val unmarshaller = context.createUnmarshaller()
+ val pluginCompatibility = unmarshaller.unmarshal(stream) as PluginCompatibility
+
+ val release = getRelease(pluginCompatibility)
+ ?: return PluginVerifyResult.decline("No verified versions for this build.")
+
+ return if (release.plugins().any { KOTLIN_PLUGIN_ID == it.id && version == it.version })
+ PluginVerifyResult.accept()
+ else
+ PluginVerifyResult.decline("Version to be verified.")
+ } catch (e: Exception) {
+ LOG.info("Exception when verifying plugin ${pluginDescriptor.pluginId.idString} version $version", e)
+ return when (e) {
+ is IOException ->
+ PluginVerifyResult.decline("unable to connect to compatibility verification repository")
+ is JAXBException -> PluginVerifyResult.decline("unable to parse compatibility verification metadata")
+ else -> PluginVerifyResult.decline("exception during verification ${e.message}")
+ }
+ }
+ }
+
+ private fun getRelease(pluginCompatibility: PluginCompatibility): StudioRelease? {
+ for (studioRelease in pluginCompatibility.releases()) {
+ if (buildInRange(studioRelease.name, studioRelease.sinceBuild, studioRelease.untilBuild)) {
+ return studioRelease
+ }
+ }
+ return null
+ }
+
+ private fun buildInRange(name: String?, sinceBuild: String?, untilBuild: String?): Boolean {
+ val descriptor = PluginNode()
+ descriptor.name = name
+ descriptor.sinceBuild = sinceBuild
+ descriptor.untilBuild = untilBuild
+ return PluginManagerCore.isCompatible(descriptor)
+ }
+
+ companion object {
+ private const val KOTLIN_PLUGIN_ID = "org.jetbrains.kotlin"
+ private const val METADATA_FILE_URL = "https://dl.google.com/android/studio/plugins/compatibility.xml"
+
+ private val LOG = Logger.getInstance(GooglePluginUpdateVerifier::class.java)
+
+ private fun PluginCompatibility.releases() = studioRelease ?: emptyArray()
+ private fun StudioRelease.plugins() = ideaPlugin ?: emptyArray()
+
+ @XmlRootElement(name = "plugin-compatibility")
+ @XmlAccessorType(XmlAccessType.FIELD)
+ class PluginCompatibility {
+ @XmlElement(name = "studio-release")
+ var studioRelease: Array<StudioRelease>? = null
+
+ override fun toString(): String {
+ return "PluginCompatibility(studioRelease=${Arrays.toString(studioRelease)})"
+ }
+ }
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ class StudioRelease {
+ @XmlAttribute(name = "until-build")
+ var untilBuild: String? = null
+ @XmlAttribute(name = "since-build")
+ var sinceBuild: String? = null
+ @XmlAttribute
+ var name: String? = null
+ @XmlAttribute
+ var channel: String? = null
+
+ @XmlElement(name = "idea-plugin")
+ var ideaPlugin: Array<IdeaPlugin>? = null
+
+ override fun toString(): String {
+ return "StudioRelease(" +
+ "untilBuild=$untilBuild, name=$name, ideaPlugin=${Arrays.toString(ideaPlugin)}, " +
+ "sinceBuild=$sinceBuild, channel=$channel" +
+ ")"
+ }
+ }
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ class IdeaPlugin {
+ @XmlAttribute
+ var id: String? = null
+ @XmlAttribute
+ var sha256: String? = null
+ @XmlAttribute
+ var channel: String? = null
+ @XmlAttribute
+ var version: String? = null
+
+ @XmlElement(name = "idea-version")
+ var ideaVersion: IdeaVersion? = null
+
+ override fun toString(): String {
+ return "IdeaPlugin(id=$id, sha256=$sha256, ideaVersion=$ideaVersion, channel=$channel, version=$version)"
+ }
+ }
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ class IdeaVersion {
+ @XmlAttribute(name = "until-build")
+ var untilBuild: String? = null
+ @XmlAttribute(name = "since-build")
+ var sinceBuild: String? = null
+
+ override fun toString(): String {
+ return "IdeaVersion(untilBuild=$untilBuild, sinceBuild=$sinceBuild)"
+ }
+ }
+ }
+}
diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidLayoutXmlFileManager.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidLayoutXmlFileManager.kt
index 752c11b4a30..84eee6c5c43 100644
--- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidLayoutXmlFileManager.kt
+++ b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidLayoutXmlFileManager.kt
@@ -18,7 +18,10 @@ package org.jetbrains.kotlin.android.synthetic.idea.res
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.ProjectRootModificationTracker
+import com.intellij.openapi.vfs.LocalFileSystem
+import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.psi.impl.PsiTreeChangePreprocessor
import com.intellij.psi.util.CachedValue
@@ -34,6 +37,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
+import java.io.File
class IDEAndroidLayoutXmlFileManager(val module: Module) : AndroidLayoutXmlFileManager(module.project) {
override val androidModule: AndroidModule?
@@ -66,7 +70,7 @@ class IDEAndroidLayoutXmlFileManager(val module: Module) : AndroidLayoutXmlFileM
val psiManager = PsiManager.getInstance(project)
val layouts = layoutGroup.layouts.map { psiFile ->
// Sometimes due to a race of later-invoked runnables, the PsiFile can be invalidated; make sure to refresh if possible,
- val layout = if (psiFile.isValid) psiFile else psiManager.findFile(psiFile.virtualFile)
+ val layout = if (psiFile.isValid) psiFile else psiManager.findFileSafe(psiFile.virtualFile)
val resources = arrayListOf<AndroidResource>()
layout?.accept(AndroidXmlVisitor { id, widgetType, attribute ->
@@ -78,6 +82,13 @@ class IDEAndroidLayoutXmlFileManager(val module: Module) : AndroidLayoutXmlFileM
return AndroidLayoutGroup(layoutGroup.name, layouts)
}
+ private fun PsiManager.findFileSafe(virtualFile: VirtualFile): PsiFile? {
+ if (virtualFile.isValid)
+ return findFile(virtualFile)
+
+ return null
+ }
+
override fun propertyToXmlAttributes(propertyDescriptor: PropertyDescriptor): List<PsiElement> {
val fqPath = propertyDescriptor.fqNameUnsafe.pathSegments()
if (fqPath.size <= SYNTHETIC_PACKAGE_PATH_LENGTH) return listOf()