Compare commits

...

34 Commits

Author SHA1 Message Date
Nicolay Mitropolsky
9ec715e879 [draft] UAST: KotlinNullabilityUAnnotation now is created for every AbstractKotlinUVariable 2017-10-20 10:43:57 +03:00
Nicolay Mitropolsky
79143680bd [UAST] Annotation retrieving via Kotlin moved to AbstractKotlinUVariable 2017-10-18 20:40:14 +03:00
Nicolay Mitropolsky
1962a8094d Uast: KotlinUField annotations now are retrieved from Kotlin Psi, not from compiled 2017-10-18 20:40:11 +03:00
Nicolay Mitropolsky
26de71f88e UAST: WrappedUAnnotation as replacement for usage of JavaUAnnotation 2017-10-18 20:40:09 +03:00
Nikolay Krasko
f2c3d85d1e Update file structure tests as FileStructurePopup api was changed in 173 2017-10-18 17:58:18 +03:00
Nicolay Mitropolsky
454f24a480 Spring-Kotlin: Gutter repaired (KT-20550, KT-20566)
Platform now allows Gutter to be placed only on leafs elements, this patch fixes it for `KotlinSpringClassAnnotator`.
2017-10-18 17:54:27 +03:00
Ilya Gorbunov
c79b427883 streamex version was changed in 173-snapshot to 0.6.5 2017-10-17 12:53:57 +03:00
Nicolay Mitropolsky
1d8de52c62 UAST: support for JvmDeclarationUElement 2017-10-17 12:53:56 +03:00
Nicolay Mitropolsky
56f9e58301 UAST test data fixes: LocalVariableWithAnnotationKt fix for variable type
it is not clear for me why it was not `String`
2017-10-17 12:53:55 +03:00
Nicolay Mitropolsky
d459dd770b UAST test data fixes: @null in render
as a "nullability" annotation for primitive types
2017-10-17 12:53:54 +03:00
Nicolay Mitropolsky
6a4c835be8 idea-version set to since-build="173.1" until-build="181.*" 2017-10-17 12:53:53 +03:00
Vyacheslav Gerasimov
0477f5fd2a Fix GradleNoduleBuilder use qualified names check 2017-10-17 12:53:52 +03:00
Nicolay Mitropolsky
142b6dd81b JvmFacade-related tests repair 2017-10-17 12:53:51 +03:00
Simon Ogorodnik
fd422b6296 Fix proguard settings for 173 2017-10-17 12:53:50 +03:00
Simon Ogorodnik
78570c1294 Fix compilation in 173 2017-10-17 12:53:49 +03:00
Anton Bannykh
66c1b88946 Fix compilation (MockParameterInfoUIContext.java)
(cherry picked from commit 21b0956)
2017-10-17 12:53:47 +03:00
Nicolay Mitropolsky
a7b19e9beb KotlinLanguageInjector using Registry to enable annotation injections
(cherry picked from commit 8bdfeb7)
2017-10-17 12:53:46 +03:00
Nikolay Krasko
d796ce0606 TODO: Remove js tests from non-compiler tests
(cherry picked from commit 38c42a2)
2017-10-17 12:53:45 +03:00
Simon Ogorodnik
a1c3f968c9 Fix compilation 2017-10-17 12:53:44 +03:00
Dmitry Jemerov
614a89ba90 Fix compatibility with BuildScriptDataBuilder API changes 2017-10-17 12:53:43 +03:00
Nicolay Mitropolsky
6a5dcbb35b KotlinLanguageInjector#injectInAnnotationCall optimization: using PsiClassNamePatternCondition to avoid calling getResolvedCall 2017-10-17 12:53:42 +03:00
Nicolay Mitropolsky
4d750606db KotlinLanguageInjector can inject into files modified for autocompletion 2017-10-17 12:53:41 +03:00
Nicolay Mitropolsky
dfb2000a69 KotlinLanguageInjector understands patterns-injections into Java annotations 2017-10-17 12:53:40 +03:00
xiexed
a0916b2cc2 KtLightAbstractAnnotation build fix for 173 (#1283) 2017-10-17 12:53:39 +03:00
Dmitry Jemerov
5e2983c1d5 Register new service and EPs added in 173 2017-10-17 12:53:38 +03:00
xiexed
c6378a245c Fixes for 173 after 28.08.17 changes in IDEA (#1271)
* `JarFileSystem.getJarRootForLocalFile` now is nullable in IDEA

* Spring-related renamings following ones in IDEA
2017-10-17 12:53:37 +03:00
Nicolay Mitropolsky
3bd5bb8028 Build fix for KotlinSpringClassAnnotator after collectNavigationMarkers nullability changes in IDEA 173 2017-10-17 12:53:36 +03:00
Vyacheslav Gerasimov
301b70a112 UAST: Fix testPropertyWithAnnotation 2017-10-17 12:53:35 +03:00
Vyacheslav Gerasimov
9c877e4e3f UAST: Add testConvertTypeInAnnotation 2017-10-17 12:53:34 +03:00
Vyacheslav Gerasimov
85979fe842 UAST: override getFunctionalInterfaceType + test 2017-10-17 12:53:33 +03:00
Vyacheslav Gerasimov
a54e3b9e9c UAST: Properly handle annotations on local variables 2017-10-17 12:53:32 +03:00
Vyacheslav Gerasimov
1bd9c229d9 Fix compilation 2017-10-17 12:53:31 +03:00
Vyacheslav Gerasimov
4901adf5ad Download IDEA 173.3188.16 2017-10-17 12:52:57 +03:00
Nikolay Krasko
88f1be9d15 == 172 -> 173 ^^^ == 2017-10-17 12:47:10 +03:00
90 changed files with 859 additions and 253 deletions

View File

@@ -28,6 +28,9 @@ import com.intellij.ide.highlighter.JavaFileType
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.lang.MetaLanguage
import com.intellij.lang.java.JavaParserDefinition
import com.intellij.lang.jvm.facade.JvmElementProvider
import com.intellij.lang.jvm.facade.JvmFacade
import com.intellij.lang.jvm.facade.JvmFacadeImpl
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.TransactionGuard
@@ -45,6 +48,7 @@ import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.*
import com.intellij.openapi.vfs.impl.ZipHandler
import com.intellij.psi.FileContextProvider
import com.intellij.psi.JavaModuleSystem
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.PsiManager
import com.intellij.psi.augment.PsiAugmentProvider
@@ -487,6 +491,8 @@ class KotlinCoreEnvironment private constructor(
//
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier::class.java)
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java)
//
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java)
}
private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) {
@@ -536,6 +542,7 @@ class KotlinCoreEnvironment private constructor(
private fun registerProjectExtensionPoints(area: ExtensionsArea) {
CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, JvmElementProvider.EP_NAME, JvmElementProvider::class.java)
}
// made public for Upsource

View File

@@ -61,6 +61,7 @@ messages/**)
-dontwarn net.jpountz.lz4.LZ4Factory
-dontwarn org.jetbrains.annotations.ReadOnly
-dontwarn org.jetbrains.annotations.Mutable
-dontwarn com.intellij.util.io.TarUtil
#-libraryjars '<rtjar>'
#-libraryjars '<jssejar>'

View File

@@ -49,6 +49,12 @@ abstract class KtLightAbstractAnnotation(parent: PsiElement, computeDelegate: ()
override fun getParameterList() = clsDelegate.parameterList
override fun canNavigate(): Boolean = super<KtLightElementBase>.canNavigate()
override fun canNavigateToSource(): Boolean = super<KtLightElementBase>.canNavigateToSource()
override fun navigate(requestFocus: Boolean) = super<KtLightElementBase>.navigate(requestFocus)
open fun fqNameMatches(fqName: String): Boolean = qualifiedName == fqName
}
@@ -264,6 +270,12 @@ class KtLightNonExistentAnnotation(parent: KtLightElement<*, *>) : KtLightElemen
override fun findDeclaredAttributeValue(attributeName: String?) = null
override fun getMetaData() = null
override fun getParameterList() = KtLightEmptyAnnotationParameterList(this)
override fun canNavigate(): Boolean = super<KtLightElementBase>.canNavigate()
override fun canNavigateToSource(): Boolean = super<KtLightElementBase>.canNavigateToSource()
override fun navigate(requestFocus: Boolean) = super<KtLightElementBase>.navigate(requestFocus)
}
class KtLightEmptyAnnotationParameterList(parent: PsiElement) : KtLightElementBase(parent), PsiAnnotationParameterList {

View File

@@ -30,14 +30,15 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
public class MockFileManager implements FileManager {
private final PsiManagerEx myManager;
// in mock tests it's LightVirtualFile, they're only alive when they're referenced,
// and there can not be several instances representing the same file
private final FactoryMap<VirtualFile, FileViewProvider> myViewProviders = new ConcurrentWeakFactoryMap<VirtualFile, FileViewProvider>() {
private final ConcurrentMap<VirtualFile, FileViewProvider> myViewProviders = new ConcurrentWeakFactoryMap<VirtualFile, FileViewProvider>() {
@Override
protected Map<VirtualFile, FileViewProvider> createMap() {
protected ConcurrentMap<VirtualFile, FileViewProvider> createMap() {
return ContainerUtil.createConcurrentWeakKeyWeakValueMap();
}

View File

@@ -31,7 +31,7 @@ fun KtUserType.aliasImportMap(): Multimap<String, String> {
return (file as KtFile).aliasImportMap()
}
private fun KtFile.aliasImportMap(): Multimap<String, String> {
fun KtFile.aliasImportMap(): Multimap<String, String> {
val cached = getUserData(ALIAS_IMPORT_DATA_KEY)
val modificationStamp = modificationStamp
if (cached != null && modificationStamp == cached.fileModificationStamp) {

View File

@@ -33,7 +33,7 @@ class KtLightClassForDecompiledDeclaration(
override val kotlinOrigin: KtClassOrObject?,
private val file: KtClsFile
) : KtLightClassBase(clsDelegate.manager) {
val fqName = kotlinOrigin?.fqName ?: FqName(clsDelegate.qualifiedName)
val fqName = kotlinOrigin?.fqName ?: FqName(clsDelegate.qualifiedName.orEmpty())
override fun copy() = this

View File

@@ -28,6 +28,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager;
import com.intellij.openapi.externalSystem.importing.ImportSpec;
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
@@ -133,7 +134,7 @@ public class GradleModuleBuilder extends AbstractExternalModuleBuilder<GradlePro
moduleName = getName();
}
else {
moduleName = ModuleGrouperKt.isQualifiedModuleNamesEnabled() && StringUtil.isNotEmpty(myProjectId.getGroupId())
moduleName = getExternalProjectSettings().isUseQualifiedModuleNames() && StringUtil.isNotEmpty(myProjectId.getGroupId())
? (myProjectId.getGroupId() + '.' + myProjectId.getArtifactId())
: myProjectId.getArtifactId();
}
@@ -232,6 +233,9 @@ public class GradleModuleBuilder extends AbstractExternalModuleBuilder<GradlePro
LOG.warn("Unexpected exception on applying frameworks templates", e);
}
// it will be set later in any case, but save is called immediately after project creation, so, to ensure that it will be properly saved as external system module
ExternalSystemModulePropertyManager.getInstance(module).setExternalId(GradleConstants.SYSTEM_ID);
final Project project = module.getProject();
if (myWizardContext.isCreatingNewProject()) {
getExternalProjectSettings().setExternalProjectPath(rootProjectPath);
@@ -488,4 +492,4 @@ public class GradleModuleBuilder extends AbstractExternalModuleBuilder<GradlePro
}
return project;
}
}
}

View File

@@ -90,6 +90,6 @@ class KotlinGradleMultiplatformModuleBuilder : GradleModuleBuilder() {
val buildScriptData = BuildScriptDataBuilder(buildGradle)
supportProvider.addSupport(buildScriptData, sdk)
buildScriptData.addDependencyNotation("implement project(\":\")")
VfsUtil.saveText(buildGradle, buildScriptData.build())
VfsUtil.saveText(buildGradle, buildScriptData.buildConfigurationPart() + buildScriptData.buildMainPart())
}
}

View File

@@ -205,15 +205,15 @@ private fun configureFacetByGradleModule(
adjustClasspath(kotlinFacet, dependencyClasspath)
}
kotlinFacet.configuration.settings.implementedModuleName = getImplementedModuleName(moduleNode, sourceSetName)
kotlinFacet.configuration.settings.implementedModuleName = getImplementedModuleName(moduleNode, sourceSetName, ideModule.project)
return kotlinFacet
}
private fun getImplementedModuleName(moduleNode: DataNode<ModuleData>, sourceSetName: String?): String? {
private fun getImplementedModuleName(moduleNode: DataNode<ModuleData>, sourceSetName: String?, project: Project): String? {
val baseModuleName = moduleNode.implementedModule?.data?.internalName
if (baseModuleName == null || sourceSetName == null) return baseModuleName
val delimiter = if(isQualifiedModuleNamesEnabled()) "." else "_"
val delimiter = if(isQualifiedModuleNamesEnabled(project)) "." else "_"
return "$baseModuleName$delimiter$sourceSetName"
}

View File

@@ -162,7 +162,6 @@ class GradleInspectionTest : GradleImportingTestCase() {
val foundProblems = presentation.problemElements
.values
.flatMap { it.toList() }
.mapNotNull { it as? ProblemDescriptorBase }
.map { it.descriptionTemplate }

View File

@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.maven
import com.intellij.codeInspection.CommonProblemDescriptor
import com.intellij.codeInspection.ProblemDescriptorBase
import com.intellij.codeInspection.QuickFix
import com.intellij.codeInspection.reference.RefEntity
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.Result
@@ -64,10 +65,11 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() {
val matcher = "<!--\\s*problem:\\s*on\\s*([^,]+),\\s*title\\s*(.+)\\s*-->".toRegex()
val expected = pomText.lines().mapNotNull { matcher.find(it) }.map { SimplifiedProblemDescription(it.groups[2]!!.value.trim(), it.groups[1]!!.value.trim()) }
val actual = runInspection(inspectionClass, myProject)
.problemElements
.filter { it.key.name == "pom.xml" }
.values
val problemElements = runInspection(inspectionClass, myProject).problemElements
val actual = problemElements
.keys()
.filter { it.name == "pom.xml" }
.map { problemElements.get(it) }
.flatMap { it.toList() }
.mapNotNull { it as? ProblemDescriptorBase }
.map { SimplifiedProblemDescription(it.descriptionTemplate, it.psiElement.text.replace("\\s+".toRegex(), "")) to it }

View File

@@ -21,6 +21,7 @@ import com.intellij.execution.process.ProcessOutputTypes
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.annotations.NotNull
import org.jetbrains.kotlin.console.actions.logError
import org.jetbrains.kotlin.diagnostics.Severity
import org.w3c.dom.Element
@@ -47,7 +48,7 @@ class ReplOutputHandler(
override fun isSilentlyDestroyOnClose() = true
override fun notifyTextAvailable(text: String, key: Key<*>?) {
override fun notifyTextAvailable(text: String, key: Key<*>) {
// hide warning about adding test folder to classpath
if (text.startsWith("warning: classpath entry points to a non-existent location")) return

View File

@@ -6,7 +6,7 @@
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains s.r.o.</vendor>
<idea-version since-build="172.1" until-build="173.*"/>
<idea-version since-build="173.1" until-build="181.*"/>
<depends>com.intellij.modules.java</depends>

View File

@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.utils.getOrPutNullable
import org.jetbrains.org.objectweb.asm.*
import java.io.File
import java.util.*
import java.util.concurrent.ConcurrentMap
fun isInlineFunctionLineNumber(file: VirtualFile, lineNumber: Int, project: Project): Boolean {
if (ProjectRootsUtil.isProjectSourceFile(project, file)) {
@@ -117,7 +118,7 @@ class WeakBytecodeDebugInfoStorage : ConcurrentWeakFactoryMap<BinaryCacheKey, By
return BytecodeDebugInfo(smapData, lineNumberMapping)
}
override fun createMap(): Map<BinaryCacheKey, BytecodeDebugInfo?> {
override fun createMap(): ConcurrentMap<BinaryCacheKey, BytecodeDebugInfo?> {
return ContainerUtil.createConcurrentWeakKeyWeakValueMap()
}
}

View File

@@ -142,7 +142,7 @@ private class OverridingMethodsUpdater(
override fun run(indicator: ProgressIndicator) {
super.run(indicator)
val processor = object : CommonProcessors.CollectProcessor<PsiMethod>() {
override fun process(psiMethod: PsiMethod?): Boolean {
override fun process(psiMethod: PsiMethod): Boolean {
if (!updateComponent(psiMethod, myRenderer.comparator)) {
indicator.cancel()
}

View File

@@ -23,18 +23,27 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.util.text.StringUtilRt
import com.intellij.patterns.PatternConditionPlus
import com.intellij.patterns.PsiClassNamePatternCondition
import com.intellij.patterns.ValuePatternCondition
import com.intellij.psi.*
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiTreeUtil
import org.intellij.plugins.intelliLang.Configuration
import org.intellij.plugins.intelliLang.inject.InjectorUtils
import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport
import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry
import org.intellij.plugins.intelliLang.inject.config.BaseInjection
import org.intellij.plugins.intelliLang.inject.config.InjectionPlace
import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport
import org.intellij.plugins.intelliLang.util.AnnotationUtilEx
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.references.KtReference
@@ -43,25 +52,30 @@ import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.annotations.argumentValue
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import java.util.*
import kotlin.collections.ArrayList
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.util.aliasImportMap
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
class KotlinLanguageInjector(
val configuration: Configuration,
val project: Project,
val temporaryPlacesRegistry: TemporaryPlacesRegistry
private val configuration: Configuration,
private val project: Project,
private val temporaryPlacesRegistry: TemporaryPlacesRegistry
) : MultiHostInjector {
companion object {
private val STRING_LITERALS_REGEXP = "\"([^\"]*)\"".toRegex()
private val ABSENT_KOTLIN_INJECTION = BaseInjection("ABSENT_KOTLIN_BASE_INJECTION")
}
val kotlinSupport: KotlinLanguageInjectionSupport? by lazy {
var annotationInjectionsEnabled = Registry.`is`("kotlin.annotation.injection.enabled", false)
private val kotlinSupport: KotlinLanguageInjectionSupport? by lazy {
ArrayList(InjectorUtils.getActiveInjectionSupports()).filterIsInstance(KotlinLanguageInjectionSupport::class.java).firstOrNull()
}
private data class KotlinCachedInjection(val modificationCount: Long, val baseInjection: BaseInjection)
private var KtStringTemplateExpression.cachedInjectionWithModification: KotlinCachedInjection? by UserDataProperty(
Key.create<KotlinCachedInjection>("CACHED_INJECTION_WITH_MODIFICATION"))
@@ -71,7 +85,7 @@ class KotlinLanguageInjector(
val support = kotlinSupport ?: return
if (!ProjectRootsUtil.isInProjectOrLibSource(ktHost)) return
if (!ProjectRootsUtil.isInProjectOrLibSource(ktHost.containingFile.originalFile)) return
val needImmediateAnswer = with(ApplicationManager.getApplication()) { isDispatchThread && !isUnitTestMode }
val kotlinCachedInjection = ktHost.cachedInjectionWithModification
@@ -152,6 +166,7 @@ class KotlinLanguageInjector(
private fun findInjectionInfo(place: KtElement, originalHost: Boolean = true): InjectionInfo? {
return injectWithExplicitCodeInstruction(place)
?: injectWithCall(place)
?: injectInAnnotationCall(place)
?: injectWithReceiver(place)
?: injectWithVariableUsage(place, originalHost)
}
@@ -172,9 +187,9 @@ class KotlinLanguageInjector(
val callExpression = qualifiedExpression.selectorExpression as? KtCallExpression ?: return null
val callee = callExpression.calleeExpression ?: return null
if (isAnalyzeOff(qualifiedExpression.project)) return null
if (isAnalyzeOff()) return null
val kotlinInjections = Configuration.getInstance().getInjections(KOTLIN_SUPPORT_ID)
val kotlinInjections = configuration.getInjections(KOTLIN_SUPPORT_ID)
val calleeName = callee.text
val possibleNames = collectPossibleNames(kotlinInjections)
@@ -217,11 +232,10 @@ class KotlinLanguageInjector(
// Given place is not original host of the injection so we stop to prevent stepping through indirect references
if (!originalHost) return null
val ktHost: KtElement = host
val ktProperty = host.parent as? KtProperty ?: return null
if (ktProperty.initializer != host) return null
if (isAnalyzeOff(ktHost.project)) return null
if (isAnalyzeOff()) return null
val searchScope = LocalSearchScope(arrayOf(ktProperty.containingFile), "", true)
return ReferencesSearch.search(ktProperty, searchScope).asSequence().mapNotNull { psiReference ->
@@ -237,7 +251,7 @@ class KotlinLanguageInjector(
val callExpression = PsiTreeUtil.getParentOfType(ktHost, KtCallExpression::class.java) ?: return null
val callee = callExpression.calleeExpression ?: return null
if (isAnalyzeOff(ktHost.project)) return null
if (isAnalyzeOff()) return null
for (reference in callee.references) {
ProgressManager.checkCanceled()
@@ -260,18 +274,30 @@ class KotlinLanguageInjector(
return null
}
private fun injectInAnnotationCall(host: KtElement): InjectionInfo? {
if (!annotationInjectionsEnabled) return null
val argument = host.parent as? KtValueArgument ?: return null
val annotationEntry = argument.parent.parent as? KtAnnotationEntry ?: return null
if (!fastCheckInjectionsExists(annotationEntry)) return null
val callDescriptor = annotationEntry.getResolvedCall(annotationEntry.analyze())?.candidateDescriptor
val psiClass = (callDescriptor as? DeclarationDescriptorWithSource)?.source?.getPsi() as? PsiClass ?: return null
val argumentName = argument.getArgumentName()?.asName?.identifier ?: "value"
val method = psiClass.findMethodsByName(argumentName, false).singleOrNull() ?: return null
return findInjection(method, configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID))
}
private fun injectionForJavaMethod(argument: KtValueArgument, javaMethod: PsiMethod): InjectionInfo? {
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
val psiParameter = javaMethod.parameterList.parameters.getOrNull(argumentIndex) ?: return null
val injectionInfo = findInjection(psiParameter, Configuration.getInstance().getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID))
val injectionInfo = findInjection(psiParameter, configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID))
if (injectionInfo != null) {
return injectionInfo
}
val annotations = AnnotationUtilEx.getAnnotationFrom(
psiParameter,
Configuration.getProjectInstance(psiParameter.project).advancedConfiguration.languageAnnotationPair,
configuration.advancedConfiguration.languageAnnotationPair,
true)
if (annotations.isNotEmpty()) {
@@ -285,7 +311,7 @@ class KotlinLanguageInjector(
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
val ktParameter = ktFunction.valueParameters.getOrNull(argumentIndex) ?: return null
val patternInjection = findInjection(ktParameter, Configuration.getInstance().getInjections(KOTLIN_SUPPORT_ID))
val patternInjection = findInjection(ktParameter, configuration.getInjections(KOTLIN_SUPPORT_ID))
if (patternInjection != null) {
return patternInjection
}
@@ -313,8 +339,8 @@ class KotlinLanguageInjector(
return null
}
private fun isAnalyzeOff(project: Project): Boolean {
return Configuration.getProjectInstance(project).advancedConfiguration.dfaOption == Configuration.DfaOption.OFF
private fun isAnalyzeOff(): Boolean {
return configuration.advancedConfiguration.dfaOption == Configuration.DfaOption.OFF
}
private class InjectionInfo(val languageId: String?, val prefix: String?, val suffix: String?) {
@@ -343,4 +369,33 @@ class KotlinLanguageInjector(
return InjectionInfo(id, prefix, suffix)
}
private val injectableTargetClassShortNames = CachedValuesManager.getManager(project)
.createCachedValue({
CachedValueProvider.Result.create(HashSet<String>().apply {
for (injection in configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) {
for (injectionPlace in injection.injectionPlaces) {
for (targetClassFQN in retrievePlaceTargetClassesFQNs(injectionPlace)) {
add(StringUtilRt.getShortName(targetClassFQN))
}
}
}
}, configuration)
}, false)
private fun fastCheckInjectionsExists(annotationEntry: KtAnnotationEntry): Boolean {
val referencedName = (annotationEntry.typeReference?.typeElement as? KtUserType)?.referencedName ?: return false
val annotationShortName = annotationEntry.containingKtFile.aliasImportMap()[referencedName].singleOrNull() ?: referencedName
return annotationShortName in injectableTargetClassShortNames.value
}
private fun retrievePlaceTargetClassesFQNs(place: InjectionPlace): Collection<String> {
val classCondition = place.elementPattern.condition.conditions.firstOrNull { it.debugMethodName == "definedInClass" }
as? PatternConditionPlus<*, *> ?: return emptyList()
val psiClassNamePatternCondition = classCondition.valuePattern.condition.conditions.
firstIsInstanceOrNull<PsiClassNamePatternCondition>() ?: return emptyList()
val valuePatternCondition = psiClassNamePatternCondition.namePattern.condition.conditions.firstIsInstanceOrNull<ValuePatternCondition<String>>() ?: return emptyList()
return valuePatternCondition.values
}
}

View File

@@ -1 +1 @@
+EmptyFile.kt
-EmptyFile.kt

View File

@@ -61,6 +61,11 @@ public class MockParameterInfoUIContext implements ParameterInfoUIContext {
return resultText;
}
@Override
public void setupRawUIComponentPresentation(String htmlText) {
throw new UnsupportedOperationException();
}
@Override
public boolean isUIComponentEnabled() {
return false;
@@ -80,6 +85,16 @@ public class MockParameterInfoUIContext implements ParameterInfoUIContext {
return myParameterOwner;
}
@Override
public boolean isSingleOverload() {
return false;
}
@Override
public boolean isSingleParameterInfo() {
return false;
}
@Override
public Color getDefaultParameterColor() {
return HintUtil.INFORMATION_COLOR;

View File

@@ -86,6 +86,21 @@ public class MockUpdateParameterInfoContext implements UpdateParameterInfoContex
return ArrayUtil.EMPTY_OBJECT_ARRAY;
}
@Override
public boolean isPreservedOnHintHidden() {
return false;
}
@Override
public void setPreservedOnHintHidden(boolean value) {
}
@Override
public boolean isInnermostContext() {
return false;
}
@Override
public Project getProject() {
return null;

View File

@@ -175,7 +175,7 @@ class UpdateConfigurationQuickFixTest : LightPlatformCodeInsightFixtureTestCase(
val editor = NewLibraryEditor()
editor.name = "KotlinJavaRuntime"
editor.addRoot(JarFileSystem.getInstance().getJarRootForLocalFile(tempVFile), OrderRootType.CLASSES)
editor.addRoot(JarFileSystem.getInstance().getJarRootForLocalFile(tempVFile)!!, OrderRootType.CLASSES)
ConfigLibraryUtil.addLibrary(editor, model)
}

View File

@@ -16,43 +16,28 @@
package org.jetbrains.kotlin.idea.structureView
import com.intellij.ide.actions.ViewStructureAction
import com.intellij.ide.util.FileStructurePopup
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider
import com.intellij.openapi.ui.Queryable.PrintInfo
import com.intellij.openapi.util.io.FileUtil
import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure
import com.intellij.util.ui.tree.TreeUtil
import org.jetbrains.kotlin.idea.completion.test.configureWithExtraFile
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
abstract class AbstractKotlinFileStructureTest : KotlinLightCodeInsightFixtureTestCase() {
abstract class AbstractKotlinFileStructureTest : KotlinFileStructureTestBase() {
override fun getTestDataPath() = PluginTestCaseBase.getTestDataPathBase() + "/structureView/fileStructure"
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
override val fileExtension = "kt"
override val treeFileName: String get() = getFileName("after")
fun doTest(path: String) {
myFixture.configureWithExtraFile(path)
val textEditor = TextEditorProvider.getInstance()!!.getTextEditor(myFixture.editor)
val popup = ViewStructureAction.createPopup(myFixture.project, textEditor)
popupFixture.popup.setup()
if (popup == null) throw AssertionError("popup mustn't be null")
popup.createCenterPanel()
popup.treeBuilder.ui!!.updater!!.setPassThroughMode(true)
popup.update()
popup.setup()
val printInfo = PrintInfo(arrayOf("text"), arrayOf("location"))
val popupText = StructureViewUtil.print(popup.tree, false, printInfo, null)
KotlinTestUtils.assertEqualsToFile(File("${FileUtil.getNameWithoutExtension(path)}.after"), popupText)
checkTree()
}
protected fun FileStructurePopup.setup() {
@@ -61,27 +46,4 @@ abstract class AbstractKotlinFileStructureTest : KotlinLightCodeInsightFixtureTe
val withInherited = InTextDirectivesUtils.isDirectiveDefined(fileText, "WITH_INHERITED")
setTreeActionState(KotlinInheritedMembersNodeProvider::class.java, withInherited)
}
fun FileStructurePopup.update() {
treeBuilder.refilter()!!.doWhenProcessed {
getStructure().rebuild()
updateRecursively(getRootNode())
treeBuilder.updateFromRoot()
TreeUtil.expandAll(tree)
}
}
fun FileStructurePopup.getFileStructureSpeedSearch() = speedSearch as FileStructurePopup.MyTreeSpeedSearch
fun FileStructurePopup.getStructure() = treeBuilder.treeStructure as FilteringTreeStructure
fun FileStructurePopup.getRootNode() = treeBuilder.rootElement as FilteringTreeStructure.FilteringNode
fun FileStructurePopup.updateRecursively(node: FilteringTreeStructure.FilteringNode) {
node.update()
for (child in node.children()!!) {
updateRecursively(child)
}
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.structureView
import com.intellij.openapi.ui.Queryable
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.text.StringUtil
import com.intellij.testFramework.FileStructureTestFixture
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.UsefulTestCase
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
abstract class KotlinFileStructureTestBase : KotlinLightCodeInsightFixtureTestCase() {
protected var myPopupFixture: FileStructureTestFixture? = null
protected val popupFixture get() = myPopupFixture!!
protected abstract val fileExtension: String
open protected val treeFileName: String
get() = getFileName("tree")
override fun setUp() {
super.setUp()
myPopupFixture = FileStructureTestFixture(myFixture)
}
protected fun configureDefault() {
myFixture.configureByFile(getFileName(fileExtension))
}
public override fun tearDown() {
try {
Disposer.dispose(popupFixture)
myPopupFixture = null
}
finally {
super.tearDown()
}
}
protected fun getFileName(ext: String): String {
return getTestName(false) + if (StringUtil.isEmpty(ext)) "" else "." + ext
}
@Suppress("unused")
protected fun checkTree(filter: String) {
configureDefault()
popupFixture.update()
popupFixture.popup.setSearchFilterForTests(filter)
PlatformTestUtil.waitForPromise(popupFixture.popup.rebuildAndUpdate())
popupFixture.speedSearch.findAndSelectElement(filter)
checkResult()
}
protected fun checkTree() {
configureDefault()
popupFixture.update()
checkResult()
}
protected fun checkResult() {
val printInfo = Queryable.PrintInfo(arrayOf("text"), arrayOf("location"))
val popupText = StructureViewUtil.print(popupFixture.tree, false, printInfo, null).trim { it <= ' ' }
UsefulTestCase.assertSameLinesWithFile(testDataPath + "/" + treeFileName, popupText)
}
}

View File

@@ -16,12 +16,18 @@
package org.jetbrains.kotlin.psi
import com.intellij.codeInsight.completion.CompletionType
import com.intellij.lang.html.HTMLLanguage
import com.intellij.lang.injection.MultiHostInjector
import com.intellij.openapi.components.ServiceManager.getService
import com.intellij.openapi.fileTypes.PlainTextLanguage
import org.intellij.lang.annotations.Language
import org.intellij.lang.regexp.RegExpLanguage
import org.intellij.plugins.intelliLang.Configuration
import org.intellij.plugins.intelliLang.inject.config.BaseInjection
import org.intellij.plugins.intelliLang.inject.config.InjectionPlace
import org.jetbrains.kotlin.idea.injection.KotlinLanguageInjector
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
class KotlinInjectionTest : AbstractInjectionTest() {
fun testInjectionOnJavaPredefinedMethodWithAnnotation() = doInjectionPresentTest(
@@ -265,7 +271,7 @@ class KotlinInjectionTest : AbstractInjectionTest() {
fun other() { foo(v) }
""",
languageId = HTMLLanguage.INSTANCE.id, unInjectShouldBePresent = false)
fun testInjectionOfCustomParameterWithAnnotation() = doInjectionPresentTest(
"""
import org.intellij.lang.annotations.Language
@@ -410,4 +416,89 @@ class KotlinInjectionTest : AbstractInjectionTest() {
ShredInfo(range(7, 15), hostRange=range(12, 22), prefix="s")
)
)
fun testInjectionInJavaAnnotation() {
myFixture.addClass("""
@interface InHtml {
String value();
}
""")
doAnnotationInjectionTest(
"""psiMethod().withName("value").withParameters().definedInClass("InHtml")""",
"""
@InHtml("<htm<caret>l></html>")
fun foo() {
}
""",
{ assertSameElements(myFixture.complete(CompletionType.BASIC).flatMap { it.allLookupStrings }, "html") }
)
}
fun testInjectionInJavaAnnotationWithNamedParam() {
myFixture.addClass("""
package myinjection;
@interface InHtml {
String html();
}
""")
doAnnotationInjectionTest(
"""psiMethod().withName("html").withParameters().definedInClass("myinjection.InHtml")""",
"""
import myinjection.InHtml
@InHtml(html = "<htm<caret>l></html>")
fun foo() {
}
""")
}
fun testInjectionInAliasedJavaAnnotation() {
myFixture.addClass("""
@interface InHtml {
String html();
}
""")
doAnnotationInjectionTest(
"""psiMethod().withName("html").withParameters().definedInClass("InHtml")""",
"""
import InHtml as InHtmlAliased
@InHtmlAliased(html = "<htm<caret>l></html>")
fun foo() {
}
"""
)
}
private fun doAnnotationInjectionTest(pattern: String, @Language("kotlin") kotlinCode: String, additionalAsserts: () -> Unit = {}) {
val customInjection = BaseInjection("java")
customInjection.injectedLanguageId = HTMLLanguage.INSTANCE.id
val elementPattern = customInjection.compiler.createElementPattern(
pattern,
"temp rule")
customInjection.setInjectionPlaces(InjectionPlace(elementPattern, true))
val kotlinLanguageInjector = MultiHostInjector.MULTIHOST_INJECTOR_EP_NAME.getExtensions(project).firstIsInstance<KotlinLanguageInjector>()
val injectionsEnabled = kotlinLanguageInjector.annotationInjectionsEnabled
try {
kotlinLanguageInjector.annotationInjectionsEnabled = true
Configuration.getInstance().replaceInjections(listOf(customInjection), listOf(), true)
doInjectionPresentTest(
kotlinCode, null,
HTMLLanguage.INSTANCE.id,
unInjectShouldBePresent = false
)
additionalAsserts()
}
finally {
kotlinLanguageInjector.annotationInjectionsEnabled = injectionsEnabled
Configuration.getInstance().replaceInjections(listOf(), listOf(customInjection), true)
}
}
}

View File

@@ -14,12 +14,9 @@
<orderEntry type="module" module-name="cli" scope="TEST" />
<orderEntry type="module" module-name="descriptor.loader.java" scope="TEST" />
<orderEntry type="module" module-name="descriptors.runtime" scope="TEST" />
<orderEntry type="module" module-name="js.tests" scope="TEST" />
<orderEntry type="module" module-name="jps-tests" scope="TEST" />
<orderEntry type="module" module-name="j2k" scope="TEST" />
<orderEntry type="library" scope="TEST" name="jps-test" level="project" />
<orderEntry type="module" module-name="js.ast" scope="TEST" />
<orderEntry type="module" module-name="js.frontend" scope="TEST" />
<orderEntry type="module" module-name="util" scope="TEST" />
<orderEntry type="module" module-name="android-extensions-compiler" scope="TEST" />
<orderEntry type="module" module-name="android-extensions-idea" scope="TEST" />

View File

@@ -17,18 +17,20 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.toLightGetter
import org.jetbrains.kotlin.asJava.toLightSetter
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.expressions.KotlinUElvisExpression
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable
abstract class KotlinAbstractUElement(private val givenParent: UElement?) : UElement {
abstract class KotlinAbstractUElement(private val givenParent: UElement?) : UElement, JvmDeclarationUElement {
override val uastParent: UElement? by lz {
givenParent ?: convertParent()
@@ -51,6 +53,15 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : UEle
parent = (parentUnwrapped as? KtProperty)?.setter
?: (parentUnwrapped as? KtParameter)?.toLightSetter()
?: parent
AnnotationUseSiteTarget.FIELD ->
parent = (parentUnwrapped as? KtProperty)
?: (parentUnwrapped as? KtParameter)
?.takeIf { it.isPropertyParameter() }
?.let(LightClassUtil::getLightClassBackingField)
?: parent
AnnotationUseSiteTarget.SETTER_PARAMETER ->
parent = (parentUnwrapped as? KtParameter)
?.toLightSetter()?.parameterList?.parameters?.firstOrNull() ?: parent
}
}
if (psi is UastKotlinPsiVariable && parent != null) {
@@ -149,7 +160,11 @@ private fun findAnnotationClassFromConstructorParameter(parameter: KtParameter):
}
abstract class KotlinAbstractUExpression(givenParent: UElement?)
: KotlinAbstractUElement(givenParent), UExpression {
: KotlinAbstractUElement(givenParent), UExpression, JvmDeclarationUElement {
override val javaPsi = null
override val sourcePsi
get() = psi
override val annotations: List<UAnnotation>
get() {

View File

@@ -63,7 +63,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
return convertDeclarationOrElement(element, parent, requiredType)
}
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
if (element is PsiFile) return convertDeclaration(element, null, requiredType)
if (element is KtLightClassForFacade) return convertDeclaration(element, null, requiredType)
@@ -99,7 +99,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return null
val resultingDescriptor = resolvedCall.resultingDescriptor
if (resultingDescriptor !is FunctionDescriptor || resultingDescriptor.name.asString() != methodName) return null
val parent = element.parent
val parentUElement = convertElementWithParent(parent, null) ?: return null
@@ -116,7 +116,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
if (element !is KtCallExpression) return null
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return null
val resultingDescriptor = resolvedCall.resultingDescriptor
if (resultingDescriptor !is ConstructorDescriptor
if (resultingDescriptor !is ConstructorDescriptor
|| resultingDescriptor.returnType.constructor.declarationDescriptor?.name?.asString() != fqName) {
return null
}
@@ -133,9 +133,13 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
internal fun convertDeclaration(element: PsiElement,
givenParent: UElement?,
requiredType: Class<out UElement>?): UElement? {
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
return { ctor(element as P, givenParent) }
}
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? = { ctor(element as P, givenParent) }
fun <P : PsiElement, K : KtElement> buildKt(ktElement: K, ctor: (P, K, UElement?) -> UElement): () -> UElement? =
{ ctor(element as P, ktElement, givenParent) }
fun <P : PsiElement, K : KtElement> buildKtOpt(ktElement: K?, ctor: (P, K?, UElement?) -> UElement): () -> UElement? =
{ ctor(element as P, ktElement, givenParent) }
val original = element.originalElement
return with(requiredType) {
@@ -147,10 +151,11 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
}
else -> el<UClass> { KotlinUClass.create(original, givenParent) }
}
is KtLightFieldImpl.KtLightEnumConstant -> el<UEnumConstant>(build(::KotlinUEnumConstant))
is KtLightField -> el<UField>(build(::KotlinUField))
is KtLightParameter, is UastKotlinPsiParameter -> el<UParameter>(build(::KotlinUParameter))
is UastKotlinPsiVariable -> el<UVariable>(build(::KotlinUVariable))
is KtLightFieldImpl.KtLightEnumConstant -> el<UEnumConstant>(buildKtOpt(original.kotlinOrigin, ::KotlinUEnumConstant))
is KtLightField -> el<UField>(buildKtOpt(original.kotlinOrigin, ::KotlinUField))
is KtLightParameter -> el<UParameter>(buildKtOpt(original.kotlinOrigin, ::KotlinUParameter))
is UastKotlinPsiParameter -> el<UParameter>(buildKt(original.ktParameter, ::KotlinUParameter))
is UastKotlinPsiVariable -> el<UVariable>(buildKt(original.ktElement, ::KotlinUVariable))
is KtEnumEntry -> el<UEnumConstant> {
convertEnumEntry(original, givenParent)
@@ -197,7 +202,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
val ownerFunction = original.ownerFunction as? KtFunction ?: return null
val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return null
val lightParameter = lightMethod.parameterList.parameters.find { it.name == original.name } ?: return null
KotlinUParameter(lightParameter, givenParent)
KotlinUParameter(lightParameter, original, givenParent)
}
is KtFile -> el<UFile> { KotlinUFile(original, this@KotlinUastLanguagePlugin) }
@@ -211,7 +216,7 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
private fun convertEnumEntry(original: KtEnumEntry, givenParent: UElement?): UElement? {
return LightClassUtil.getLightClassBackingField(original)?.let { psiField ->
if (psiField is KtLightFieldImpl.KtLightEnumConstant) {
KotlinUEnumConstant(psiField, givenParent)
KotlinUEnumConstant(psiField, psiField.kotlinOrigin, givenParent)
}
else {
null
@@ -245,7 +250,7 @@ private fun convertNonLocalProperty(property: KtProperty,
val methods = LightClassUtil.getLightClassPropertyMethods(property)
return methods.backingField?.let { backingField ->
with(requiredType) {
el<UField> { KotlinUField(backingField, givenParent) }
el<UField> { KotlinUField(backingField, (backingField as? KtLightElement<*,*>)?.kotlinOrigin, givenParent) }
}
} ?: methods.getter?.let { getter ->
KotlinUastLanguagePlugin().convertDeclaration(getter, givenParent, requiredType)
@@ -275,7 +280,7 @@ internal object KotlinConverter {
val declarationsExpression = KotlinUDeclarationsExpression(givenParent)
declarationsExpression.apply {
declarations = element.parameters.mapIndexed { i, p ->
KotlinUParameter(UastKotlinPsiParameter.create(p, element, declarationsExpression, i), this)
KotlinUParameter(UastKotlinPsiParameter.create(p, element, declarationsExpression, i), p, this)
}
}
}
@@ -285,7 +290,7 @@ internal object KotlinConverter {
if (element is KtProperty && !element.isLocal) {
el<UField> {
LightClassUtil.getLightClassBackingField(element)?.let {
KotlinUField(it, givenParent)
KotlinUField(it, element, givenParent)
}
}
}
@@ -365,13 +370,13 @@ internal object KotlinConverter {
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
val declarationsExpression = KotlinUDestructuringDeclarationExpression(givenParent, expression)
declarationsExpression.apply {
val tempAssignment = KotlinULocalVariable(UastKotlinPsiVariable.create(expression, declarationsExpression), declarationsExpression)
val tempAssignment = KotlinULocalVariable(UastKotlinPsiVariable.create(expression, declarationsExpression), expression, declarationsExpression)
val destructuringAssignments = expression.entries.mapIndexed { i, entry ->
val psiFactory = KtPsiFactory(expression.project)
val initializer = psiFactory.createAnalyzableExpression("${tempAssignment.name}.component${i + 1}()",
expression.containingFile)
initializer.destructuringDeclarationInitializer = true
KotlinULocalVariable(UastKotlinPsiVariable.create(entry, tempAssignment.psi, declarationsExpression, initializer), declarationsExpression)
KotlinULocalVariable(UastKotlinPsiVariable.create(entry, tempAssignment.psi, declarationsExpression, initializer), entry, declarationsExpression)
}
declarations = listOf(tempAssignment) + destructuringAssignments
}
@@ -495,7 +500,7 @@ private fun convertVariablesDeclaration(
val declarationsExpression = KotlinUDeclarationsExpression(null, parent, psi)
val parentPsiElement = parent?.psi
val variable = KotlinUAnnotatedLocalVariable(
UastKotlinPsiVariable.create(psi, parentPsiElement, declarationsExpression), declarationsExpression) { annotationParent ->
UastKotlinPsiVariable.create(psi, parentPsiElement, declarationsExpression), psi, declarationsExpression) { annotationParent ->
psi.annotationEntries.map { KotlinUAnnotation(it, annotationParent) }
}
return declarationsExpression.apply { declarations = listOf(variable) }

View File

@@ -1,6 +1,7 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiClass
import org.jetbrains.kotlin.asJava.toLightAnnotation
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtParameter
@@ -17,6 +18,11 @@ class KotlinUAnnotation(
override val psi: KtAnnotationEntry,
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), UAnnotation {
override val javaPsi = psi.toLightAnnotation()
override val sourcePsi = psi
private val resolvedAnnotation: AnnotationDescriptor? by lz { psi.analyze()[BindingContext.ANNOTATION, psi] }
private val resolvedCall: ResolvedCall<*>? by lz { psi.getResolvedCall(psi.analyze()) }

View File

@@ -28,7 +28,7 @@ import org.jetbrains.uast.java.AbstractJavaUClass
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
import org.jetbrains.uast.kotlin.declarations.UastLightIdentifier
abstract class AbstractKotlinUClass(private val givenParent: UElement?) : AbstractJavaUClass() {
abstract class AbstractKotlinUClass(private val givenParent: UElement?) : AbstractJavaUClass(), JvmDeclarationUElement {
override val uastParent: UElement? by lz {
givenParent ?: KotlinUastLanguagePlugin().convertElementWithParent(psi.parent ?: psi.containingFile, null)
}
@@ -41,6 +41,10 @@ open class KotlinUClass private constructor(
val ktClass = psi.kotlinOrigin
override val javaPsi: KtLightClass = psi
override val sourcePsi: KtClassOrObject? = ktClass
override val psi = unwrap<UClass, PsiClass>(psi)
override fun getOriginalElement(): PsiElement? = super.getOriginalElement()
@@ -100,6 +104,7 @@ open class KotlinUClass private constructor(
else -> KotlinUClass(psi, containingElement)
}
}
}
class KotlinPrimaryConstructorUMethod(
@@ -112,6 +117,10 @@ class KotlinPrimaryConstructorUMethod(
?.takeIf { it.isNotEmpty() }
?.let { KotlinUBlockExpression.create(it, this) }
}
override val javaPsi = psi
override val sourcePsi = psi.kotlinOrigin
}
class KotlinUAnonymousClass(
@@ -121,6 +130,10 @@ class KotlinUAnonymousClass(
override val psi: PsiAnonymousClass = unwrap<UAnonymousClass, PsiAnonymousClass>(psi)
override val javaPsi: PsiAnonymousClass = psi
override val sourcePsi: KtClassOrObject? = (psi as? KtLightClass)?.kotlinOrigin
override fun getOriginalElement(): PsiElement? = super<AbstractKotlinUClass>.getOriginalElement()
override fun getSuperClass(): UClass? = super<AbstractKotlinUClass>.getSuperClass()
@@ -149,6 +162,10 @@ class KotlinScriptUClass(
override val uastAnchor: UElement
get() = UIdentifier(nameIdentifier, this)
override val javaPsi: PsiClass = psi
override val sourcePsi: KtClassOrObject? = psi.kotlinOrigin
override val psi = unwrap<UClass, KtLightClassForScript>(psi)
override fun getSuperClass(): UClass? = super.getSuperClass()
@@ -182,5 +199,7 @@ class KotlinScriptUClass(
val initializers = script.declarations.filterIsInstance<KtScriptInitializer>()
KotlinUBlockExpression.create(initializers, this)
}
override val javaPsi = psi
override val sourcePsi = psi.kotlinOrigin
}
}

View File

@@ -18,6 +18,7 @@ package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
import org.jetbrains.kotlin.asJava.findFacadeClass
import org.jetbrains.kotlin.asJava.toLightClass
@@ -26,13 +27,17 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.uast.*
import java.util.*
class KotlinUFile(override val psi: KtFile, override val languagePlugin: UastLanguagePlugin) : UFile {
class KotlinUFile(override val psi: KtFile, override val languagePlugin: UastLanguagePlugin) : UFile, JvmDeclarationUElement {
override val packageName: String
get() = psi.packageFqName.asString()
override val annotations: List<UAnnotation>
get() = psi.annotationEntries.map { KotlinUAnnotation(it, this) }
override val javaPsi: PsiElement? = null
override val sourcePsi: PsiElement? = psi
override val allCommentsInFile by lz {
val comments = ArrayList<UComment>(0)
psi.accept(object : PsiRecursiveElementWalkingVisitor() {

View File

@@ -30,6 +30,11 @@ class KotlinUImportStatement(
override val psi: KtImportDirective,
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), UImportStatement {
override val javaPsi = null
override val sourcePsi = psi
override val isOnDemand: Boolean
get() = psi.isAllUnder

View File

@@ -34,6 +34,10 @@ open class KotlinUMethod(
) : KotlinAbstractUElement(givenParent), UAnnotationMethod, JavaUElementWithComments, PsiMethod by psi {
override val psi: KtLightMethod = unwrap<UMethod, KtLightMethod>(psi)
override val javaPsi = psi
override val sourcePsi = psi.kotlinOrigin
override val uastDefaultValue by lz {
val annotationParameter = psi.kotlinOrigin as? KtParameter ?: return@lz null
val defaultValue = annotationParameter.defaultValue ?: return@lz null
@@ -53,7 +57,7 @@ open class KotlinUMethod(
}
override val uastParameters by lz {
psi.parameterList.parameters.map { KotlinUParameter(it, this) }
psi.parameterList.parameters.map { KotlinUParameter(it, (it as? KtLightElement<*, *>)?.kotlinOrigin, this) }
}
override val uastAnchor: UElement

View File

@@ -17,17 +17,21 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.*
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtVariableDeclaration
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.TypeNullability
import org.jetbrains.kotlin.types.typeUtil.nullability
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.uast.*
import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.java.JavaAbstractUExpression
import org.jetbrains.uast.java.JavaUAnnotation
import org.jetbrains.uast.java.annotations
import org.jetbrains.uast.kotlin.declarations.UastLightIdentifier
import org.jetbrains.uast.kotlin.internal.KotlinUElementWithComments
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
@@ -74,7 +78,20 @@ abstract class AbstractKotlinUVariable(givenParent: UElement?)
override fun getContainingFile(): PsiFile = unwrapFakeFileForLightClass(psi.containingFile)
override val annotations: List<UAnnotation> by lz { psi.annotations.map { JavaUAnnotation(it, this) } }
override val annotations by lz {
val sourcePsi = sourcePsi ?: return@lz psi.annotations.map { WrappedUAnnotation(it, this) }
SmartList<UAnnotation>(KotlinNullabilityUAnnotation(sourcePsi, this)).also { annotations ->
(sourcePsi as? KtModifierListOwner)?.annotationEntries?.
filter { it.useSiteTarget?.getAnnotationUseSiteTarget().let { acceptsAnnotationTarget(it) } }?.
mapTo(annotations) { KotlinUAnnotation(it, this) }
}
}
abstract protected fun acceptsAnnotationTarget(target: AnnotationUseSiteTarget?): Boolean
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
@@ -82,18 +99,50 @@ abstract class AbstractKotlinUVariable(givenParent: UElement?)
get() = UIdentifier(nameIdentifier, this)
override fun equals(other: Any?) = other is AbstractKotlinUVariable && psi == other.psi
class WrappedUAnnotation(psiAnnotation: PsiAnnotation, override val uastParent: UElement) : UAnnotation, JvmDeclarationUElement {
override val javaPsi: PsiAnnotation = psiAnnotation
override val psi: PsiAnnotation = javaPsi
override val sourcePsi: PsiElement? = null
override val attributeValues: List<UNamedExpression> by lz {
psi.parameterList.attributes.map { WrappedUNamedExpression(it, this) }
}
class WrappedUNamedExpression(pair: PsiNameValuePair, override val uastParent: UElement?) : UNamedExpression, JvmDeclarationUElement {
override val name: String? = pair.name
override val psi = pair
override val javaPsi: PsiElement? = psi
override val sourcePsi: PsiElement? = null
override val annotations: List<UAnnotation> = emptyList()
override val expression: UExpression by lz { toUExpression(psi.value) }
}
override val qualifiedName: String? = psi.qualifiedName
override fun findAttributeValue(name: String?): UExpression? = psi.findAttributeValue(name)?.let { toUExpression(it) }
override fun findDeclaredAttributeValue(name: String?): UExpression? = psi.findDeclaredAttributeValue(name)?.let { toUExpression(it) }
override fun resolve(): PsiClass? = psi.nameReferenceElement?.resolve() as? PsiClass
}
}
private fun toUExpression(psi: PsiElement?): UExpression = psi.toUElementOfType<UExpression>() ?: UastEmptyExpression
class KotlinUVariable(
psi: PsiVariable,
override val sourcePsi: KtElement,
givenParent: UElement?
) : AbstractKotlinUVariable(givenParent), UVariable, PsiVariable by psi {
override val psi = unwrap<UVariable, PsiVariable>(psi)
override val annotations by lz { psi.annotations.map { JavaUAnnotation(it, this) } }
override val javaPsi = unwrap<UVariable, PsiVariable>(psi)
override val psi = javaPsi
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
override fun acceptsAnnotationTarget(target: AnnotationUseSiteTarget?): Boolean = true
override fun getInitializer(): PsiExpression? {
return super<AbstractKotlinUVariable>.getInitializer()
}
@@ -109,14 +158,34 @@ class KotlinUVariable(
override fun getContainingFile(): PsiFile {
return super.getContainingFile()
}
}
open class KotlinUParameter(
psi: PsiParameter,
final override val sourcePsi: KtElement?,
givenParent: UElement?
) : AbstractKotlinUVariable(givenParent), UParameter, PsiParameter by psi {
override val psi = unwrap<UParameter, PsiParameter>(psi)
final override val javaPsi = unwrap<UParameter, PsiParameter>(psi)
override val psi = javaPsi
private val isLightConstructorParam by lz { psi.getParentOfType<PsiMethod>(true)?.isConstructor }
private val isKtConstructorParam by lz { sourcePsi?.getParentOfType<KtCallableDeclaration>(true)?.let { it is KtPrimaryConstructor } }
override fun acceptsAnnotationTarget(target: AnnotationUseSiteTarget?): Boolean =
sourcePsi.let { sourcePsi ->
(sourcePsi is KtParameter) &&
(isKtConstructorParam == isLightConstructorParam && target == null ||
if (isLightConstructorParam == true)
target == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
else
target == AnnotationUseSiteTarget.SETTER_PARAMETER
)
}
override fun getInitializer(): PsiExpression? {
return super<AbstractKotlinUVariable>.getInitializer()
@@ -135,12 +204,64 @@ open class KotlinUParameter(
}
}
class KotlinNullabilityUAnnotation(val annotatedElement: PsiElement, override val uastParent: UElement) : UAnnotation, JvmDeclarationUElement {
private fun getTargetType(annotatedElement: PsiElement): KotlinType? {
if (annotatedElement is KtCallableDeclaration) {
annotatedElement.typeReference?.getType()?.let { return it }
}
if (annotatedElement is KtProperty) {
annotatedElement.initializer?.let { it.getType(it.analyze()) }?.let { return it }
annotatedElement.delegateExpression?.let { it.getType(it.analyze())?.arguments?.firstOrNull()?.type }?.let { return it }
}
annotatedElement.getParentOfType<KtProperty>(false)?.let {
it.typeReference?.getType() ?: it.initializer?.let { it.getType(it.analyze()) }
}?.let { return it }
return null
}
val nullability by lz { getTargetType(annotatedElement)?.nullability() }
override val attributeValues: List<UNamedExpression>
get() = emptyList()
override val psi: PsiElement?
get() = null
override val javaPsi: PsiElement?
get() = null
override val sourcePsi: PsiElement?
get() = null
override val qualifiedName: String?
get() = when (nullability) {
TypeNullability.NOT_NULL -> NotNull::class.qualifiedName
TypeNullability.NULLABLE -> Nullable::class.qualifiedName
TypeNullability.FLEXIBLE -> "FlexibleNullability"
null -> null
}
override fun findAttributeValue(name: String?): UExpression? = null
override fun findDeclaredAttributeValue(name: String?): UExpression? = null
override fun resolve(): PsiClass? = null
}
open class KotlinUField(
psi: PsiField,
override val sourcePsi: KtElement?,
givenParent: UElement?
) : AbstractKotlinUVariable(givenParent), UField, PsiField by psi {
override val psi = unwrap<UField, PsiField>(psi)
override val javaPsi = unwrap<UField, PsiField>(psi)
override val psi = javaPsi
override fun acceptsAnnotationTarget(target: AnnotationUseSiteTarget?): Boolean =
target == AnnotationUseSiteTarget.FIELD ||
(sourcePsi is KtProperty) && (target == null || target == AnnotationUseSiteTarget.PROPERTY)
override fun getInitializer(): PsiExpression? {
return super<AbstractKotlinUVariable>.getInitializer()
@@ -173,10 +294,15 @@ open class KotlinUField(
open class KotlinULocalVariable(
psi: PsiLocalVariable,
override val sourcePsi: KtElement,
givenParent: UElement?
) : AbstractKotlinUVariable(givenParent), ULocalVariable, PsiLocalVariable by psi {
override val psi = unwrap<ULocalVariable, PsiLocalVariable>(psi)
override val javaPsi = unwrap<ULocalVariable, PsiLocalVariable>(psi)
override fun acceptsAnnotationTarget(target: AnnotationUseSiteTarget?): Boolean = true
override val psi = javaPsi
override fun getInitializer(): PsiExpression? {
return super<AbstractKotlinUVariable>.getInitializer()
@@ -205,24 +331,31 @@ open class KotlinULocalVariable(
open class KotlinUAnnotatedLocalVariable(
psi: PsiLocalVariable,
sourcePsi: KtElement,
uastParent: UElement?,
computeAnnotations: (parent: UElement) -> List<UAnnotation>
) : KotlinULocalVariable(psi, uastParent) {
) : KotlinULocalVariable(psi, sourcePsi, uastParent) {
override val annotations: List<UAnnotation> by lz { computeAnnotations(this) }
}
open class KotlinUEnumConstant(
psi: PsiEnumConstant,
override val sourcePsi: KtElement?,
givenParent: UElement?
) : AbstractKotlinUVariable(givenParent), UEnumConstant, PsiEnumConstant by psi {
override val initializingClass: UClass? by lz {
(psi.initializingClass as? KtLightClass)?.let { initializingClass ->
KotlinUClass.create(initializingClass, this)
}
}
override val psi = unwrap<UEnumConstant, PsiEnumConstant>(psi)
override val javaPsi = unwrap<UEnumConstant, PsiEnumConstant>(psi)
override val psi = javaPsi
override fun acceptsAnnotationTarget(target: AnnotationUseSiteTarget?): Boolean = true
override fun getContainingFile(): PsiFile {
return super.getContainingFile()
@@ -245,7 +378,7 @@ open class KotlinUEnumConstant(
get() = null
override val classReference: UReferenceExpression?
get() = KotlinEnumConstantClassReference(psi, this)
get() = KotlinEnumConstantClassReference(psi, sourcePsi, this)
override val typeArgumentCount: Int
get() = 0
@@ -272,8 +405,12 @@ open class KotlinUEnumConstant(
private class KotlinEnumConstantClassReference(
override val psi: PsiEnumConstant,
override val sourcePsi: KtElement?,
private val givenParent: UElement?
) : JavaAbstractUExpression(), USimpleNameReferenceExpression {
override val javaPsi: PsiElement?
get() = psi
override val uastParent: UElement? by lz {
givenParent ?: KotlinUastLanguagePlugin().convertElementWithParent(psi.parent ?: psi.containingFile, null)
}

View File

@@ -14,25 +14,29 @@ import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable
private fun createVariableReferenceExpression(variable: UVariable, containingElement: UElement?) =
object : USimpleNameReferenceExpression {
object : USimpleNameReferenceExpression, JvmDeclarationUElement {
override val psi: PsiElement? = null
override fun resolve(): PsiElement? = variable
override val uastParent: UElement? = containingElement
override val resolvedName: String? = variable.name
override val annotations: List<UAnnotation> = emptyList()
override val identifier: String = variable.name.orAnonymous()
override val javaPsi: PsiElement? = null
override val sourcePsi: PsiElement? = null
}
private fun createNullLiteralExpression(containingElement: UElement?) =
object : ULiteralExpression {
object : ULiteralExpression, JvmDeclarationUElement {
override val psi: PsiElement? = null
override val uastParent: UElement? = containingElement
override val value: Any? = null
override val annotations: List<UAnnotation> = emptyList()
override val javaPsi: PsiElement? = null
override val sourcePsi: PsiElement? = null
}
private fun createNotEqWithNullExpression(variable: UVariable, containingElement: UElement?) =
object : UBinaryExpression {
object : UBinaryExpression, JvmDeclarationUElement {
override val psi: PsiElement? = null
override val uastParent: UElement? = containingElement
override val leftOperand: UExpression by lz { createVariableReferenceExpression(variable, this) }
@@ -41,6 +45,8 @@ private fun createNotEqWithNullExpression(variable: UVariable, containingElement
override val operatorIdentifier: UIdentifier? = UIdentifier(null, this)
override fun resolveOperator(): PsiMethod? = null
override val annotations: List<UAnnotation> = emptyList()
override val javaPsi: PsiElement? = null
override val sourcePsi: PsiElement? = null
}
private fun createElvisExpressions(
@@ -50,12 +56,14 @@ private fun createElvisExpressions(
psiParent: PsiElement): List<UExpression> {
val declaration = KotlinUDeclarationsExpression(containingElement)
val tempVariable = KotlinULocalVariable(UastKotlinPsiVariable.create(left, declaration, psiParent), declaration)
val tempVariable = KotlinULocalVariable(UastKotlinPsiVariable.create(left, declaration, psiParent), left, declaration)
declaration.declarations = listOf(tempVariable)
val ifExpression = object : UIfExpression {
val ifExpression = object : UIfExpression, JvmDeclarationUElement {
override val psi: PsiElement? = null
override val uastParent: UElement? = containingElement
override val javaPsi: PsiElement? = null
override val sourcePsi: PsiElement? = null
override val condition: UExpression by lz { createNotEqWithNullExpression(tempVariable, this) }
override val thenExpression: UExpression? by lz { createVariableReferenceExpression(tempVariable, this) }
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this ) }
@@ -82,7 +90,9 @@ class KotlinUElvisExpression(
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), UExpressionList, KotlinEvaluatableUElement {
override val psi: PsiElement? = elvisExpression
override val javaPsi: PsiElement? = null
override val sourcePsi: PsiElement? = elvisExpression
override val psi: PsiElement? = sourcePsi
override val kind = KotlinSpecialExpressionKinds.ELVIS
override val annotations: List<UAnnotation> = emptyList()
override val expressions: List<UExpression> by lz {

View File

@@ -30,8 +30,10 @@ class KotlinUBlockExpression(
private class KotlinLazyUBlockExpression(
override val uastParent: UElement?,
expressionProducer: (expressionParent: UElement?) -> List<UExpression>
) : UBlockExpression {
) : UBlockExpression, JvmDeclarationUElement {
override val psi: PsiElement? = null
override val javaPsi: PsiElement? = null
override val sourcePsi: PsiElement? = null
override val annotations: List<UAnnotation> = emptyList()
override val expressions by lz { expressionProducer(this) }
}

View File

@@ -27,11 +27,15 @@ class KotlinUCatchClause(
override val psi: KtCatchClause,
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), UCatchClause {
override val javaPsi = null
override val sourcePsi = psi
override val body by lz { KotlinConverter.convertOrEmpty(psi.catchBody, this) }
override val parameters by lz {
val parameter = psi.catchParameter ?: return@lz emptyList<UParameter>()
listOf(KotlinUParameter(UastKotlinPsiParameter.create(parameter, psi, this, 0), this))
listOf(KotlinUParameter(UastKotlinPsiParameter.create(parameter, psi, this, 0), psi, this))
}
override val typeReferences by lz {

View File

@@ -25,6 +25,9 @@ open class KotlinUDeclarationsExpression(
val psiAnchor: PsiElement? = null
) : KotlinAbstractUExpression(givenParent), UDeclarationsExpression {
override val sourcePsi: PsiElement?
get() = psiAnchor
override val uastParent: UElement?
get() = if (psiAnchor != null) doConvertParent(this, psiAnchor.parent) else super.uastParent

View File

@@ -34,7 +34,7 @@ class KotlinUForEachExpression(
override val variable by lz {
val parameter = psi.loopParameter?.let { UastKotlinPsiParameter.create(it, psi, this, 0) }
?: UastPsiParameterNotResolved(psi, KotlinLanguage.INSTANCE)
KotlinUParameter(parameter, this)
KotlinUParameter(parameter, psi, this)
}
override val forIdentifier: UIdentifier

View File

@@ -28,14 +28,14 @@ class KotlinULambdaExpression(
override val psi: KtLambdaExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), ULambdaExpression, KotlinUElementWithType {
val functionalInterfaceType: PsiType?
override val functionalInterfaceType: PsiType?
get() = getFunctionalInterfaceType()
override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) }
override val valueParameters by lz {
psi.valueParameters.mapIndexed { i, p ->
KotlinUParameter(UastKotlinPsiParameter.create(p, psi, this, i), this)
KotlinUParameter(UastKotlinPsiParameter.create(p, psi, this, i), psi, this)
}
}

View File

@@ -23,19 +23,23 @@ import org.jetbrains.uast.*
class KotlinUNamedExpression private constructor(
override val name: String?,
override val sourcePsi: PsiElement?,
givenParent: UElement?,
expressionProducer: (UElement) -> UExpression
) : KotlinAbstractUElement(givenParent), UNamedExpression {
override val expression: UExpression by lz { expressionProducer(this) }
override val annotations: List<UAnnotation> = emptyList()
override val psi: PsiElement? = null
override val javaPsi: PsiElement? = null
companion object {
internal fun create(name: String?, valueArgument: ValueArgument, uastParent: UElement?): UNamedExpression {
val expression = valueArgument.getArgumentExpression()
return KotlinUNamedExpression(name, uastParent) { expressionParent ->
return KotlinUNamedExpression(name, valueArgument.asElement(), uastParent) { expressionParent ->
expression?.let { expressionParent.getLanguagePlugin().convert<UExpression>(it, expressionParent) } ?: UastEmptyExpression
}
}
@@ -44,7 +48,7 @@ class KotlinUNamedExpression private constructor(
name: String?,
valueArguments: List<ValueArgument>,
uastParent: UElement?): UNamedExpression {
return KotlinUNamedExpression(name, uastParent) { expressionParent ->
return KotlinUNamedExpression(name, null, uastParent) { expressionParent ->
KotlinUVarargExpression(valueArguments, expressionParent)
}
}

View File

@@ -75,6 +75,10 @@ class KotlinUObjectLiteralExpression(
override val psi: KtSuperTypeCallEntry,
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), USimpleNameReferenceExpression {
override val javaPsi = null
override val sourcePsi = psi
override fun resolve() = (psi.resolveCallToDeclaration(this) as? PsiMethod)?.containingClass
override val annotations: List<UAnnotation>

View File

@@ -69,7 +69,9 @@ class KotlinUSwitchEntry(
is KtBlockExpression -> exprPsi.statements.map { KotlinConverter.convertOrEmpty(it, this) }
else -> listOf(KotlinConverter.convertOrEmpty(exprPsi, this))
}
expressions = userExpressions + object : UBreakExpression {
expressions = userExpressions + object : UBreakExpression, JvmDeclarationUElement {
override val javaPsi: PsiElement? = null
override val sourcePsi: PsiElement? = null
override val psi: PsiElement?
get() = null
override val label: String?

View File

@@ -1,5 +1,6 @@
package org.jetbrains.uast.kotlin.expressions
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiType
import com.intellij.psi.PsiVariable
import org.jetbrains.kotlin.psi.KtFunction
@@ -14,6 +15,10 @@ internal class KotlinLocalFunctionUVariable(
override val psi: PsiVariable,
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), UVariable, PsiVariable by psi {
override val javaPsi = psi
override val sourcePsi: PsiElement? = (psi as? UastKotlinPsiVariable?)?.ktElement ?: psi
override val uastInitializer: UExpression? by lz {
createLocalFunctionLambdaExpression(function, this)
}
@@ -27,14 +32,13 @@ private class KotlinLocalFunctionULambdaExpression(
override val psi: KtFunction,
givenParent: UElement?
): KotlinAbstractUExpression(givenParent), ULambdaExpression {
val functionalInterfaceType: PsiType?
get() = null
override val functionalInterfaceType: PsiType? = null
override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) }
override val valueParameters by lz {
psi.valueParameters.mapIndexed { i, p ->
KotlinUParameter(UastKotlinPsiParameter.create(p, psi, this, i), this)
KotlinUParameter(UastKotlinPsiParameter.create(p, psi, this, i), p, this)
}
}

View File

@@ -17,10 +17,11 @@
package org.jetbrains.uast.kotlin.internal
import com.intellij.psi.PsiComment
import org.jetbrains.uast.JvmDeclarationUElement
import org.jetbrains.uast.UComment
import org.jetbrains.uast.UElement
interface KotlinUElementWithComments : UElement {
interface KotlinUElementWithComments : UElement, JvmDeclarationUElement {
override val comments: List<UComment>
get() {
val psi = psi ?: return emptyList()

View File

@@ -1,6 +1,6 @@
UFile (package = ) [public final class CycleInTypeParametersKt {...]
UClass (name = CycleInTypeParametersKt) [public final class CycleInTypeParametersKt {...}]
UField (name = a) [private static final var a: Device<?> = null as? Device<?>]
UField (name = a) [@org.jetbrains.annotations.Nullable private static final var a: Device<?> = null as? Device<?>]
UAnnotation (fqName = org.jetbrains.annotations.Nullable) [@org.jetbrains.annotations.Nullable]
UBinaryExpressionWithType [null as? Device<?>] : PsiType:Device<?>
ULiteralExpression (value = null) [null] : PsiType:Void

View File

@@ -2,7 +2,7 @@ UFile (package = )
UClass (name = DefaultParameterValuesKt)
UAnnotationMethod (name = foo)
UParameter (name = a)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
ULiteralExpression (value = 1)
UParameter (name = foo)
UAnnotation (fqName = org.jetbrains.annotations.Nullable)

View File

@@ -1,4 +1,4 @@
public final class DefaultParameterValuesKt {
public static final fun foo(a: int, foo: java.lang.String) : void {
public static final fun foo(@org.jetbrains.annotations.NotNull a: int, @org.jetbrains.annotations.Nullable foo: java.lang.String) : void {
}
}

View File

@@ -1,5 +1,5 @@
public final class ElvisKt {
public static final fun foo(bar: java.lang.String) : java.lang.String = null
public static final fun foo(@org.jetbrains.annotations.NotNull bar: java.lang.String) : java.lang.String = null
public static final fun bar() : int = 42
public static final fun baz() : java.lang.String {
return elvis {

View File

@@ -3,8 +3,8 @@ public enum Style {
public fun getExitAnimation() : java.lang.String = "bar"
fun SHEET() = UastEmptyExpression
}
private final var value: java.lang.String
@org.jetbrains.annotations.NotNull private final var value: java.lang.String
public abstract fun getExitAnimation() : java.lang.String = UastEmptyExpression
public final fun getValue() : java.lang.String = UastEmptyExpression
protected fun Style(value: java.lang.String) = UastEmptyExpression
protected fun Style(@org.jetbrains.annotations.NotNull value: java.lang.String) = UastEmptyExpression
}

View File

@@ -3,9 +3,9 @@ UFile (package = )
UAnnotationMethod (name = Foo)
UClass (name = Bar)
UField (name = a)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UField (name = b)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UAnnotationMethod (name = getAPlusB)
UBinaryExpression (operator = +)
USimpleNameReferenceExpression (identifier = a)
@@ -14,9 +14,9 @@ UFile (package = )
UAnnotationMethod (name = getB)
UAnnotationMethod (name = Bar)
UParameter (name = a)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UParameter (name = b)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UClass (name = Baz)
UAnnotationMethod (name = doNothing)
USimpleNameReferenceExpression (identifier = Unit)

View File

@@ -1,12 +1,12 @@
public final class Foo {
public fun Foo() = UastEmptyExpression
public static final class Bar {
private final var a: int
private final var b: int
@org.jetbrains.annotations.NotNull private final var a: int
@org.jetbrains.annotations.NotNull private final var b: int
public final fun getAPlusB() : int = a + b
public final fun getA() : int = UastEmptyExpression
public final fun getB() : int = UastEmptyExpression
public fun Bar(a: int, b: int) = UastEmptyExpression
public fun Bar(@org.jetbrains.annotations.NotNull a: int, @org.jetbrains.annotations.NotNull b: int) = UastEmptyExpression
public static final class Baz {
public final fun doNothing() : void = Unit
public fun Baz() = UastEmptyExpression

View File

@@ -22,6 +22,7 @@ UFile (package = )
UVariable (name = someLocalFun)
ULambdaExpression
UParameter (name = text)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
ULiteralExpression (value = 42)
UReturnExpression
UBinaryExpression (operator = ==)

View File

@@ -9,7 +9,7 @@ public final class LocalDeclarationsKt {
var baz: kotlin.jvm.functions.Function0<? extends kotlin.Unit> = fun () {
<init>()
}
var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (var text: java.lang.String) {
var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {
42
}
return bar() == <init>()

View File

@@ -18,10 +18,11 @@ UFile (package = ) [public final class LocalDeclarationsKt {...]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [<init>()] : PsiType:<ErrorType>
UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))]
USimpleNameReferenceExpression (identifier = <init>) [<init>] : PsiType:<ErrorType>
UDeclarationsExpression [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (var text: java.lang.String) {...}]
UVariable (name = someLocalFun) [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (var text: java.lang.String) {...}]
ULambdaExpression [fun (var text: java.lang.String) {...}]
UParameter (name = text) [var text: java.lang.String]
UDeclarationsExpression [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}]
UVariable (name = someLocalFun) [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}]
ULambdaExpression [fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}]
UParameter (name = text) [@org.jetbrains.annotations.NotNull var text: java.lang.String]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
ULiteralExpression (value = 42) [42] : PsiType:int
UReturnExpression [return bar() == <init>()] : PsiType:Void
UBinaryExpression (operator = ==) [bar() == <init>()] : PsiType:boolean

View File

@@ -18,10 +18,11 @@ UFile (package = ) [public final class LocalDeclarationsKt {...]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [<init>()] = external <init>()()
UIdentifier (Identifier (Local)) [UIdentifier (Identifier (Local))]
USimpleNameReferenceExpression (identifier = <init>) [<init>] = external <init>()()
UDeclarationsExpression [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (var text: java.lang.String) {...}] = Undetermined
UVariable (name = someLocalFun) [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (var text: java.lang.String) {...}]
ULambdaExpression [fun (var text: java.lang.String) {...}] = Undetermined
UParameter (name = text) [var text: java.lang.String]
UDeclarationsExpression [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}] = Undetermined
UVariable (name = someLocalFun) [var someLocalFun: kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.String,? extends java.lang.Integer> = fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}]
ULambdaExpression [fun (@org.jetbrains.annotations.NotNull var text: java.lang.String) {...}] = Undetermined
UParameter (name = text) [@org.jetbrains.annotations.NotNull var text: java.lang.String]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
ULiteralExpression (value = 42) [42] = 42
UReturnExpression [return bar() == <init>()] = Nothing
UBinaryExpression (operator = ==) [bar() == <init>()] = Undetermined

View File

@@ -0,0 +1,6 @@
annotation class TestAnnotation
fun foo() {
@TestAnnotation
val bar = "lorem ipsum"
}

View File

@@ -0,0 +1,9 @@
UFile (package = )
UClass (name = LocalVariableWithAnnotationKt)
UAnnotationMethod (name = foo)
UBlockExpression
UDeclarationsExpression
ULocalVariable (name = bar)
UAnnotation (fqName = TestAnnotation)
ULiteralExpression (value = "lorem ipsum")
UClass (name = TestAnnotation)

View File

@@ -0,0 +1,8 @@
public final class LocalVariableWithAnnotationKt {
public static final fun foo() : void {
@TestAnnotation var bar: java.lang.String = "lorem ipsum"
}
}
public abstract annotation TestAnnotation {
}

View File

@@ -6,26 +6,26 @@ UFile (package = )
UClass (name = MyAnnotation5)
UClass (name = Test1)
UField (name = bar)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UAnnotationMethod (name = getBar)
UAnnotationMethod (name = setBar)
UParameter (name = p)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UAnnotationMethod (name = Test1)
UParameter (name = bar)
UAnnotation (fqName = MyAnnotation)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UClass (name = Test2)
UField (name = bar)
UAnnotation (fqName = MyAnnotation5)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UAnnotationMethod (name = getBar)
UAnnotation (fqName = MyAnnotation)
UAnnotationMethod (name = setBar)
UAnnotation (fqName = MyAnnotation2)
UParameter (name = p)
UAnnotation (fqName = MyAnnotation3)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UAnnotationMethod (name = Test2)
UParameter (name = bar)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)

View File

@@ -14,17 +14,17 @@ public abstract annotation MyAnnotation5 {
}
public final class Test1 {
private var bar: int
@org.jetbrains.annotations.NotNull private var bar: int
public final fun getBar() : int = UastEmptyExpression
public final fun setBar(p: int) : void = UastEmptyExpression
public fun Test1(bar: int) = UastEmptyExpression
public final fun setBar(@org.jetbrains.annotations.NotNull p: int) : void = UastEmptyExpression
public fun Test1(@org.jetbrains.annotations.NotNull @MyAnnotation bar: int) = UastEmptyExpression
}
public final class Test2 {
private var bar: int
@org.jetbrains.annotations.NotNull @MyAnnotation5 private var bar: int
@MyAnnotation
public final fun getBar() : int = UastEmptyExpression
@MyAnnotation2
public final fun setBar(p: int) : void = UastEmptyExpression
public fun Test2(bar: int) = UastEmptyExpression
public final fun setBar(@org.jetbrains.annotations.NotNull @MyAnnotation3 p: int) : void = UastEmptyExpression
public fun Test2(@org.jetbrains.annotations.NotNull bar: int) = UastEmptyExpression
}

View File

@@ -2,13 +2,13 @@ UFile (package = )
UClass (name = ParametersWithDefaultValuesKt)
UAnnotationMethod (name = foo)
UParameter (name = a)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UParameter (name = b)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UParameter (name = c)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
ULiteralExpression (value = 0)
UParameter (name = flag)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
ULiteralExpression (value = false)
UBlockExpression

View File

@@ -1,4 +1,4 @@
public final class ParametersWithDefaultValuesKt {
public static final fun foo(a: int, b: java.lang.String, c: int, flag: boolean) : void {
public static final fun foo(@org.jetbrains.annotations.NotNull a: int, @org.jetbrains.annotations.NotNull b: java.lang.String, @org.jetbrains.annotations.NotNull c: int, @org.jetbrains.annotations.NotNull flag: boolean) : void {
}
}

View File

@@ -1,9 +1,9 @@
public final class PropertyTest {
public final fun getStringRepresentation() : java.lang.String = this.toString()
public final fun setStringRepresentation(value: java.lang.String) : void {
public final fun setStringRepresentation(@org.jetbrains.annotations.NotNull value: java.lang.String) : void {
setDataFromString(value)
}
public final fun setDataFromString(data: java.lang.String) : void {
public final fun setDataFromString(@org.jetbrains.annotations.NotNull data: java.lang.String) : void {
}
public fun PropertyTest() = UastEmptyExpression
}

View File

@@ -1,5 +1,5 @@
public final class PropertyDelegateKt {
private static final var sdCardPath$delegate: kotlin.Lazy
@org.jetbrains.annotations.NotNull private static final var sdCardPath$delegate: kotlin.Lazy
public static final fun getSdCardPath() : java.lang.String = UastEmptyExpression
public static final fun localPropertyTest() : void {
var sdCardPathLocal: java.lang.String

View File

@@ -1,7 +1,7 @@
public final class TestPropertyInitializer {
private var withSetter: java.lang.String = "/sdcard"
@org.jetbrains.annotations.NotNull private var withSetter: java.lang.String = "/sdcard"
public final fun getWithSetter() : java.lang.String = field
public final fun setWithSetter(p: java.lang.String) : void {
public final fun setWithSetter(@org.jetbrains.annotations.NotNull p: java.lang.String) : void {
field = p
}
public fun TestPropertyInitializer() = UastEmptyExpression

View File

@@ -1,5 +1,5 @@
public final class PropertyInitializerWithoutSetterKt {
private static var withoutSetter: java.lang.String = "/sdcard"
@org.jetbrains.annotations.NotNull private static var withoutSetter: java.lang.String = "/sdcard"
public static final fun getWithoutSetter() : java.lang.String = field
public static final fun setWithoutSetter(p: java.lang.String) : void = UastEmptyExpression
public static final fun setWithoutSetter(@org.jetbrains.annotations.NotNull p: java.lang.String) : void = UastEmptyExpression
}

View File

@@ -1,10 +1,11 @@
UFile (package = )
UClass (name = PropertyWithAnnotationKt)
UField (name = prop1)
UAnnotation (fqName = null)
UAnnotation (fqName = TestAnnotation)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
ULiteralExpression (value = 0)
UField (name = prop3)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
ULiteralExpression (value = 0)
UAnnotationMethod (name = getProp1)
UAnnotationMethod (name = getProp2)
@@ -15,7 +16,7 @@ UFile (package = )
UAnnotationMethod (name = setProp3)
UAnnotation (fqName = TestAnnotation)
UParameter (name = value)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UBlockExpression
UBinaryExpression (operator = =)
USimpleNameReferenceExpression (identifier = field)

View File

@@ -1,12 +1,12 @@
public final class PropertyWithAnnotationKt {
private static final var prop1: int = 0
private static var prop3: int = 0
@org.jetbrains.annotations.NotNull @TestAnnotation private static final var prop1: int = 0
@org.jetbrains.annotations.NotNull private static var prop3: int = 0
public static final fun getProp1() : int = UastEmptyExpression
@TestAnnotation
public static final fun getProp2() : int = 0
public static final fun getProp3() : int = 0
@TestAnnotation
public static final fun setProp3(value: int) : void {
public static final fun setProp3(@org.jetbrains.annotations.NotNull value: int) : void {
field = value
}
}

View File

@@ -1,5 +1,5 @@
public final class Simple {
private final var property: java.lang.String = "Mary"
@org.jetbrains.annotations.NotNull private final var property: java.lang.String = "Mary"
public final fun method() : void {
println("Hello, world!")
}

View File

@@ -1,6 +1,6 @@
UFile (package = ) [public final class Simple {...]
UClass (name = Simple) [public final class Simple {...}]
UField (name = property) [private final var property: java.lang.String = "Mary"]
UField (name = property) [@org.jetbrains.annotations.NotNull private final var property: java.lang.String = "Mary"]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
ULiteralExpression (value = "Mary") ["Mary"] = "Mary"
UAnnotationMethod (name = method) [public final fun method() : void {...}]

View File

@@ -0,0 +1,9 @@
class SimpleAnnotated {
@Suppress("abc")
fun method() {
println("Hello, world!")
}
@SinceKotlin("1.0")
val property: String = "Mary"
}

View File

@@ -2,7 +2,7 @@ UFile (package = )
UClass (name = SimpleScript)
UAnnotationMethod (name = getBarOrNull)
UParameter (name = flag)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UBlockExpression
UReturnExpression
UIfExpression
@@ -30,10 +30,10 @@ UFile (package = )
ULiteralExpression (value = "Goodbye World!")
UClass (name = Bar)
UField (name = b)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
ULiteralExpression (value = 0)
UField (name = a)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UAnnotationMethod (name = getB)
UAnnotationMethod (name = getAPlusB)
UBinaryExpression (operator = +)
@@ -42,7 +42,7 @@ UFile (package = )
UAnnotationMethod (name = getA)
UAnnotationMethod (name = Bar)
UParameter (name = a)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UClass (name = Baz)
UAnnotationMethod (name = doSomething)
UBlockExpression

View File

@@ -1,19 +1,19 @@
public class SimpleScript : kotlin.script.templates.standard.ScriptTemplateWithArgs {
public final fun getBarOrNull(flag: boolean) : SimpleScript.Bar {
public final fun getBarOrNull(@org.jetbrains.annotations.NotNull flag: boolean) : SimpleScript.Bar {
return if (flag) <init>(42) else null
}
public fun SimpleScript(p: java.lang.String[]) {
public fun SimpleScript(@null p: java.lang.String[]) {
println("Hello World!")
getBarOrNull(true)
println("Goodbye World!")
}
public static final class Bar {
private final var b: int = 0
private final var a: int
@org.jetbrains.annotations.NotNull private final var b: int = 0
@org.jetbrains.annotations.NotNull private final var a: int
public final fun getB() : int = UastEmptyExpression
public final fun getAPlusB() : int = a + b
public final fun getA() : int = UastEmptyExpression
public fun Bar(a: int) = UastEmptyExpression
public fun Bar(@org.jetbrains.annotations.NotNull a: int) = UastEmptyExpression
public static final class Baz {
public final fun doSomething() : void {
}

View File

@@ -1,8 +1,8 @@
public final class StringTemplateKt {
private static final var foo: java.lang.String = "lorem"
private static final var bar: java.lang.String = "ipsum"
private static final var baz: java.lang.String = "dolor"
private static final var foobarbaz: java.lang.String = foo + " " + bar + " " + baz
@org.jetbrains.annotations.NotNull private static final var foo: java.lang.String = "lorem"
@org.jetbrains.annotations.NotNull private static final var bar: java.lang.String = "ipsum"
@org.jetbrains.annotations.NotNull private static final var baz: java.lang.String = "dolor"
@org.jetbrains.annotations.NotNull private static final var foobarbaz: java.lang.String = foo + " " + bar + " " + baz
public static final fun getFoo() : java.lang.String = UastEmptyExpression
public static final fun getBar() : java.lang.String = UastEmptyExpression
public static final fun getBaz() : java.lang.String = UastEmptyExpression

View File

@@ -0,0 +1,6 @@
class C {
@Test
fun foo() {
}
}

View File

@@ -1,14 +1,14 @@
public abstract interface Callback {
public abstract fun onError(throwable: java.lang.Throwable) : void = UastEmptyExpression
public abstract fun onError(@org.jetbrains.annotations.NotNull throwable: java.lang.Throwable) : void = UastEmptyExpression
}
public final class Model {
public final fun crashMe(clazz: java.lang.Class<T>, factory: kotlin.jvm.functions.Function0<? extends T>) : void {
public final fun crashMe(@org.jetbrains.annotations.NotNull clazz: java.lang.Class<T>, @org.jetbrains.annotations.NotNull factory: kotlin.jvm.functions.Function0<? extends T>) : void {
throw <init>()
}
public fun Model() {
{
crashMe(Callback.java, {
crashMe(Callback.java, {
anonymous object : Callback {
override fun onError(throwable: Throwable) {
throw UnsupportedOperationException("")

View File

@@ -1,13 +1,13 @@
UFile (package = ) [public abstract interface Callback {...]
UClass (name = Callback) [public abstract interface Callback {...}]
UAnnotationMethod (name = onError) [public abstract fun onError(throwable: java.lang.Throwable) : void = UastEmptyExpression]
UParameter (name = throwable) [var throwable: java.lang.Throwable]
UAnnotationMethod (name = onError) [public abstract fun onError(@org.jetbrains.annotations.NotNull throwable: java.lang.Throwable) : void = UastEmptyExpression]
UParameter (name = throwable) [@org.jetbrains.annotations.NotNull var throwable: java.lang.Throwable]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UClass (name = Model) [public final class Model {...}]
UAnnotationMethod (name = crashMe) [public final fun crashMe(clazz: java.lang.Class<T>, factory: kotlin.jvm.functions.Function0<? extends T>) : void {...}]
UParameter (name = clazz) [var clazz: java.lang.Class<T>]
UAnnotationMethod (name = crashMe) [public final fun crashMe(@org.jetbrains.annotations.NotNull clazz: java.lang.Class<T>, @org.jetbrains.annotations.NotNull factory: kotlin.jvm.functions.Function0<? extends T>) : void {...}]
UParameter (name = clazz) [@org.jetbrains.annotations.NotNull var clazz: java.lang.Class<T>]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UParameter (name = factory) [var factory: kotlin.jvm.functions.Function0<? extends T>]
UParameter (name = factory) [@org.jetbrains.annotations.NotNull var factory: kotlin.jvm.functions.Function0<? extends T>]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}] : PsiType:Void
UThrowExpression [throw <init>()] : PsiType:Void
@@ -27,8 +27,8 @@ UFile (package = ) [public abstract interface Callback {...]
UBlockExpression [{...}]
UObjectLiteralExpression [anonymous object : Callback {... }] : PsiType:Callback
UClass (name = null) [final class null {...}]
UAnnotationMethod (name = onError) [public fun onError(throwable: java.lang.Throwable) : void {...}]
UParameter (name = throwable) [var throwable: java.lang.Throwable]
UAnnotationMethod (name = onError) [public fun onError(@org.jetbrains.annotations.NotNull throwable: java.lang.Throwable) : void {...}]
UParameter (name = throwable) [@org.jetbrains.annotations.NotNull var throwable: java.lang.Throwable]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}] : PsiType:Void
UThrowExpression [throw <init>("")] : PsiType:Void

View File

@@ -1,5 +1,5 @@
public final class WhenIsKt {
public static final fun foo(bar: java.lang.Object) : java.lang.String = switch (bar) {
public static final fun foo(@org.jetbrains.annotations.NotNull bar: java.lang.Object) : java.lang.String = switch (bar) {
it is java.lang.String -> {
bar
break

View File

@@ -6,7 +6,7 @@ UFile (package = )
UIdentifier (Identifier (readLine))
USimpleNameReferenceExpression (identifier = readLine)
UField (name = b)
UAnnotation (fqName = null)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
USwitchExpression
USimpleNameReferenceExpression (identifier = a)
UExpressionList (when)

View File

@@ -1,23 +1,23 @@
public final class WhenStringLiteralKt {
private static final var a: java.lang.String = readLine()
private static final var b: int = switch (a) {
@org.jetbrains.annotations.Nullable private static final var a: java.lang.String = readLine()
@org.jetbrains.annotations.NotNull private static final var b: int = switch (a) {
"abc" -> {
1
break
}
"def", "ghi" -> {
2
break
}
-> {
3
break
}
}
public static final fun getA() : java.lang.String = UastEmptyExpression
public static final fun getB() : int = UastEmptyExpression
public static final fun <no name provided>() : void {

View File

@@ -3,11 +3,11 @@ package org.jetbrains.uast.test.kotlin
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiRecursiveElementVisitor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
import org.jetbrains.uast.UDeclaration
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UFile
import org.jetbrains.uast.*
import org.jetbrains.uast.java.JavaUAnnotation
import org.jetbrains.uast.kotlin.KOTLIN_CACHED_UELEMENT_KEY
import org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin
import org.jetbrains.uast.test.common.RenderLogTestBase
@@ -32,6 +32,7 @@ abstract class AbstractKotlinRenderLogTest : AbstractKotlinUastTest(), RenderLog
}
file.checkContainingFileForAllElements()
file.checkJvmDeclarationsImplementations()
}
private fun checkParentConsistency(file: UFile) {
@@ -95,6 +96,29 @@ abstract class AbstractKotlinRenderLogTest : AbstractKotlinUastTest(), RenderLog
}
})
}
private fun UFile.checkJvmDeclarationsImplementations() {
accept(object : UastVisitor {
override fun visitElement(node: UElement): Boolean {
val jvmDeclaration = node as? JvmDeclarationUElement
?: throw AssertionError("${node.javaClass} should implement 'JvmDeclarationUElement'")
if (jvmDeclaration is UIdentifier) return false // probably should be fixed in platform to fully support in in Kotlin
jvmDeclaration.sourcePsi?.let {
assertTrue("sourcePsi should be physical but ${it.javaClass} found for [${it.text}] " +
"for ${jvmDeclaration.javaClass}->${jvmDeclaration.uastParent?.javaClass}", it is KtElement)
}
jvmDeclaration.javaPsi?.let {
assertTrue("javaPsi should be light but ${it.javaClass} found for [${it.text}] " +
"for ${jvmDeclaration.javaClass}->${jvmDeclaration.uastParent?.javaClass}", it !is KtElement)
}
return false
}
})
}
}
private fun PsiFile.clearUastCaches() {

View File

@@ -5,6 +5,7 @@ import com.intellij.testFramework.UsefulTestCase
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtLiteralStringTemplateEntry
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.psi.KtUserType
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
@@ -72,6 +73,27 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
}
}
@Test fun testSAM() {
doTest("SAM") { _, file ->
assertNull(file.findElementByText<ULambdaExpression>("{ /* Not SAM */ }").functionalInterfaceType)
assertEquals("java.lang.Runnable",
file.findElementByText<ULambdaExpression>("{/* Variable */}").functionalInterfaceType?.canonicalText)
assertEquals("java.lang.Runnable",
file.findElementByText<ULambdaExpression>("{/* Assignment */}").functionalInterfaceType?.canonicalText)
assertEquals("java.lang.Runnable",
file.findElementByText<ULambdaExpression>("{/* Type Cast */}").functionalInterfaceType?.canonicalText)
assertEquals("java.lang.Runnable",
file.findElementByText<ULambdaExpression>("{/* Argument */}").functionalInterfaceType?.canonicalText)
assertEquals("java.lang.Runnable",
file.findElementByText<ULambdaExpression>("{/* Return */}").functionalInterfaceType?.canonicalText)
}
}
@Test fun testParameterPropertyWithAnnotation() {
doTest("ParameterPropertyWithAnnotation") { _, file ->
val test1 = file.classes.find { it.name == "Test1" }!!
@@ -102,6 +124,14 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
}
}
@Test fun testConvertTypeInAnnotation() {
doTest("TypeInAnnotation") { _, file ->
val index = file.psi.text.indexOf("Test")
val element = file.psi.findElementAt(index)!!.getParentOfType<KtUserType>(false)!!
assertNotNull(element.getUastParentOfType(UAnnotation::class.java))
}
}
@Test fun testElvisType() {
doTest("ElvisType") { _, file ->
val elvisExpression = file.findElementByText<UExpression>("text ?: return")
@@ -131,23 +161,19 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
fun testWhenStringLiteral() {
doTest("WhenStringLiteral") { _, file ->
fun UFile.findULiteralExpressionFromPsi(refText: String): ULiteralExpression =
this.psi.findElementAt(file.psi.text.indexOf(refText))!!
.parentsWithSelf.mapNotNull { it.toUElementOfType<ULiteralExpression>() }.first()
file.findULiteralExpressionFromPsi("abc").let { literalExpression ->
file.findFromPsi<ULiteralExpression>("abc").let { literalExpression ->
val psi = literalExpression.psi!!
Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
UsefulTestCase.assertInstanceOf(literalExpression.uastParent, USwitchClauseExpressionWithBody::class.java)
}
file.findULiteralExpressionFromPsi("def").let { literalExpression ->
file.findFromPsi<ULiteralExpression>("def").let { literalExpression ->
val psi = literalExpression.psi!!
Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
UsefulTestCase.assertInstanceOf(literalExpression.uastParent, USwitchClauseExpressionWithBody::class.java)
}
file.findULiteralExpressionFromPsi("def1").let { literalExpression ->
file.findFromPsi<ULiteralExpression>("def1").let { literalExpression ->
val psi = literalExpression.psi!!
Assert.assertTrue(psi is KtLiteralStringTemplateEntry)
UsefulTestCase.assertInstanceOf(literalExpression.uastParent, UBlockExpression::class.java)
@@ -156,4 +182,21 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
}
}
@Test
fun testSimpleAnnotated() {
doTest("SimpleAnnotated") { _, file ->
file.findFromPsi<UField>("@SinceKotlin(\"1.0\")\n val property: String = \"Mary\"").let { field ->
val annotation = field.annotations.assertedFind("kotlin.SinceKotlin") { it.qualifiedName }
Assert.assertEquals(annotation.findDeclaredAttributeValue("version")?.evaluateString(), "1.0")
}
}
}
}
fun <T, R> Iterable<T>.assertedFind(value: R, transform: (T) -> R): T = find { transform(it) == value } ?: throw AssertionError("'$value' not found, only ${this.joinToString { transform(it).toString() }}")
inline fun <reified T : UElement> UFile.findFromPsi(refText: String): T = this.psi.findElementAt(this.psi.text.indexOf(refText))!!
.parentsWithSelf.mapNotNull { it.toUElementOfType<T>() }.first().also {
if (it.psi?.text != refText) throw AssertionError("requested text '$refText' found as ${it.psi?.text}")
}

View File

@@ -29,6 +29,8 @@ class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() {
@Test fun testPropertyDelegate() = doTest("PropertyDelegate") { testName, file -> check(testName, file, false) }
@Test fun testLocalVariableWithAnnotation() = doTest("LocalVariableWithAnnotation")
@Test fun testPropertyWithAnnotation() = doTest("PropertyWithAnnotation")
@Test fun testIfStatement() = doTest("IfStatement")

View File

@@ -37,7 +37,8 @@ import com.intellij.spring.model.SpringModelSearchParameters
import com.intellij.spring.model.actions.generate.GenerateSpringBeanDependenciesUtil
import com.intellij.spring.model.actions.generate.GenerateSpringBeanDependenciesUtil.*
import com.intellij.spring.model.actions.generate.SpringBeanClassMember
import com.intellij.spring.model.highlighting.SpringConstructorArgResolveUtil
import com.intellij.spring.model.highlighting.xml.SpringConstructorArgResolveUtil
import com.intellij.spring.model.utils.SpringBeanCoreUtils
import com.intellij.spring.model.utils.SpringBeanUtils
import com.intellij.spring.model.utils.SpringModelSearchers

View File

@@ -18,7 +18,8 @@ package org.jetbrains.kotlin.idea.spring.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import com.intellij.spring.model.highlighting.SpringJavaAutowiredMembersInspection
import com.intellij.spring.model.highlighting.autowire.SpringJavaAutowiredMembersInspection
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
import org.jetbrains.kotlin.idea.inspections.registerWithElementsUnwrapped

View File

@@ -16,8 +16,8 @@ import com.intellij.spring.CommonSpringModel
import com.intellij.spring.SpringBundle
import com.intellij.spring.model.SpringBeanPointer
import com.intellij.spring.model.converters.SpringConverterUtil
import com.intellij.spring.model.highlighting.SpringAutowireUtil
import com.intellij.spring.model.highlighting.SpringJavaAutowiringInspection
import com.intellij.spring.model.highlighting.autowire.SpringJavaInjectionPointsAutowiringInspection
import com.intellij.spring.model.utils.SpringAutowireUtil
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.toLightClass
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
class SpringKotlinAutowiringInspection : AbstractKotlinInspection() {
// Based on SpringJavaAutowiringInspection.AddSpringBeanQualifierFix
// Based on SpringJavaInjectionPointsAutowiringInspection.AddSpringBeanQualifierFix
class AddQualifierFix(
modifierListOwner: KtModifierListOwner,
private val beanPointers: Collection<SpringBeanPointer<*>>,
@@ -86,16 +86,16 @@ class SpringKotlinAutowiringInspection : AbstractKotlinInspection() {
}
}
private val javaInspection by lazy { SpringJavaAutowiringInspection() }
private val javaInspection by lazy { SpringJavaInjectionPointsAutowiringInspection() }
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = object : KtVisitorVoid() {
// TODO: SpringJavaAutowiringInspection.checkAutowiredMethod() is not accessible here
// TODO: SpringJavaInjectionPointsAutowiringInspection.checkAutowiredMethod() is not accessible here
private fun checkAutowiredMethod(psiMethod: PsiMethod, holder: ProblemsHolder, springModel: CommonSpringModel, required: Boolean) {
val resourceAnnotation = SpringAutowireUtil.getResourceAnnotation(psiMethod)
when {
resourceAnnotation != null -> {
val propertyType = PropertyUtil.getPropertyType(psiMethod) ?: return
SpringJavaAutowiringInspection.checkAutowiredPsiMember(psiMethod, propertyType, holder, springModel, required)
SpringJavaInjectionPointsAutowiringInspection.checkInjectionPoint(psiMethod, propertyType, holder, springModel, required)
}
psiMethod.parameterList.parametersCount == 0 &&
SpringAutowireUtil.isAutowiredByAnnotation(psiMethod) -> {
@@ -107,7 +107,7 @@ class SpringKotlinAutowiringInspection : AbstractKotlinInspection() {
else -> {
for (parameter in psiMethod.parameterList.parameters) {
if (AnnotationUtil.isAnnotated(parameter, "org.springframework.beans.factory.annotation.Value", true)) continue
SpringJavaAutowiringInspection.checkAutowiredPsiMember(parameter, parameter.type, holder, springModel, required)
SpringJavaInjectionPointsAutowiringInspection.checkInjectionPoint(parameter, parameter.type, holder, springModel, required)
}
}
}
@@ -153,7 +153,7 @@ class SpringKotlinAutowiringInspection : AbstractKotlinInspection() {
private fun PsiField.processLightField() {
if (!SpringAutowireUtil.isAutowiredByAnnotation(this)) return
processLightMember { holder, model, required ->
SpringJavaAutowiringInspection.checkAutowiredPsiMember(this, type, holder, model, required)
SpringJavaInjectionPointsAutowiringInspection.checkInjectionPoint(this, type, holder, model, required)
}
}

View File

@@ -22,8 +22,10 @@ import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo
import com.intellij.navigation.GotoRelatedItem
import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.openapi.util.NotNullLazyValue
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.spring.gutter.SpringClassAnnotator
import com.intellij.util.Function
import com.intellij.util.SmartList
@@ -38,6 +40,7 @@ import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
import javax.swing.Icon
@@ -69,7 +72,7 @@ class KotlinSpringClassAnnotator : SpringClassAnnotator() {
return null
}
private fun doCollectMarkers(psiElement: PsiElement, result: MutableCollection<in RelatedItemLineMarkerInfo<PsiElement>>?) {
private fun doCollectMarkers(psiElement: PsiElement, result: MutableCollection<in RelatedItemLineMarkerInfo<PsiElement>>) {
if (psiElement is KtProperty || psiElement is KtParameter) {
for (it in (psiElement as KtDeclaration).toLightElements()) {
val nameIdentifier = (it as? PsiNameIdentifierOwner)?.nameIdentifier ?: continue
@@ -93,6 +96,13 @@ class KotlinSpringClassAnnotator : SpringClassAnnotator() {
private val iconAlignmentField by lazy { LineMarkerInfo::class.java.getDeclaredField("myIconAlignment").apply { isAccessible = true } }
private val targetsField by lazy { RelatedItemLineMarkerInfo::class.java.getDeclaredField("myTargets").apply { isAccessible = true } }
override fun getIdentifierLocal(annotation: PsiAnnotation): PsiElement? {
return when (annotation) {
is KtLightAnnotationForSourceEntry -> annotation.kotlinOrigin.getCallNameExpression()?.getIdentifier()
else -> super.getIdentifierLocal(annotation)
}
}
override fun collectNavigationMarkers(psiElement: PsiElement, result: MutableCollection<in RelatedItemLineMarkerInfo<PsiElement>>) {
val newItems = SmartList<RelatedItemLineMarkerInfo<PsiElement>>()
@@ -101,8 +111,14 @@ class KotlinSpringClassAnnotator : SpringClassAnnotator() {
newItems.mapNotNullTo(result) { item ->
val itemElement = item.element
val elementToAnnotate = when (itemElement) {
is KtLightIdentifier -> itemElement.origin
is KtLightIdentifier -> itemElement.origin.let { ktElement ->
when (ktElement) {
is KtParameterList -> ktElement.leftParenthesis
else -> ktElement
}
}
is KtLightElement<*, *> -> itemElement.kotlinOrigin
is LeafPsiElement -> itemElement
else -> return@mapNotNullTo item
}
if (elementToAnnotate == null) return@mapNotNullTo null

View File

@@ -20,8 +20,8 @@ import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.psi.*
import com.intellij.spring.model.DefaultSpringBeanQualifier
import com.intellij.spring.model.converters.SpringConverterUtil
import com.intellij.spring.model.highlighting.SpringAutowireUtil
import com.intellij.spring.model.jam.qualifiers.SpringJamQualifier
import com.intellij.spring.model.utils.SpringAutowireUtil
import com.intellij.spring.model.utils.SpringModelSearchers
import com.intellij.spring.references.SpringQualifierReference
import org.jetbrains.kotlin.asJava.elements.KtLightElement

View File

@@ -2,7 +2,7 @@
springConfig: ["config.xml"],
file: "Bean.kt",
icon: "SpringBeanMethod",
tooltip: "Navigate to the spring bean ",
tooltip: "Navigate to the spring bean",
naming: "bean",
targets: ["bean"]
}

View File

@@ -73,7 +73,8 @@ abstract class AbstractSpringClassAnnotatorTest : KotlinLightCodeInsightFixtureT
val iconName = config.getString("icon")
val icon = SpringApiIcons::class.java.getField(iconName)[null]
val gutterMark = myFixture.findGutter(fileName)!!.let {
val gutter = myFixture.findGutter(fileName) ?: throw AssertionError("no gutter for '$fileName'")
val gutterMark = gutter.let {
if (it.icon == icon) it
else myFixture.findGuttersAtCaret().let { gutters ->
gutters.firstOrNull() { it.icon == icon }

View File

@@ -1,9 +1,10 @@
<project xmlns:if="ant:if" xmlns:unless="ant:unless" name="Update Dependencies" default="update">
<!--172 -> 173-->
<import file="common.xml" optional="false"/>
<import file="node_utils.xml" optional="false"/>
<property name="automerge_dummy" value="This property is used to trick git merge. Do not delete empty lines around."/>
<property name="ideaVersion" value="172.4343.14"/>
<property name="ideaVersion" value="173.3188.16"/>
<property name="idea.repository.type" value="releases"/> <!-- releases or snapshots -->
<property name="idea.kotlin.branch" value="rc"/>
@@ -566,7 +567,7 @@
<file file="@{idea.dir}/lib/xpp3-1.1.4-min.jar"/>
<file file="@{idea.dir}/lib/asm-all.jar"/>
<file file="@{idea.dir}/lib/snappy-in-java-0.5.1.jar"/>
<file file="@{idea.dir}/lib/streamex-0.6.2.jar"/>
<file file="@{idea.dir}/lib/streamex-0.6.5.jar"/>
<!-- TODO temporary workaround since util-rt is not packaged into intellij-core.jar -->
<file file="@{idea.dir}/lib/util.jar"/>