The stages of TopDownAnalyzer now only talk to each other through TopDownAnalysisContext
This commit is contained in:
@@ -7,7 +7,6 @@ import com.intellij.psi.PsiElement;
|
|||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
|
||||||
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
@@ -26,30 +25,23 @@ import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
|
|||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class BodyResolver {
|
public class BodyResolver {
|
||||||
private final JetSemanticServices semanticServices;
|
|
||||||
private final ClassDescriptorResolver classDescriptorResolver;
|
|
||||||
private final BindingTrace trace;
|
|
||||||
private final BindingTraceAdapter traceForConstructors;
|
|
||||||
private final BindingTraceAdapter traceForMembers;
|
|
||||||
private final DeclarationResolver declarationResolver;
|
|
||||||
private final TopDownAnalysisContext context;
|
private final TopDownAnalysisContext context;
|
||||||
|
|
||||||
public BodyResolver(JetSemanticServices semanticServices, @NotNull BindingTrace trace, TopDownAnalysisContext context, DeclarationResolver declarationResolver) {
|
private final BindingTraceAdapter traceForConstructors;
|
||||||
this.semanticServices = semanticServices;
|
private final BindingTraceAdapter traceForMembers;
|
||||||
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
|
|
||||||
this.trace = trace;
|
public BodyResolver(TopDownAnalysisContext context) {
|
||||||
this.declarationResolver = declarationResolver;
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
// This allows access to backing fields
|
// This allows access to backing fields
|
||||||
this.traceForConstructors = new BindingTraceAdapter(trace).addHandler(BindingContext.REFERENCE_TARGET, new BindingTraceAdapter.RecordHandler<JetReferenceExpression, DeclarationDescriptor>() {
|
this.traceForConstructors = new BindingTraceAdapter(context.getTrace()).addHandler(BindingContext.REFERENCE_TARGET, new BindingTraceAdapter.RecordHandler<JetReferenceExpression, DeclarationDescriptor>() {
|
||||||
@Override
|
@Override
|
||||||
public void handleRecord(WritableSlice<JetReferenceExpression, DeclarationDescriptor> slice, JetReferenceExpression expression, DeclarationDescriptor descriptor) {
|
public void handleRecord(WritableSlice<JetReferenceExpression, DeclarationDescriptor> slice, JetReferenceExpression expression, DeclarationDescriptor descriptor) {
|
||||||
if (expression instanceof JetSimpleNameExpression) {
|
if (expression instanceof JetSimpleNameExpression) {
|
||||||
JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
|
JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
|
||||||
if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
|
if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
|
||||||
if (!BodyResolver.this.trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) descriptor)) {
|
if (!BodyResolver.this.context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) descriptor)) {
|
||||||
BodyResolver.this.trace.getErrorHandler().genericError(expression.getNode(), "This property does not have a backing field");
|
BodyResolver.this.context.getTrace().getErrorHandler().genericError(expression.getNode(), "This property does not have a backing field");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,12 +49,12 @@ public class BodyResolver {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// This tracks access to properties in order to register primary constructor parameters that yield real fields (JET-9)
|
// This tracks access to properties in order to register primary constructor parameters that yield real fields (JET-9)
|
||||||
this.traceForMembers = new BindingTraceAdapter(trace).addHandler(BindingContext.REFERENCE_TARGET, new BindingTraceAdapter.RecordHandler<JetReferenceExpression, DeclarationDescriptor>() {
|
this.traceForMembers = new BindingTraceAdapter(context.getTrace()).addHandler(BindingContext.REFERENCE_TARGET, new BindingTraceAdapter.RecordHandler<JetReferenceExpression, DeclarationDescriptor>() {
|
||||||
@Override
|
@Override
|
||||||
public void handleRecord(WritableSlice<JetReferenceExpression, DeclarationDescriptor> slice, JetReferenceExpression expression, DeclarationDescriptor descriptor) {
|
public void handleRecord(WritableSlice<JetReferenceExpression, DeclarationDescriptor> slice, JetReferenceExpression expression, DeclarationDescriptor descriptor) {
|
||||||
if (descriptor instanceof PropertyDescriptor) {
|
if (descriptor instanceof PropertyDescriptor) {
|
||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||||
if (BodyResolver.this.declarationResolver.getPrimaryConstructorParameterProperties().contains(propertyDescriptor)) {
|
if (BodyResolver.this.context.getPrimaryConstructorParameterProperties().contains(propertyDescriptor)) {
|
||||||
traceForMembers.record(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
|
traceForMembers.record(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +91,7 @@ public class BodyResolver {
|
|||||||
protected void bindOverridesInAClass(MutableClassDescriptor classDescriptor) {
|
protected void bindOverridesInAClass(MutableClassDescriptor classDescriptor) {
|
||||||
|
|
||||||
for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) {
|
for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) {
|
||||||
JetFunction function = (JetFunction) trace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaredFunction);
|
JetFunction function = (JetFunction) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaredFunction);
|
||||||
assert function != null;
|
assert function != null;
|
||||||
JetModifierList modifierList = function.getModifierList();
|
JetModifierList modifierList = function.getModifierList();
|
||||||
ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null;
|
ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null;
|
||||||
@@ -109,19 +101,19 @@ public class BodyResolver {
|
|||||||
FunctionDescriptor overridden = findFunctionOverridableBy(declaredFunction, supertype);
|
FunctionDescriptor overridden = findFunctionOverridableBy(declaredFunction, supertype);
|
||||||
if (overridden != null) {
|
if (overridden != null) {
|
||||||
if (hasOverrideModifier && !overridden.getModality().isOpen() && !foundError) {
|
if (hasOverrideModifier && !overridden.getModality().isOpen() && !foundError) {
|
||||||
trace.getErrorHandler().genericError(overrideNode, "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and can not be overridden");
|
context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and can not be overridden");
|
||||||
foundError = true;
|
foundError = true;
|
||||||
}
|
}
|
||||||
((FunctionDescriptorImpl) declaredFunction).addOverriddenFunction(overridden);
|
((FunctionDescriptorImpl) declaredFunction).addOverriddenFunction(overridden);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() == 0) {
|
if (hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() == 0) {
|
||||||
trace.getErrorHandler().genericError(overrideNode, "Method " + declaredFunction.getName() + " overrides nothing");
|
context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + declaredFunction.getName() + " overrides nothing");
|
||||||
}
|
}
|
||||||
PsiElement nameIdentifier = function.getNameIdentifier();
|
PsiElement nameIdentifier = function.getNameIdentifier();
|
||||||
if (!hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) {
|
if (!hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) {
|
||||||
FunctionDescriptor overriddenMethod = declaredFunction.getOverriddenDescriptors().iterator().next();
|
FunctionDescriptor overriddenMethod = declaredFunction.getOverriddenDescriptors().iterator().next();
|
||||||
trace.getErrorHandler().genericError(nameIdentifier.getNode(),
|
context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(),
|
||||||
"Method " + declaredFunction.getName() + " overrides method " + overriddenMethod.getName() + " in class " +
|
"Method " + declaredFunction.getName() + " overrides method " + overriddenMethod.getName() + " in class " +
|
||||||
overriddenMethod.getContainingDeclaration().getName() + " and needs 'override' modifier");
|
overriddenMethod.getContainingDeclaration().getName() + " and needs 'override' modifier");
|
||||||
}
|
}
|
||||||
@@ -132,7 +124,7 @@ public class BodyResolver {
|
|||||||
private FunctionDescriptor findFunctionOverridableBy(@NotNull FunctionDescriptor declaredFunction, @NotNull JetType supertype) {
|
private FunctionDescriptor findFunctionOverridableBy(@NotNull FunctionDescriptor declaredFunction, @NotNull JetType supertype) {
|
||||||
FunctionGroup functionGroup = supertype.getMemberScope().getFunctionGroup(declaredFunction.getName());
|
FunctionGroup functionGroup = supertype.getMemberScope().getFunctionGroup(declaredFunction.getName());
|
||||||
for (FunctionDescriptor functionDescriptor : functionGroup.getFunctionDescriptors()) {
|
for (FunctionDescriptor functionDescriptor : functionGroup.getFunctionDescriptors()) {
|
||||||
if (FunctionDescriptorUtil.isOverridableBy(semanticServices.getTypeChecker(), functionDescriptor, declaredFunction).isSuccess()) {
|
if (FunctionDescriptorUtil.isOverridableBy(context.getSemanticServices().getTypeChecker(), functionDescriptor, declaredFunction).isSuccess()) {
|
||||||
return functionDescriptor;
|
return functionDescriptor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,10 +137,10 @@ public class BodyResolver {
|
|||||||
JetClass jetClass = entry.getKey();
|
JetClass jetClass = entry.getKey();
|
||||||
if (classDescriptor.getUnsubstitutedPrimaryConstructor() == null) {
|
if (classDescriptor.getUnsubstitutedPrimaryConstructor() == null) {
|
||||||
for (PropertyDescriptor propertyDescriptor : classDescriptor.getProperties()) {
|
for (PropertyDescriptor propertyDescriptor : classDescriptor.getProperties()) {
|
||||||
if (trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
if (context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||||
PsiElement nameIdentifier = jetClass.getNameIdentifier();
|
PsiElement nameIdentifier = jetClass.getNameIdentifier();
|
||||||
if (nameIdentifier != null) {
|
if (nameIdentifier != null) {
|
||||||
trace.getErrorHandler().genericError(nameIdentifier.getNode(),
|
context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(),
|
||||||
"This class must have a primary constructor, because property " + propertyDescriptor.getName() + " has a backing field");
|
"This class must have a primary constructor, because property " + propertyDescriptor.getName() + " has a backing field");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -173,7 +165,7 @@ public class BodyResolver {
|
|||||||
final JetScope scopeForConstructor = primaryConstructor == null
|
final JetScope scopeForConstructor = primaryConstructor == null
|
||||||
? null
|
? null
|
||||||
: getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution(), true);
|
: getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution(), true);
|
||||||
final JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
final JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
||||||
|
|
||||||
final Map<JetTypeReference, JetType> supertypes = Maps.newLinkedHashMap();
|
final Map<JetTypeReference, JetType> supertypes = Maps.newLinkedHashMap();
|
||||||
JetVisitorVoid visitor = new JetVisitorVoid() {
|
JetVisitorVoid visitor = new JetVisitorVoid() {
|
||||||
@@ -185,9 +177,9 @@ public class BodyResolver {
|
|||||||
@Override
|
@Override
|
||||||
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
|
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
|
||||||
if (descriptor.getKind() == ClassKind.TRAIT) {
|
if (descriptor.getKind() == ClassKind.TRAIT) {
|
||||||
trace.getErrorHandler().genericError(specifier.getNode(), "Traits can not use delegation");
|
context.getTrace().getErrorHandler().genericError(specifier.getNode(), "Traits can not use delegation");
|
||||||
}
|
}
|
||||||
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
JetType supertype = context.getTrace().getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||||
recordSupertype(specifier.getTypeReference(), supertype);
|
recordSupertype(specifier.getTypeReference(), supertype);
|
||||||
JetExpression delegateExpression = specifier.getDelegateExpression();
|
JetExpression delegateExpression = specifier.getDelegateExpression();
|
||||||
if (delegateExpression != null) {
|
if (delegateExpression != null) {
|
||||||
@@ -195,8 +187,8 @@ public class BodyResolver {
|
|||||||
? descriptor.getScopeForMemberResolution()
|
? descriptor.getScopeForMemberResolution()
|
||||||
: scopeForConstructor;
|
: scopeForConstructor;
|
||||||
JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE);
|
JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE);
|
||||||
if (type != null && supertype != null && !semanticServices.getTypeChecker().isSubtypeOf(type, supertype)) {
|
if (type != null && supertype != null && !context.getSemanticServices().getTypeChecker().isSubtypeOf(type, supertype)) {
|
||||||
trace.getErrorHandler().typeMismatch(delegateExpression, supertype, type);
|
context.getTrace().getErrorHandler().typeMismatch(delegateExpression, supertype, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,31 +198,31 @@ public class BodyResolver {
|
|||||||
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
||||||
ASTNode node = valueArgumentList == null ? call.getNode() : valueArgumentList.getNode();
|
ASTNode node = valueArgumentList == null ? call.getNode() : valueArgumentList.getNode();
|
||||||
if (descriptor.getKind() == ClassKind.TRAIT) {
|
if (descriptor.getKind() == ClassKind.TRAIT) {
|
||||||
trace.getErrorHandler().genericError(node, "Traits can not initialize supertypes");
|
context.getTrace().getErrorHandler().genericError(node, "Traits can not initialize supertypes");
|
||||||
}
|
}
|
||||||
JetTypeReference typeReference = call.getTypeReference();
|
JetTypeReference typeReference = call.getTypeReference();
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||||
JetType supertype = typeInferrer.getCallResolver().resolveCall(trace, scopeForConstructor, null, call, NO_EXPECTED_TYPE);
|
JetType supertype = typeInferrer.getCallResolver().resolveCall(context.getTrace(), scopeForConstructor, null, call, NO_EXPECTED_TYPE);
|
||||||
if (supertype != null) {
|
if (supertype != null) {
|
||||||
recordSupertype(typeReference, supertype);
|
recordSupertype(typeReference, supertype);
|
||||||
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
|
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
|
||||||
if (classDescriptor != null) {
|
if (classDescriptor != null) {
|
||||||
if (classDescriptor.getKind() == ClassKind.TRAIT) {
|
if (classDescriptor.getKind() == ClassKind.TRAIT) {
|
||||||
trace.getErrorHandler().genericError(node, "A trait may not have a constructor");
|
context.getTrace().getErrorHandler().genericError(node, "A trait may not have a constructor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
|
recordSupertype(typeReference, context.getTrace().getBindingContext().get(BindingContext.TYPE, typeReference));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (descriptor.getKind() != ClassKind.TRAIT) {
|
else if (descriptor.getKind() != ClassKind.TRAIT) {
|
||||||
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
|
JetType supertype = context.getTrace().getBindingContext().get(BindingContext.TYPE, typeReference);
|
||||||
recordSupertype(typeReference, supertype);
|
recordSupertype(typeReference, supertype);
|
||||||
|
|
||||||
assert valueArgumentList != null;
|
assert valueArgumentList != null;
|
||||||
trace.getErrorHandler().genericError(valueArgumentList.getNode(),
|
context.getTrace().getErrorHandler().genericError(valueArgumentList.getNode(),
|
||||||
"Class " + JetPsiUtil.safeName(jetClass.getName()) + " must have a constructor in order to be able to initialize supertypes");
|
"Class " + JetPsiUtil.safeName(jetClass.getName()) + " must have a constructor in order to be able to initialize supertypes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,14 +231,14 @@ public class BodyResolver {
|
|||||||
@Override
|
@Override
|
||||||
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
||||||
JetTypeReference typeReference = specifier.getTypeReference();
|
JetTypeReference typeReference = specifier.getTypeReference();
|
||||||
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
|
JetType supertype = context.getTrace().getBindingContext().get(BindingContext.TYPE, typeReference);
|
||||||
recordSupertype(typeReference, supertype);
|
recordSupertype(typeReference, supertype);
|
||||||
if (supertype != null) {
|
if (supertype != null) {
|
||||||
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
|
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
|
||||||
if (classDescriptor != null) {
|
if (classDescriptor != null) {
|
||||||
if (descriptor.getKind() != ClassKind.TRAIT) {
|
if (descriptor.getKind() != ClassKind.TRAIT) {
|
||||||
if (classDescriptor.hasConstructors() && !ErrorUtils.isError(classDescriptor.getTypeConstructor()) && classDescriptor.getKind() != ClassKind.TRAIT) {
|
if (classDescriptor.hasConstructors() && !ErrorUtils.isError(classDescriptor.getTypeConstructor()) && classDescriptor.getKind() != ClassKind.TRAIT) {
|
||||||
trace.getErrorHandler().genericError(specifier.getNode(), "This type has a constructor, and thus must be initialized here");
|
context.getTrace().getErrorHandler().genericError(specifier.getNode(), "This type has a constructor, and thus must be initialized here");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,7 +281,7 @@ public class BodyResolver {
|
|||||||
if (classDescriptor != null) {
|
if (classDescriptor != null) {
|
||||||
if (classDescriptor.getKind() != ClassKind.TRAIT) {
|
if (classDescriptor.getKind() != ClassKind.TRAIT) {
|
||||||
if (classAppeared) {
|
if (classAppeared) {
|
||||||
trace.getErrorHandler().genericError(typeReference.getNode(), "Only one class may appear in a supertype list");
|
context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "Only one class may appear in a supertype list");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
classAppeared = true;
|
classAppeared = true;
|
||||||
@@ -297,16 +289,16 @@ public class BodyResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
trace.getErrorHandler().genericError(typeReference.getNode(), "Only classes and traits may serve as supertypes");
|
context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "Only classes and traits may serve as supertypes");
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeConstructor constructor = supertype.getConstructor();
|
TypeConstructor constructor = supertype.getConstructor();
|
||||||
if (!typeConstructors.add(constructor)) {
|
if (!typeConstructors.add(constructor)) {
|
||||||
trace.getErrorHandler().genericError(typeReference.getNode(), "A supertype appears twice");
|
context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "A supertype appears twice");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constructor.isSealed() && !allowedFinalSupertypes.contains(constructor)) {
|
if (constructor.isSealed() && !allowedFinalSupertypes.contains(constructor)) {
|
||||||
trace.getErrorHandler().genericError(typeReference.getNode(), "This type is final, so it cannot be inherited from");
|
context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "This type is final, so it cannot be inherited from");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -330,20 +322,20 @@ public class BodyResolver {
|
|||||||
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||||
assert primaryConstructor != null;
|
assert primaryConstructor != null;
|
||||||
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
||||||
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(createFieldAssignTrackingTrace(), JetFlowInformationProvider.NONE); // TODO : flow
|
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(createFieldAssignTrackingTrace(), JetFlowInformationProvider.NONE); // TODO : flow
|
||||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
||||||
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), NO_EXPECTED_TYPE);
|
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), NO_EXPECTED_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
||||||
trace.getErrorHandler().genericError(anonymousInitializer.getNode(), "Anonymous initializers are only allowed in the presence of a primary constructor");
|
context.getTrace().getErrorHandler().genericError(anonymousInitializer.getNode(), "Anonymous initializers are only allowed in the presence of a primary constructor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveSecondaryConstructorBodies() {
|
private void resolveSecondaryConstructorBodies() {
|
||||||
for (Map.Entry<JetDeclaration, ConstructorDescriptor> entry : declarationResolver.getConstructors().entrySet()) {
|
for (Map.Entry<JetDeclaration, ConstructorDescriptor> entry : this.context.getConstructors().entrySet()) {
|
||||||
JetDeclaration declaration = entry.getKey();
|
JetDeclaration declaration = entry.getKey();
|
||||||
ConstructorDescriptor descriptor = entry.getValue();
|
ConstructorDescriptor descriptor = entry.getValue();
|
||||||
|
|
||||||
@@ -356,17 +348,17 @@ public class BodyResolver {
|
|||||||
private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) {
|
private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) {
|
||||||
final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor, declaringScope, false);
|
final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor, declaringScope, false);
|
||||||
|
|
||||||
final JetTypeInferrer.Services typeInferrerForInitializers = semanticServices.getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE);
|
final JetTypeInferrer.Services typeInferrerForInitializers = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE);
|
||||||
|
|
||||||
JetClass containingClass = PsiTreeUtil.getParentOfType(declaration, JetClass.class);
|
JetClass containingClass = PsiTreeUtil.getParentOfType(declaration, JetClass.class);
|
||||||
assert containingClass != null : "This must be guaranteed by the parser";
|
assert containingClass != null : "This must be guaranteed by the parser";
|
||||||
if (!containingClass.hasPrimaryConstructor()) {
|
if (!containingClass.hasPrimaryConstructor()) {
|
||||||
trace.getErrorHandler().genericError(declaration.getNameNode(), "A secondary constructor may appear only in a class that has a primary constructor");
|
context.getTrace().getErrorHandler().genericError(declaration.getNameNode(), "A secondary constructor may appear only in a class that has a primary constructor");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
List<JetDelegationSpecifier> initializers = declaration.getInitializers();
|
List<JetDelegationSpecifier> initializers = declaration.getInitializers();
|
||||||
if (initializers.isEmpty()) {
|
if (initializers.isEmpty()) {
|
||||||
trace.getErrorHandler().genericError(declaration.getNameNode(), "Secondary constructors must have an initializer list");
|
context.getTrace().getErrorHandler().genericError(declaration.getNameNode(), "Secondary constructors must have an initializer list");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
initializers.get(0).accept(new JetVisitorVoid() {
|
initializers.get(0).accept(new JetVisitorVoid() {
|
||||||
@@ -374,7 +366,7 @@ public class BodyResolver {
|
|||||||
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
||||||
JetTypeReference typeReference = call.getTypeReference();
|
JetTypeReference typeReference = call.getTypeReference();
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
typeInferrerForInitializers.getCallResolver().resolveCall(trace, functionInnerScope, null, call, NO_EXPECTED_TYPE);
|
typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(), functionInnerScope, null, call, NO_EXPECTED_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,24 +376,24 @@ public class BodyResolver {
|
|||||||
// TODO : check: if a this() call is present, no other initializers are allowed
|
// TODO : check: if a this() call is present, no other initializers are allowed
|
||||||
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
||||||
|
|
||||||
typeInferrerForInitializers.getCallResolver().resolveCall(trace,
|
typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(),
|
||||||
functionInnerScope,
|
functionInnerScope,
|
||||||
null, call, NO_EXPECTED_TYPE);
|
null, call, NO_EXPECTED_TYPE);
|
||||||
// call.getThisReference(),
|
// call.getThisReference(),
|
||||||
// classDescriptor,
|
// classDescriptor,
|
||||||
// classDescriptor.getDefaultType(),
|
// classDescriptor.getDefaultType(),
|
||||||
// call);
|
// call);
|
||||||
// trace.getErrorHandler().genericError(call.getNode(), "this-calls are not supported");
|
// context.getTrace().getErrorHandler().genericError(call.getNode(), "this-calls are not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
|
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
|
||||||
trace.getErrorHandler().genericError(specifier.getNode(), "'by'-clause is only supported for primary constructors");
|
context.getTrace().getErrorHandler().genericError(specifier.getNode(), "'by'-clause is only supported for primary constructors");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
||||||
trace.getErrorHandler().genericError(specifier.getNode(), "Constructor parameters required");
|
context.getTrace().getErrorHandler().genericError(specifier.getNode(), "Constructor parameters required");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -411,15 +403,15 @@ public class BodyResolver {
|
|||||||
});
|
});
|
||||||
for (int i = 1, initializersSize = initializers.size(); i < initializersSize; i++) {
|
for (int i = 1, initializersSize = initializers.size(); i < initializersSize; i++) {
|
||||||
JetDelegationSpecifier initializer = initializers.get(i);
|
JetDelegationSpecifier initializer = initializers.get(i);
|
||||||
trace.getErrorHandler().genericError(initializer.getNode(), "Only one call to 'this(...)' is allowed");
|
context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Only one call to 'this(...)' is allowed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JetExpression bodyExpression = declaration.getBodyExpression();
|
JetExpression bodyExpression = declaration.getBodyExpression();
|
||||||
if (bodyExpression != null) {
|
if (bodyExpression != null) {
|
||||||
classDescriptorResolver.computeFlowData(declaration, bodyExpression);
|
context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
|
||||||
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(declaration, bodyExpression);
|
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
|
||||||
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, flowInformationProvider);
|
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, flowInformationProvider);
|
||||||
|
|
||||||
typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, JetStandardClasses.getUnitType());
|
typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, JetStandardClasses.getUnitType());
|
||||||
}
|
}
|
||||||
@@ -427,7 +419,7 @@ public class BodyResolver {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JetScope getInnerScopeForConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull JetScope declaringScope, boolean primary) {
|
private JetScope getInnerScopeForConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull JetScope declaringScope, boolean primary) {
|
||||||
WritableScope constructorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), trace.getErrorHandler()).setDebugName("Inner scope for constructor");
|
WritableScope constructorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), context.getTrace().getErrorHandler()).setDebugName("Inner scope for constructor");
|
||||||
for (PropertyDescriptor propertyDescriptor : ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getProperties()) {
|
for (PropertyDescriptor propertyDescriptor : ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getProperties()) {
|
||||||
constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
|
constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
|
||||||
}
|
}
|
||||||
@@ -435,7 +427,7 @@ public class BodyResolver {
|
|||||||
constructorScope.setThisType(descriptor.getContainingDeclaration().getDefaultType());
|
constructorScope.setThisType(descriptor.getContainingDeclaration().getDefaultType());
|
||||||
|
|
||||||
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) {
|
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) {
|
||||||
JetParameter parameter = (JetParameter) trace.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, valueParameterDescriptor);
|
JetParameter parameter = (JetParameter) context.getTrace().getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, valueParameterDescriptor);
|
||||||
if (parameter.getValOrVarNode() == null || !primary) {
|
if (parameter.getValOrVarNode() == null || !primary) {
|
||||||
constructorScope.addVariableDescriptor(valueParameterDescriptor);
|
constructorScope.addVariableDescriptor(valueParameterDescriptor);
|
||||||
}
|
}
|
||||||
@@ -455,16 +447,16 @@ public class BodyResolver {
|
|||||||
MutableClassDescriptor classDescriptor = entry.getValue();
|
MutableClassDescriptor classDescriptor = entry.getValue();
|
||||||
|
|
||||||
for (JetProperty property : jetClass.getProperties()) {
|
for (JetProperty property : jetClass.getProperties()) {
|
||||||
final PropertyDescriptor propertyDescriptor = declarationResolver.getProperties().get(property);
|
final PropertyDescriptor propertyDescriptor = this.context.getProperties().get(property);
|
||||||
assert propertyDescriptor != null;
|
assert propertyDescriptor != null;
|
||||||
|
|
||||||
JetScope declaringScope = declarationResolver.getDeclaringScopes().get(property);
|
JetScope declaringScope = this.context.getDeclaringScopes().get(property);
|
||||||
|
|
||||||
JetExpression initializer = property.getInitializer();
|
JetExpression initializer = property.getInitializer();
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||||
if (primaryConstructor == null) {
|
if (primaryConstructor == null) {
|
||||||
trace.getErrorHandler().genericError(initializer.getNode(), "Property initializers are not allowed when no primary constructor is present");
|
context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Property initializers are not allowed when no primary constructor is present");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetScope scope = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
JetScope scope = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
||||||
@@ -479,12 +471,12 @@ public class BodyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Top-level properties & properties of objects
|
// Top-level properties & properties of objects
|
||||||
for (Map.Entry<JetProperty, PropertyDescriptor> entry : declarationResolver.getProperties().entrySet()) {
|
for (Map.Entry<JetProperty, PropertyDescriptor> entry : this.context.getProperties().entrySet()) {
|
||||||
JetProperty property = entry.getKey();
|
JetProperty property = entry.getKey();
|
||||||
if (processed.contains(property)) continue;
|
if (processed.contains(property)) continue;
|
||||||
|
|
||||||
final PropertyDescriptor propertyDescriptor = entry.getValue();
|
final PropertyDescriptor propertyDescriptor = entry.getValue();
|
||||||
JetScope declaringScope = declarationResolver.getDeclaringScopes().get(property);
|
JetScope declaringScope = this.context.getDeclaringScopes().get(property);
|
||||||
|
|
||||||
JetExpression initializer = property.getInitializer();
|
JetExpression initializer = property.getInitializer();
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
@@ -497,7 +489,7 @@ public class BodyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull PropertyDescriptor propertyDescriptor) {
|
private JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||||
WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, trace.getErrorHandler()).setDebugName("Property declaration inner scope");
|
WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, context.getTrace().getErrorHandler()).setDebugName("Property declaration inner scope");
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) {
|
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) {
|
||||||
result.addTypeParameterDescriptor(typeParameterDescriptor);
|
result.addTypeParameterDescriptor(typeParameterDescriptor);
|
||||||
}
|
}
|
||||||
@@ -511,7 +503,7 @@ public class BodyResolver {
|
|||||||
private void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor, JetScope declaringScope) {
|
private void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor, JetScope declaringScope) {
|
||||||
BindingTraceAdapter fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor);
|
BindingTraceAdapter fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor);
|
||||||
|
|
||||||
WritableScope accessorScope = new WritableScopeImpl(getPropertyDeclarationInnerScope(declaringScope, propertyDescriptor), declaringScope.getContainingDeclaration(), trace.getErrorHandler()).setDebugName("Accessor scope");
|
WritableScope accessorScope = new WritableScopeImpl(getPropertyDeclarationInnerScope(declaringScope, propertyDescriptor), declaringScope.getContainingDeclaration(), context.getTrace().getErrorHandler()).setDebugName("Accessor scope");
|
||||||
accessorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
|
accessorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
|
||||||
|
|
||||||
JetPropertyAccessor getter = property.getGetter();
|
JetPropertyAccessor getter = property.getGetter();
|
||||||
@@ -535,39 +527,39 @@ public class BodyResolver {
|
|||||||
ASTNode nameNode = nameIdentifier == null ? property.getNode() : nameIdentifier.getNode();
|
ASTNode nameNode = nameIdentifier == null ? property.getNode() : nameIdentifier.getNode();
|
||||||
if (propertyDescriptor.getModality() == Modality.ABSTRACT) {
|
if (propertyDescriptor.getModality() == Modality.ABSTRACT) {
|
||||||
if (classDescriptor == null) {
|
if (classDescriptor == null) {
|
||||||
trace.getErrorHandler().genericError(property.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
|
context.getTrace().getErrorHandler().genericError(property.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
|
||||||
"Global property can not be abstract");
|
"Global property can not be abstract");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (classDescriptor.getModality() != Modality.ABSTRACT) {
|
if (classDescriptor.getModality() != Modality.ABSTRACT) {
|
||||||
trace.getErrorHandler().genericError(property.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
|
context.getTrace().getErrorHandler().genericError(property.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
|
||||||
"Abstract property " + property.getName() + " in non-abstract class " + classDescriptor.getName());
|
"Abstract property " + property.getName() + " in non-abstract class " + classDescriptor.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
trace.getErrorHandler().genericError(initializer.getNode(), "Property with initializer can not be abstract");
|
context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Property with initializer can not be abstract");
|
||||||
}
|
}
|
||||||
if (getter != null && getter.getBodyExpression() != null) {
|
if (getter != null && getter.getBodyExpression() != null) {
|
||||||
trace.getErrorHandler().genericError(getter.getNode(), "Property with getter implementation can not be abstract");
|
context.getTrace().getErrorHandler().genericError(getter.getNode(), "Property with getter implementation can not be abstract");
|
||||||
}
|
}
|
||||||
if (setter != null && setter.getBodyExpression() != null) {
|
if (setter != null && setter.getBodyExpression() != null) {
|
||||||
trace.getErrorHandler().genericError(setter.getNode(), "Property with setter implementation can not be abstract");
|
context.getTrace().getErrorHandler().genericError(setter.getNode(), "Property with setter implementation can not be abstract");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean backingFieldRequired = trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
|
boolean backingFieldRequired = context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
|
||||||
if (backingFieldRequired) {
|
if (backingFieldRequired) {
|
||||||
if (initializer == null && !trace.getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) {
|
if (initializer == null && !context.getTrace().getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) {
|
||||||
if (classDescriptor == null || (getter != null && getter.getBodyExpression() != null) || (setter != null && setter.getBodyExpression() != null)) {
|
if (classDescriptor == null || (getter != null && getter.getBodyExpression() != null) || (setter != null && setter.getBodyExpression() != null)) {
|
||||||
trace.getErrorHandler().genericError(nameNode, "Property must be initialized");
|
context.getTrace().getErrorHandler().genericError(nameNode, "Property must be initialized");
|
||||||
} else if (classDescriptor.getKind() != ClassKind.TRAIT) {
|
} else if (classDescriptor.getKind() != ClassKind.TRAIT) {
|
||||||
trace.getErrorHandler().genericError(nameNode, "Property must be initialized or be abstract");
|
context.getTrace().getErrorHandler().genericError(nameNode, "Property must be initialized or be abstract");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
trace.getErrorHandler().genericError(initializer.getNode(), "Initializer is not allowed here because this property has no backing field");
|
context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Initializer is not allowed here because this property has no backing field");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -581,7 +573,7 @@ public class BodyResolver {
|
|||||||
if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
|
if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
|
||||||
// This check may be considered redundant as long as $x is only accessible from accessors to $x
|
// This check may be considered redundant as long as $x is only accessible from accessors to $x
|
||||||
if (descriptor == propertyDescriptor) { // TODO : original?
|
if (descriptor == propertyDescriptor) { // TODO : original?
|
||||||
traceForMembers.record(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor); // TODO: this trace?
|
traceForMembers.record(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor); // TODO: this context.getTrace()?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -606,8 +598,8 @@ public class BodyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
|
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
|
||||||
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(property, initializer); // TODO : flow JET-15
|
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15
|
||||||
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, flowInformationProvider);
|
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, flowInformationProvider);
|
||||||
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, NO_EXPECTED_TYPE);
|
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, NO_EXPECTED_TYPE);
|
||||||
|
|
||||||
JetType expectedType = propertyDescriptor.getInType();
|
JetType expectedType = propertyDescriptor.getInType();
|
||||||
@@ -615,17 +607,17 @@ public class BodyResolver {
|
|||||||
expectedType = propertyDescriptor.getOutType();
|
expectedType = propertyDescriptor.getOutType();
|
||||||
}
|
}
|
||||||
if (type != null && expectedType != null
|
if (type != null && expectedType != null
|
||||||
&& !semanticServices.getTypeChecker().isSubtypeOf(type, expectedType)) {
|
&& !context.getSemanticServices().getTypeChecker().isSubtypeOf(type, expectedType)) {
|
||||||
trace.getErrorHandler().typeMismatch(initializer, expectedType, type);
|
context.getTrace().getErrorHandler().typeMismatch(initializer, expectedType, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveFunctionBodies() {
|
private void resolveFunctionBodies() {
|
||||||
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : declarationResolver.getFunctions().entrySet()) {
|
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : this.context.getFunctions().entrySet()) {
|
||||||
JetDeclaration declaration = entry.getKey();
|
JetDeclaration declaration = entry.getKey();
|
||||||
FunctionDescriptor descriptor = entry.getValue();
|
FunctionDescriptor descriptor = entry.getValue();
|
||||||
|
|
||||||
JetScope declaringScope = declarationResolver.getDeclaringScopes().get(declaration);
|
JetScope declaringScope = this.context.getDeclaringScopes().get(declaration);
|
||||||
assert declaringScope != null;
|
assert declaringScope != null;
|
||||||
|
|
||||||
resolveFunctionBody(traceForMembers, (JetNamedFunction) declaration, descriptor, declaringScope);
|
resolveFunctionBody(traceForMembers, (JetNamedFunction) declaration, descriptor, declaringScope);
|
||||||
@@ -642,8 +634,8 @@ public class BodyResolver {
|
|||||||
JetExpression bodyExpression = function.getBodyExpression();
|
JetExpression bodyExpression = function.getBodyExpression();
|
||||||
|
|
||||||
if (bodyExpression != null) {
|
if (bodyExpression != null) {
|
||||||
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(function.asElement(), bodyExpression);
|
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(function.asElement(), bodyExpression);
|
||||||
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(trace, flowInformationProvider);
|
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace, flowInformationProvider);
|
||||||
|
|
||||||
typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor);
|
typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor);
|
||||||
}
|
}
|
||||||
@@ -678,24 +670,24 @@ public class BodyResolver {
|
|||||||
boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS;
|
boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS;
|
||||||
boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT;
|
boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT;
|
||||||
if (hasAbstractModifier && !inAbstractClass && !inTrait && !inEnum) {
|
if (hasAbstractModifier && !inAbstractClass && !inTrait && !inEnum) {
|
||||||
trace.getErrorHandler().genericError(abstractNode, "Abstract method " + function.getName() + " in non-abstract class " + classDescriptor.getName());
|
context.getTrace().getErrorHandler().genericError(abstractNode, "Abstract method " + function.getName() + " in non-abstract class " + classDescriptor.getName());
|
||||||
}
|
}
|
||||||
if (hasAbstractModifier && inTrait) {
|
if (hasAbstractModifier && inTrait) {
|
||||||
trace.getErrorHandler().genericWarning(abstractNode, "Abstract modifier is not necessary in traits");
|
context.getTrace().getErrorHandler().genericWarning(abstractNode, "Abstract modifier is not necessary in traits");
|
||||||
}
|
}
|
||||||
if (function.getBodyExpression() != null && hasAbstractModifier) {
|
if (function.getBodyExpression() != null && hasAbstractModifier) {
|
||||||
trace.getErrorHandler().genericError(abstractNode, "Method " + function.getName() + " with body can not be abstract");
|
context.getTrace().getErrorHandler().genericError(abstractNode, "Method " + function.getName() + " with body can not be abstract");
|
||||||
}
|
}
|
||||||
if (function.getBodyExpression() == null && !hasAbstractModifier && !inTrait && nameIdentifier != null) {
|
if (function.getBodyExpression() == null && !hasAbstractModifier && !inTrait && nameIdentifier != null) {
|
||||||
trace.getErrorHandler().genericError(nameIdentifier.getNode(), "Method " + function.getName() + " without body must be abstract");
|
context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Method " + function.getName() + " without body must be abstract");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (hasAbstractModifier) {
|
if (hasAbstractModifier) {
|
||||||
trace.getErrorHandler().genericError(abstractNode, "Function " + function.getName() + " can not be abstract");
|
context.getTrace().getErrorHandler().genericError(abstractNode, "Function " + function.getName() + " can not be abstract");
|
||||||
}
|
}
|
||||||
if (function.getBodyExpression() == null && !hasAbstractModifier && nameIdentifier != null) {
|
if (function.getBodyExpression() == null && !hasAbstractModifier && nameIdentifier != null) {
|
||||||
trace.getErrorHandler().genericError(nameIdentifier.getNode(), "Function " + function.getName() + " must have body");
|
context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Function " + function.getName() + " must have body");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION;
|
||||||
|
|
||||||
@@ -18,22 +14,12 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION;
|
|||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class DeclarationResolver {
|
public class DeclarationResolver {
|
||||||
private final BindingTrace trace;
|
|
||||||
private final AnnotationResolver annotationResolver;
|
private final AnnotationResolver annotationResolver;
|
||||||
private final ClassDescriptorResolver classDescriptorResolver;
|
|
||||||
private final TopDownAnalysisContext context;
|
private final TopDownAnalysisContext context;
|
||||||
|
|
||||||
private final Map<JetNamedFunction, FunctionDescriptorImpl> functions = Maps.newLinkedHashMap();
|
public DeclarationResolver(TopDownAnalysisContext context) {
|
||||||
private final Map<JetDeclaration, ConstructorDescriptor> constructors = Maps.newLinkedHashMap();
|
|
||||||
private final Map<JetProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
|
|
||||||
private final Set<PropertyDescriptor> primaryConstructorParameterProperties = Sets.newHashSet();
|
|
||||||
private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap();
|
|
||||||
|
|
||||||
public DeclarationResolver(JetSemanticServices semanticServices, BindingTrace trace, TopDownAnalysisContext context) {
|
|
||||||
this.trace = trace;
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.annotationResolver = new AnnotationResolver(semanticServices, trace);
|
this.annotationResolver = new AnnotationResolver(context.getSemanticServices(), context.getTrace());
|
||||||
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process() {
|
public void process() {
|
||||||
@@ -63,7 +49,7 @@ public class DeclarationResolver {
|
|||||||
if (modifierList != null) {
|
if (modifierList != null) {
|
||||||
List<JetAnnotationEntry> annotationEntries = modifierList.getAnnotationEntries();
|
List<JetAnnotationEntry> annotationEntries = modifierList.getAnnotationEntries();
|
||||||
for (JetAnnotationEntry annotationEntry : annotationEntries) {
|
for (JetAnnotationEntry annotationEntry : annotationEntries) {
|
||||||
AnnotationDescriptor annotationDescriptor = trace.get(ANNOTATION, annotationEntry);
|
AnnotationDescriptor annotationDescriptor = context.getTrace().get(ANNOTATION, annotationEntry);
|
||||||
if (annotationDescriptor != null) {
|
if (annotationDescriptor != null) {
|
||||||
annotationResolver.resolveAnnotationStub(mutableClassDescriptor.getScopeForSupertypeResolution(), annotationEntry, annotationDescriptor);
|
annotationResolver.resolveAnnotationStub(mutableClassDescriptor.getScopeForSupertypeResolution(), annotationEntry, annotationDescriptor);
|
||||||
}
|
}
|
||||||
@@ -105,30 +91,30 @@ public class DeclarationResolver {
|
|||||||
declaration.accept(new JetVisitorVoid() {
|
declaration.accept(new JetVisitorVoid() {
|
||||||
@Override
|
@Override
|
||||||
public void visitNamedFunction(JetNamedFunction function) {
|
public void visitNamedFunction(JetNamedFunction function) {
|
||||||
FunctionDescriptorImpl functionDescriptor = classDescriptorResolver.resolveFunctionDescriptor(namespaceLike, scope, function);
|
FunctionDescriptorImpl functionDescriptor = context.getClassDescriptorResolver().resolveFunctionDescriptor(namespaceLike, scope, function);
|
||||||
namespaceLike.addFunctionDescriptor(functionDescriptor);
|
namespaceLike.addFunctionDescriptor(functionDescriptor);
|
||||||
functions.put(function, functionDescriptor);
|
context.getFunctions().put(function, functionDescriptor);
|
||||||
declaringScopes.put(function, scope);
|
context.getDeclaringScopes().put(function, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitProperty(JetProperty property) {
|
public void visitProperty(JetProperty property) {
|
||||||
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(namespaceLike, scope, property);
|
PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolvePropertyDescriptor(namespaceLike, scope, property);
|
||||||
namespaceLike.addPropertyDescriptor(propertyDescriptor);
|
namespaceLike.addPropertyDescriptor(propertyDescriptor);
|
||||||
properties.put(property, propertyDescriptor);
|
context.getProperties().put(property, propertyDescriptor);
|
||||||
declaringScopes.put(property, scope);
|
context.getDeclaringScopes().put(property, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
|
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
|
||||||
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, declaration, context.getObjects().get(declaration));
|
PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, declaration, context.getObjects().get(declaration));
|
||||||
namespaceLike.addPropertyDescriptor(propertyDescriptor);
|
namespaceLike.addPropertyDescriptor(propertyDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitEnumEntry(JetEnumEntry enumEntry) {
|
public void visitEnumEntry(JetEnumEntry enumEntry) {
|
||||||
if (enumEntry.getPrimaryConstructorParameterList() == null) {
|
if (enumEntry.getPrimaryConstructorParameterList() == null) {
|
||||||
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, enumEntry, context.getClasses().get(enumEntry));
|
PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, enumEntry, context.getClasses().get(enumEntry));
|
||||||
MutableClassDescriptor classObjectDescriptor = ((MutableClassDescriptor) namespaceLike).getClassObjectDescriptor();
|
MutableClassDescriptor classObjectDescriptor = ((MutableClassDescriptor) namespaceLike).getClassObjectDescriptor();
|
||||||
assert classObjectDescriptor != null;
|
assert classObjectDescriptor != null;
|
||||||
classObjectDescriptor.addPropertyDescriptor(propertyDescriptor);
|
classObjectDescriptor.addPropertyDescriptor(propertyDescriptor);
|
||||||
@@ -142,20 +128,20 @@ public class DeclarationResolver {
|
|||||||
if (!klass.hasPrimaryConstructor()) return;
|
if (!klass.hasPrimaryConstructor()) return;
|
||||||
|
|
||||||
if (classDescriptor.getKind() == ClassKind.TRAIT) {
|
if (classDescriptor.getKind() == ClassKind.TRAIT) {
|
||||||
trace.getErrorHandler().genericError(klass.getPrimaryConstructorParameterList().getNode(), "A trait may not have a constructor");
|
context.getTrace().getErrorHandler().genericError(klass.getPrimaryConstructorParameterList().getNode(), "A trait may not have a constructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : not all the parameters are real properties
|
// TODO : not all the parameters are real properties
|
||||||
JetScope memberScope = classDescriptor.getScopeForSupertypeResolution();
|
JetScope memberScope = classDescriptor.getScopeForSupertypeResolution();
|
||||||
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructorDescriptor(memberScope, classDescriptor, klass);
|
ConstructorDescriptor constructorDescriptor = context.getClassDescriptorResolver().resolvePrimaryConstructorDescriptor(memberScope, classDescriptor, klass);
|
||||||
for (JetParameter parameter : klass.getPrimaryConstructorParameters()) {
|
for (JetParameter parameter : klass.getPrimaryConstructorParameters()) {
|
||||||
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePrimaryConstructorParameterToAProperty(
|
PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolvePrimaryConstructorParameterToAProperty(
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
memberScope,
|
memberScope,
|
||||||
parameter
|
parameter
|
||||||
);
|
);
|
||||||
classDescriptor.addPropertyDescriptor(propertyDescriptor);
|
classDescriptor.addPropertyDescriptor(propertyDescriptor);
|
||||||
primaryConstructorParameterProperties.add(propertyDescriptor);
|
context.getPrimaryConstructorParameterProperties().add(propertyDescriptor);
|
||||||
}
|
}
|
||||||
if (constructorDescriptor != null) {
|
if (constructorDescriptor != null) {
|
||||||
classDescriptor.setPrimaryConstructor(constructorDescriptor);
|
classDescriptor.setPrimaryConstructor(constructorDescriptor);
|
||||||
@@ -164,34 +150,15 @@ public class DeclarationResolver {
|
|||||||
|
|
||||||
private void processSecondaryConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) {
|
private void processSecondaryConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) {
|
||||||
if (classDescriptor.getKind() == ClassKind.TRAIT) {
|
if (classDescriptor.getKind() == ClassKind.TRAIT) {
|
||||||
trace.getErrorHandler().genericError(constructor.getNameNode(), "A trait may not have a constructor");
|
context.getTrace().getErrorHandler().genericError(constructor.getNameNode(), "A trait may not have a constructor");
|
||||||
}
|
}
|
||||||
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolveSecondaryConstructorDescriptor(
|
ConstructorDescriptor constructorDescriptor = context.getClassDescriptorResolver().resolveSecondaryConstructorDescriptor(
|
||||||
classDescriptor.getScopeForMemberResolution(),
|
classDescriptor.getScopeForMemberResolution(),
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
constructor);
|
constructor);
|
||||||
classDescriptor.addConstructor(constructorDescriptor);
|
classDescriptor.addConstructor(constructorDescriptor);
|
||||||
constructors.put(constructor, constructorDescriptor);
|
context.getConstructors().put(constructor, constructorDescriptor);
|
||||||
declaringScopes.put(constructor, classDescriptor.getScopeForMemberLookup());
|
context.getDeclaringScopes().put(constructor, classDescriptor.getScopeForMemberLookup());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<PropertyDescriptor> getPrimaryConstructorParameterProperties() {
|
|
||||||
return primaryConstructorParameterProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<JetDeclaration, ConstructorDescriptor> getConstructors() {
|
|
||||||
return constructors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<JetProperty, PropertyDescriptor> getProperties() {
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<JetDeclaration, JetScope> getDeclaringScopes() {
|
|
||||||
return declaringScopes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<JetNamedFunction, FunctionDescriptorImpl> getFunctions() {
|
|
||||||
return functions;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,52 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import org.jetbrains.jet.lang.descriptors.MutableClassDescriptor;
|
import com.google.common.collect.Sets;
|
||||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorImpl;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class TopDownAnalysisContext {
|
/*package*/ class TopDownAnalysisContext {
|
||||||
|
|
||||||
|
private final BindingTrace trace;
|
||||||
|
private final JetSemanticServices semanticServices;
|
||||||
|
private final ClassDescriptorResolver classDescriptorResolver;
|
||||||
|
|
||||||
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
|
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
|
||||||
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
|
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
|
||||||
protected final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
|
protected final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
|
||||||
protected final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
|
protected final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
|
||||||
|
|
||||||
|
private final Map<JetNamedFunction, FunctionDescriptorImpl> functions = Maps.newLinkedHashMap();
|
||||||
|
private final Map<JetDeclaration, ConstructorDescriptor> constructors = Maps.newLinkedHashMap();
|
||||||
|
private final Map<JetProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
|
||||||
|
private final Set<PropertyDescriptor> primaryConstructorParameterProperties = Sets.newHashSet();
|
||||||
|
private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap();
|
||||||
|
|
||||||
|
public TopDownAnalysisContext(JetSemanticServices semanticServices, BindingTrace trace) {
|
||||||
|
this.trace = trace;
|
||||||
|
this.semanticServices = semanticServices;
|
||||||
|
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindingTrace getTrace() {
|
||||||
|
return trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JetSemanticServices getSemanticServices() {
|
||||||
|
return semanticServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassDescriptorResolver getClassDescriptorResolver() {
|
||||||
|
return classDescriptorResolver;
|
||||||
|
}
|
||||||
|
|
||||||
public Map<JetClass, MutableClassDescriptor> getClasses() {
|
public Map<JetClass, MutableClassDescriptor> getClasses() {
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
@@ -35,5 +63,24 @@ public class TopDownAnalysisContext {
|
|||||||
return namespaceDescriptors;
|
return namespaceDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<PropertyDescriptor> getPrimaryConstructorParameterProperties() {
|
||||||
|
return primaryConstructorParameterProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<JetDeclaration, ConstructorDescriptor> getConstructors() {
|
||||||
|
return constructors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<JetProperty, PropertyDescriptor> getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<JetDeclaration, JetScope> getDeclaringScopes() {
|
||||||
|
return declaringScopes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<JetNamedFunction, FunctionDescriptorImpl> getFunctions() {
|
||||||
|
return functions;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,26 +60,22 @@ public class TopDownAnalyzer {
|
|||||||
@NotNull JetSemanticServices semanticServices,
|
@NotNull JetSemanticServices semanticServices,
|
||||||
@NotNull BindingTrace trace,
|
@NotNull BindingTrace trace,
|
||||||
@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
|
@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
|
||||||
TypeHierarchyResolver typeHierarchyResolver = new TypeHierarchyResolver(semanticServices, trace);
|
TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace);
|
||||||
TopDownAnalysisContext context = typeHierarchyResolver.process(outerScope, owner, declarations);
|
new TypeHierarchyResolver(context).process(outerScope, owner, declarations);
|
||||||
|
new DeclarationResolver(context).process();
|
||||||
DeclarationResolver declarationResolver = new DeclarationResolver(semanticServices, trace, context);
|
new BodyResolver(context).resolveBehaviorDeclarationBodies();
|
||||||
declarationResolver.process();
|
|
||||||
|
|
||||||
new BodyResolver(semanticServices, trace, context, declarationResolver).resolveBehaviorDeclarationBodies();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void processStandardLibraryNamespace(
|
public static void processStandardLibraryNamespace(
|
||||||
@NotNull JetSemanticServices semanticServices,
|
@NotNull JetSemanticServices semanticServices,
|
||||||
@NotNull BindingTrace trace,
|
@NotNull BindingTrace trace,
|
||||||
@NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) {
|
@NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) {
|
||||||
TypeHierarchyResolver typeHierarchyResolver = new TypeHierarchyResolver(semanticServices, trace);
|
TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace);
|
||||||
TopDownAnalysisContext context = typeHierarchyResolver.processStandardLibraryNamespace(outerScope, standardLibraryNamespace, namespace);
|
context.getNamespaceScopes().put(namespace, standardLibraryNamespace.getMemberScope());
|
||||||
|
context.getNamespaceDescriptors().put(namespace, standardLibraryNamespace);
|
||||||
DeclarationResolver declarationResolver = new DeclarationResolver(semanticServices, trace, context);
|
new TypeHierarchyResolver(context).process(outerScope, standardLibraryNamespace, namespace.getDeclarations());
|
||||||
declarationResolver.process();
|
new DeclarationResolver(context).process();
|
||||||
|
BodyResolver bodyResolver = new BodyResolver(context) {
|
||||||
BodyResolver bodyResolver = new BodyResolver(semanticServices, trace, context, declarationResolver) {
|
|
||||||
@Override
|
@Override
|
||||||
protected void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor, @Nullable ClassDescriptor classDescriptor) {
|
protected void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor, @Nullable ClassDescriptor classDescriptor) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
|
||||||
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
@@ -19,43 +18,24 @@ import java.util.Map;
|
|||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class TypeHierarchyResolver {
|
public class TypeHierarchyResolver {
|
||||||
|
private final TopDownAnalysisContext context;
|
||||||
|
|
||||||
private final BindingTrace trace;
|
public TypeHierarchyResolver(TopDownAnalysisContext context) {
|
||||||
private final JetSemanticServices semanticServices;
|
this.context = context;
|
||||||
private final ClassDescriptorResolver classDescriptorResolver;
|
|
||||||
|
|
||||||
public TypeHierarchyResolver(JetSemanticServices semanticServices, BindingTrace trace) {
|
|
||||||
this.trace = trace;
|
|
||||||
this.semanticServices = semanticServices;
|
|
||||||
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TopDownAnalysisContext process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
|
public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
|
||||||
TopDownAnalysisContext context = new TopDownAnalysisContext();
|
collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes
|
||||||
return doProcess(outerScope, owner, declarations, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TopDownAnalysisContext processStandardLibraryNamespace(@NotNull JetScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) {
|
createTypeConstructors(); // create type constructors for classes and generic parameters
|
||||||
TopDownAnalysisContext context = new TopDownAnalysisContext();
|
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
|
||||||
context.getNamespaceScopes().put(namespace, standardLibraryNamespace.getMemberScope());
|
checkTypesInClassHeaders(); // Generic bounds and supertype lists
|
||||||
context.getNamespaceDescriptors().put(namespace, standardLibraryNamespace);
|
|
||||||
return doProcess(outerScope, standardLibraryNamespace, namespace.getDeclarations(), context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TopDownAnalysisContext doProcess(JetScope outerScope, NamespaceLike owner, List<JetDeclaration> declarations, TopDownAnalysisContext context) {
|
|
||||||
collectNamespacesAndClassifiers(outerScope, owner, declarations, context); // namespaceScopes, classes
|
|
||||||
|
|
||||||
createTypeConstructors(context); // create type constructors for classes and generic parameters
|
|
||||||
resolveTypesInClassHeaders(context); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
|
|
||||||
checkTypesInClassHeaders(context); // Generic bounds and supertype lists
|
|
||||||
return context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectNamespacesAndClassifiers(
|
private void collectNamespacesAndClassifiers(
|
||||||
@NotNull final JetScope outerScope,
|
@NotNull final JetScope outerScope,
|
||||||
@NotNull final NamespaceLike owner,
|
@NotNull final NamespaceLike owner,
|
||||||
@NotNull Collection<JetDeclaration> declarations,
|
@NotNull Collection<JetDeclaration> declarations) {
|
||||||
@NotNull final TopDownAnalysisContext context) {
|
|
||||||
for (JetDeclaration declaration : declarations) {
|
for (JetDeclaration declaration : declarations) {
|
||||||
declaration.accept(new JetVisitorVoid() {
|
declaration.accept(new JetVisitorVoid() {
|
||||||
@Override
|
@Override
|
||||||
@@ -72,26 +52,26 @@ public class TypeHierarchyResolver {
|
|||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
namespaceDescriptor.initialize(new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, trace.getErrorHandler()).setDebugName("Namespace member scope"));
|
namespaceDescriptor.initialize(new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, context.getTrace().getErrorHandler()).setDebugName("Namespace member scope"));
|
||||||
owner.addNamespace(namespaceDescriptor);
|
owner.addNamespace(namespaceDescriptor);
|
||||||
trace.record(BindingContext.NAMESPACE, namespace, namespaceDescriptor);
|
context.getTrace().record(BindingContext.NAMESPACE, namespace, namespaceDescriptor);
|
||||||
}
|
}
|
||||||
context.getNamespaceDescriptors().put(namespace, namespaceDescriptor);
|
context.getNamespaceDescriptors().put(namespace, namespaceDescriptor);
|
||||||
|
|
||||||
WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), trace.getErrorHandler());
|
WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), context.getTrace().getErrorHandler());
|
||||||
context.getNamespaceScopes().put(namespace, namespaceScope);
|
context.getNamespaceScopes().put(namespace, namespaceScope);
|
||||||
|
|
||||||
processImports(namespace, namespaceScope, outerScope);
|
processImports(namespace, namespaceScope, outerScope);
|
||||||
|
|
||||||
collectNamespacesAndClassifiers(namespaceScope, namespaceDescriptor, namespace.getDeclarations(), context);
|
collectNamespacesAndClassifiers(namespaceScope, namespaceDescriptor, namespace.getDeclarations());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitClass(JetClass klass) {
|
public void visitClass(JetClass klass) {
|
||||||
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope, getClassKind(klass));
|
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(context.getTrace(), owner, outerScope, getClassKind(klass));
|
||||||
|
|
||||||
if (klass.hasModifier(JetTokens.ENUM_KEYWORD)) {
|
if (klass.hasModifier(JetTokens.ENUM_KEYWORD)) {
|
||||||
MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor(trace, mutableClassDescriptor, outerScope, ClassKind.OBJECT);
|
MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor(context.getTrace(), mutableClassDescriptor, outerScope, ClassKind.OBJECT);
|
||||||
classObjectDescriptor.setName("class-object-for-" + klass.getName());
|
classObjectDescriptor.setName("class-object-for-" + klass.getName());
|
||||||
classObjectDescriptor.setModality(Modality.FINAL);
|
classObjectDescriptor.setModality(Modality.FINAL);
|
||||||
classObjectDescriptor.createTypeConstructor();
|
classObjectDescriptor.createTypeConstructor();
|
||||||
@@ -122,7 +102,7 @@ public class TypeHierarchyResolver {
|
|||||||
context.getClasses().put(enumEntry, classDescriptor);
|
context.getClasses().put(enumEntry, classDescriptor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, classObjectDescriptor, outerScope, ClassKind.CLASS); // TODO : Special kind for enum entry classes?
|
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(context.getTrace(), classObjectDescriptor, outerScope, ClassKind.CLASS); // TODO : Special kind for enum entry classes?
|
||||||
visitClassOrObject(
|
visitClassOrObject(
|
||||||
enumEntry,
|
enumEntry,
|
||||||
(Map) context.getClasses(),
|
(Map) context.getClasses(),
|
||||||
@@ -134,7 +114,7 @@ public class TypeHierarchyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private MutableClassDescriptor createClassDescriptorForObject(@NotNull JetClassOrObject declaration, @NotNull NamespaceLike owner) {
|
private MutableClassDescriptor createClassDescriptorForObject(@NotNull JetClassOrObject declaration, @NotNull NamespaceLike owner) {
|
||||||
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope, ClassKind.OBJECT) {
|
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(context.getTrace(), owner, outerScope, ClassKind.OBJECT) {
|
||||||
@Override
|
@Override
|
||||||
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
|
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
|
||||||
return ClassObjectStatus.NOT_ALLOWED;
|
return ClassObjectStatus.NOT_ALLOWED;
|
||||||
@@ -142,7 +122,7 @@ public class TypeHierarchyResolver {
|
|||||||
};
|
};
|
||||||
visitClassOrObject(declaration, (Map) context.getObjects(), owner, outerScope, mutableClassDescriptor);
|
visitClassOrObject(declaration, (Map) context.getObjects(), owner, outerScope, mutableClassDescriptor);
|
||||||
createPrimaryConstructor(mutableClassDescriptor);
|
createPrimaryConstructor(mutableClassDescriptor);
|
||||||
trace.record(BindingContext.CLASS, declaration, mutableClassDescriptor);
|
context.getTrace().record(BindingContext.CLASS, declaration, mutableClassDescriptor);
|
||||||
return mutableClassDescriptor;
|
return mutableClassDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,12 +141,12 @@ public class TypeHierarchyResolver {
|
|||||||
// declaringScopes.put((JetDeclaration) declaration, outerScope);
|
// declaringScopes.put((JetDeclaration) declaration, outerScope);
|
||||||
|
|
||||||
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
|
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
|
||||||
collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations(), context);
|
collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitTypedef(JetTypedef typedef) {
|
public void visitTypedef(JetTypedef typedef) {
|
||||||
trace.getErrorHandler().genericError(typedef.getNode(), "Unsupported [TopDownAnalyzer]");
|
context.getTrace().getErrorHandler().genericError(typedef.getNode(), "Unsupported [TopDownAnalyzer]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -176,10 +156,10 @@ public class TypeHierarchyResolver {
|
|||||||
NamespaceLike.ClassObjectStatus status = owner.setClassObjectDescriptor(createClassDescriptorForObject(objectDeclaration, owner));
|
NamespaceLike.ClassObjectStatus status = owner.setClassObjectDescriptor(createClassDescriptorForObject(objectDeclaration, owner));
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case DUPLICATE:
|
case DUPLICATE:
|
||||||
trace.getErrorHandler().genericError(classObject.getNode(), "Only one class object is allowed per class");
|
context.getTrace().getErrorHandler().genericError(classObject.getNode(), "Only one class object is allowed per class");
|
||||||
break;
|
break;
|
||||||
case NOT_ALLOWED:
|
case NOT_ALLOWED:
|
||||||
trace.getErrorHandler().genericError(classObject.getNode(), "A class object is not allowed here");
|
context.getTrace().getErrorHandler().genericError(classObject.getNode(), "A class object is not allowed here");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,13 +180,13 @@ public class TypeHierarchyResolver {
|
|||||||
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
|
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
|
||||||
for (JetImportDirective importDirective : importDirectives) {
|
for (JetImportDirective importDirective : importDirectives) {
|
||||||
if (importDirective.isAbsoluteInRootNamespace()) {
|
if (importDirective.isAbsoluteInRootNamespace()) {
|
||||||
trace.getErrorHandler().genericError(namespace.getNode(), "Unsupported by TDA"); // TODO
|
context.getTrace().getErrorHandler().genericError(namespace.getNode(), "Unsupported by TDA"); // TODO
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (importDirective.isAllUnder()) {
|
if (importDirective.isAllUnder()) {
|
||||||
JetExpression importedReference = importDirective.getImportedReference();
|
JetExpression importedReference = importDirective.getImportedReference();
|
||||||
if (importedReference != null) {
|
if (importedReference != null) {
|
||||||
JetTypeInferrer.Services typeInferrerServices = semanticServices.getTypeInferrerServices(trace, JetFlowInformationProvider.THROW_EXCEPTION);
|
JetTypeInferrer.Services typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace(), JetFlowInformationProvider.THROW_EXCEPTION);
|
||||||
JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference);
|
JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference);
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
namespaceScope.importScope(type.getMemberScope());
|
namespaceScope.importScope(type.getMemberScope());
|
||||||
@@ -220,7 +200,7 @@ public class TypeHierarchyResolver {
|
|||||||
JetExpression importedReference = importDirective.getImportedReference();
|
JetExpression importedReference = importDirective.getImportedReference();
|
||||||
if (importedReference instanceof JetDotQualifiedExpression) {
|
if (importedReference instanceof JetDotQualifiedExpression) {
|
||||||
JetDotQualifiedExpression reference = (JetDotQualifiedExpression) importedReference;
|
JetDotQualifiedExpression reference = (JetDotQualifiedExpression) importedReference;
|
||||||
JetType type = semanticServices.getTypeInferrerServices(trace, JetFlowInformationProvider.THROW_EXCEPTION).getTypeWithNamespaces(namespaceScope, reference.getReceiverExpression());
|
JetType type = context.getSemanticServices().getTypeInferrerServices(context.getTrace(), JetFlowInformationProvider.THROW_EXCEPTION).getTypeWithNamespaces(namespaceScope, reference.getReceiverExpression());
|
||||||
JetExpression selectorExpression = reference.getSelectorExpression();
|
JetExpression selectorExpression = reference.getSelectorExpression();
|
||||||
if (selectorExpression != null) {
|
if (selectorExpression != null) {
|
||||||
referenceExpression = (JetSimpleNameExpression) selectorExpression;
|
referenceExpression = (JetSimpleNameExpression) selectorExpression;
|
||||||
@@ -241,7 +221,7 @@ public class TypeHierarchyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (classifierDescriptor != null) {
|
if (classifierDescriptor != null) {
|
||||||
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor);
|
context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor);
|
||||||
|
|
||||||
String aliasName = importDirective.getAliasName();
|
String aliasName = importDirective.getAliasName();
|
||||||
String importedClassifierName = aliasName != null ? aliasName : classifierDescriptor.getName();
|
String importedClassifierName = aliasName != null ? aliasName : classifierDescriptor.getName();
|
||||||
@@ -251,11 +231,11 @@ public class TypeHierarchyResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTypeConstructors(TopDownAnalysisContext context) {
|
private void createTypeConstructors() {
|
||||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
||||||
JetClass jetClass = entry.getKey();
|
JetClass jetClass = entry.getKey();
|
||||||
MutableClassDescriptor descriptor = entry.getValue();
|
MutableClassDescriptor descriptor = entry.getValue();
|
||||||
classDescriptorResolver.resolveMutableClassDescriptor(jetClass, descriptor);
|
context.getClassDescriptorResolver().resolveMutableClassDescriptor(jetClass, descriptor);
|
||||||
descriptor.createTypeConstructor();
|
descriptor.createTypeConstructor();
|
||||||
}
|
}
|
||||||
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
|
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
|
||||||
@@ -265,30 +245,30 @@ public class TypeHierarchyResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveTypesInClassHeaders(TopDownAnalysisContext context) {
|
private void resolveTypesInClassHeaders() {
|
||||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
||||||
JetClass jetClass = entry.getKey();
|
JetClass jetClass = entry.getKey();
|
||||||
MutableClassDescriptor descriptor = entry.getValue();
|
MutableClassDescriptor descriptor = entry.getValue();
|
||||||
classDescriptorResolver.resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(), descriptor.getTypeConstructor().getParameters());
|
context.getClassDescriptorResolver().resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(), descriptor.getTypeConstructor().getParameters());
|
||||||
classDescriptorResolver.resolveSupertypes(jetClass, descriptor);
|
context.getClassDescriptorResolver().resolveSupertypes(jetClass, descriptor);
|
||||||
}
|
}
|
||||||
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
|
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
|
||||||
JetClassOrObject jetClass = entry.getKey();
|
JetClassOrObject jetClass = entry.getKey();
|
||||||
MutableClassDescriptor descriptor = entry.getValue();
|
MutableClassDescriptor descriptor = entry.getValue();
|
||||||
classDescriptorResolver.resolveSupertypes(jetClass, descriptor);
|
context.getClassDescriptorResolver().resolveSupertypes(jetClass, descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkTypesInClassHeaders(TopDownAnalysisContext context) {
|
private void checkTypesInClassHeaders() {
|
||||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
||||||
JetClass jetClass = entry.getKey();
|
JetClass jetClass = entry.getKey();
|
||||||
|
|
||||||
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
|
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
|
||||||
JetTypeReference typeReference = delegationSpecifier.getTypeReference();
|
JetTypeReference typeReference = delegationSpecifier.getTypeReference();
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
JetType type = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
|
JetType type = context.getTrace().getBindingContext().get(BindingContext.TYPE, typeReference);
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
classDescriptorResolver.checkBounds(typeReference, type);
|
context.getClassDescriptorResolver().checkBounds(typeReference, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -296,9 +276,9 @@ public class TypeHierarchyResolver {
|
|||||||
for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) {
|
for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) {
|
||||||
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
|
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
|
||||||
if (extendsBound != null) {
|
if (extendsBound != null) {
|
||||||
JetType type = trace.getBindingContext().get(BindingContext.TYPE, extendsBound);
|
JetType type = context.getTrace().getBindingContext().get(BindingContext.TYPE, extendsBound);
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
classDescriptorResolver.checkBounds(extendsBound, type);
|
context.getClassDescriptorResolver().checkBounds(extendsBound, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,9 +286,9 @@ public class TypeHierarchyResolver {
|
|||||||
for (JetTypeConstraint constraint : jetClass.getTypeConstaints()) {
|
for (JetTypeConstraint constraint : jetClass.getTypeConstaints()) {
|
||||||
JetTypeReference extendsBound = constraint.getBoundTypeReference();
|
JetTypeReference extendsBound = constraint.getBoundTypeReference();
|
||||||
if (extendsBound != null) {
|
if (extendsBound != null) {
|
||||||
JetType type = trace.getBindingContext().get(BindingContext.TYPE, extendsBound);
|
JetType type = context.getTrace().getBindingContext().get(BindingContext.TYPE, extendsBound);
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
classDescriptorResolver.checkBounds(extendsBound, type);
|
context.getClassDescriptorResolver().checkBounds(extendsBound, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user