Convert to kotlin: DeclarationResolver.kt

This commit is contained in:
Pavel V. Talanov
2015-03-02 19:59:11 +03:00
parent 4a156c5c8c
commit 9628d98f38
2 changed files with 115 additions and 128 deletions
@@ -745,7 +745,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.anew(thisDescriptorType); iv.anew(thisDescriptorType);
iv.dup(); iv.dup();
ConstructorDescriptor constructor = DeclarationResolver.getConstructorOfDataClass(descriptor); ConstructorDescriptor constructor = getConstructorOfDataClass(descriptor);
assert function.getValueParameters().size() == constructor.getValueParameters().size() : assert function.getValueParameters().size() == constructor.getValueParameters().size() :
"Number of parameters of copy function and constructor are different. " + "Number of parameters of copy function and constructor are different. " +
"Copy: " + function.getValueParameters().size() + ", " + "Copy: " + function.getValueParameters().size() + ", " +
@@ -792,6 +792,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
} }
private static ConstructorDescriptor getConstructorOfDataClass(@NotNull ClassDescriptor classDescriptor) {
Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
assert constructors.size() == 1 : "Data class must have only one constructor: " + classDescriptor.getConstructors();
return constructors.iterator().next();
}
private void generateEnumMethodsAndConstInitializers() { private void generateEnumMethodsAndConstInitializers() {
if (isEnumClass(descriptor)) { if (isEnumClass(descriptor)) {
generateEnumValuesMethod(); generateEnumValuesMethod();
@@ -14,195 +14,176 @@
* limitations under the License. * limitations under the License.
*/ */
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.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.openapi.util.Pair
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement
import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtil
import kotlin.Function1; import kotlin.Function1
import kotlin.KotlinPackage; import kotlin.KotlinPackage
import org.jetbrains.annotations.NotNull; 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.JetFile; import org.jetbrains.kotlin.psi.JetNamedDeclaration
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.lazy.descriptors.LazyPackageDescriptor; import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.JetScope; import org.jetbrains.kotlin.utils.*
import org.jetbrains.kotlin.utils.UtilsPackage;
import javax.inject.Inject; import javax.inject.Inject
import java.util.Collection; import java.util.HashSet
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.kotlin.diagnostics.Errors.REDECLARATION; import org.jetbrains.kotlin.diagnostics.Errors.REDECLARATION
public class DeclarationResolver { public class DeclarationResolver {
private AnnotationResolver annotationResolver; private var annotationResolver: AnnotationResolver? = null
private BindingTrace trace; private var trace: BindingTrace? = null
@Inject Inject
public void setAnnotationResolver(@NotNull AnnotationResolver annotationResolver) { public fun setAnnotationResolver(annotationResolver: AnnotationResolver) {
this.annotationResolver = annotationResolver; this.annotationResolver = annotationResolver
} }
@Inject Inject
public void setTrace(@NotNull BindingTrace trace) { public fun setTrace(trace: BindingTrace) {
this.trace = trace; this.trace = trace
} }
public void resolveAnnotationsOnFiles(@NotNull TopDownAnalysisContext c, @NotNull final FileScopeProvider scopeProvider) { public fun resolveAnnotationsOnFiles(c: TopDownAnalysisContext, scopeProvider: FileScopeProvider) {
Map<JetFile, JetScope> file2scope = UtilsPackage.keysToMap(c.getFiles(), new Function1<JetFile, JetScope>() { val file2scope = c.getFiles().keysToMap<JetFile, JetScope>(object : Function1<JetFile, JetScope> {
@Override override fun invoke(file: JetFile): JetScope {
public JetScope invoke(JetFile file) { return scopeProvider.getFileScope(file)
return scopeProvider.getFileScope(file);
} }
}); })
resolveAnnotationsOnFiles(file2scope); resolveAnnotationsOnFiles(file2scope)
} }
private void resolveAnnotationsOnFiles(@NotNull Map<JetFile, ? extends JetScope> file2scope) { private fun resolveAnnotationsOnFiles(file2scope: Map<JetFile, out JetScope>) {
for (Map.Entry<JetFile, ? extends JetScope> entry : file2scope.entrySet()) { for (entry in file2scope.entrySet()) {
JetFile file = entry.getKey(); val file = entry.getKey()
JetScope fileScope = entry.getValue(); val fileScope = entry.getValue()
annotationResolver.resolveAnnotationsWithArguments(fileScope, file.getAnnotationEntries(), trace); annotationResolver!!.resolveAnnotationsWithArguments(fileScope, file.getAnnotationEntries(), trace)
annotationResolver.resolveAnnotationsWithArguments(fileScope, file.getDanglingAnnotations(), trace); annotationResolver!!.resolveAnnotationsWithArguments(fileScope, file.getDanglingAnnotations(), trace)
} }
} }
@NotNull public fun checkRedeclarationsInInnerClassNames(c: TopDownAnalysisContext) {
public static ConstructorDescriptor getConstructorOfDataClass(@NotNull ClassDescriptor classDescriptor) { for (classDescriptor in c.getDeclaredClasses().values()) {
Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
assert constructors.size() == 1 : "Data class must have only one constructor: " + classDescriptor.getConstructors();
return constructors.iterator().next();
}
public void checkRedeclarationsInInnerClassNames(@NotNull TopDownAnalysisContext c) {
for (ClassDescriptorWithResolutionScopes classDescriptor : c.getDeclaredClasses().values()) {
if (classDescriptor.getKind() == ClassKind.CLASS_OBJECT) { if (classDescriptor.getKind() == ClassKind.CLASS_OBJECT) {
// Class objects should be considered during analysing redeclarations in classes // Class objects should be considered during analysing redeclarations in classes
continue; continue
} }
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors(); var allDescriptors: MutableCollection<DeclarationDescriptor> = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors()
ClassDescriptorWithResolutionScopes classObj = classDescriptor.getDefaultObjectDescriptor(); val classObj = classDescriptor.getDefaultObjectDescriptor()
if (classObj != null) { if (classObj != null) {
Collection<DeclarationDescriptor> classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors(); val classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors()
if (!classObjDescriptors.isEmpty()) { if (!classObjDescriptors.isEmpty()) {
allDescriptors = Lists.newArrayList(allDescriptors); allDescriptors = Lists.newArrayList<DeclarationDescriptor>(allDescriptors)
allDescriptors.addAll(classObjDescriptors); allDescriptors.addAll(classObjDescriptors)
} }
} }
Multimap<Name, DeclarationDescriptor> descriptorMap = HashMultimap.create(); val descriptorMap = HashMultimap.create<Name, DeclarationDescriptor>()
for (DeclarationDescriptor desc : allDescriptors) { for (desc in allDescriptors) {
if (desc instanceof ClassDescriptor || desc instanceof PropertyDescriptor) { if (desc is ClassDescriptor || desc is PropertyDescriptor) {
descriptorMap.put(desc.getName(), desc); descriptorMap.put(desc.getName(), desc)
} }
} }
reportRedeclarations(descriptorMap); reportRedeclarations(descriptorMap)
} }
} }
private void reportRedeclarations(@NotNull Multimap<Name, DeclarationDescriptor> descriptorMap) { private fun reportRedeclarations(descriptorMap: Multimap<Name, DeclarationDescriptor>) {
Set<Pair<PsiElement, Name>> redeclarations = Sets.newHashSet(); val redeclarations = Sets.newHashSet<Pair<PsiElement, Name>>()
for (Name name : descriptorMap.keySet()) { for (name in descriptorMap.keySet()) {
Collection<DeclarationDescriptor> descriptors = descriptorMap.get(name); val descriptors = descriptorMap.get(name)
if (descriptors.size() > 1) { if (descriptors.size() > 1) {
// We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at OverloadResolver // We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at OverloadResolver
for (DeclarationDescriptor descriptor : descriptors) { for (descriptor in descriptors) {
if (descriptor instanceof ClassDescriptor) { if (descriptor is ClassDescriptor) {
for (DeclarationDescriptor descriptor2 : descriptors) { for (descriptor2 in descriptors) {
if (descriptor == descriptor2) { if (descriptor == descriptor2) {
continue; continue
} }
redeclarations.add(Pair.create( redeclarations.add(Pair.create<PsiElement, Name>(DescriptorToSourceUtils.classDescriptorToDeclaration(descriptor as ClassDescriptor), descriptor.getName()))
DescriptorToSourceUtils.classDescriptorToDeclaration((ClassDescriptor) descriptor), descriptor.getName() if (descriptor2 is PropertyDescriptor) {
)); redeclarations.add(Pair.create<PsiElement, Name>(DescriptorToSourceUtils.descriptorToDeclaration(descriptor2), descriptor2.getName()))
if (descriptor2 instanceof PropertyDescriptor) {
redeclarations.add(Pair.create(
DescriptorToSourceUtils.descriptorToDeclaration(descriptor2), descriptor2.getName()
));
} }
} }
} }
} }
} }
} }
for (Pair<PsiElement, Name> redeclaration : redeclarations) { for (redeclaration in redeclarations) {
trace.report(REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().asString())); trace!!.report(REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().asString()))
} }
} }
public void checkRedeclarationsInPackages( public fun checkRedeclarationsInPackages(topLevelDescriptorProvider: TopLevelDescriptorProvider, topLevelFqNames: Multimap<FqName, JetElement>) {
@NotNull TopLevelDescriptorProvider topLevelDescriptorProvider, for (entry in topLevelFqNames.asMap().entrySet()) {
@NotNull Multimap<FqName, JetElement> topLevelFqNames val fqName = entry.getKey()
) { val declarationsOrPackageDirectives = entry.getValue()
for (Map.Entry<FqName, Collection<JetElement>> entry : topLevelFqNames.asMap().entrySet()) {
FqName fqName = entry.getKey();
Collection<JetElement> declarationsOrPackageDirectives = entry.getValue();
if (fqName.isRoot()) continue; if (fqName.isRoot()) continue
Set<DeclarationDescriptor> descriptors = getTopLevelDescriptorsByFqName(topLevelDescriptorProvider, fqName); val descriptors = getTopLevelDescriptorsByFqName(topLevelDescriptorProvider, fqName)
if (descriptors.size() > 1) { if (descriptors.size() > 1) {
for (JetElement declarationOrPackageDirective : declarationsOrPackageDirectives) { for (declarationOrPackageDirective in declarationsOrPackageDirectives) {
PsiElement reportAt = declarationOrPackageDirective instanceof JetNamedDeclaration val reportAt = if (declarationOrPackageDirective is JetNamedDeclaration)
? declarationOrPackageDirective declarationOrPackageDirective
: ((JetPackageDirective) declarationOrPackageDirective).getNameIdentifier(); else
trace.report(Errors.REDECLARATION.on(reportAt, fqName.shortName().asString())); (declarationOrPackageDirective as JetPackageDirective).getNameIdentifier()
trace!!.report(Errors.REDECLARATION.on(reportAt, fqName.shortName().asString()))
} }
} }
} }
} }
@NotNull class object {
private static Set<DeclarationDescriptor> getTopLevelDescriptorsByFqName(
@NotNull TopLevelDescriptorProvider topLevelDescriptorProvider,
@NotNull FqName fqName
) {
FqName parentFqName = fqName.parent();
Set<DeclarationDescriptor> descriptors = new HashSet<DeclarationDescriptor>(); public fun getConstructorOfDataClass(classDescriptor: ClassDescriptor): ConstructorDescriptor {
val constructors = classDescriptor.getConstructors()
LazyPackageDescriptor parentFragment = topLevelDescriptorProvider.getPackageFragment(parentFqName); assert(constructors.size() == 1) { "Data class must have only one constructor: " + classDescriptor.getConstructors() }
if (parentFragment != null) { return constructors.iterator().next()
// Filter out extension properties
descriptors.addAll(
KotlinPackage.filter(
parentFragment.getMemberScope().getProperties(fqName.shortName()),
new Function1<VariableDescriptor, Boolean>() {
@Override
public Boolean invoke(VariableDescriptor descriptor) {
return descriptor.getExtensionReceiverParameter() == null;
}
}
)
);
} }
ContainerUtil.addIfNotNull(descriptors, topLevelDescriptorProvider.getPackageFragment(fqName)); private fun getTopLevelDescriptorsByFqName(topLevelDescriptorProvider: TopLevelDescriptorProvider, fqName: FqName): Set<DeclarationDescriptor> {
val parentFqName = fqName.parent()
descriptors.addAll(topLevelDescriptorProvider.getTopLevelClassDescriptors(fqName)); val descriptors = HashSet<DeclarationDescriptor>()
return descriptors;
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
}
} }