diff --git a/idea/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index ae6f9387c57bec4ea4c242d1e5ad363d0e282c88..71404fa4bb76e04ca978985fa0148aadd7283923 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -7,7 +7,6 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; @@ -26,30 +25,23 @@ import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE; * @author abreslav */ public class BodyResolver { - private final JetSemanticServices semanticServices; - private final ClassDescriptorResolver classDescriptorResolver; - private final BindingTrace trace; + private final TopDownAnalysisContext context; + private final BindingTraceAdapter traceForConstructors; private final BindingTraceAdapter traceForMembers; - private final DeclarationResolver declarationResolver; - private final TopDownAnalysisContext context; - public BodyResolver(JetSemanticServices semanticServices, @NotNull BindingTrace trace, TopDownAnalysisContext context, DeclarationResolver declarationResolver) { - this.semanticServices = semanticServices; - this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace); - this.trace = trace; - this.declarationResolver = declarationResolver; + public BodyResolver(TopDownAnalysisContext context) { this.context = context; // This allows access to backing fields - this.traceForConstructors = new BindingTraceAdapter(trace).addHandler(BindingContext.REFERENCE_TARGET, new BindingTraceAdapter.RecordHandler() { + this.traceForConstructors = new BindingTraceAdapter(context.getTrace()).addHandler(BindingContext.REFERENCE_TARGET, new BindingTraceAdapter.RecordHandler() { @Override public void handleRecord(WritableSlice slice, JetReferenceExpression expression, DeclarationDescriptor descriptor) { if (expression instanceof JetSimpleNameExpression) { JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression; if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) { - if (!BodyResolver.this.trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) descriptor)) { - BodyResolver.this.trace.getErrorHandler().genericError(expression.getNode(), "This property does not have a backing field"); + if (!BodyResolver.this.context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) descriptor)) { + 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.traceForMembers = new BindingTraceAdapter(trace).addHandler(BindingContext.REFERENCE_TARGET, new BindingTraceAdapter.RecordHandler() { + this.traceForMembers = new BindingTraceAdapter(context.getTrace()).addHandler(BindingContext.REFERENCE_TARGET, new BindingTraceAdapter.RecordHandler() { @Override public void handleRecord(WritableSlice slice, JetReferenceExpression expression, DeclarationDescriptor descriptor) { if (descriptor instanceof PropertyDescriptor) { 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); } } @@ -99,7 +91,7 @@ public class BodyResolver { protected void bindOverridesInAClass(MutableClassDescriptor classDescriptor) { 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; JetModifierList modifierList = function.getModifierList(); ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null; @@ -109,19 +101,19 @@ public class BodyResolver { FunctionDescriptor overridden = findFunctionOverridableBy(declaredFunction, supertype); if (overridden != null) { 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; } ((FunctionDescriptorImpl) declaredFunction).addOverriddenFunction(overridden); } } 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(); if (!hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) { 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 " + overriddenMethod.getContainingDeclaration().getName() + " and needs 'override' modifier"); } @@ -132,7 +124,7 @@ public class BodyResolver { private FunctionDescriptor findFunctionOverridableBy(@NotNull FunctionDescriptor declaredFunction, @NotNull JetType supertype) { FunctionGroup functionGroup = supertype.getMemberScope().getFunctionGroup(declaredFunction.getName()); for (FunctionDescriptor functionDescriptor : functionGroup.getFunctionDescriptors()) { - if (FunctionDescriptorUtil.isOverridableBy(semanticServices.getTypeChecker(), functionDescriptor, declaredFunction).isSuccess()) { + if (FunctionDescriptorUtil.isOverridableBy(context.getSemanticServices().getTypeChecker(), functionDescriptor, declaredFunction).isSuccess()) { return functionDescriptor; } } @@ -145,10 +137,10 @@ public class BodyResolver { JetClass jetClass = entry.getKey(); if (classDescriptor.getUnsubstitutedPrimaryConstructor() == null) { 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(); 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"); } break; @@ -173,7 +165,7 @@ public class BodyResolver { final JetScope scopeForConstructor = primaryConstructor == null ? null : 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 supertypes = Maps.newLinkedHashMap(); JetVisitorVoid visitor = new JetVisitorVoid() { @@ -185,9 +177,9 @@ public class BodyResolver { @Override public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) { 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); JetExpression delegateExpression = specifier.getDelegateExpression(); if (delegateExpression != null) { @@ -195,8 +187,8 @@ public class BodyResolver { ? descriptor.getScopeForMemberResolution() : scopeForConstructor; JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE); - if (type != null && supertype != null && !semanticServices.getTypeChecker().isSubtypeOf(type, supertype)) { - trace.getErrorHandler().typeMismatch(delegateExpression, supertype, type); + if (type != null && supertype != null && !context.getSemanticServices().getTypeChecker().isSubtypeOf(type, supertype)) { + context.getTrace().getErrorHandler().typeMismatch(delegateExpression, supertype, type); } } } @@ -206,31 +198,31 @@ public class BodyResolver { JetValueArgumentList valueArgumentList = call.getValueArgumentList(); ASTNode node = valueArgumentList == null ? call.getNode() : valueArgumentList.getNode(); 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(); if (typeReference != 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) { recordSupertype(typeReference, supertype); ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor != null) { 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 { - recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference)); + recordSupertype(typeReference, context.getTrace().getBindingContext().get(BindingContext.TYPE, typeReference)); } } 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); 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"); } } @@ -239,14 +231,14 @@ public class BodyResolver { @Override public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) { JetTypeReference typeReference = specifier.getTypeReference(); - JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference); + JetType supertype = context.getTrace().getBindingContext().get(BindingContext.TYPE, typeReference); recordSupertype(typeReference, supertype); if (supertype != null) { ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor != null) { if (descriptor.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.getKind() != ClassKind.TRAIT) { 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 { classAppeared = true; @@ -297,16 +289,16 @@ public class BodyResolver { } } 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(); 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)) { - 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(); assert primaryConstructor != null; 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) { typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), NO_EXPECTED_TYPE); } } else { 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() { - for (Map.Entry entry : declarationResolver.getConstructors().entrySet()) { + for (Map.Entry entry : this.context.getConstructors().entrySet()) { JetDeclaration declaration = entry.getKey(); ConstructorDescriptor descriptor = entry.getValue(); @@ -356,17 +348,17 @@ public class BodyResolver { private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) { 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); assert containingClass != null : "This must be guaranteed by the parser"; 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 { List initializers = declaration.getInitializers(); 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 { initializers.get(0).accept(new JetVisitorVoid() { @@ -374,7 +366,7 @@ public class BodyResolver { public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) { JetTypeReference typeReference = call.getTypeReference(); 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 ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); - typeInferrerForInitializers.getCallResolver().resolveCall(trace, + typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(), functionInnerScope, null, call, NO_EXPECTED_TYPE); // call.getThisReference(), // classDescriptor, // classDescriptor.getDefaultType(), // call); -// trace.getErrorHandler().genericError(call.getNode(), "this-calls are not supported"); +// context.getTrace().getErrorHandler().genericError(call.getNode(), "this-calls are not supported"); } @Override 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 public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) { - trace.getErrorHandler().genericError(specifier.getNode(), "Constructor parameters required"); + context.getTrace().getErrorHandler().genericError(specifier.getNode(), "Constructor parameters required"); } @Override @@ -411,15 +403,15 @@ public class BodyResolver { }); for (int i = 1, initializersSize = initializers.size(); i < initializersSize; 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(); if (bodyExpression != null) { - classDescriptorResolver.computeFlowData(declaration, bodyExpression); - JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(declaration, bodyExpression); - JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, flowInformationProvider); + context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression); + JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression); + JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, flowInformationProvider); typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, JetStandardClasses.getUnitType()); } @@ -427,7 +419,7 @@ public class BodyResolver { @NotNull 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()) { constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor); } @@ -435,7 +427,7 @@ public class BodyResolver { constructorScope.setThisType(descriptor.getContainingDeclaration().getDefaultType()); 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) { constructorScope.addVariableDescriptor(valueParameterDescriptor); } @@ -455,16 +447,16 @@ public class BodyResolver { MutableClassDescriptor classDescriptor = entry.getValue(); for (JetProperty property : jetClass.getProperties()) { - final PropertyDescriptor propertyDescriptor = declarationResolver.getProperties().get(property); + final PropertyDescriptor propertyDescriptor = this.context.getProperties().get(property); assert propertyDescriptor != null; - JetScope declaringScope = declarationResolver.getDeclaringScopes().get(property); + JetScope declaringScope = this.context.getDeclaringScopes().get(property); JetExpression initializer = property.getInitializer(); if (initializer != null) { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); 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 { JetScope scope = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true); @@ -479,12 +471,12 @@ public class BodyResolver { } // Top-level properties & properties of objects - for (Map.Entry entry : declarationResolver.getProperties().entrySet()) { + for (Map.Entry entry : this.context.getProperties().entrySet()) { JetProperty property = entry.getKey(); if (processed.contains(property)) continue; final PropertyDescriptor propertyDescriptor = entry.getValue(); - JetScope declaringScope = declarationResolver.getDeclaringScopes().get(property); + JetScope declaringScope = this.context.getDeclaringScopes().get(property); JetExpression initializer = property.getInitializer(); if (initializer != null) { @@ -497,7 +489,7 @@ public class BodyResolver { } 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()) { result.addTypeParameterDescriptor(typeParameterDescriptor); } @@ -511,7 +503,7 @@ public class BodyResolver { private void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor, JetScope declaringScope) { 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); JetPropertyAccessor getter = property.getGetter(); @@ -535,39 +527,39 @@ public class BodyResolver { ASTNode nameNode = nameIdentifier == null ? property.getNode() : nameIdentifier.getNode(); if (propertyDescriptor.getModality() == Modality.ABSTRACT) { 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"); return; } 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()); return; } 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) { - 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) { - 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; } - boolean backingFieldRequired = trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor); + boolean backingFieldRequired = context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor); 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)) { - trace.getErrorHandler().genericError(nameNode, "Property must be initialized"); + context.getTrace().getErrorHandler().genericError(nameNode, "Property must be initialized"); } 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 { 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) { // This check may be considered redundant as long as $x is only accessible from accessors to $x 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) { - JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(property, initializer); // TODO : flow JET-15 - JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, flowInformationProvider); + JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15 + JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, flowInformationProvider); JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, NO_EXPECTED_TYPE); JetType expectedType = propertyDescriptor.getInType(); @@ -615,17 +607,17 @@ public class BodyResolver { expectedType = propertyDescriptor.getOutType(); } if (type != null && expectedType != null - && !semanticServices.getTypeChecker().isSubtypeOf(type, expectedType)) { - trace.getErrorHandler().typeMismatch(initializer, expectedType, type); + && !context.getSemanticServices().getTypeChecker().isSubtypeOf(type, expectedType)) { + context.getTrace().getErrorHandler().typeMismatch(initializer, expectedType, type); } } private void resolveFunctionBodies() { - for (Map.Entry entry : declarationResolver.getFunctions().entrySet()) { + for (Map.Entry entry : this.context.getFunctions().entrySet()) { JetDeclaration declaration = entry.getKey(); FunctionDescriptor descriptor = entry.getValue(); - JetScope declaringScope = declarationResolver.getDeclaringScopes().get(declaration); + JetScope declaringScope = this.context.getDeclaringScopes().get(declaration); assert declaringScope != null; resolveFunctionBody(traceForMembers, (JetNamedFunction) declaration, descriptor, declaringScope); @@ -642,8 +634,8 @@ public class BodyResolver { JetExpression bodyExpression = function.getBodyExpression(); if (bodyExpression != null) { - JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(function.asElement(), bodyExpression); - JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(trace, flowInformationProvider); + JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(function.asElement(), bodyExpression); + JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace, flowInformationProvider); typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor); } @@ -678,24 +670,24 @@ public class BodyResolver { boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS; boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT; 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) { - 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) { - 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) { - 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; } 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) { - trace.getErrorHandler().genericError(nameIdentifier.getNode(), "Function " + function.getName() + " must have body"); + context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Function " + function.getName() + " must have body"); } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java index e5dce792f49717b1ca20d698a20a55fb2a6da651..2eba49a2047ccf589011e2ddc225991c74f9eb8c 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java @@ -1,16 +1,12 @@ 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.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; import java.util.List; import java.util.Map; -import java.util.Set; import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION; @@ -18,22 +14,12 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION; * @author abreslav */ public class DeclarationResolver { - private final BindingTrace trace; private final AnnotationResolver annotationResolver; - private final ClassDescriptorResolver classDescriptorResolver; private final TopDownAnalysisContext context; - private final Map functions = Maps.newLinkedHashMap(); - private final Map constructors = Maps.newLinkedHashMap(); - private final Map properties = Maps.newLinkedHashMap(); - private final Set primaryConstructorParameterProperties = Sets.newHashSet(); - private final Map declaringScopes = Maps.newHashMap(); - - public DeclarationResolver(JetSemanticServices semanticServices, BindingTrace trace, TopDownAnalysisContext context) { - this.trace = trace; + public DeclarationResolver(TopDownAnalysisContext context) { this.context = context; - this.annotationResolver = new AnnotationResolver(semanticServices, trace); - this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace); + this.annotationResolver = new AnnotationResolver(context.getSemanticServices(), context.getTrace()); } public void process() { @@ -63,7 +49,7 @@ public class DeclarationResolver { if (modifierList != null) { List annotationEntries = modifierList.getAnnotationEntries(); for (JetAnnotationEntry annotationEntry : annotationEntries) { - AnnotationDescriptor annotationDescriptor = trace.get(ANNOTATION, annotationEntry); + AnnotationDescriptor annotationDescriptor = context.getTrace().get(ANNOTATION, annotationEntry); if (annotationDescriptor != null) { annotationResolver.resolveAnnotationStub(mutableClassDescriptor.getScopeForSupertypeResolution(), annotationEntry, annotationDescriptor); } @@ -105,30 +91,30 @@ public class DeclarationResolver { declaration.accept(new JetVisitorVoid() { @Override public void visitNamedFunction(JetNamedFunction function) { - FunctionDescriptorImpl functionDescriptor = classDescriptorResolver.resolveFunctionDescriptor(namespaceLike, scope, function); + FunctionDescriptorImpl functionDescriptor = context.getClassDescriptorResolver().resolveFunctionDescriptor(namespaceLike, scope, function); namespaceLike.addFunctionDescriptor(functionDescriptor); - functions.put(function, functionDescriptor); - declaringScopes.put(function, scope); + context.getFunctions().put(function, functionDescriptor); + context.getDeclaringScopes().put(function, scope); } @Override public void visitProperty(JetProperty property) { - PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(namespaceLike, scope, property); + PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolvePropertyDescriptor(namespaceLike, scope, property); namespaceLike.addPropertyDescriptor(propertyDescriptor); - properties.put(property, propertyDescriptor); - declaringScopes.put(property, scope); + context.getProperties().put(property, propertyDescriptor); + context.getDeclaringScopes().put(property, scope); } @Override 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); } @Override public void visitEnumEntry(JetEnumEntry enumEntry) { 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(); assert classObjectDescriptor != null; classObjectDescriptor.addPropertyDescriptor(propertyDescriptor); @@ -142,20 +128,20 @@ public class DeclarationResolver { if (!klass.hasPrimaryConstructor()) return; 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 JetScope memberScope = classDescriptor.getScopeForSupertypeResolution(); - ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructorDescriptor(memberScope, classDescriptor, klass); + ConstructorDescriptor constructorDescriptor = context.getClassDescriptorResolver().resolvePrimaryConstructorDescriptor(memberScope, classDescriptor, klass); for (JetParameter parameter : klass.getPrimaryConstructorParameters()) { - PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePrimaryConstructorParameterToAProperty( + PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolvePrimaryConstructorParameterToAProperty( classDescriptor, memberScope, parameter ); classDescriptor.addPropertyDescriptor(propertyDescriptor); - primaryConstructorParameterProperties.add(propertyDescriptor); + context.getPrimaryConstructorParameterProperties().add(propertyDescriptor); } if (constructorDescriptor != null) { classDescriptor.setPrimaryConstructor(constructorDescriptor); @@ -164,34 +150,15 @@ public class DeclarationResolver { private void processSecondaryConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) { 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, constructor); classDescriptor.addConstructor(constructorDescriptor); - constructors.put(constructor, constructorDescriptor); - declaringScopes.put(constructor, classDescriptor.getScopeForMemberLookup()); - } - - public Set getPrimaryConstructorParameterProperties() { - return primaryConstructorParameterProperties; - } - - public Map getConstructors() { - return constructors; + context.getConstructors().put(constructor, constructorDescriptor); + context.getDeclaringScopes().put(constructor, classDescriptor.getScopeForMemberLookup()); } - public Map getProperties() { - return properties; - } - - public Map getDeclaringScopes() { - return declaringScopes; - } - - public Map getFunctions() { - return functions; - } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java index 60acd494cf0d1465b5ed5da216824f490281f0a0..7fc9a95c4605d5fb5700ea7c65da5ae87e7c942a 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java @@ -1,24 +1,52 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Maps; -import org.jetbrains.jet.lang.descriptors.MutableClassDescriptor; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorImpl; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetNamespace; -import org.jetbrains.jet.lang.psi.JetObjectDeclaration; +import com.google.common.collect.Sets; +import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.*; import java.util.Map; +import java.util.Set; /** * @author abreslav */ -public class TopDownAnalysisContext { +/*package*/ class TopDownAnalysisContext { + + private final BindingTrace trace; + private final JetSemanticServices semanticServices; + private final ClassDescriptorResolver classDescriptorResolver; private final Map classes = Maps.newLinkedHashMap(); private final Map objects = Maps.newLinkedHashMap(); protected final Map namespaceScopes = Maps.newHashMap(); protected final Map namespaceDescriptors = Maps.newHashMap(); + private final Map functions = Maps.newLinkedHashMap(); + private final Map constructors = Maps.newLinkedHashMap(); + private final Map properties = Maps.newLinkedHashMap(); + private final Set primaryConstructorParameterProperties = Sets.newHashSet(); + private final Map 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 getClasses() { return classes; } @@ -35,5 +63,24 @@ public class TopDownAnalysisContext { return namespaceDescriptors; } + public Set getPrimaryConstructorParameterProperties() { + return primaryConstructorParameterProperties; + } + + public Map getConstructors() { + return constructors; + } + + public Map getProperties() { + return properties; + } + + public Map getDeclaringScopes() { + return declaringScopes; + } + + public Map getFunctions() { + return functions; + } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 3d4f1e1ef1061307308fce693b862a211871e77b..62fa5cf00087c22365aa6c6519229d6767e549d1 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -60,26 +60,22 @@ public class TopDownAnalyzer { @NotNull JetSemanticServices semanticServices, @NotNull BindingTrace trace, @NotNull JetScope outerScope, NamespaceLike owner, @NotNull List declarations) { - TypeHierarchyResolver typeHierarchyResolver = new TypeHierarchyResolver(semanticServices, trace); - TopDownAnalysisContext context = typeHierarchyResolver.process(outerScope, owner, declarations); - - DeclarationResolver declarationResolver = new DeclarationResolver(semanticServices, trace, context); - declarationResolver.process(); - - new BodyResolver(semanticServices, trace, context, declarationResolver).resolveBehaviorDeclarationBodies(); + TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace); + new TypeHierarchyResolver(context).process(outerScope, owner, declarations); + new DeclarationResolver(context).process(); + new BodyResolver(context).resolveBehaviorDeclarationBodies(); } public static void processStandardLibraryNamespace( @NotNull JetSemanticServices semanticServices, @NotNull BindingTrace trace, @NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) { - TypeHierarchyResolver typeHierarchyResolver = new TypeHierarchyResolver(semanticServices, trace); - TopDownAnalysisContext context = typeHierarchyResolver.processStandardLibraryNamespace(outerScope, standardLibraryNamespace, namespace); - - DeclarationResolver declarationResolver = new DeclarationResolver(semanticServices, trace, context); - declarationResolver.process(); - - BodyResolver bodyResolver = new BodyResolver(semanticServices, trace, context, declarationResolver) { + TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace); + context.getNamespaceScopes().put(namespace, standardLibraryNamespace.getMemberScope()); + context.getNamespaceDescriptors().put(namespace, standardLibraryNamespace); + new TypeHierarchyResolver(context).process(outerScope, standardLibraryNamespace, namespace.getDeclarations()); + new DeclarationResolver(context).process(); + BodyResolver bodyResolver = new BodyResolver(context) { @Override protected void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor, @Nullable ClassDescriptor classDescriptor) { } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 81deb8ebedc4af308361ae5576351954c1ab6508..9d27a9f3a5053cdded0c85bd041544ca76975bfe 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -1,7 +1,6 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -19,43 +18,24 @@ import java.util.Map; * @author abreslav */ public class TypeHierarchyResolver { + private final TopDownAnalysisContext context; - private final BindingTrace trace; - private final JetSemanticServices semanticServices; - 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 declarations) { - TopDownAnalysisContext context = new TopDownAnalysisContext(); - return doProcess(outerScope, owner, declarations, context); - } - - public TopDownAnalysisContext processStandardLibraryNamespace(@NotNull JetScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) { - TopDownAnalysisContext context = new TopDownAnalysisContext(); - context.getNamespaceScopes().put(namespace, standardLibraryNamespace.getMemberScope()); - context.getNamespaceDescriptors().put(namespace, standardLibraryNamespace); - return doProcess(outerScope, standardLibraryNamespace, namespace.getDeclarations(), context); + public TypeHierarchyResolver(TopDownAnalysisContext context) { + this.context = context; } - private TopDownAnalysisContext doProcess(JetScope outerScope, NamespaceLike owner, List declarations, TopDownAnalysisContext context) { - collectNamespacesAndClassifiers(outerScope, owner, declarations, context); // namespaceScopes, classes + public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List declarations) { + collectNamespacesAndClassifiers(outerScope, owner, declarations); // 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; + createTypeConstructors(); // create type constructors for classes and generic parameters + resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution) + checkTypesInClassHeaders(); // Generic bounds and supertype lists } private void collectNamespacesAndClassifiers( @NotNull final JetScope outerScope, @NotNull final NamespaceLike owner, - @NotNull Collection declarations, - @NotNull final TopDownAnalysisContext context) { + @NotNull Collection declarations) { for (JetDeclaration declaration : declarations) { declaration.accept(new JetVisitorVoid() { @Override @@ -72,26 +52,26 @@ public class TypeHierarchyResolver { Collections.emptyList(), // TODO 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); - trace.record(BindingContext.NAMESPACE, namespace, namespaceDescriptor); + context.getTrace().record(BindingContext.NAMESPACE, 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); processImports(namespace, namespaceScope, outerScope); - collectNamespacesAndClassifiers(namespaceScope, namespaceDescriptor, namespace.getDeclarations(), context); + collectNamespacesAndClassifiers(namespaceScope, namespaceDescriptor, namespace.getDeclarations()); } @Override 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)) { - 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.setModality(Modality.FINAL); classObjectDescriptor.createTypeConstructor(); @@ -122,7 +102,7 @@ public class TypeHierarchyResolver { context.getClasses().put(enumEntry, classDescriptor); } 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( enumEntry, (Map) context.getClasses(), @@ -134,7 +114,7 @@ public class TypeHierarchyResolver { } 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 public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { return ClassObjectStatus.NOT_ALLOWED; @@ -142,7 +122,7 @@ public class TypeHierarchyResolver { }; visitClassOrObject(declaration, (Map) context.getObjects(), owner, outerScope, mutableClassDescriptor); createPrimaryConstructor(mutableClassDescriptor); - trace.record(BindingContext.CLASS, declaration, mutableClassDescriptor); + context.getTrace().record(BindingContext.CLASS, declaration, mutableClassDescriptor); return mutableClassDescriptor; } @@ -161,12 +141,12 @@ public class TypeHierarchyResolver { // declaringScopes.put((JetDeclaration) declaration, outerScope); JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution(); - collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations(), context); + collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations()); } @Override public void visitTypedef(JetTypedef typedef) { - trace.getErrorHandler().genericError(typedef.getNode(), "Unsupported [TopDownAnalyzer]"); + context.getTrace().getErrorHandler().genericError(typedef.getNode(), "Unsupported [TopDownAnalyzer]"); } @Override @@ -176,10 +156,10 @@ public class TypeHierarchyResolver { NamespaceLike.ClassObjectStatus status = owner.setClassObjectDescriptor(createClassDescriptorForObject(objectDeclaration, owner)); switch (status) { 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; 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; } } @@ -200,13 +180,13 @@ public class TypeHierarchyResolver { List importDirectives = namespace.getImportDirectives(); for (JetImportDirective importDirective : importDirectives) { if (importDirective.isAbsoluteInRootNamespace()) { - trace.getErrorHandler().genericError(namespace.getNode(), "Unsupported by TDA"); // TODO + context.getTrace().getErrorHandler().genericError(namespace.getNode(), "Unsupported by TDA"); // TODO continue; } if (importDirective.isAllUnder()) { JetExpression importedReference = importDirective.getImportedReference(); 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); if (type != null) { namespaceScope.importScope(type.getMemberScope()); @@ -220,7 +200,7 @@ public class TypeHierarchyResolver { JetExpression importedReference = importDirective.getImportedReference(); if (importedReference instanceof JetDotQualifiedExpression) { 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(); if (selectorExpression != null) { referenceExpression = (JetSimpleNameExpression) selectorExpression; @@ -241,7 +221,7 @@ public class TypeHierarchyResolver { } if (classifierDescriptor != null) { - trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor); + context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor); String aliasName = importDirective.getAliasName(); 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 entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); MutableClassDescriptor descriptor = entry.getValue(); - classDescriptorResolver.resolveMutableClassDescriptor(jetClass, descriptor); + context.getClassDescriptorResolver().resolveMutableClassDescriptor(jetClass, descriptor); descriptor.createTypeConstructor(); } for (Map.Entry entry : context.getObjects().entrySet()) { @@ -265,30 +245,30 @@ public class TypeHierarchyResolver { } } - private void resolveTypesInClassHeaders(TopDownAnalysisContext context) { + private void resolveTypesInClassHeaders() { for (Map.Entry entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); MutableClassDescriptor descriptor = entry.getValue(); - classDescriptorResolver.resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(), descriptor.getTypeConstructor().getParameters()); - classDescriptorResolver.resolveSupertypes(jetClass, descriptor); + context.getClassDescriptorResolver().resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(), descriptor.getTypeConstructor().getParameters()); + context.getClassDescriptorResolver().resolveSupertypes(jetClass, descriptor); } for (Map.Entry entry : context.getObjects().entrySet()) { JetClassOrObject jetClass = entry.getKey(); MutableClassDescriptor descriptor = entry.getValue(); - classDescriptorResolver.resolveSupertypes(jetClass, descriptor); + context.getClassDescriptorResolver().resolveSupertypes(jetClass, descriptor); } } - private void checkTypesInClassHeaders(TopDownAnalysisContext context) { + private void checkTypesInClassHeaders() { for (Map.Entry entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) { JetTypeReference typeReference = delegationSpecifier.getTypeReference(); if (typeReference != null) { - JetType type = trace.getBindingContext().get(BindingContext.TYPE, typeReference); + JetType type = context.getTrace().getBindingContext().get(BindingContext.TYPE, typeReference); if (type != null) { - classDescriptorResolver.checkBounds(typeReference, type); + context.getClassDescriptorResolver().checkBounds(typeReference, type); } } } @@ -296,9 +276,9 @@ public class TypeHierarchyResolver { for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) { JetTypeReference extendsBound = jetTypeParameter.getExtendsBound(); if (extendsBound != null) { - JetType type = trace.getBindingContext().get(BindingContext.TYPE, extendsBound); + JetType type = context.getTrace().getBindingContext().get(BindingContext.TYPE, extendsBound); if (type != null) { - classDescriptorResolver.checkBounds(extendsBound, type); + context.getClassDescriptorResolver().checkBounds(extendsBound, type); } } } @@ -306,9 +286,9 @@ public class TypeHierarchyResolver { for (JetTypeConstraint constraint : jetClass.getTypeConstaints()) { JetTypeReference extendsBound = constraint.getBoundTypeReference(); if (extendsBound != null) { - JetType type = trace.getBindingContext().get(BindingContext.TYPE, extendsBound); + JetType type = context.getTrace().getBindingContext().get(BindingContext.TYPE, extendsBound); if (type != null) { - classDescriptorResolver.checkBounds(extendsBound, type); + context.getClassDescriptorResolver().checkBounds(extendsBound, type); } } }