Prettify code in DeclarationResolver.kt
This commit is contained in:
@@ -17,65 +17,44 @@
|
|||||||
package org.jetbrains.kotlin.resolve
|
package org.jetbrains.kotlin.resolve
|
||||||
|
|
||||||
import com.google.common.collect.HashMultimap
|
import com.google.common.collect.HashMultimap
|
||||||
import com.google.common.collect.Lists
|
|
||||||
import com.google.common.collect.Multimap
|
import com.google.common.collect.Multimap
|
||||||
import com.google.common.collect.Sets
|
import com.google.common.collect.Sets
|
||||||
import com.intellij.openapi.util.Pair
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.util.containers.ContainerUtil
|
|
||||||
import kotlin.Function1
|
|
||||||
import kotlin.KotlinPackage
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.JetElement
|
import org.jetbrains.kotlin.psi.JetElement
|
||||||
import org.jetbrains.kotlin.psi.JetFile
|
|
||||||
import org.jetbrains.kotlin.psi.JetNamedDeclaration
|
|
||||||
import org.jetbrains.kotlin.psi.JetPackageDirective
|
import org.jetbrains.kotlin.psi.JetPackageDirective
|
||||||
import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
|
import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
|
||||||
import org.jetbrains.kotlin.resolve.lazy.TopLevelDescriptorProvider
|
import org.jetbrains.kotlin.resolve.lazy.TopLevelDescriptorProvider
|
||||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
|
||||||
import org.jetbrains.kotlin.utils.*
|
import org.jetbrains.kotlin.utils.*
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.REDECLARATION
|
import org.jetbrains.kotlin.diagnostics.Errors.REDECLARATION
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
public class DeclarationResolver {
|
public class DeclarationResolver {
|
||||||
private var annotationResolver: AnnotationResolver? = null
|
private var _annotationResolver: AnnotationResolver by Delegates.notNull()
|
||||||
private var trace: BindingTrace? = null
|
private var _trace: BindingTrace by Delegates.notNull()
|
||||||
|
|
||||||
|
|
||||||
Inject
|
Inject
|
||||||
public fun setAnnotationResolver(annotationResolver: AnnotationResolver) {
|
public fun setAnnotationResolver(annotationResolver: AnnotationResolver) {
|
||||||
this.annotationResolver = annotationResolver
|
this._annotationResolver = annotationResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
Inject
|
Inject
|
||||||
public fun setTrace(trace: BindingTrace) {
|
public fun setTrace(trace: BindingTrace) {
|
||||||
this.trace = trace
|
this._trace = trace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public fun resolveAnnotationsOnFiles(c: TopDownAnalysisContext, scopeProvider: FileScopeProvider) {
|
public fun resolveAnnotationsOnFiles(c: TopDownAnalysisContext, scopeProvider: FileScopeProvider) {
|
||||||
val file2scope = c.getFiles().keysToMap<JetFile, JetScope>(object : Function1<JetFile, JetScope> {
|
val filesToScope = c.getFiles().keysToMap { scopeProvider.getFileScope(it) }
|
||||||
override fun invoke(file: JetFile): JetScope {
|
for ((file, fileScope) in filesToScope) {
|
||||||
return scopeProvider.getFileScope(file)
|
_annotationResolver.resolveAnnotationsWithArguments(fileScope, file.getAnnotationEntries(), _trace)
|
||||||
}
|
_annotationResolver.resolveAnnotationsWithArguments(fileScope, file.getDanglingAnnotations(), _trace)
|
||||||
})
|
|
||||||
|
|
||||||
resolveAnnotationsOnFiles(file2scope)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun resolveAnnotationsOnFiles(file2scope: Map<JetFile, out JetScope>) {
|
|
||||||
for (entry in file2scope.entrySet()) {
|
|
||||||
val file = entry.getKey()
|
|
||||||
val fileScope = entry.getValue()
|
|
||||||
annotationResolver!!.resolveAnnotationsWithArguments(fileScope, file.getAnnotationEntries(), trace)
|
|
||||||
annotationResolver!!.resolveAnnotationsWithArguments(fileScope, file.getDanglingAnnotations(), trace)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,14 +65,12 @@ public class DeclarationResolver {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var allDescriptors: MutableCollection<DeclarationDescriptor> = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors()
|
var allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors()
|
||||||
|
|
||||||
val classObj = classDescriptor.getDefaultObjectDescriptor()
|
val classObj = classDescriptor.getDefaultObjectDescriptor()
|
||||||
if (classObj != null) {
|
if (classObj != null) {
|
||||||
val classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors()
|
val classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors()
|
||||||
if (!classObjDescriptors.isEmpty()) {
|
if (classObjDescriptors.isNotEmpty()) {
|
||||||
allDescriptors = Lists.newArrayList<DeclarationDescriptor>(allDescriptors)
|
allDescriptors = allDescriptors + classObjDescriptors
|
||||||
allDescriptors.addAll(classObjDescriptors)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,80 +88,63 @@ public class DeclarationResolver {
|
|||||||
private fun reportRedeclarations(descriptorMap: Multimap<Name, DeclarationDescriptor>) {
|
private fun reportRedeclarations(descriptorMap: Multimap<Name, DeclarationDescriptor>) {
|
||||||
val redeclarations = Sets.newHashSet<Pair<PsiElement, Name>>()
|
val redeclarations = Sets.newHashSet<Pair<PsiElement, Name>>()
|
||||||
for (name in descriptorMap.keySet()) {
|
for (name in descriptorMap.keySet()) {
|
||||||
val descriptors = descriptorMap.get(name)
|
val descriptors = descriptorMap[name]
|
||||||
if (descriptors.size() > 1) {
|
if (descriptors.size() <= 1) {
|
||||||
// We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at OverloadResolver
|
continue
|
||||||
for (descriptor in descriptors) {
|
}
|
||||||
if (descriptor is ClassDescriptor) {
|
// We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at OverloadResolver
|
||||||
for (descriptor2 in descriptors) {
|
for (descriptor in descriptors) {
|
||||||
if (descriptor == descriptor2) {
|
if (descriptor is ClassDescriptor) {
|
||||||
continue
|
for (descriptor2 in descriptors) {
|
||||||
}
|
if (descriptor identityEquals descriptor2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
redeclarations.add(Pair.create<PsiElement, Name>(DescriptorToSourceUtils.classDescriptorToDeclaration(descriptor as ClassDescriptor), descriptor.getName()))
|
redeclarations.add(Pair(DescriptorToSourceUtils.classDescriptorToDeclaration(descriptor), descriptor.getName()))
|
||||||
if (descriptor2 is PropertyDescriptor) {
|
if (descriptor2 is PropertyDescriptor) {
|
||||||
redeclarations.add(Pair.create<PsiElement, Name>(DescriptorToSourceUtils.descriptorToDeclaration(descriptor2), descriptor2.getName()))
|
redeclarations.add(Pair(DescriptorToSourceUtils.descriptorToDeclaration(descriptor2), descriptor2.getName()))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (redeclaration in redeclarations) {
|
for ((first, second) in redeclarations) {
|
||||||
trace!!.report(REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().asString()))
|
_trace.report(REDECLARATION.on(first, second.asString()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun checkRedeclarationsInPackages(topLevelDescriptorProvider: TopLevelDescriptorProvider, topLevelFqNames: Multimap<FqName, JetElement>) {
|
public fun checkRedeclarationsInPackages(topLevelDescriptorProvider: TopLevelDescriptorProvider, topLevelFqNames: Multimap<FqName, JetElement>) {
|
||||||
for (entry in topLevelFqNames.asMap().entrySet()) {
|
for ((fqName, declarationsOrPackageDirectives) in topLevelFqNames.asMap()) {
|
||||||
val fqName = entry.getKey()
|
|
||||||
val declarationsOrPackageDirectives = entry.getValue()
|
|
||||||
|
|
||||||
if (fqName.isRoot()) continue
|
if (fqName.isRoot()) continue
|
||||||
|
|
||||||
val descriptors = getTopLevelDescriptorsByFqName(topLevelDescriptorProvider, fqName)
|
val descriptors = getTopLevelDescriptorsByFqName(topLevelDescriptorProvider, fqName)
|
||||||
|
|
||||||
if (descriptors.size() > 1) {
|
if (descriptors.size() > 1) {
|
||||||
for (declarationOrPackageDirective in declarationsOrPackageDirectives) {
|
for (declarationOrPackageDirective in declarationsOrPackageDirectives) {
|
||||||
val reportAt = if (declarationOrPackageDirective is JetNamedDeclaration)
|
val reportAt =
|
||||||
declarationOrPackageDirective
|
if (declarationOrPackageDirective is JetPackageDirective) declarationOrPackageDirective.getNameIdentifier()
|
||||||
else
|
else declarationOrPackageDirective
|
||||||
(declarationOrPackageDirective as JetPackageDirective).getNameIdentifier()
|
_trace.report(Errors.REDECLARATION.on(reportAt, fqName.shortName().asString()))
|
||||||
trace!!.report(Errors.REDECLARATION.on(reportAt, fqName.shortName().asString()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class object {
|
private fun getTopLevelDescriptorsByFqName(topLevelDescriptorProvider: TopLevelDescriptorProvider, fqName: FqName): Set<DeclarationDescriptor> {
|
||||||
|
val parentFqName = fqName.parent()
|
||||||
|
|
||||||
public fun getConstructorOfDataClass(classDescriptor: ClassDescriptor): ConstructorDescriptor {
|
val descriptors = HashSet<DeclarationDescriptor>()
|
||||||
val constructors = classDescriptor.getConstructors()
|
|
||||||
assert(constructors.size() == 1) { "Data class must have only one constructor: " + classDescriptor.getConstructors() }
|
val parentFragment = topLevelDescriptorProvider.getPackageFragment(parentFqName)
|
||||||
return constructors.iterator().next()
|
if (parentFragment != null) {
|
||||||
|
// Filter out extension properties
|
||||||
|
descriptors.addAll(parentFragment.getMemberScope().getProperties(fqName.shortName()).filter {
|
||||||
|
it.getExtensionReceiverParameter() == null
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTopLevelDescriptorsByFqName(topLevelDescriptorProvider: TopLevelDescriptorProvider, fqName: FqName): Set<DeclarationDescriptor> {
|
descriptors.addIfNotNull(topLevelDescriptorProvider.getPackageFragment(fqName))
|
||||||
val parentFqName = fqName.parent()
|
descriptors.addAll(topLevelDescriptorProvider.getTopLevelClassDescriptors(fqName))
|
||||||
|
return descriptors
|
||||||
val descriptors = HashSet<DeclarationDescriptor>()
|
|
||||||
|
|
||||||
val parentFragment = topLevelDescriptorProvider.getPackageFragment(parentFqName)
|
|
||||||
if (parentFragment != null) {
|
|
||||||
// Filter out extension properties
|
|
||||||
descriptors.addAll(KotlinPackage.filter<VariableDescriptor>(parentFragment.getMemberScope().getProperties(fqName.shortName()), object : Function1<VariableDescriptor, Boolean> {
|
|
||||||
override fun invoke(descriptor: VariableDescriptor): Boolean? {
|
|
||||||
return descriptor.getExtensionReceiverParameter() == null
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
ContainerUtil.addIfNotNull<DeclarationDescriptor>(descriptors, topLevelDescriptorProvider.getPackageFragment(fqName))
|
|
||||||
|
|
||||||
descriptors.addAll(topLevelDescriptorProvider.getTopLevelClassDescriptors(fqName))
|
|
||||||
return descriptors
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user