diff --git a/idea/src/org/jetbrains/jet/lang/JetSemanticServices.java b/idea/src/org/jetbrains/jet/lang/JetSemanticServices.java index 121f666028b..2092d88e075 100644 --- a/idea/src/org/jetbrains/jet/lang/JetSemanticServices.java +++ b/idea/src/org/jetbrains/jet/lang/JetSemanticServices.java @@ -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); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java b/idea/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java index f614cc326a6..0fe670224a6 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java @@ -59,4 +59,5 @@ public class JetPropertyAccessor extends JetDeclaration implements JetDeclaratio public JetTypeReference getReturnTypeReference() { return findChildByClass(JetTypeReference.class); } + } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 59d942ef956..33337eaf0d3 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -27,4 +27,5 @@ public interface BindingContext { boolean isBlock(JetFunctionLiteralExpression expression); boolean isStatement(JetExpression expression); + boolean hasBackingField(PropertyDescriptor propertyDescriptor); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java b/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java index c7ee7f96d0e..d30ee81bcde 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java @@ -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 expressionTypes = new HashMap(); private final Map resolutionResults = new HashMap(); private final Map labelResolutionResults = new HashMap(); @@ -23,6 +23,7 @@ public class BindingTraceContext extends BindingTrace implements BindingContext private final Map constructorDeclarationsToDescriptors = new HashMap(); private final Set blocks = new HashSet(); private final Set statements = new HashSet(); + private final Set fieldMentionedInAccessor = new HashSet(); 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); + } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index 25be2a5c05b..d06e4c556b6 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -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 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 ? "" : name, - parameter.isMutable() ? type : null, + isMutable ? type : null, type); + propertyDescriptor.initialize(null, null); trace.recordDeclarationResolution(parameter, propertyDescriptor); return propertyDescriptor; } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 63c5aae5b84..45787dfa4bb 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -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 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); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index b8ee58cfa9d..f38e78711e3 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -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.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; diff --git a/idea/src/org/jetbrains/jet/lang/types/BindingTrace.java b/idea/src/org/jetbrains/jet/lang/types/BindingTrace.java index f11f5665945..a5b764f374d 100644 --- a/idea/src/org/jetbrains/jet/lang/types/BindingTrace.java +++ b/idea/src/org/jetbrains/jet/lang/types/BindingTrace.java @@ -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); } diff --git a/idea/src/org/jetbrains/jet/lang/types/BindingTraceAdapter.java b/idea/src/org/jetbrains/jet/lang/types/BindingTraceAdapter.java new file mode 100644 index 00000000000..30ddaca36f4 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/types/BindingTraceAdapter.java @@ -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); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java index 91c9300edc1..c6b0b47ce18 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -89,7 +89,7 @@ public class ErrorUtils { private static final JetType ERROR_PROPERTY_TYPE = createErrorType(""); private static final VariableDescriptor ERROR_PROPERTY = new PropertyDescriptor( - ERROR_CLASS, Collections.emptyList(), "", ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE); + ERROR_CLASS, Collections.emptyList(), new MemberModifiers(false, false, false), true, "", ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE); private static FunctionDescriptor createErrorFunction(List typeParameters, List positionedValueArgumentTypes) { FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.emptyList(), ""); diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 141d9d51709..a9760ad3436 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -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); - } } } diff --git a/idea/src/org/jetbrains/jet/lang/types/MemberDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/MemberDescriptor.java index 003a404274b..e53fa28713c 100644 --- a/idea/src/org/jetbrains/jet/lang/types/MemberDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/MemberDescriptor.java @@ -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(); } diff --git a/idea/src/org/jetbrains/jet/lang/types/MemberModifiers.java b/idea/src/org/jetbrains/jet/lang/types/MemberModifiers.java new file mode 100644 index 00000000000..fca3e8e0067 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/types/MemberModifiers.java @@ -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(); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyAccessorDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/PropertyAccessorDescriptor.java index d06eb547037..c4133f928e5 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertyAccessorDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertyAccessorDescriptor.java @@ -10,8 +10,15 @@ import java.util.List; */ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorImpl implements FunctionDescriptor { - protected PropertyAccessorDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List attributes, @NotNull String name) { + private final boolean hasBody; + + protected PropertyAccessorDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List attributes, @NotNull String name, boolean hasBody) { super(correspondingProperty.getContainingDeclaration(), attributes, name); + this.hasBody = hasBody; + } + + public boolean hasBody() { + return hasBody; } @NotNull diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java index 36053939463..b73338ebc2c 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java @@ -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 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 ); diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyGetterDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/PropertyGetterDescriptor.java index 4306294df2a..875d2999d89 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertyGetterDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertyGetterDescriptor.java @@ -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 attributes, @Nullable JetType returnType) { - super(correspondingProperty, attributes, "get-" + correspondingProperty.getName()); + public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List attributes, @Nullable JetType returnType, boolean hasBody) { + super(correspondingProperty, attributes, "get-" + correspondingProperty.getName(), hasBody); this.returnType = returnType == null ? correspondingProperty.getOutType() : returnType; } diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertySetterDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/PropertySetterDescriptor.java index d4094268d8e..bd8a134a608 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertySetterDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertySetterDescriptor.java @@ -12,8 +12,8 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor impleme private MutableValueParameterDescriptor parameter; - public PropertySetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List attributes) { - super(correspondingProperty, attributes, "set-" + correspondingProperty.getName()); + public PropertySetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List attributes, boolean hasBody) { + super(correspondingProperty, attributes, "set-" + correspondingProperty.getName(), hasBody); } public void initialize(@NotNull MutableValueParameterDescriptor parameter) {