Complete resolve for array access expressions
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<TextRange> getRanges() {
|
||||
List<TextRange> list = new ArrayList<TextRange>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 "<TBD>";
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ public class JetVisitor extends PsiElementVisitor {
|
||||
visitExpression(expression);
|
||||
}
|
||||
|
||||
public void visitReferenceExpression(JetReferenceExpression expression) {
|
||||
public void visitReferenceExpression(JetSimpleNameExpression expression) {
|
||||
visitExpression(expression);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ public class JavaTypeTransformer {
|
||||
|
||||
@NotNull
|
||||
public Type transform(PsiType javaType) {
|
||||
System.out.println("javaType = " + javaType.getInternalCanonicalText());
|
||||
return javaType.accept(new PsiTypeVisitor<Type>() {
|
||||
@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<TypeProjection> arguments = Collections.<TypeProjection>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
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Type> 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<Type> 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<Type> 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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<String>() `plus`+ "1"
|
||||
new X<String>() `plus`plus "sadfas"
|
||||
new X<String>().`plus`plus("")
|
||||
}
|
||||
}
|
||||
|
||||
~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 <T> 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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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"));
|
||||
|
||||
Reference in New Issue
Block a user