diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index 9df453a71ec..052dec313e7 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -34,6 +34,7 @@ public interface JetNodeTypes { // TODO: Not sure if we really need separate PSI nodes for the class parameters? JetNodeType PRIMARY_CONSTRUCTOR_PARAMETERS_LIST = new JetNodeType("PRIMARY_CONSTRUCTOR_PARAMETERS_LIST", JetParameterList.class); JetNodeType PRIMARY_CONSTRUCTOR_PARAMETER = new JetNodeType("PRIMARY_CONSTRUCTOR_PARAMETER", JetParameter.class); + JetNodeType CLASS_BODY = new JetNodeType("CLASS_BODY", JetClassBody.class); JetNodeType IMPORT_DIRECTIVE = new JetNodeType("IMPORT_DIRECTIVE", JetImportDirective.class); JetNodeType IMPORTED = new JetNodeType("IMPORTED"); // TODO: ??? diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetArgument.java b/idea/src/org/jetbrains/jet/lang/psi/JetArgument.java index 7b39b0810b0..9d4bf669d36 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetArgument.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetArgument.java @@ -17,11 +17,12 @@ public class JetArgument extends JetElement { visitor.visitArgument(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetExpression getArgumentExpression() { return findChildByClass(JetExpression.class); } + @Nullable public String getArgumentName() { ASTNode firstChildNode = getNode().getFirstChildNode(); return firstChildNode.getElementType() == JetTokens.IDENTIFIER ? firstChildNode.getText() : null; diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetAttribute.java b/idea/src/org/jetbrains/jet/lang/psi/JetAttribute.java index 89e19875349..b3dd2d19b96 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetAttribute.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetAttribute.java @@ -21,7 +21,7 @@ public class JetAttribute extends JetElement { visitor.visitAttribute(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetTypeReference getTypeReference() { return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java index 523c440ed95..b18da975842 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java @@ -27,7 +27,7 @@ public class JetBinaryExpression extends JetExpression { return left; } - @Nullable + @Nullable(IF_NOT_PARSED) public JetExpression getRight() { ASTNode node = getOperationTokenNode(); while (node != null) { @@ -48,7 +48,7 @@ public class JetBinaryExpression extends JetExpression { return operationNode; } - @Nullable + @NotNull public JetToken getOperationSign() { return (JetToken) getOperationTokenNode().getElementType(); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java index f3107c81625..dc2e5416e90 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java @@ -27,7 +27,7 @@ public class JetBinaryExpressionWithTypeRHS extends JetExpression { return left; } - @Nullable + @Nullable(IF_NOT_PARSED) public JetTypeReference getRight() { ASTNode node = getOperationTokenNode(); while (node != null) { @@ -48,7 +48,7 @@ public class JetBinaryExpressionWithTypeRHS extends JetExpression { return operationNode; } - @Nullable + @NotNull public JetToken getOperationSign() { return (JetToken) getOperationTokenNode().getElementType(); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetCatchSection.java b/idea/src/org/jetbrains/jet/lang/psi/JetCatchSection.java index c8256b0f7ab..9ae812262f1 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetCatchSection.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetCatchSection.java @@ -20,12 +20,12 @@ public class JetCatchSection extends JetElement { visitor.visitCatchSection(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetParameterList getParameterList() { return (JetParameterList) findChildByType(JetNodeTypes.VALUE_PARAMETER_LIST); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetParameter getCatchParameter() { JetParameterList list = getParameterList(); if (list == null) return null; @@ -34,6 +34,7 @@ public class JetCatchSection extends JetElement { } + @Nullable(IF_NOT_PARSED) public JetExpression getCatchBody() { return findChildByClass(JetExpression.class); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java b/idea/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java index 41ba77f8172..c3eeb0d3b2b 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java @@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author max @@ -17,8 +16,10 @@ public class JetClassInitializer extends JetDeclaration { visitor.visitAnonymousInitializer(this); } - @Nullable + @NotNull public JetExpression getBody() { - return findChildByClass(JetExpression.class); + JetExpression body = findChildByClass(JetExpression.class); + assert body != null; + return body; } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetConstructor.java b/idea/src/org/jetbrains/jet/lang/psi/JetConstructor.java index 9e35c077c6f..f1d12827dd8 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetConstructor.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetConstructor.java @@ -21,7 +21,7 @@ public class JetConstructor extends JetDeclaration { visitor.visitConstructor(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetParameterList getParameterList() { return (JetParameterList) findChildByType(JetNodeTypes.VALUE_PARAMETER_LIST); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetDecomposer.java b/idea/src/org/jetbrains/jet/lang/psi/JetDecomposer.java index 13b383ed13d..7d87d4ed22b 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetDecomposer.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetDecomposer.java @@ -21,7 +21,7 @@ public class JetDecomposer extends JetNamedDeclaration { visitor.visitDecomposer(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetDecomposerPropertyList getPropertyList() { return (JetDecomposerPropertyList) findChildByType(JetNodeTypes.DECOMPOSER_PROPERTY_LIST); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetDoWhileExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetDoWhileExpression.java index 638ff95ef33..5263b926911 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetDoWhileExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetDoWhileExpression.java @@ -18,11 +18,12 @@ public class JetDoWhileExpression extends JetExpression { visitor.visitDoWhileExpression(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetExpression getCondition() { return findExpressionUnder(JetNodeTypes.CONDITION); } + @Nullable(IF_NOT_PARSED) public JetExpression getBody() { return findExpressionUnder(JetNodeTypes.BODY); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetElement.java b/idea/src/org/jetbrains/jet/lang/psi/JetElement.java index b4bd3734fc5..8ec901ce218 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetElement.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetElement.java @@ -15,6 +15,8 @@ public class JetElement extends ASTWrapperPsiElement { super(node); } + protected static final String IF_NOT_PARSED = "Returns null if has parsing error"; + @NotNull @Override public Language getLanguage() { diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetExtension.java b/idea/src/org/jetbrains/jet/lang/psi/JetExtension.java index 455353146af..9ccf90dba1e 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetExtension.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetExtension.java @@ -21,6 +21,7 @@ public class JetExtension extends JetTypeParameterListOwner { visitor.visitExtension(this); } + @NotNull public List getDeclarations() { JetClassBody body = (JetClassBody) findChildByType(JetNodeTypes.CLASS_BODY); if (body == null) return Collections.emptyList(); @@ -28,7 +29,7 @@ public class JetExtension extends JetTypeParameterListOwner { return body.getDeclarations(); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetTypeReference getTargetTypeRef() { return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java b/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java index 73414e49175..9fc2de3727d 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java @@ -24,7 +24,7 @@ public class JetFunction extends JetTypeParameterListOwner { visitor.visitFunction(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetParameterList getParameterList() { return (JetParameterList) findChildByType(JetNodeTypes.VALUE_PARAMETER_LIST); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetIfExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetIfExpression.java index 64763cae9af..190663f8a9d 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetIfExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetIfExpression.java @@ -18,15 +18,17 @@ public class JetIfExpression extends JetExpression { visitor.visitIfExpression(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetExpression getCondition() { return findExpressionUnder(JetNodeTypes.CONDITION); } + @Nullable(IF_NOT_PARSED) public JetExpression getThen() { return findExpressionUnder(JetNodeTypes.THEN); } + @Nullable public JetExpression getElse() { return findExpressionUnder(JetNodeTypes.ELSE); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetImportDirective.java b/idea/src/org/jetbrains/jet/lang/psi/JetImportDirective.java index b8a050507bc..34e292260e1 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetImportDirective.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetImportDirective.java @@ -19,6 +19,7 @@ public class JetImportDirective extends JetElement { visitor.visitImportDirective(this); } + @NotNull public String getImportedName() { StringBuilder answer = new StringBuilder(); ASTNode childNode = getNode().getFirstChildNode(); diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetMatchExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetMatchExpression.java index 94f0876ed8e..d5ee2bb03a5 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetMatchExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetMatchExpression.java @@ -25,7 +25,7 @@ public class JetMatchExpression extends JetExpression { return left; } - @Nullable + @Nullable(IF_NOT_PARSED) public JetMatchBlock getMatchBlock() { return (JetMatchBlock) findChildByType(JetNodeTypes.MATCH_BLOCK); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetNewExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetNewExpression.java index 281ca8340f2..40e6bad4d0f 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetNewExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetNewExpression.java @@ -21,6 +21,7 @@ public class JetNewExpression extends JetExpression { visitor.visitNewExpression(this); } + @Nullable(IF_NOT_PARSED) public JetTypeReference getTypeReference() { return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetObjectLiteralExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetObjectLiteralExpression.java index 170e60e31a6..aa2657f0000 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetObjectLiteralExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetObjectLiteralExpression.java @@ -35,6 +35,7 @@ public class JetObjectLiteralExpression extends JetExpression implements JetClas } @Override + @NotNull public List getDeclarations() { JetClassBody body = (JetClassBody) findChildByType(JetNodeTypes.CLASS_BODY); if (body == null) return Collections.emptyList(); diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java index 2fe42726000..fde399bebd5 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java @@ -19,8 +19,11 @@ public class JetPostfixExpression extends JetExpression { visitor.visitPostfixExpression(this); } + @NotNull public JetExpression getBaseExpression() { - return findChildByClass(JetExpression.class); + JetExpression answer = findChildByClass(JetExpression.class); + assert answer != null; + return answer; } @NotNull diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java index 64613380f5f..caaef63eef2 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java @@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; @@ -19,8 +18,11 @@ public class JetPrefixExpression extends JetExpression { visitor.visitPrefixExpression(this); } + @NotNull public JetExpression getBaseExpression() { - return findChildByClass(JetExpression.class); + JetExpression answer = findChildByClass(JetExpression.class); + assert answer != null; + return answer; } @NotNull @@ -30,7 +32,7 @@ public class JetPrefixExpression extends JetExpression { return operationNode; } - @Nullable + @NotNull public JetToken getOperationSign() { return (JetToken) getOperationTokenNode().getElementType(); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetProperty.java b/idea/src/org/jetbrains/jet/lang/psi/JetProperty.java index 04c41ff9416..b934096b030 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetProperty.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetProperty.java @@ -71,6 +71,7 @@ public class JetProperty extends JetNamedDeclaration { return null; } + @Nullable public JetPropertyAccessor getSetter() { for (JetPropertyAccessor accessor : getAccessors()) { if (accessor.isSetter()) return accessor; diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetQualifiedExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetQualifiedExpression.java index 924d8969263..8f21266e085 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetQualifiedExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetQualifiedExpression.java @@ -22,7 +22,7 @@ public abstract class JetQualifiedExpression extends JetExpression { return left; } - @Nullable + @Nullable(IF_NOT_PARSED) public JetExpression getSelectorExpression() { ASTNode node = getOperationTokenNode(); while (node != null) { @@ -42,7 +42,7 @@ public abstract class JetQualifiedExpression extends JetExpression { return operationNode; } - @Nullable + @NotNull public JetToken getOperationSign() { return (JetToken) getOperationTokenNode().getElementType(); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetThrowExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetThrowExpression.java index 55bf69cc750..c66a2e1d825 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetThrowExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetThrowExpression.java @@ -17,7 +17,7 @@ public class JetThrowExpression extends JetExpression { visitor.visitThrowExpression(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetExpression getThrownExpression() { return findChildByClass(JetExpression.class); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java b/idea/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java index 9fab67b143a..e18fad3bde8 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java @@ -25,7 +25,7 @@ public class JetTypeConstraint extends JetElement { findChildByType(JetTokens.OBJECT_KEYWORD) != null; } - @Nullable + @Nullable(IF_NOT_PARSED) public JetTypeReference getSubjectTypeReference() { ASTNode node = getNode().getFirstChildNode(); while (node != null) { @@ -38,7 +38,7 @@ public class JetTypeConstraint extends JetElement { return null; } - @Nullable + @Nullable(IF_NOT_PARSED) public JetTypeReference getExtendsTypeReference() { boolean passedColon = false; ASTNode node = getNode().getFirstChildNode(); diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetTypeParameterListOwner.java b/idea/src/org/jetbrains/jet/lang/psi/JetTypeParameterListOwner.java index 9ae6667409e..7ffadb377cc 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetTypeParameterListOwner.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetTypeParameterListOwner.java @@ -21,6 +21,7 @@ public class JetTypeParameterListOwner extends JetNamedDeclaration { return (JetTypeParameterList) findChildByType(JetNodeTypes.TYPE_PARAMETER_LIST); } + @NotNull public List getTypeParameters() { JetTypeParameterList list = getTypeParameterList(); if (list == null) return Collections.emptyList(); diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetTypedef.java b/idea/src/org/jetbrains/jet/lang/psi/JetTypedef.java index 9f352fb4b9b..bf7838e6164 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetTypedef.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetTypedef.java @@ -18,7 +18,7 @@ public class JetTypedef extends JetTypeParameterListOwner { visitor.visitTypedef(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetTypeReference getTypeReference() { return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetWhileExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetWhileExpression.java index 89c1b43b591..61ab7666661 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetWhileExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetWhileExpression.java @@ -18,11 +18,12 @@ public class JetWhileExpression extends JetExpression { visitor.visitWhileExpression(this); } - @Nullable + @Nullable(IF_NOT_PARSED) public JetExpression getCondition() { return findExpressionUnder(JetNodeTypes.CONDITION); } + @Nullable(IF_NOT_PARSED) public JetExpression getBody() { return findExpressionUnder(JetNodeTypes.BODY); } diff --git a/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java b/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java index 8d28e0e2f2d..7cc2b58a512 100644 --- a/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java +++ b/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java @@ -4,22 +4,24 @@ package org.jetbrains.jet.parsing; import com.intellij.openapi.application.PathManager; +import com.intellij.psi.PsiErrorElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testFramework.ParsingTestCase; import junit.framework.TestSuite; import org.jetbrains.annotations.NonNls; +import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetVisitor; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; import java.util.List; public class JetParsingTest extends ParsingTestCase { @@ -49,7 +51,6 @@ public class JetParsingTest extends ParsingTestCase { @Override protected void checkResult(@NonNls String targetDataName, PsiFile file) throws IOException { - super.checkResult(targetDataName, file); file.acceptChildren(new JetVisitor() { @Override public void visitJetElement(JetElement elem) { @@ -60,7 +61,20 @@ public class JetParsingTest extends ParsingTestCase { throw new RuntimeException(throwable); } } + + @Override + public void visitBinaryExpression(JetBinaryExpression expression) { + super.visitBinaryExpression(expression); + JetExpression right = expression.getRight(); + JetExpression left = expression.getLeft(); + assertNotSame(left, right); + if (right == null) { + assertNotNull("Imcomplete binary operation in parsed OK test", PsiTreeUtil.findChildOfType(expression, PsiErrorElement.class) != null); + } + } }); + + super.checkResult(targetDataName, file); } private void checkPsiGetters(JetElement elem) throws Throwable {