Resolve "componentN" functions for data classes
Reuse existing (but not used) VALUE_PARAMETER_AS_PROPERTY in BindingContext to store mapping from constructor's value parameters to property descriptors. Create a new slice DATA_CLASS_COMPONENT_FUNCTION to store mapping from constructor's value parameters to generated componentN functions.
This commit is contained in:
@@ -220,8 +220,11 @@ public interface BindingContext {
|
||||
.setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS).build();
|
||||
|
||||
WritableSlice<JetReferenceExpression, PsiElement> LABEL_TARGET = Slices.<JetReferenceExpression, PsiElement>sliceBuilder().build();
|
||||
WritableSlice<JetParameter, PropertyDescriptor> VALUE_PARAMETER_AS_PROPERTY =
|
||||
Slices.<JetParameter, PropertyDescriptor>sliceBuilder().build();
|
||||
WritableSlice<ValueParameterDescriptor, PropertyDescriptor> VALUE_PARAMETER_AS_PROPERTY =
|
||||
Slices.<ValueParameterDescriptor, PropertyDescriptor>sliceBuilder().build();
|
||||
|
||||
WritableSlice<ValueParameterDescriptor, FunctionDescriptor> DATA_CLASS_COMPONENT_FUNCTION =
|
||||
Slices.<ValueParameterDescriptor, FunctionDescriptor>sliceBuilder().build();
|
||||
|
||||
WritableSlice<FqName, ClassDescriptor> FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice<FqName, ClassDescriptor>(DO_NOTHING, true);
|
||||
WritableSlice<FqName, NamespaceDescriptor> FQNAME_TO_NAMESPACE_DESCRIPTOR =
|
||||
|
||||
@@ -28,6 +28,8 @@ import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
@@ -88,6 +90,7 @@ public class DeclarationResolver {
|
||||
resolveConstructorHeaders();
|
||||
resolveAnnotationStubsOnClassesAndConstructors();
|
||||
resolveFunctionAndPropertyHeaders();
|
||||
createComponentFunctionsForDataClasses();
|
||||
importsResolver.processMembersImports(rootScope);
|
||||
checkRedeclarationsInNamespaces();
|
||||
checkRedeclarationsInInnerClassNames();
|
||||
@@ -210,6 +213,38 @@ public class DeclarationResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private void createComponentFunctionsForDataClasses() {
|
||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
||||
JetClass jetClass = entry.getKey();
|
||||
MutableClassDescriptor classDescriptor = entry.getValue();
|
||||
|
||||
if (jetClass.hasPrimaryConstructor() && JetStandardLibrary.isData(classDescriptor)) {
|
||||
createComponentFunctions(classDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createComponentFunctions(MutableClassDescriptor classDescriptor) {
|
||||
Set<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
|
||||
assert constructors.size() == 1 : "Data class hasn't a single constructor: " + constructors.size();
|
||||
ConstructorDescriptor constructor = constructors.iterator().next();
|
||||
|
||||
int parameterIndex = 0;
|
||||
for (ValueParameterDescriptor parameter : constructor.getValueParameters()) {
|
||||
if (!ErrorUtils.isErrorType(parameter.getType())) {
|
||||
PropertyDescriptor property = trace.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
|
||||
if (property != null) {
|
||||
++parameterIndex;
|
||||
|
||||
SimpleFunctionDescriptor functionDescriptor =
|
||||
DescriptorResolver.createComponentFunctionDescriptor(parameterIndex, property, parameter, classDescriptor, trace);
|
||||
|
||||
classDescriptor.getBuilder().addFunctionDescriptor(functionDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) {
|
||||
if (classDescriptor.getKind() == ClassKind.TRAIT) {
|
||||
JetParameterList primaryConstructorParameterList = klass.getPrimaryConstructorParameterList();
|
||||
|
||||
@@ -58,6 +58,7 @@ import static org.jetbrains.jet.lexer.JetTokens.OVERRIDE_KEYWORD;
|
||||
public class DescriptorResolver {
|
||||
public static final Name VALUE_OF_METHOD_NAME = Name.identifier("valueOf");
|
||||
public static final Name VALUES_METHOD_NAME = Name.identifier("values");
|
||||
public static final String COMPONENT_FUNCTION_NAME_PREFIX = "component";
|
||||
|
||||
@NotNull
|
||||
private TypeResolver typeResolver;
|
||||
@@ -295,6 +296,40 @@ public class DescriptorResolver {
|
||||
return functionDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SimpleFunctionDescriptor createComponentFunctionDescriptor(
|
||||
int parameterIndex,
|
||||
@NotNull PropertyDescriptor property,
|
||||
@NotNull ValueParameterDescriptor parameter,
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
String functionName = COMPONENT_FUNCTION_NAME_PREFIX + parameterIndex;
|
||||
JetType returnType = property.getType();
|
||||
|
||||
SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
|
||||
classDescriptor,
|
||||
Collections.<AnnotationDescriptor>emptyList(),
|
||||
Name.identifier(functionName),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
);
|
||||
|
||||
functionDescriptor.initialize(
|
||||
null,
|
||||
classDescriptor.getImplicitReceiver(),
|
||||
Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(),
|
||||
returnType,
|
||||
Modality.FINAL,
|
||||
property.getVisibility(),
|
||||
true
|
||||
);
|
||||
|
||||
trace.record(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter, functionDescriptor);
|
||||
|
||||
return functionDescriptor;
|
||||
}
|
||||
|
||||
public static Visibility getDefaultVisibility(JetModifierListOwner modifierListOwner, DeclarationDescriptor containingDescriptor) {
|
||||
Visibility defaultVisibility;
|
||||
if (containingDescriptor instanceof ClassDescriptor) {
|
||||
@@ -1076,6 +1111,7 @@ public class DescriptorResolver {
|
||||
getter.initialize(propertyDescriptor.getType());
|
||||
|
||||
trace.record(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter, propertyDescriptor);
|
||||
trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter, propertyDescriptor);
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -277,7 +277,7 @@ public class ExpressionTypingUtils {
|
||||
) {
|
||||
int componentIndex = 1;
|
||||
for (JetMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
final Name componentName = Name.identifier("component" + componentIndex);
|
||||
final Name componentName = Name.identifier(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX + componentIndex);
|
||||
componentIndex++;
|
||||
|
||||
JetType expectedType = getExpectedTypeForComponent(context, entry);
|
||||
|
||||
Reference in New Issue
Block a user