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