Tests for hasBackingField

This commit is contained in:
Andrey Breslav
2011-04-20 16:17:46 +04:00
parent 311282b00c
commit 9add2b6114
9 changed files with 89 additions and 14 deletions
@@ -287,7 +287,7 @@ public class ExpressionCodegen extends JetVisitor {
for (JetElement statement : statements) {
if (statement instanceof JetProperty) {
final VariableDescriptor variableDescriptor = bindingContext.getPropertyDescriptor((JetProperty) statement);
final VariableDescriptor variableDescriptor = bindingContext.getVariableDescriptor((JetProperty) statement);
final Type type = typeMapper.mapType(variableDescriptor.getOutType());
myMap.enter(variableDescriptor, type.getSize());
}
@@ -309,7 +309,7 @@ public class ExpressionCodegen extends JetVisitor {
for (JetElement statement : statements) {
if (statement instanceof JetProperty) {
JetProperty var = (JetProperty) statement;
VariableDescriptor variableDescriptor = bindingContext.getPropertyDescriptor(var);
VariableDescriptor variableDescriptor = bindingContext.getVariableDescriptor(var);
Type outType = typeMapper.mapType(variableDescriptor.getOutType());
int index = myMap.leave(variableDescriptor);
@@ -923,7 +923,7 @@ public class ExpressionCodegen extends JetVisitor {
@Override
public void visitProperty(JetProperty property) {
VariableDescriptor variableDescriptor = bindingContext.getPropertyDescriptor(property);
VariableDescriptor variableDescriptor = bindingContext.getVariableDescriptor(property);
int index = myMap.getIndex(variableDescriptor);
assert index >= 0;
@@ -37,6 +37,12 @@ public class JetHighlighter extends SyntaxHighlighterBase {
SyntaxHighlighterColors.KEYWORD.getDefaultAttributes()
);
public static final TextAttributesKey JET_PROPERTY_WITH_BACKING_FIELD_IDENTIFIER = TextAttributesKey.createTextAttributesKey(
"JET.PROPERTY.WITH.BACKING.FIELD.IDENTIFIER",
// TODO: proper attributes
SyntaxHighlighterColors.NUMBER.getDefaultAttributes()
);
public static final TextAttributesKey JET_LABEL_IDENTIFIER = TextAttributesKey.createTextAttributesKey(
"JET.LABEL.IDENTIFIER",
// TODO: proper attributes
@@ -12,13 +12,14 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ErrorHandler;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.jet.lang.JetHighlighter;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.PropertyDescriptor;
import org.jetbrains.jet.lang.types.VariableDescriptor;
import java.util.Collection;
import java.util.HashSet;
@@ -77,6 +78,8 @@ public class JetPsiChecker implements Annotator {
holder.createErrorAnnotation(declarationPsiElement, "Redeclaration");
}
}
highlightBackingFields(holder, file, bindingContext);
}
catch (ProcessCanceledException e) {
throw e;
@@ -88,4 +91,26 @@ public class JetPsiChecker implements Annotator {
}
}
}
private void highlightBackingFields(final AnnotationHolder holder, JetFile file, final BindingContext bindingContext) {
file.acceptChildren(new JetVisitor() {
@Override
public void visitProperty(JetProperty property) {
VariableDescriptor propertyDescriptor = bindingContext.getVariableDescriptor(property);
if (propertyDescriptor instanceof PropertyDescriptor) {
if (bindingContext.hasBackingField((PropertyDescriptor) propertyDescriptor)) {
holder.createInfoAnnotation(
property.getNameIdentifier(),
"This property has a backing field")
.setTextAttributes(JetHighlighter.JET_PROPERTY_WITH_BACKING_FIELD_IDENTIFIER);
}
}
}
@Override
public void visitJetElement(JetElement elem) {
elem.acceptChildren(this);
}
});
}
}
@@ -12,7 +12,7 @@ public interface BindingContext {
ClassDescriptor getClassDescriptor(JetClass declaration);
TypeParameterDescriptor getTypeParameterDescriptor(JetTypeParameter declaration);
FunctionDescriptor getFunctionDescriptor(JetFunction declaration);
VariableDescriptor getPropertyDescriptor(JetProperty declaration);
VariableDescriptor getVariableDescriptor(JetProperty declaration);
VariableDescriptor getParameterDescriptor(JetParameter declaration);
JetType getExpressionType(JetExpression expression);
@@ -118,7 +118,7 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
}
@Override
public VariableDescriptor getPropertyDescriptor(JetProperty declaration) {
public VariableDescriptor getVariableDescriptor(JetProperty declaration) {
return (VariableDescriptor) declarationsToDescriptors.get(declaration);
}
@@ -301,9 +301,10 @@ public class TopDownAnalyzer {
super.recordReferenceResolution(expression, descriptor);
if (expression instanceof JetSimpleNameExpression) {
JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER
&& descriptor == propertyDescriptor) { // TODO : original?
recordFieldAccessFromAccessor(propertyDescriptor);
if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
if (descriptor == propertyDescriptor) { // TODO : original?
recordFieldAccessFromAccessor(propertyDescriptor);
}
}
}
}
@@ -320,7 +321,6 @@ public class TopDownAnalyzer {
if (setter != null && setterDescriptor != null) {
resolveFunctionBody(fieldAccessTrackingTrace, setter, setterDescriptor, declaringScope);
}
}
}
@@ -0,0 +1,31 @@
class Test {
<info>abstract</info> val x : Int
<info>abstract</info> val x1 : Int <info>get</info>
<info>abstract</info> val x2 : Int <info>get</info>() = 1
val <info>a</info> : Int
val <info>b</info> : Int <info>get</info>
val <info>c</info> = 1
val <info>c1</info> = 1
<info>get</info>
val c2 : Int
<info>get</info>() = 1
val c3 : Int
<info>get</info>() { return 1 }
val c4 : Int
<info>get</info>() { 1 }
<info>abstract</info> var y : Int
<info>abstract</info> var y1 : Int <info>get</info>
<info>abstract</info> var y2 : Int <info>set</info>
<info>abstract</info> var y3 : Int <info>set</info> <info>get</info>
<info>abstract</info> var y4 : Int <info>set</info> <info>get</info>() = 1
<info>abstract</info> var y5 : Int <info>set</info>(x) {} <info>get</info>() = 1
var <info>v</info> : Int
var <info>v1</info> : Int <info>get</info>
var <info>v2</info> : Int <info>get</info> <info>set</info>
var <info>v3</info> : Int <info>get</info>() = 1; <info>set</info>
var v4 : Int <info>get</info>() = 1; <info>set</info>(x){}
}
@@ -20,6 +20,7 @@ import java.util.List;
*/
public abstract class JetTestCaseBase extends LightDaemonAnalyzerTestCase {
private boolean checkInfos = false;
private String dataPath;
protected final String name;
@@ -28,6 +29,11 @@ public abstract class JetTestCaseBase extends LightDaemonAnalyzerTestCase {
this.name = name;
}
public final JetTestCaseBase setCheckInfos(boolean checkInfos) {
this.checkInfos = checkInfos;
return this;
}
public static Sdk jdkFromIdeaHome() {
return new JavaSdkImpl().createJdk("JDK", "idea/testData/mockJDK-1.7/jre", true);
}
@@ -57,7 +63,7 @@ public abstract class JetTestCaseBase extends LightDaemonAnalyzerTestCase {
@Override
protected void runTest() throws Throwable {
doTest(getTestFilePath(), true, false);
doTest(getTestFilePath(), true, checkInfos);
}
@NotNull
@@ -16,13 +16,20 @@ public class JetPsiCheckerTest extends JetTestCaseBase {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(JetTestCaseBase.suiteForDirectory(getTestDataPathBase(), "/checker/", true, new JetTestCaseBase.NamedTestFactory() {
suite.addTest(JetTestCaseBase.suiteForDirectory(getTestDataPathBase(), "/checker/", false, new JetTestCaseBase.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name) {
return new JetPsiCheckerTest(dataPath, name);
}
}));
suite.addTest(JetTestCaseBase.suiteForDirectory(getTestDataPathBase(), "/checker/infos/", false, new JetTestCaseBase.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name) {
return new JetPsiCheckerTest(dataPath, name).setCheckInfos(true);
}
}));
return suite;
}
}