Associate synthetic component function descriptors with corresponding

constructor parameters
This commit is contained in:
Alexey Sedunov
2014-08-05 17:57:53 +04:00
parent 386e39f4a2
commit 311166737f
13 changed files with 59 additions and 17 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.jet.codegen;
import com.google.common.collect.Lists;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import kotlin.Function0;
import kotlin.Function1;
@@ -43,6 +44,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
@@ -63,6 +65,7 @@ import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
@@ -75,7 +78,6 @@ import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.descriptors.serialization.NameSerializationUtil.createNameResolver;
import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
import static org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage.getResolvedCallWithAssert;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.DelegationToTraitImpl;
@@ -821,7 +823,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Override
public void generateComponentFunction(@NotNull FunctionDescriptor function, @NotNull final ValueParameterDescriptor parameter) {
functionCodegen.generateMethod(OtherOrigin(myClass, function), typeMapper.mapSignature(function), function, new FunctionGenerationStrategy() {
PsiElement originalElement = DescriptorToSourceUtils.descriptorToDeclaration(parameter);
functionCodegen.generateMethod(OtherOrigin(originalElement, function), typeMapper.mapSignature(function), function, new FunctionGenerationStrategy() {
@Override
public void generateBody(
@NotNull MethodVisitor mv,
@@ -390,7 +390,7 @@ public class DescriptorResolver {
Annotations.EMPTY,
Name.identifier(functionName),
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
parameter.getSource()
);
functionDescriptor.initialize(
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -169,7 +170,7 @@ public class OverloadResolver {
}
OverloadUtil.OverloadCompatibilityInfo overloadable = OverloadUtil.isOverloadable(member, member2);
if (!overloadable.isSuccess()) {
if (!overloadable.isSuccess() && member.getKind() != CallableMemberDescriptor.Kind.SYNTHESIZED) {
JetDeclaration jetDeclaration = (JetDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(member);
if (jetDeclaration != null) {
redeclarations.add(Pair.create(jetDeclaration, member));
@@ -33,6 +33,8 @@ import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.SmartList;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
@@ -257,7 +259,15 @@ public class LightClassUtil {
if (getterWrapper == null || setterWrapper == null) {
// If some getter or setter isn't found yet try to get it from wrappers for general declaration
List<PsiMethod> wrappers = getPsiMethodWrappers(jetDeclaration, true);
List<PsiMethod> wrappers = KotlinPackage.filter(
getPsiMethodWrappers(jetDeclaration, true),
new Function1<PsiMethod, Boolean>() {
@Override
public Boolean invoke(PsiMethod method) {
return JvmAbi.isAccessorName(method.getName());
}
}
);
assert wrappers.size() <= 2 : "Maximum two wrappers are expected to be generated for declaration: " + jetDeclaration.getText();
for (PsiMethod wrapper : wrappers) {
@@ -0,0 +1,6 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
data class <!CONFLICTING_JVM_DECLARATIONS!>A(val x: Int, val y: String)<!> {
<!CONFLICTING_OVERLOADS!>fun copy(x: Int, y: String)<!> = x
<!CONFLICTING_OVERLOADS!>fun copy(x: Int, y: String)<!> = A(x, y)
}
@@ -1,4 +1,4 @@
data class <!CONFLICTING_JVM_DECLARATIONS!>A(val x: Int, val y: String)<!> {
data class A(<!CONFLICTING_JVM_DECLARATIONS!>val x: Int<!>, val y: String) {
<!CONFLICTING_OVERLOADS!>fun component1()<!> = 1
<!CONFLICTING_OVERLOADS!>fun component2()<!> = 2
}
}
@@ -1777,8 +1777,14 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest("compiler/testData/diagnostics/tests/dataClasses/componentNamedComponent1.kt");
}
@TestMetadata("conflictingCopyOverloads.kt")
public void testConflictingCopyOverloads() throws Exception {
doTest("compiler/testData/diagnostics/tests/dataClasses/conflictingCopyOverloads.kt");
}
@TestMetadata("conflictingOverloads.kt")
public void testConflictingOverloads() throws Exception {
public void
testConflictingOverloads() throws Exception {
doTest("compiler/testData/diagnostics/tests/dataClasses/conflictingOverloads.kt");
}
@@ -62,6 +62,10 @@ public final class JvmAbi {
return isDelegated ? propertyName.asString() + DELEGATED_PROPERTY_NAME_SUFFIX : propertyName.asString();
}
public static boolean isAccessorName(String name) {
return name.startsWith(JvmAbi.GETTER_PREFIX) || name.startsWith(JvmAbi.SETTER_PREFIX);
}
private JvmAbi() {
}
}
@@ -0,0 +1,8 @@
package org.jetbrains.jet.lang.resolve.name
import java.util.regex.Pattern
public val COMPONENT_FUNCTION_PATTERN: Pattern = Pattern.compile("^component(\\d+)$")
public fun String.isComponentFunctionName(): Boolean = COMPONENT_FUNCTION_PATTERN.matcher(this).matches()
public fun Name.isComponentFunctionName(): Boolean = asString().isComponentFunctionName()
@@ -29,6 +29,8 @@ import java.util.*
import org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumEntry
import org.jetbrains.jet.lang.resolve.DescriptorUtils.isSyntheticClassObject
import org.jetbrains.jet.lang.types.error.MissingDependencyErrorClass
import org.jetbrains.jet.lang.resolve.DescriptorResolver
import org.jetbrains.jet.lang.resolve.name.isComponentFunctionName
public fun buildDecompiledText(
classFile: VirtualFile,
@@ -125,7 +127,9 @@ private fun buildDecompiledText(packageFqName: FqName, descriptors: List<Declara
if (member.getContainingDeclaration() != descriptor) {
continue
}
if (member is CallableMemberDescriptor && member.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
if (member is CallableMemberDescriptor
&& member.getKind() != CallableMemberDescriptor.Kind.DECLARATION
&& !member.getName().isComponentFunctionName()) {
continue
}
@@ -70,12 +70,11 @@ import org.jetbrains.jet.plugin.caches.resolve.getAnalysisResults
import org.jetbrains.jet.plugin.caches.resolve.getBindingContext
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
import org.jetbrains.jet.lang.resolve.name.COMPONENT_FUNCTION_PATTERN
private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"
private val TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt"
private val ATTRIBUTE_FUNCTION_NAME = "FUNCTION_NAME"
private val COMPONENT_FUNCTION_PATTERN = Pattern.compile("^component(\\d+)$")
/**
* Represents a single choice for a type (e.g. parameter type or return type).
@@ -24,8 +24,7 @@ import com.intellij.openapi.util.TextRange
class JetMultiDeclarationReference(element: JetMultiDeclaration) : JetMultiReference<JetMultiDeclaration>(element) {
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
return expression.getEntries().map { entry ->
//TODO: remove getOriginal
context.get(BindingContext.COMPONENT_RESOLVED_CALL, entry)?.getCandidateDescriptor()?.getOriginal()
context.get(BindingContext.COMPONENT_RESOLVED_CALL, entry)?.getCandidateDescriptor()
}.filterNotNull()
}
@@ -115,12 +115,14 @@ abstract class AbstractJetReference<T : JetElement>(element: T)
private fun resolveToPsiElements(targetDescriptor: DeclarationDescriptor): Collection<PsiElement> {
val result = HashSet<PsiElement>()
val project = expression.getProject()
result.addAll(DescriptorToSourceUtils.descriptorToDeclarations(targetDescriptor))
result.addAll(DescriptorToDeclarationUtil.findDecompiledAndBuiltInDeclarations(project, targetDescriptor))
// todo: remove getOriginal()
val originalDescriptor = targetDescriptor.getOriginal()
result.addAll(DescriptorToSourceUtils.descriptorToDeclarations(originalDescriptor))
result.addAll(DescriptorToDeclarationUtil.findDecompiledAndBuiltInDeclarations(project, originalDescriptor))
if (targetDescriptor is PackageViewDescriptor) {
if (originalDescriptor is PackageViewDescriptor) {
val psiFacade = JavaPsiFacade.getInstance(project)
val fqName = (targetDescriptor as PackageViewDescriptor).getFqName().asString()
val fqName = (originalDescriptor as PackageViewDescriptor).getFqName().asString()
ContainerUtil.addIfNotNull(result, psiFacade.findPackage(fqName))
ContainerUtil.addIfNotNull(result, psiFacade.findClass(fqName, project.allScope()))
}