hasBackingField() supported in the BindingContext
This commit is contained in:
@@ -45,7 +45,7 @@ public class JetSemanticServices {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetTypeInferrer getTypeInferrer(BindingTrace trace, JetFlowInformationProvider flowInformationProvider) {
|
||||
public JetTypeInferrer getTypeInferrer(@NotNull BindingTrace trace, @NotNull JetFlowInformationProvider flowInformationProvider) {
|
||||
return new JetTypeInferrer(trace, flowInformationProvider, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,4 +59,5 @@ public class JetPropertyAccessor extends JetDeclaration implements JetDeclaratio
|
||||
public JetTypeReference getReturnTypeReference() {
|
||||
return findChildByClass(JetTypeReference.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,4 +27,5 @@ public interface BindingContext {
|
||||
|
||||
boolean isBlock(JetFunctionLiteralExpression expression);
|
||||
boolean isStatement(JetExpression expression);
|
||||
boolean hasBackingField(PropertyDescriptor propertyDescriptor);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.Set;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class BindingTraceContext extends BindingTrace implements BindingContext {
|
||||
public class BindingTraceContext implements BindingContext, BindingTrace {
|
||||
private final Map<JetExpression, JetType> expressionTypes = new HashMap<JetExpression, JetType>();
|
||||
private final Map<JetReferenceExpression, DeclarationDescriptor> resolutionResults = new HashMap<JetReferenceExpression, DeclarationDescriptor>();
|
||||
private final Map<JetReferenceExpression, PsiElement> labelResolutionResults = new HashMap<JetReferenceExpression, PsiElement>();
|
||||
@@ -23,6 +23,7 @@ public class BindingTraceContext extends BindingTrace implements BindingContext
|
||||
private final Map<PsiElement, ConstructorDescriptor> constructorDeclarationsToDescriptors = new HashMap<PsiElement, ConstructorDescriptor>();
|
||||
private final Set<JetFunctionLiteralExpression> blocks = new HashSet<JetFunctionLiteralExpression>();
|
||||
private final Set<JetElement> statements = new HashSet<JetElement>();
|
||||
private final Set<PropertyDescriptor> fieldMentionedInAccessor = new HashSet<PropertyDescriptor>();
|
||||
|
||||
private JetScope toplevelScope;
|
||||
|
||||
@@ -70,6 +71,11 @@ public class BindingTraceContext extends BindingTrace implements BindingContext
|
||||
// assert oldValue == null || oldValue == value : key + ": " + oldValue + " and " + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordFieldAccessFromAccessor(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
fieldMentionedInAccessor.add(propertyDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordBlock(JetFunctionLiteralExpression expression) {
|
||||
blocks.add(expression);
|
||||
@@ -164,4 +170,24 @@ public class BindingTraceContext extends BindingTrace implements BindingContext
|
||||
public boolean isStatement(@NotNull JetExpression expression) {
|
||||
return statements.contains(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
if (propertyDescriptor.getModifiers().isAbstract()) return false;
|
||||
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
|
||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||
if (getter == null) {
|
||||
return true;
|
||||
}
|
||||
else if (propertyDescriptor.isVar() && setter == null) {
|
||||
return true;
|
||||
}
|
||||
else if (setter != null && !setter.hasBody()) {
|
||||
return true;
|
||||
}
|
||||
else if (!getter.hasBody()) {
|
||||
return true;
|
||||
}
|
||||
return fieldMentionedInAccessor.contains(propertyDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ import java.util.List;
|
||||
*/
|
||||
public class ClassDescriptorResolver {
|
||||
|
||||
private static final MemberModifiers DEFAULT_MODIFIERS = new MemberModifiers(false, false, false);
|
||||
|
||||
private final JetSemanticServices semanticServices;
|
||||
private final TypeResolver typeResolver;
|
||||
private final BindingTrace trace;
|
||||
@@ -321,23 +323,37 @@ public class ClassDescriptorResolver {
|
||||
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
|
||||
JetType type = getType(scope, property);
|
||||
|
||||
boolean isVar = property.isVar();
|
||||
JetModifierList modifierList = property.getModifierList();
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||
containingDeclaration,
|
||||
AttributeResolver.INSTANCE.resolveAttributes(property.getModifierList()),
|
||||
AttributeResolver.INSTANCE.resolveAttributes(modifierList),
|
||||
resolveModifiers(modifierList, DEFAULT_MODIFIERS), // TODO : default modifiers differ in different contexts
|
||||
isVar,
|
||||
JetPsiUtil.safeName(property.getName()),
|
||||
property.isVar() ? type : null,
|
||||
isVar ? type : null,
|
||||
type);
|
||||
|
||||
propertyDescriptor.initialize(
|
||||
resolvePropertyGetterDescriptor(scope, property, propertyDescriptor),
|
||||
resolvePropertySetterDescriptors(scope, property, propertyDescriptor));
|
||||
resolvePropertySetterDescriptor(scope, property, propertyDescriptor));
|
||||
|
||||
trace.recordDeclarationResolution(property, propertyDescriptor);
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private MemberModifiers resolveModifiers(@Nullable JetModifierList modifierList, @NotNull MemberModifiers defaultModifiers) {
|
||||
if (modifierList == null) return defaultModifiers;
|
||||
return new MemberModifiers(
|
||||
modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD),
|
||||
modifierList.hasModifier(JetTokens.VIRTUAL_KEYWORD),
|
||||
modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD)
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PropertySetterDescriptor resolvePropertySetterDescriptors(@NotNull JetScope scope, @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||
private PropertySetterDescriptor resolvePropertySetterDescriptor(@NotNull JetScope scope, @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||
JetPropertyAccessor setter = property.getSetter();
|
||||
if (setter != null && !property.isVar()) {
|
||||
semanticServices.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter");
|
||||
@@ -348,7 +364,7 @@ public class ClassDescriptorResolver {
|
||||
List<Attribute> attributes = AttributeResolver.INSTANCE.resolveAttributes(setter.getModifierList());
|
||||
JetParameter parameter = setter.getParameter();
|
||||
|
||||
setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, attributes);
|
||||
setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, attributes, setter.getBodyExpression() != null);
|
||||
if (parameter != null) {
|
||||
if (parameter.isRef()) {
|
||||
semanticServices.getErrorHandler().genericError(parameter.getRefNode(), "Setter parameters can not be 'ref'");
|
||||
@@ -399,7 +415,7 @@ public class ClassDescriptorResolver {
|
||||
returnType = typeResolver.resolveType(scope, returnTypeReference);
|
||||
}
|
||||
|
||||
getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, attributes, returnType);
|
||||
getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, attributes, returnType, getter.getBodyExpression() != null);
|
||||
trace.recordDeclarationResolution(getter, getterDescriptor);
|
||||
}
|
||||
return getterDescriptor;
|
||||
@@ -479,12 +495,17 @@ public class ClassDescriptorResolver {
|
||||
@NotNull JetParameter parameter) {
|
||||
JetType type = resolveParameterType(scope, parameter);
|
||||
String name = parameter.getName();
|
||||
VariableDescriptorImpl propertyDescriptor = new PropertyDescriptor(
|
||||
boolean isMutable = parameter.isMutable();
|
||||
JetModifierList modifierList = parameter.getModifierList();
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||
classDescriptor,
|
||||
AttributeResolver.INSTANCE.resolveAttributes(parameter.getModifierList()),
|
||||
AttributeResolver.INSTANCE.resolveAttributes(modifierList),
|
||||
resolveModifiers(modifierList, DEFAULT_MODIFIERS),
|
||||
isMutable,
|
||||
name == null ? "<no name>" : name,
|
||||
parameter.isMutable() ? type : null,
|
||||
isMutable ? type : null,
|
||||
type);
|
||||
propertyDescriptor.initialize(null, null);
|
||||
trace.recordDeclarationResolution(parameter, propertyDescriptor);
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -267,7 +268,7 @@ public class TopDownAnalyzer {
|
||||
JetExpression bodyExpression = declarationWithBody.getBodyExpression();
|
||||
|
||||
if (declaration instanceof JetFunction) {
|
||||
resolveFunctionBody((JetFunction) declaration, (FunctionDescriptorImpl) descriptor, declaringScope);
|
||||
resolveFunctionBody(trace, (JetFunction) declaration, (FunctionDescriptorImpl) descriptor, declaringScope);
|
||||
}
|
||||
else if (declaration instanceof JetConstructor) {
|
||||
if (bodyExpression != null) {
|
||||
@@ -283,7 +284,7 @@ public class TopDownAnalyzer {
|
||||
|
||||
for (Map.Entry<JetProperty, PropertyDescriptor> entry : properties.entrySet()) {
|
||||
JetProperty declaration = entry.getKey();
|
||||
PropertyDescriptor descriptor = entry.getValue();
|
||||
final PropertyDescriptor propertyDescriptor = entry.getValue();
|
||||
WritableScope declaringScope = declaringScopes.get(declaration);
|
||||
|
||||
JetExpression initializer = declaration.getInitializer();
|
||||
@@ -294,22 +295,40 @@ public class TopDownAnalyzer {
|
||||
// TODO : check type
|
||||
}
|
||||
|
||||
BindingTraceAdapter fieldAccessTrackingTrace = new BindingTraceAdapter(trace) {
|
||||
@Override
|
||||
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
|
||||
super.recordReferenceResolution(expression, descriptor);
|
||||
if (expression instanceof JetSimpleNameExpression) {
|
||||
JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
|
||||
if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER
|
||||
&& descriptor == propertyDescriptor) { // TODO : original?
|
||||
recordFieldAccessFromAccessor(propertyDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
JetPropertyAccessor getter = declaration.getGetter();
|
||||
PropertyGetterDescriptor getterDescriptor = descriptor.getGetter();
|
||||
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
|
||||
if (getter != null && getterDescriptor != null) {
|
||||
resolveFunctionBody(getter, getterDescriptor, declaringScope);
|
||||
resolveFunctionBody(fieldAccessTrackingTrace, getter, getterDescriptor, declaringScope);
|
||||
}
|
||||
|
||||
JetPropertyAccessor setter = declaration.getSetter();
|
||||
PropertySetterDescriptor setterDescriptor = descriptor.getSetter();
|
||||
PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
|
||||
if (setter != null && setterDescriptor != null) {
|
||||
resolveFunctionBody(setter, setterDescriptor, declaringScope);
|
||||
resolveFunctionBody(fieldAccessTrackingTrace, setter, setterDescriptor, declaringScope);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveFunctionBody(@NotNull JetDeclarationWithBody function, @NotNull MutableFunctionDescriptor functionDescriptor, @NotNull WritableScope declaringScope) {
|
||||
private void resolveFunctionBody(
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetDeclarationWithBody function,
|
||||
@NotNull MutableFunctionDescriptor functionDescriptor,
|
||||
@NotNull WritableScope declaringScope) {
|
||||
JetExpression bodyExpression = function.getBodyExpression();
|
||||
if (bodyExpression != null) {
|
||||
JetFlowInformationProvider flowInformationProvider = computeFlowData(function.asElement(), bodyExpression);
|
||||
|
||||
@@ -62,11 +62,14 @@ public class JavaClassMembersScope implements JetScope {
|
||||
}
|
||||
|
||||
JetType type = semanticServices.getTypeTransformer().transform(field.getType());
|
||||
VariableDescriptorImpl propertyDescriptor = new PropertyDescriptor(
|
||||
boolean isFinal = field.hasModifierProperty(PsiModifier.FINAL);
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||
containingDeclaration,
|
||||
Collections.<Attribute>emptyList(),
|
||||
new MemberModifiers(false, false, false),
|
||||
!isFinal,
|
||||
field.getName(),
|
||||
field.hasModifierProperty(PsiModifier.FINAL) ? null : type,
|
||||
isFinal ? null : type,
|
||||
type);
|
||||
semanticServices.getTrace().recordDeclarationResolution(field, propertyDescriptor);
|
||||
return propertyDescriptor;
|
||||
|
||||
@@ -8,45 +8,73 @@ import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class BindingTrace {
|
||||
public static final BindingTrace DUMMY = new BindingTrace();
|
||||
public interface BindingTrace {
|
||||
public static final BindingTrace DUMMY = new BindingTrace() {
|
||||
|
||||
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||
}
|
||||
@Override
|
||||
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||
}
|
||||
|
||||
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
|
||||
@Override
|
||||
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element) {
|
||||
}
|
||||
|
||||
public void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element) {
|
||||
@Override
|
||||
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull JetType type) {
|
||||
}
|
||||
|
||||
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||
@Override
|
||||
public void setToplevelScope(JetScope toplevelScope) {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void recordBlock(JetFunctionLiteralExpression expression) {
|
||||
}
|
||||
|
||||
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull JetType type) {
|
||||
@Override
|
||||
public void recordStatement(@NotNull JetElement statement) {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void removeStatementRecord(@NotNull JetElement statement) {
|
||||
}
|
||||
|
||||
public void setToplevelScope(JetScope toplevelScope) {
|
||||
@Override
|
||||
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void recordFieldAccessFromAccessor(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
}
|
||||
};
|
||||
|
||||
public void recordBlock(JetFunctionLiteralExpression expression) {
|
||||
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type);
|
||||
|
||||
}
|
||||
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor);
|
||||
|
||||
public void recordStatement(@NotNull JetElement statement) {
|
||||
public void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element);
|
||||
|
||||
}
|
||||
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor);
|
||||
|
||||
public void removeStatementRecord(@NotNull JetElement statement) {
|
||||
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull JetType type);
|
||||
|
||||
}
|
||||
public void setToplevelScope(JetScope toplevelScope);
|
||||
|
||||
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
|
||||
public void recordBlock(JetFunctionLiteralExpression expression);
|
||||
|
||||
}
|
||||
public void recordStatement(@NotNull JetElement statement);
|
||||
|
||||
public void removeStatementRecord(@NotNull JetElement statement);
|
||||
|
||||
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression);
|
||||
|
||||
public void recordFieldAccessFromAccessor(@NotNull PropertyDescriptor propertyDescriptor);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class BindingTraceAdapter implements BindingTrace {
|
||||
private final BindingTrace originalTrace;
|
||||
|
||||
public BindingTraceAdapter(BindingTrace originalTrace) {
|
||||
this.originalTrace = originalTrace;
|
||||
}
|
||||
|
||||
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||
originalTrace.recordExpressionType(expression, type);
|
||||
}
|
||||
|
||||
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
|
||||
originalTrace.recordReferenceResolution(expression, descriptor);
|
||||
}
|
||||
|
||||
public void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element) {
|
||||
originalTrace.recordLabelResolution(expression, element);
|
||||
}
|
||||
|
||||
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||
originalTrace.recordDeclarationResolution(declaration, descriptor);
|
||||
}
|
||||
|
||||
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull JetType type) {
|
||||
originalTrace.recordTypeResolution(typeReference, type);
|
||||
}
|
||||
|
||||
public void setToplevelScope(JetScope toplevelScope) {
|
||||
originalTrace.setToplevelScope(toplevelScope);
|
||||
}
|
||||
|
||||
public void recordBlock(JetFunctionLiteralExpression expression) {
|
||||
originalTrace.recordBlock(expression);
|
||||
}
|
||||
|
||||
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
|
||||
originalTrace.removeReferenceResolution(referenceExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordStatement(@NotNull JetElement statement) {
|
||||
originalTrace.recordStatement(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordFieldAccessFromAccessor(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
originalTrace.recordFieldAccessFromAccessor(propertyDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeStatementRecord(@NotNull JetElement statement) {
|
||||
originalTrace.removeStatementRecord(statement);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public class ErrorUtils {
|
||||
|
||||
private static final JetType ERROR_PROPERTY_TYPE = createErrorType("<ERROR PROPERTY TYPE>");
|
||||
private static final VariableDescriptor ERROR_PROPERTY = new PropertyDescriptor(
|
||||
ERROR_CLASS, Collections.<Attribute>emptyList(), "<ERROR PROPERTY>", ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE);
|
||||
ERROR_CLASS, Collections.<Attribute>emptyList(), new MemberModifiers(false, false, false), true, "<ERROR PROPERTY>", ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE);
|
||||
|
||||
private static FunctionDescriptor createErrorFunction(List<TypeParameterDescriptor> typeParameters, List<JetType> positionedValueArgumentTypes) {
|
||||
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.<Attribute>emptyList(), "<ERROR FUNCTION>");
|
||||
|
||||
@@ -440,8 +440,10 @@ public class JetTypeInferrer {
|
||||
public void visitSimpleNameExpression(JetSimpleNameExpression expression) {
|
||||
// TODO : other members
|
||||
// TODO : type substitutions???
|
||||
if (expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
|
||||
PropertyDescriptor property = scope.getPropertyByFieldReference(expression.getReferencedName());
|
||||
String referencedName = expression.getReferencedName();
|
||||
if (expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER
|
||||
&& referencedName != null) {
|
||||
PropertyDescriptor property = scope.getPropertyByFieldReference(referencedName);
|
||||
if (property == null) {
|
||||
semanticServices.getErrorHandler().unresolvedReference(expression);
|
||||
}
|
||||
@@ -452,7 +454,6 @@ public class JetTypeInferrer {
|
||||
}
|
||||
else {
|
||||
assert expression.getReferencedNameElementType() == JetTokens.IDENTIFIER;
|
||||
String referencedName = expression.getReferencedName();
|
||||
if (referencedName != null) {
|
||||
VariableDescriptor variable = scope.getVariable(referencedName);
|
||||
if (variable != null) {
|
||||
@@ -1566,54 +1567,16 @@ public class JetTypeInferrer {
|
||||
}
|
||||
}
|
||||
|
||||
private class CachedBindingTrace extends BindingTrace {
|
||||
private final BindingTrace originalTrace;
|
||||
private class CachedBindingTrace extends BindingTraceAdapter {
|
||||
|
||||
public CachedBindingTrace(BindingTrace originalTrace) {
|
||||
this.originalTrace = originalTrace;
|
||||
super(originalTrace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||
originalTrace.recordExpressionType(expression, type);
|
||||
super.recordExpressionType(expression, type);
|
||||
typeCache.put(expression, type);
|
||||
}
|
||||
|
||||
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
|
||||
originalTrace.recordReferenceResolution(expression, descriptor);
|
||||
}
|
||||
|
||||
public void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element) {
|
||||
originalTrace.recordLabelResolution(expression, element);
|
||||
}
|
||||
|
||||
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||
originalTrace.recordDeclarationResolution(declaration, descriptor);
|
||||
}
|
||||
|
||||
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull JetType type) {
|
||||
originalTrace.recordTypeResolution(typeReference, type);
|
||||
}
|
||||
|
||||
public void setToplevelScope(JetScope toplevelScope) {
|
||||
originalTrace.setToplevelScope(toplevelScope);
|
||||
}
|
||||
|
||||
public void recordBlock(JetFunctionLiteralExpression expression) {
|
||||
originalTrace.recordBlock(expression);
|
||||
}
|
||||
|
||||
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
|
||||
originalTrace.removeReferenceResolution(referenceExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordStatement(@NotNull JetElement statement) {
|
||||
originalTrace.recordStatement(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeStatementRecord(@NotNull JetElement statement) {
|
||||
originalTrace.removeStatementRecord(statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface MemberDescriptor {
|
||||
boolean isAbstract();
|
||||
boolean isVirtual();
|
||||
boolean isOverride();
|
||||
@NotNull
|
||||
MemberModifiers getModifiers();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class MemberModifiers {
|
||||
|
||||
private final boolean isAbstract;
|
||||
private final boolean isVirtual;
|
||||
private final boolean isOverride;
|
||||
|
||||
public MemberModifiers(boolean isAbstract, boolean isVirtual, boolean isOverride) {
|
||||
this.isAbstract = isAbstract;
|
||||
this.isVirtual = isVirtual;
|
||||
this.isOverride = isOverride;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return isAbstract;
|
||||
}
|
||||
|
||||
public boolean isVirtual() {
|
||||
return isVirtual;
|
||||
}
|
||||
|
||||
public boolean isOverride() {
|
||||
return isOverride;
|
||||
}
|
||||
|
||||
public boolean isOverridable() {
|
||||
return isAbstract() || isVirtual() || isOverride();
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,15 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorImpl implements FunctionDescriptor {
|
||||
|
||||
protected PropertyAccessorDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Attribute> attributes, @NotNull String name) {
|
||||
private final boolean hasBody;
|
||||
|
||||
protected PropertyAccessorDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Attribute> attributes, @NotNull String name, boolean hasBody) {
|
||||
super(correspondingProperty.getContainingDeclaration(), attributes, name);
|
||||
this.hasBody = hasBody;
|
||||
}
|
||||
|
||||
public boolean hasBody() {
|
||||
return hasBody;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -8,19 +8,40 @@ import java.util.List;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class PropertyDescriptor extends VariableDescriptorImpl {
|
||||
public class PropertyDescriptor extends VariableDescriptorImpl implements MemberDescriptor {
|
||||
|
||||
private final MemberModifiers memberModifiers;
|
||||
private final boolean isVar;
|
||||
private PropertyGetterDescriptor getter;
|
||||
private PropertySetterDescriptor setter;
|
||||
private boolean hasBackingField;
|
||||
|
||||
public PropertyDescriptor(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@NotNull List<Attribute> attributes,
|
||||
@NotNull MemberModifiers memberModifiers,
|
||||
boolean isVar,
|
||||
@NotNull String name,
|
||||
@Nullable JetType inType,
|
||||
@Nullable JetType outType) {
|
||||
super(containingDeclaration, attributes, name, inType, outType);
|
||||
assert !isVar || inType != null;
|
||||
assert outType != null;
|
||||
this.isVar = isVar;
|
||||
this.memberModifiers = memberModifiers;
|
||||
}
|
||||
|
||||
public PropertyDescriptor(
|
||||
@NotNull PropertyDescriptor original,
|
||||
@Nullable JetType inType,
|
||||
@Nullable JetType outType) {
|
||||
this(
|
||||
original.getContainingDeclaration(),
|
||||
original.getAttributes(), // TODO : substitute?
|
||||
original.getModifiers(),
|
||||
original.isVar,
|
||||
original.getName(),
|
||||
inType,
|
||||
outType);
|
||||
}
|
||||
|
||||
public void initialize(@Nullable PropertyGetterDescriptor getter, @Nullable PropertySetterDescriptor setter) {
|
||||
@@ -28,6 +49,16 @@ public class PropertyDescriptor extends VariableDescriptorImpl {
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
public boolean isVar() {
|
||||
return isVar;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public MemberModifiers getModifiers() {
|
||||
return memberModifiers;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PropertyGetterDescriptor getGetter() {
|
||||
return getter;
|
||||
@@ -38,23 +69,18 @@ public class PropertyDescriptor extends VariableDescriptorImpl {
|
||||
return setter;
|
||||
}
|
||||
|
||||
public boolean hasBackingFiled() {
|
||||
return hasBackingField;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VariableDescriptor substitute(TypeSubstitutor substitutor) {
|
||||
JetType originalInType = getInType();
|
||||
JetType inType = originalInType == null ? null : substitutor.substitute(originalInType, Variance.IN_VARIANCE);
|
||||
JetType outType = substitutor.substitute(getOutType(), Variance.OUT_VARIANCE);
|
||||
JetType originalOutType = getOutType();
|
||||
JetType outType = originalOutType == null ? null : substitutor.substitute(originalOutType, Variance.OUT_VARIANCE);
|
||||
if (inType == null && outType == null) {
|
||||
return null; // TODO : tell the user that the property was projected out
|
||||
}
|
||||
return new PropertyDescriptor(
|
||||
getContainingDeclaration(),
|
||||
getAttributes(), // TODO
|
||||
getName(),
|
||||
this,
|
||||
inType,
|
||||
outType
|
||||
);
|
||||
|
||||
@@ -12,8 +12,8 @@ import java.util.List;
|
||||
public class PropertyGetterDescriptor extends PropertyAccessorDescriptor implements MutableFunctionDescriptor {
|
||||
private JetType returnType;
|
||||
|
||||
public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Attribute> attributes, @Nullable JetType returnType) {
|
||||
super(correspondingProperty, attributes, "get-" + correspondingProperty.getName());
|
||||
public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Attribute> attributes, @Nullable JetType returnType, boolean hasBody) {
|
||||
super(correspondingProperty, attributes, "get-" + correspondingProperty.getName(), hasBody);
|
||||
this.returnType = returnType == null ? correspondingProperty.getOutType() : returnType;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor impleme
|
||||
|
||||
private MutableValueParameterDescriptor parameter;
|
||||
|
||||
public PropertySetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Attribute> attributes) {
|
||||
super(correspondingProperty, attributes, "set-" + correspondingProperty.getName());
|
||||
public PropertySetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Attribute> attributes, boolean hasBody) {
|
||||
super(correspondingProperty, attributes, "set-" + correspondingProperty.getName(), hasBody);
|
||||
}
|
||||
|
||||
public void initialize(@NotNull MutableValueParameterDescriptor parameter) {
|
||||
|
||||
Reference in New Issue
Block a user