Resolve for array access. Proper references are pending
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
package org.jetbrains.jet.lang.annotations;
|
package org.jetbrains.jet.lang.annotations;
|
||||||
|
|
||||||
|
import com.intellij.codeInspection.ProblemHighlightType;
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.lang.annotation.AnnotationHolder;
|
import com.intellij.lang.annotation.AnnotationHolder;
|
||||||
import com.intellij.lang.annotation.Annotator;
|
import com.intellij.lang.annotation.Annotator;
|
||||||
|
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
@@ -28,7 +30,7 @@ public class JetPsiChecker implements Annotator {
|
|||||||
final BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, new ErrorHandler() {
|
final BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, new ErrorHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void unresolvedReference(JetReferenceExpression referenceExpression) {
|
public void unresolvedReference(JetReferenceExpression referenceExpression) {
|
||||||
holder.createErrorAnnotation(referenceExpression, "Unresolved");
|
holder.createErrorAnnotation(referenceExpression, "Unresolved").setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,6 +61,9 @@ public class JetPsiChecker implements Annotator {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
catch (ProcessCanceledException e) {
|
||||||
|
// Canceled. We are fine
|
||||||
|
}
|
||||||
catch (Throwable e) {
|
catch (Throwable e) {
|
||||||
// TODO
|
// TODO
|
||||||
holder.createErrorAnnotation(new TextRange(0, 1), e.getClass().getCanonicalName() + ": " + e.getMessage());
|
holder.createErrorAnnotation(new TextRange(0, 1), e.getClass().getCanonicalName() + ": " + e.getMessage());
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public class TypeResolver {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
private Type resolveTypeElement(final JetScope scope, final List<Attribute> attributes, JetTypeElement typeElement, final boolean nullable) {
|
private Type resolveTypeElement(final JetScope scope, final List<Attribute> attributes, JetTypeElement typeElement, final boolean nullable) {
|
||||||
final Type[] result = new Type[1];
|
final Type[] result = new Type[1];
|
||||||
if (typeElement != null) {
|
if (typeElement != null) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
|
||||||
@@ -293,7 +294,7 @@ public class JetTypeChecker {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSubtypeOf(Type subtype, Type supertype) {
|
public boolean isSubtypeOf(@NotNull Type subtype, @NotNull Type supertype) {
|
||||||
if (!supertype.isNullable() && subtype.isNullable()) {
|
if (!supertype.isNullable() && subtype.isNullable()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public class JetTypeInferrer {
|
|||||||
if (expression.getOperationReference().getReferencedNameElementType() == JetTokens.COLON) {
|
if (expression.getOperationReference().getReferencedNameElementType() == JetTokens.COLON) {
|
||||||
Type actualType = getType(scope, expression.getLeft(), false);
|
Type actualType = getType(scope, expression.getLeft(), false);
|
||||||
Type expectedType = typeResolver.resolveType(scope, expression.getRight());
|
Type expectedType = typeResolver.resolveType(scope, expression.getRight());
|
||||||
if (!semanticServices.getTypeChecker().isSubtypeOf(actualType, expectedType)) {
|
if (actualType != null && !semanticServices.getTypeChecker().isSubtypeOf(actualType, expectedType)) {
|
||||||
// TODO
|
// TODO
|
||||||
semanticServices.getErrorHandler().typeMismatch(expression.getLeft(), expectedType, actualType);
|
semanticServices.getErrorHandler().typeMismatch(expression.getLeft(), expectedType, actualType);
|
||||||
}
|
}
|
||||||
@@ -350,11 +350,53 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
else if (operationType == JetTokens.PLUS) {
|
else if (operationType == JetTokens.PLUS) {
|
||||||
result[0] = getTypeForBinaryCall(expression, "plus", scope);
|
result[0] = getTypeForBinaryCall(expression, "plus", scope);
|
||||||
|
}
|
||||||
|
else if (operationType == JetTokens.EQ) {
|
||||||
|
JetExpression left = expression.getLeft();
|
||||||
|
if (left instanceof JetArrayAccessExpression) {
|
||||||
|
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left;
|
||||||
|
resolveArrayAccessToLValue(arrayAccessExpression, expression.getRight(), expression.getOperationReference());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
result[0] = null; // TODO : This is not an expression, in fact!
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitArrayAccessExpression(JetArrayAccessExpression expression) {
|
||||||
|
JetExpression arrayExpression = expression.getArrayExpression();
|
||||||
|
Type receiverType = getType(scope, arrayExpression, false);
|
||||||
|
List<JetExpression> indexExpressions = expression.getIndexExpressions();
|
||||||
|
List<Type> argumentTypes = getTypes(scope, indexExpressions);
|
||||||
|
if (argumentTypes == null) return;
|
||||||
|
|
||||||
|
// TODO : record unresolved
|
||||||
|
FunctionDescriptor functionDescriptor = lookupFunction(scope, null, "get", receiverType, argumentTypes);
|
||||||
|
if (functionDescriptor != null) {
|
||||||
|
result[0] = functionDescriptor.getUnsubstitutedReturnType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetReferenceExpression operationSign) {
|
||||||
|
List<Type> argumentTypes = getTypes(scope, arrayAccessExpression.getIndexExpressions());
|
||||||
|
if (argumentTypes == null) return;
|
||||||
|
Type rhsType = getType(scope, rightHandSide, false);
|
||||||
|
if (rhsType == null) return;
|
||||||
|
argumentTypes.add(rhsType);
|
||||||
|
|
||||||
|
Type receiverType = getType(scope, arrayAccessExpression.getArrayExpression(), false);
|
||||||
|
if (receiverType == null) return;
|
||||||
|
|
||||||
|
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "set", receiverType, argumentTypes);
|
||||||
|
if (functionDescriptor != null) {
|
||||||
|
result[0] = functionDescriptor.getUnsubstitutedReturnType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitJetElement(JetElement elem) {
|
public void visitJetElement(JetElement elem) {
|
||||||
throw new IllegalArgumentException("Unsupported element: " + elem);
|
throw new IllegalArgumentException("Unsupported element: " + elem);
|
||||||
@@ -369,9 +411,7 @@ public class JetTypeInferrer {
|
|||||||
return ErrorType.createErrorType("No right argument");
|
return ErrorType.createErrorType("No right argument");
|
||||||
}
|
}
|
||||||
Type rightType = getType(scope, right, false);
|
Type rightType = getType(scope, right, false);
|
||||||
OverloadDomain overloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(leftType, scope, name);
|
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, name, leftType, Collections.singletonList(rightType));
|
||||||
overloadDomain = wrapForTracing(overloadDomain, operationSign);
|
|
||||||
FunctionDescriptor functionDescriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(Collections.<Type>emptyList(), Collections.singletonList(rightType));
|
|
||||||
if (functionDescriptor != null) {
|
if (functionDescriptor != null) {
|
||||||
return functionDescriptor.getUnsubstitutedReturnType();
|
return functionDescriptor.getUnsubstitutedReturnType();
|
||||||
}
|
}
|
||||||
@@ -384,6 +424,26 @@ public class JetTypeInferrer {
|
|||||||
return result[0];
|
return result[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private FunctionDescriptor lookupFunction(JetScope scope, JetReferenceExpression reference, String name, Type receiverType, List<Type> argumentTypes) {
|
||||||
|
OverloadDomain overloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(receiverType, scope, name);
|
||||||
|
overloadDomain = wrapForTracing(overloadDomain, reference);
|
||||||
|
return overloadDomain.getFunctionDescriptorForPositionedArguments(Collections.<Type>emptyList(), argumentTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private List<Type> getTypes(JetScope scope, List<JetExpression> indexExpressions) {
|
||||||
|
List<Type> argumentTypes = new ArrayList<Type>();
|
||||||
|
for (JetExpression indexExpression : indexExpressions) {
|
||||||
|
Type type = getType(scope, indexExpression, false);
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
argumentTypes.add(type);
|
||||||
|
}
|
||||||
|
return argumentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private OverloadDomain getOverloadDomain(final JetScope scope, JetExpression calleeExpression) {
|
private OverloadDomain getOverloadDomain(final JetScope scope, JetExpression calleeExpression) {
|
||||||
final OverloadDomain[] result = new OverloadDomain[1];
|
final OverloadDomain[] result = new OverloadDomain[1];
|
||||||
@@ -440,7 +500,7 @@ public class JetTypeInferrer {
|
|||||||
return wrapForTracing(result[0], reference[0]);
|
return wrapForTracing(result[0], reference[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OverloadDomain wrapForTracing(final OverloadDomain overloadDomain, final JetReferenceExpression referenceExpression) {
|
private OverloadDomain wrapForTracing(final OverloadDomain overloadDomain, @Nullable final JetReferenceExpression referenceExpression) {
|
||||||
if (overloadDomain == null) return OverloadDomain.EMPTY;
|
if (overloadDomain == null) return OverloadDomain.EMPTY;
|
||||||
return new OverloadDomain() {
|
return new OverloadDomain() {
|
||||||
@Override
|
@Override
|
||||||
@@ -458,9 +518,13 @@ public class JetTypeInferrer {
|
|||||||
public FunctionDescriptor getFunctionDescriptorForPositionedArguments(@NotNull List<Type> typeArguments, @NotNull List<Type> positionedValueArgumentTypes) {
|
public FunctionDescriptor getFunctionDescriptorForPositionedArguments(@NotNull List<Type> typeArguments, @NotNull List<Type> positionedValueArgumentTypes) {
|
||||||
FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes);
|
FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
trace.recordReferenceResolution(referenceExpression, descriptor);
|
if (referenceExpression != null) {
|
||||||
|
trace.recordReferenceResolution(referenceExpression, descriptor);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
|
if (referenceExpression != null) {
|
||||||
|
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
@@ -476,7 +540,9 @@ public class JetTypeInferrer {
|
|||||||
// TODO: consider other declarations
|
// TODO: consider other declarations
|
||||||
if (statement instanceof JetProperty) {
|
if (statement instanceof JetProperty) {
|
||||||
JetProperty property = (JetProperty) statement;
|
JetProperty property = (JetProperty) statement;
|
||||||
scope.addPropertyDescriptor(classDescriptorResolver.resolvePropertyDescriptor(scope, property));
|
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(scope, property);
|
||||||
|
scope.addPropertyDescriptor(propertyDescriptor);
|
||||||
|
trace.recordDeclarationResolution(property, propertyDescriptor);
|
||||||
}
|
}
|
||||||
else if (statement instanceof JetExpression) {
|
else if (statement instanceof JetExpression) {
|
||||||
getType(scope, (JetExpression) statement, true);
|
getType(scope, (JetExpression) statement, true);
|
||||||
|
|||||||
Reference in New Issue
Block a user