diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index 28858aac19d..3c2d11cfa90 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -93,8 +93,8 @@ public interface JetNodeTypes { JetNodeType FUNCTION_LITERAL = new JetNodeType("FUNCTION_LITERAL", JetFunctionLiteralExpression.class); JetNodeType ANNOTATED_EXPRESSION = new JetNodeType("ANNOTATED_EXPRESSION", JetAnnotatedExpression.class); - JetNodeType REFERENCE_EXPRESSION = new JetNodeType("REFERENCE_EXPRESSION", JetReferenceExpression.class); - JetNodeType OPERATION_REFERENCE = new JetNodeType("OPERATION_REFERENCE", JetReferenceExpression.class); + JetNodeType REFERENCE_EXPRESSION = new JetNodeType("REFERENCE_EXPRESSION", JetSimpleNameExpression.class); + JetNodeType OPERATION_REFERENCE = new JetNodeType("OPERATION_REFERENCE", JetSimpleNameExpression.class); JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class); JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class); diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 161cb49a81d..56f528c4951 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -246,7 +246,7 @@ public class ExpressionCodegen extends JetVisitor { } @Override - public void visitReferenceExpression(JetReferenceExpression expression) { + public void visitReferenceExpression(JetSimpleNameExpression expression) { final DeclarationDescriptor descriptor = bindingContext.resolveReferenceExpression(expression); int index = myMap.getIndex(descriptor); if (index >= 0) { @@ -267,8 +267,8 @@ public class ExpressionCodegen extends JetVisitor { JetExpression callee = expression.getCalleeExpression(); - if (callee instanceof JetReferenceExpression) { - DeclarationDescriptor funDescriptor = bindingContext.resolveReferenceExpression((JetReferenceExpression) callee); + if (callee instanceof JetSimpleNameExpression) { + DeclarationDescriptor funDescriptor = bindingContext.resolveReferenceExpression((JetSimpleNameExpression) callee); if (funDescriptor instanceof FunctionDescriptor) { } else { diff --git a/idea/src/org/jetbrains/jet/lang/ErrorHandler.java b/idea/src/org/jetbrains/jet/lang/ErrorHandler.java index f3c6aec0bf6..f17e7147046 100644 --- a/idea/src/org/jetbrains/jet/lang/ErrorHandler.java +++ b/idea/src/org/jetbrains/jet/lang/ErrorHandler.java @@ -13,7 +13,7 @@ public class ErrorHandler { public static final ErrorHandler THROW_EXCEPTION = new ErrorHandler() { @Override public void unresolvedReference(JetReferenceExpression referenceExpression) { - throw new IllegalStateException("Unresolved reference: " + referenceExpression.getReferencedName()); + throw new IllegalStateException("Unresolved reference: " + referenceExpression.getText()); } @Override diff --git a/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java b/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java index 098fa1bc513..ee892f5b2e7 100644 --- a/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java +++ b/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java @@ -7,7 +7,9 @@ import com.intellij.lang.annotation.Annotator; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; +import com.intellij.psi.MultiRangeReference; 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.*; @@ -30,7 +32,15 @@ public class JetPsiChecker implements Annotator { final BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, new ErrorHandler() { @Override public void unresolvedReference(JetReferenceExpression referenceExpression) { - holder.createErrorAnnotation(referenceExpression, "Unresolved").setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + PsiReference reference = referenceExpression.getReference(); + if (reference instanceof MultiRangeReference) { + MultiRangeReference mrr = (MultiRangeReference) reference; + for (TextRange range : mrr.getRanges()) { + holder.createErrorAnnotation(range.shiftRight(referenceExpression.getTextOffset()), "Unresolved").setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + } + } else { + holder.createErrorAnnotation(referenceExpression, "Unresolved").setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + } } @Override diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java index 5b3e5269817..a1e1dff7dfa 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java @@ -1,22 +1,32 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.MultiRangeReference; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetNodeTypes; +import org.jetbrains.jet.lexer.JetTokens; +import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * @author max */ -public class JetArrayAccessExpression extends JetExpression { +public class JetArrayAccessExpression extends JetReferenceExpression { public JetArrayAccessExpression(@NotNull ASTNode node) { super(node); } + @Override + public PsiReference getReference() { + return new JetArrayAccessReference(); + } + @Override public void accept(JetVisitor visitor) { visitor.visitArrayAccessExpression(this); @@ -35,4 +45,34 @@ public class JetArrayAccessExpression extends JetExpression { if (container == null) return Collections.emptyList(); return PsiTreeUtil.getChildrenOfTypeAsList(container, JetExpression.class); } + + private class JetArrayAccessReference extends JetPsiReference implements MultiRangeReference { + + @Override + public PsiElement getElement() { + return JetArrayAccessExpression.this; + } + + @Override + public TextRange getRangeInElement() { + return getElement().getTextRange().shiftRight(-getElement().getTextOffset()); + } + + @Override + public List getRanges() { + List list = new ArrayList(); + + JetContainerNode indices = (JetContainerNode) findChildByType(JetNodeTypes.INDICES); + TextRange textRange = indices.getNode().findChildByType(JetTokens.LBRACKET).getTextRange(); + TextRange lBracketRange = textRange.shiftRight(-getTextOffset()); + + list.add(lBracketRange); + + textRange = indices.getNode().findChildByType(JetTokens.RBRACKET).getTextRange(); + TextRange rBracketRange = textRange.shiftRight(-getTextOffset()); + list.add(rBracketRange); + + return list; + } + } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java index 4a2bc25a14b..d78a60be617 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java @@ -41,8 +41,8 @@ public class JetBinaryExpression extends JetExpression { } @NotNull - public JetReferenceExpression getOperationReference() { - return (JetReferenceExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE); + public JetSimpleNameExpression getOperationReference() { + return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE); } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java index 028e7817f77..9f793d08152 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java @@ -40,8 +40,8 @@ public class JetBinaryExpressionWithTypeRHS extends JetExpression { return null; } @NotNull - public JetReferenceExpression getOperationReference() { - return (JetReferenceExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE); + public JetSimpleNameExpression getOperationReference() { + return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE); } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java index f8cdea04daa..cc844e507bf 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java @@ -1,118 +1,71 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.TokenSet; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.ErrorHandler; -import org.jetbrains.jet.lang.parsing.JetExpressionParsing; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lexer.JetTokens; /** - * @author max + * @author abreslav */ -public class JetReferenceExpression extends JetExpression { - private static final TokenSet REFERENCE_TOKENS = TokenSet.create(JetTokens.IDENTIFIER, JetTokens.FIELD_IDENTIFIER); - +public abstract class JetReferenceExpression extends JetExpression { public JetReferenceExpression(@NotNull ASTNode node) { super(node); } - @Nullable @IfNotParsed - public String getReferencedName() { - PsiElement referencedNameElement = getReferencedNameElement(); - return referencedNameElement == null ? null : referencedNameElement.getNode().getText(); + protected PsiElement doResolve() { + JetFile file = (JetFile) getContainingFile(); + BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, ErrorHandler.DO_NOTHING); + PsiElement psiElement = bindingContext.resolveToDeclarationPsiElement(this); + return psiElement == null + ? file + : psiElement; } - @Nullable @IfNotParsed - public PsiElement getReferencedNameElement() { - PsiElement element = findChildByType(REFERENCE_TOKENS); - if (element == null) { - element = findChildByType(JetExpressionParsing.ALL_OPERATIONS); + @Override + public abstract PsiReference getReference(); + + protected abstract class JetPsiReference implements PsiReference { + + @Override + public PsiElement resolve() { + return doResolve(); + } + + @NotNull + @Override + public String getCanonicalText() { + return ""; + } + + @Override + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + @Override + public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + @Override + public boolean isReferenceTo(PsiElement element) { + return resolve() == element; + } + + @NotNull + @Override + public Object[] getVariants() { + return EMPTY_ARRAY; + } + + @Override + public boolean isSoft() { + return false; } - return element; } - - @Nullable @IfNotParsed - public IElementType getReferencedNameElementType() { - PsiElement element = getReferencedNameElement(); - return element == null ? null : element.getNode().getElementType(); - } - - @Override - public PsiReference findReferenceAt(int offset) { - return getReference(); - } - - @Override - public PsiReference getReference() { - if (getReferencedName() == null) return null; - return new PsiReference() { - @Override - public PsiElement getElement() { - return getReferencedNameElement(); - } - - @Override - public TextRange getRangeInElement() { - return new TextRange(0, getElement().getTextLength()); - } - - @Override - public PsiElement resolve() { - PsiElement element = getElement(); - JetFile file = (JetFile) element.getContainingFile(); - BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, ErrorHandler.DO_NOTHING); - PsiElement psiElement = bindingContext.resolveToDeclarationPsiElement(JetReferenceExpression.this); - return psiElement == null - ? file - : psiElement; - } - - @NotNull - @Override - public String getCanonicalText() { - return getReferencedName(); - } - - @Override - public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { - throw new IncorrectOperationException(); - } - - @Override - public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { - throw new IncorrectOperationException(); - } - - @Override - public boolean isReferenceTo(PsiElement element) { - return resolve() == element; - } - - @NotNull - @Override - public Object[] getVariants() { - return EMPTY_ARRAY; - } - - @Override - public boolean isSoft() { - return false; - } - }; - } - - @Override - public void accept(JetVisitor visitor) { - visitor.visitReferenceExpression(this); - } - } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java new file mode 100644 index 00000000000..1c12071cc6a --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java @@ -0,0 +1,71 @@ +package org.jetbrains.jet.lang.psi; + +import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.parsing.JetExpressionParsing; +import org.jetbrains.jet.lexer.JetTokens; + +/** + * @author max + */ +public class JetSimpleNameExpression extends JetReferenceExpression { + private static final TokenSet REFERENCE_TOKENS = TokenSet.create(JetTokens.IDENTIFIER, JetTokens.FIELD_IDENTIFIER); + + public JetSimpleNameExpression(@NotNull ASTNode node) { + super(node); + } + + @Nullable @IfNotParsed + public String getReferencedName() { + PsiElement referencedNameElement = getReferencedNameElement(); + return referencedNameElement == null ? null : referencedNameElement.getNode().getText(); + } + + @Nullable @IfNotParsed + public PsiElement getReferencedNameElement() { + PsiElement element = findChildByType(REFERENCE_TOKENS); + if (element == null) { + element = findChildByType(JetExpressionParsing.ALL_OPERATIONS); + } + return element; + } + + @Nullable @IfNotParsed + public IElementType getReferencedNameElementType() { + PsiElement element = getReferencedNameElement(); + return element == null ? null : element.getNode().getElementType(); + } + + @Override + public PsiReference findReferenceAt(int offset) { + return getReference(); + } + + @Override + public PsiReference getReference() { + return new JetPsiReference() { + + @Override + public PsiElement getElement() { + return getReferencedNameElement(); + } + + @Override + public TextRange getRangeInElement() { + return new TextRange(0, getElement().getTextLength()); + } + }; + } + + @Override + public void accept(JetVisitor visitor) { + visitor.visitReferenceExpression(this); + } + +} diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetUserType.java b/idea/src/org/jetbrains/jet/lang/psi/JetUserType.java index e7c383956dc..22b303bad3a 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetUserType.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetUserType.java @@ -37,8 +37,8 @@ public class JetUserType extends JetTypeElement { } @Nullable @IfNotParsed - public JetReferenceExpression getReferenceExpression() { - return (JetReferenceExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION); + public JetSimpleNameExpression getReferenceExpression() { + return (JetSimpleNameExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION); } @Nullable @@ -48,7 +48,7 @@ public class JetUserType extends JetTypeElement { @Nullable public String getReferencedName() { - JetReferenceExpression referenceExpression = getReferenceExpression(); + JetSimpleNameExpression referenceExpression = getReferenceExpression(); return referenceExpression == null ? null : referenceExpression.getReferencedName(); } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java index 5037a02439a..66e9b019b8d 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java @@ -142,7 +142,7 @@ public class JetVisitor extends PsiElementVisitor { visitExpression(expression); } - public void visitReferenceExpression(JetReferenceExpression expression) { + public void visitReferenceExpression(JetSimpleNameExpression expression) { visitExpression(expression); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/JetModuleUtil.java b/idea/src/org/jetbrains/jet/lang/resolve/JetModuleUtil.java index 412527a64d7..a3ae81d39f2 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/JetModuleUtil.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/JetModuleUtil.java @@ -1,7 +1,6 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.jet.lang.psi.JetElement; -import org.jetbrains.jet.lang.psi.JetReferenceExpression; /** * @author abreslav diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 4464143bf11..5e68d7eed8a 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -166,7 +166,7 @@ public class TypeResolver { @Nullable public ClassDescriptor resolveClass(JetScope scope, JetUserType userType) { - JetReferenceExpression expression = userType.getReferenceExpression(); + JetSimpleNameExpression expression = userType.getReferenceExpression(); if (userType.isAbsoluteInRootNamespace()) { return JetModuleUtil.getRootNamespaceScope(userType).getClass(expression.getReferencedName()); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index 99ce320f463..048a6156da1 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -25,6 +25,7 @@ public class JavaTypeTransformer { @NotNull public Type transform(PsiType javaType) { + System.out.println("javaType = " + javaType.getInternalCanonicalText()); return javaType.accept(new PsiTypeVisitor() { @Override public Type visitClassType(PsiClassType classType) { @@ -32,9 +33,11 @@ public class JavaTypeTransformer { if (psiClass == null) { return ErrorType.createErrorType("Unresolved java class: " + classType.getPresentableText()); } + if ("java.lang.Object".equals(psiClass.getQualifiedName())) { return JetStandardClasses.getNullableAnyType(); } + ClassDescriptor descriptor = resolver.resolveClass(psiClass); // TODO : arguments & raw types List arguments = Collections.emptyList(); // TODO @@ -59,6 +62,11 @@ public class JavaTypeTransformer { Type type = transform(arrayType.getComponentType()); return TypeUtils.makeNullable(standardLibrary.getArrayType(type)); } + + @Override + public Type visitType(PsiType type) { + throw new UnsupportedOperationException("Unsupported type: " + type.getPresentableText()); // TODO + } }); } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 25b3e7e9dd0..01b53aa8c1f 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -42,7 +42,7 @@ public class JetTypeInferrer { final Type[] result = new Type[1]; expression.accept(new JetVisitor() { @Override - public void visitReferenceExpression(JetReferenceExpression expression) { + public void visitReferenceExpression(JetSimpleNameExpression expression) { // TODO : other members // TODO : type substitutions??? String referencedName = expression.getReferencedName(); @@ -348,7 +348,7 @@ public class JetTypeInferrer { @Override public void visitBinaryExpression(JetBinaryExpression expression) { - JetReferenceExpression operationSign = expression.getOperationReference(); + JetSimpleNameExpression operationSign = expression.getOperationReference(); IElementType operationType = operationSign.getReferencedNameElementType(); if (operationType == JetTokens.IDENTIFIER) { @@ -359,8 +359,9 @@ public class JetTypeInferrer { } else if (operationType == JetTokens.EQ) { JetExpression left = expression.getLeft(); - if (left instanceof JetArrayAccessExpression) { - JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left; + JetExpression deparenthesized = deparenthesize(left); + if (deparenthesized instanceof JetArrayAccessExpression) { + JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized; resolveArrayAccessToLValue(arrayAccessExpression, expression.getRight(), expression.getOperationReference()); } else { @@ -380,14 +381,13 @@ public class JetTypeInferrer { List argumentTypes = getTypes(scope, indexExpressions); if (argumentTypes == null) return; - // TODO : record unresolved - FunctionDescriptor functionDescriptor = lookupFunction(scope, null, "get", receiverType, argumentTypes); + FunctionDescriptor functionDescriptor = lookupFunction(scope, expression, "get", receiverType, argumentTypes); if (functionDescriptor != null) { result[0] = functionDescriptor.getUnsubstitutedReturnType(); } } - private void resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetReferenceExpression operationSign) { + private void resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign) { List argumentTypes = getTypes(scope, arrayAccessExpression.getIndexExpressions()); if (argumentTypes == null) return; Type rhsType = getType(scope, rightHandSide, false); @@ -397,6 +397,8 @@ public class JetTypeInferrer { Type receiverType = getType(scope, arrayAccessExpression.getArrayExpression(), false); if (receiverType == null) return; + // TODO : nasty hack: effort is duplicated + lookupFunction(scope, arrayAccessExpression, "set", receiverType, argumentTypes); FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "set", receiverType, argumentTypes); if (functionDescriptor != null) { result[0] = functionDescriptor.getUnsubstitutedReturnType(); @@ -409,7 +411,7 @@ public class JetTypeInferrer { } private Type getTypeForBinaryCall(JetBinaryExpression expression, String name, JetScope scope) { - JetReferenceExpression operationSign = expression.getOperationReference(); + JetSimpleNameExpression operationSign = expression.getOperationReference(); JetExpression left = expression.getLeft(); Type leftType = getType(scope, left, false); JetExpression right = expression.getRight(); @@ -430,6 +432,14 @@ public class JetTypeInferrer { return result[0]; } + @NotNull + private JetExpression deparenthesize(@NotNull JetExpression expression) { + while (expression instanceof JetParenthesizedExpression) { + expression = ((JetParenthesizedExpression) expression).getExpression(); + } + return expression; + } + @Nullable private FunctionDescriptor lookupFunction(JetScope scope, JetReferenceExpression reference, String name, Type receiverType, List argumentTypes) { OverloadDomain overloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(receiverType, scope, name); @@ -453,7 +463,7 @@ public class JetTypeInferrer { private OverloadDomain getOverloadDomain(final JetScope scope, JetExpression calleeExpression) { final OverloadDomain[] result = new OverloadDomain[1]; - final JetReferenceExpression[] reference = new JetReferenceExpression[1]; + final JetSimpleNameExpression[] reference = new JetSimpleNameExpression[1]; calleeExpression.accept(new JetVisitor() { @Override @@ -472,8 +482,8 @@ public class JetTypeInferrer { public void visitQualifiedExpression(JetQualifiedExpression expression) { // . or ?. JetExpression selectorExpression = expression.getSelectorExpression(); - if (selectorExpression instanceof JetReferenceExpression) { - JetReferenceExpression referenceExpression = (JetReferenceExpression) selectorExpression; + if (selectorExpression instanceof JetSimpleNameExpression) { + JetSimpleNameExpression referenceExpression = (JetSimpleNameExpression) selectorExpression; Type receiverType = getType(scope, expression.getReceiverExpression(), false); if (receiverType != null) { @@ -486,7 +496,7 @@ public class JetTypeInferrer { } @Override - public void visitReferenceExpression(JetReferenceExpression expression) { + public void visitReferenceExpression(JetSimpleNameExpression expression) { // a -- create a hierarchical lookup domain for this.a result[0] = semanticServices.getOverloadResolver().getOverloadDomain(null, scope, expression.getReferencedName()); reference[0] = expression; @@ -506,7 +516,7 @@ public class JetTypeInferrer { return wrapForTracing(result[0], reference[0]); } - private OverloadDomain wrapForTracing(final OverloadDomain overloadDomain, @Nullable final JetReferenceExpression referenceExpression) { + private OverloadDomain wrapForTracing(final OverloadDomain overloadDomain, @NotNull final JetReferenceExpression referenceExpression) { if (overloadDomain == null) return OverloadDomain.EMPTY; return new OverloadDomain() { @Override diff --git a/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java b/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java index d5bcbf3f139..a87008b758f 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java @@ -18,7 +18,13 @@ public class JetQuickDocumentationProvider extends QuickDocumentationProvider { @Override public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) { - JetReferenceExpression ref = PsiTreeUtil.getParentOfType(originalElement, JetReferenceExpression.class); + JetReferenceExpression ref; + if (originalElement instanceof JetReferenceExpression) { + ref = (JetReferenceExpression) originalElement; + } + else { + ref = PsiTreeUtil.getParentOfType(originalElement, JetReferenceExpression.class); + } if (ref != null) { BindingContext bindingContext = AnalyzingUtils.analyzeFile((JetFile) element.getContainingFile(), ErrorHandler.DO_NOTHING); DeclarationDescriptor declarationDescriptor = bindingContext.resolveReferenceExpression(ref); diff --git a/idea/testData/resolve/ResolveOfInfixExpressions.jet b/idea/testData/resolve/ResolveOfInfixExpressions.jet index ec0884052ac..266c851579f 100644 --- a/idea/testData/resolve/ResolveOfInfixExpressions.jet +++ b/idea/testData/resolve/ResolveOfInfixExpressions.jet @@ -1,3 +1,6 @@ +import java.* +import util.* + ~X~class X<~T~T> { fun foo(a : `T`T) : `X`X<`T`T>{} ~plus~fun plus(t : `T`T) : Int {} @@ -11,4 +14,26 @@ new X() `plus`+ "1" new X() `plus`plus "sadfas" new X().`plus`plus("") -} \ No newline at end of file +} + +~Foo~class Foo { + ~set1~fun set(i : Int, val : String) {} + ~get1~fun get(i : Int) : Int {} + ~get2~fun get(i : Int, j : Int) : String {} + ~get3~fun get(i : Object) : Any {return i } +} + +fun tt(t : T) : T { + val x : List = 0 + x`java::java.util.List.get()`[1] + val foo = new Foo + foo`!`[null, 1] + foo`get2`[1, 1] + foo`get1`[1] + foo`set1`[1] = "" + foo`!`[1, 2] = "" + x`java::java.util.List.set()`[1] = null + (x`java::java.util.List.set()`[1]) = null + x`!`[null] = null + (x`!`[null, 2]) = null +} diff --git a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java index b0e338bc129..bfd938e8863 100644 --- a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java +++ b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java @@ -3,6 +3,7 @@ package org.jetbrains.jet.resolve; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Document; import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.jet.lang.ErrorHandler; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.psi.*; @@ -79,7 +80,7 @@ public class ExpectedResolveData { JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(file.getProject(), new ErrorHandler() { @Override public void unresolvedReference(JetReferenceExpression referenceExpression) { - unresolvedReferences.add(referenceExpression.getReferencedNameElement()); + unresolvedReferences.add(referenceExpression); } }); JetStandardLibrary lib = semanticServices.getStandardLibrary(); @@ -105,7 +106,8 @@ public class ExpectedResolveData { PsiElement element = file.findElementAt(position); if ("!".equals(name)) { - assertTrue("Must have been unresolved: " + element, unresolvedReferences.contains(element)); + JetReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(element, JetReferenceExpression.class); + assertTrue("Must have been unresolved: " + referenceExpression.getText(), unresolvedReferences.contains(referenceExpression)); continue; } @@ -141,8 +143,9 @@ public class ExpectedResolveData { actualName = actual.toString(); } } + assertNotNull(reference); assertSame( - "Reference `" + name + "`" + reference.getReferencedName() + " at " + reference.getTextOffset() + " is resolved into " + actualName + ".", + "Reference `" + name + "`" + reference.getText() + " at " + reference.getTextOffset() + " is resolved into " + actualName + ".", expected, actual); } diff --git a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java index f6169707e53..266eeffded7 100644 --- a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -39,7 +39,10 @@ public class JetResolveTest extends ExtensibleResolveTestCase { PsiClass java_util_Collections = findClass("java.util.Collections"); nameToDeclaration.put("java::java.util.Collections.emptyList()", findMethod(java_util_Collections, "emptyList")); nameToDeclaration.put("java::java.util.Collections", java_util_Collections); - nameToDeclaration.put("java::java.util.List", findClass("java.util.List")); + PsiClass java_util_List = findClass("java.util.List"); + nameToDeclaration.put("java::java.util.List", java_util_List); + nameToDeclaration.put("java::java.util.List.set()", java_util_List.findMethodsByName("set", true)[0]); + nameToDeclaration.put("java::java.util.List.get()", java_util_List.findMethodsByName("get", true)[0]); nameToDeclaration.put("java::java", findPackage("java")); nameToDeclaration.put("java::java.util", findPackage("java.util")); nameToDeclaration.put("java::java.lang", findPackage("java.lang"));