提交 7601e715 编写于 作者: A Andrey Breslav

Working on error messages for overload resolution

上级 fe84695b
......@@ -12,6 +12,7 @@ Foo<Bar<X>, T, Object> // user type
type
: attributes typeDescriptor
// IF YOU CHANGE THIS, please, update TYPE_FIRST in JetParsing
typeDescriptor
: selfType
: functionType
......
......@@ -31,7 +31,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
COLON
);
private static final TokenSet EXPRESSION_FIRST = TokenSet.orSet(TokenSet.create(
/*package*/ static final TokenSet EXPRESSION_FIRST = TokenSet.orSet(TokenSet.create(
// Prefix
MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL, LBRACKET, LABEL_IDENTIFIER, AT, ATAT,
// Atomic
......@@ -82,7 +82,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
NAMESPACE_KEYWORD // for absolute qualified names
), MODIFIER_KEYWORDS);
private static final TokenSet EXPRESSION_FOLLOW = TokenSet.create(
/*package*/ static final TokenSet EXPRESSION_FOLLOW = TokenSet.create(
SEMICOLON, DOUBLE_ARROW, COMMA, RBRACE, RPAR, RBRACKET
);
......@@ -533,7 +533,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
else if (!parseLiteralConstant()) {
// TODO: better recovery if FIRST(expression) did not match
errorAndAdvance("Expecting an expression");
errorWithRecovery("Expecting an expression", EXPRESSION_FOLLOW);
}
}
......@@ -1494,7 +1494,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
PsiBuilder.Marker list = mark();
myBuilder.disableNewlines();
expect(LPAR, "Expecting an argument list", TokenSet.create(RPAR));
expect(LPAR, "Expecting an argument list", EXPRESSION_FOLLOW);
if (!at(RPAR)) {
while (true) {
......@@ -1509,7 +1509,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
}
expect(RPAR, "Expecting ')'");
expect(RPAR, "Expecting ')'", EXPRESSION_FOLLOW);
myBuilder.restoreNewlinesState();
list.done(VALUE_ARGUMENT_LIST);
......
......@@ -37,7 +37,7 @@ public class JetParsing extends AbstractJetParsing {
private static final TokenSet TYPE_PARAMETER_GT_RECOVERY_SET = TokenSet.create(WHERE_KEYWORD, WRAPS_KEYWORD, LPAR, COLON, LBRACE, GT);
private static final TokenSet PARAMETER_NAME_RECOVERY_SET = TokenSet.create(COLON, EQ, COMMA, RPAR);
private static final TokenSet NAMESPACE_NAME_RECOVERY_SET = TokenSet.create(DOT, EOL_OR_SEMICOLON);
/*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LBRACE, LPAR);
/*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LBRACE, LPAR, CAPITALIZED_THIS_KEYWORD);
public static JetParsing createForTopLevel(SemanticWhitespaceAwarePsiBuilder builder) {
builder.setDebugMode(true);
......@@ -835,10 +835,17 @@ public class JetParsing extends AbstractJetParsing {
advance(); // FUN_KEYWORD
// Recovery for the case of class A { fun| }
if (at(RBRACE)) {
error("Function body expected");
return FUN;
}
if (at(LT)) {
parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR));
}
int lastDot = findLastBefore(TokenSet.create(DOT), TokenSet.create(LPAR), true);
if (lastDot == -1) { // There's no explicit receiver type specified
......@@ -1246,7 +1253,7 @@ public class JetParsing extends AbstractJetParsing {
PsiBuilder.Marker reference = mark();
while (true) {
expect(IDENTIFIER, "Type name expected", TokenSet.create(LT));
expect(IDENTIFIER, "Type name expected", TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW));
reference.done(REFERENCE_EXPRESSION);
parseTypeArgumentList();
......
......@@ -13,7 +13,7 @@ public class JetArgument extends JetElement {
super(node);
}
public void accept(JetVisitor visitor) {
public void accept(@NotNull JetVisitor visitor) {
visitor.visitArgument(this);
}
......@@ -25,6 +25,9 @@ public class JetArgument extends JetElement {
@Nullable
public String getArgumentName() {
ASTNode firstChildNode = getNode().getFirstChildNode();
if (firstChildNode == null) {
return null;
}
return firstChildNode.getElementType() == JetTokens.IDENTIFIER ? firstChildNode.getText() : null;
}
......
......@@ -2,6 +2,7 @@ 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.JetNodeTypes;
import java.util.ArrayList;
......@@ -25,6 +26,7 @@ public class JetTypeReference extends JetElement {
return findChildrenByType(JetNodeTypes.ATTRIBUTE_ANNOTATION);
}
@Nullable
public JetTypeElement getTypeElement() {
return findChildByClass(JetTypeElement.class);
}
......
......@@ -329,7 +329,7 @@ public class ClassDescriptorResolver {
}
@Nullable
private ConstructorDescriptor resolvePrimaryConstructor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetClass classElement) {
public ConstructorDescriptor resolvePrimaryConstructor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetClass classElement) {
JetParameterList primaryConstructorParameterList = classElement.getPrimaryConstructorParameterList();
if (primaryConstructorParameterList != null) {
return createConstructorDescriptor(
......
......@@ -13,14 +13,12 @@ import java.util.Map;
public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor {
private final WritableScope unsubstitutedMemberScope;
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
private final JetSemanticServices semanticServices;
private TypeConstructor typeConstructor;
public MutableClassDescriptor(@NotNull JetSemanticServices semanticServices, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
super(containingDeclaration);
this.unsubstitutedMemberScope = semanticServices.createWritableScope(outerScope, this);
this.semanticServices = semanticServices;
}
@NotNull
......
......@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.types.FunctionDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import java.util.List;
......@@ -12,17 +11,18 @@ import java.util.Map;
* @author abreslav
*/
public interface OverloadDomain {
OverloadDomain EMPTY = new OverloadDomain() {
@Nullable
@NotNull
@Override
public FunctionDescriptor getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
return null;
public OverloadResolutionResult getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
return OverloadResolutionResult.nameNotFound();
}
@Nullable
@NotNull
@Override
public FunctionDescriptor getFunctionDescriptorForPositionedArguments(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
return null;
public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
return OverloadResolutionResult.nameNotFound();
}
@Override
......@@ -32,24 +32,19 @@ public interface OverloadDomain {
};
/**
* @param typeArguments
* @param valueArgumentTypes
* @param functionLiteralArgumentType
* @return A function descriptor with NO type parameters (they are already substituted), or null
* @return A function descriptor with NO type parameters (they are already substituted) wrapped together with a result code
*/
@Nullable
FunctionDescriptor getFunctionDescriptorForNamedArguments(
@NotNull
OverloadResolutionResult getFunctionDescriptorForNamedArguments(
@NotNull List<JetType> typeArguments,
@NotNull Map<String, JetType> valueArgumentTypes,
@Nullable JetType functionLiteralArgumentType);
/**
* @param typeArguments
* @param positionedValueArgumentTypes
* @return A function descriptor with NO type parameters (they are already substituted), or null
* @return A function descriptor with NO type parameters (they are already substituted) wrapped together with a result code
*/
@Nullable
FunctionDescriptor getFunctionDescriptorForPositionedArguments(
@NotNull
OverloadResolutionResult getFunctionDescriptorForPositionedArguments(
@NotNull List<JetType> typeArguments,
@NotNull List<JetType> positionedValueArgumentTypes);
......
package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.FunctionDescriptor;
import java.util.Collection;
/**
* @author abreslav
*/
public class OverloadResolutionResult {
public enum Code {
SUCCESS(true),
NAME_NOT_FOUND(false),
SINGLE_FUNCTION_ARGUMENT_MISMATCH(false),
AMBIGUITY(false);
private final boolean success;
Code(boolean success) {
this.success = success;
}
boolean isSuccess() {
return success;
}
}
public static OverloadResolutionResult success(@NotNull FunctionDescriptor functionDescriptor) {
return new OverloadResolutionResult(Code.SUCCESS, functionDescriptor);
}
public static OverloadResolutionResult nameNotFound() {
return new OverloadResolutionResult(Code.NAME_NOT_FOUND, null);
}
public static OverloadResolutionResult singleFunctionArgumentMismatch(FunctionDescriptor functionDescriptor) {
return new OverloadResolutionResult(Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH, functionDescriptor);
}
public static OverloadResolutionResult ambiguity(Collection<FunctionDescriptor> functionDescriptors) {
return new OverloadResolutionResult(Code.AMBIGUITY, null); // TODO
}
private final FunctionDescriptor functionDescriptor;
private final Code resultCode;
public OverloadResolutionResult(@NotNull Code resultCode, FunctionDescriptor functionDescriptor) {
this.functionDescriptor = functionDescriptor;
this.resultCode = resultCode;
}
@NotNull // This is done on purpose, despite the fact that errors may not carry a descriptor:
// one should not call this method at all in that case
public FunctionDescriptor getFunctionDescriptor() {
assert functionDescriptor != null;
return functionDescriptor;
}
@NotNull
public Code getResultCode() {
return resultCode;
}
public boolean isSuccess() {
return resultCode.isSuccess();
}
public boolean singleFunction() {
return isSuccess() || resultCode == Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH;
}
}
......@@ -34,11 +34,12 @@ public class OverloadResolver {
}
return new OverloadDomain() {
@NotNull
@Override
public FunctionDescriptor getFunctionDescriptorForPositionedArguments(@NotNull final List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull final List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
Collection<FunctionDescriptor> possiblyApplicableFunctions = functionGroup.getPossiblyApplicableFunctions(typeArguments, positionedValueArgumentTypes);
if (possiblyApplicableFunctions.isEmpty()) {
return null;
return OverloadResolutionResult.nameNotFound(); // TODO : it may be found, only the number of params did not match
}
List<FunctionDescriptor> applicable = new ArrayList<FunctionDescriptor>();
......@@ -84,9 +85,9 @@ public class OverloadResolver {
}
if (applicable.size() == 0) {
return null;
return OverloadResolutionResult.nameNotFound();
} else if (applicable.size() == 1) {
return applicable.get(0);
return OverloadResolutionResult.success(applicable.get(0));
} else {
// TODO : varargs
......@@ -100,10 +101,10 @@ public class OverloadResolver {
maximallySpecific.add(me);
}
if (maximallySpecific.isEmpty()) {
return null;
return OverloadResolutionResult.ambiguity(applicable);
}
if (maximallySpecific.size() == 1) {
return maximallySpecific.get(0);
return OverloadResolutionResult.success(maximallySpecific.get(0));
}
throw new UnsupportedOperationException();
}
......@@ -114,8 +115,9 @@ public class OverloadResolver {
return functionGroup.isEmpty();
}
@NotNull
@Override
public FunctionDescriptor getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
public OverloadResolutionResult getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
throw new UnsupportedOperationException(); // TODO
}
};
......
......@@ -36,7 +36,7 @@ public class TopDownAnalyzer {
trace.setToplevelScope(toplevelScope); // TODO : this is a hack
collectTypeDeclarators(toplevelScope, declarations);
resolveTypeDeclarations();
collectBehaviorDeclarators(toplevelScope, declarations);
processBehaviorDeclarators(toplevelScope, declarations);
resolveBehaviorDeclarationBodies();
}
......@@ -136,24 +136,26 @@ public class TopDownAnalyzer {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void collectBehaviorDeclarators(@NotNull final WritableScope declaringScope, List<JetDeclaration> declarations) {
private void processBehaviorDeclarators(@NotNull final WritableScope declaringScope, List<JetDeclaration> declarations) {
for (JetDeclaration declaration : declarations) {
declaration.accept(new JetVisitor() {
@Override
public void visitClass(JetClass klass) {
collectBehaviorDeclarators(classes.get(klass).getUnsubstitutedMemberScope(), klass.getDeclarations());
MutableClassDescriptor mutableClassDescriptor = classes.get(klass);
processBehaviorDeclarators(mutableClassDescriptor.getUnsubstitutedMemberScope(), klass.getDeclarations());
processPrimaryConstructor(mutableClassDescriptor, klass);
}
@Override
public void visitClassObject(JetClassObject classObject) {
processClassObject(classObject);
collectBehaviorDeclarators(declaringScope, classObject.getObject().getDeclarations());
processBehaviorDeclarators(declaringScope, classObject.getObject().getDeclarations());
}
@Override
public void visitNamespace(JetNamespace namespace) {
WritableScope namespaceScope = namespaceScopes.get(namespace);
collectBehaviorDeclarators(namespaceScope, namespace.getDeclarations());
processBehaviorDeclarators(namespaceScope, namespace.getDeclarations());
}
@Override
......@@ -179,13 +181,20 @@ public class TopDownAnalyzer {
@Override
public void visitDeclaration(JetDeclaration dcl) {
throw new UnsupportedOperationException(); // TODO
throw new UnsupportedOperationException(dcl.getText() + " " + dcl.getClass().getCanonicalName()); // TODO
}
});
}
}
private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) {
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructor(classDescriptor.getUnsubstitutedMemberScope(), classDescriptor, klass);
if (constructorDescriptor != null) {
classDescriptor.addConstructor(constructorDescriptor);
}
}
private void processConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) {
classDescriptor.addConstructor(classDescriptorResolver.resolveConstructorDescriptor(classDescriptor.getUnsubstitutedMemberScope(), classDescriptor, constructor, false));
}
......
......@@ -41,9 +41,14 @@ public class TypeResolver {
typeElement.accept(new JetVisitor() {
@Override
public void visitUserType(JetUserType type) {
JetSimpleNameExpression referenceExpression = type.getReferenceExpression();
String referencedName = type.getReferencedName();
if (referenceExpression == null || referencedName == null) {
return;
}
ClassDescriptor classDescriptor = resolveClass(scope, type);
if (classDescriptor != null) {
trace.recordReferenceResolution(type.getReferenceExpression(), classDescriptor);
trace.recordReferenceResolution(referenceExpression, classDescriptor);
TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
if (arguments.size() != typeConstructor.getParameters().size()) {
......@@ -59,9 +64,9 @@ public class TypeResolver {
}
}
else if (type.getTypeArguments().isEmpty()) {
TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameter(type.getReferencedName());
TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameter(referencedName);
if (typeParameterDescriptor != null) {
trace.recordReferenceResolution(type.getReferenceExpression(), typeParameterDescriptor);
trace.recordReferenceResolution(referenceExpression, typeParameterDescriptor);
result[0] = new JetTypeImpl(
attributes,
typeParameterDescriptor.getTypeConstructor(),
......@@ -71,11 +76,11 @@ public class TypeResolver {
JetStandardClasses.STUB
);
} else {
semanticServices.getErrorHandler().unresolvedReference(type.getReferenceExpression());
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
}
else {
semanticServices.getErrorHandler().unresolvedReference(type.getReferenceExpression());
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
}
......@@ -171,14 +176,21 @@ public class TypeResolver {
@Nullable
public ClassDescriptor resolveClass(JetScope scope, JetUserType userType) {
JetSimpleNameExpression expression = userType.getReferenceExpression();
if (expression == null) {
return null;
}
String referencedName = expression.getReferencedName();
if (referencedName == null) {
return null;
}
if (userType.isAbsoluteInRootNamespace()) {
return JetModuleUtil.getRootNamespaceScope(userType).getClass(expression.getReferencedName());
return JetModuleUtil.getRootNamespaceScope(userType).getClass(referencedName);
}
JetUserType qualifier = userType.getQualifier();
if (qualifier != null) {
scope = resolveClassLookupScope(scope, qualifier);
}
return scope.getClass(expression.getReferencedName());
return scope.getClass(referencedName);
}
private JetScope resolveClassLookupScope(JetScope scope, JetUserType userType) {
......
......@@ -18,6 +18,7 @@ public class WritableFunctionGroup implements FunctionGroup {
this.name = name;
}
@NotNull
@Override
public String getName() {
return name;
......@@ -51,7 +52,8 @@ public class WritableFunctionGroup implements FunctionGroup {
for (FunctionDescriptor functionDescriptor : getFunctionDescriptors()) {
// TODO : type argument inference breaks this logic
if (functionDescriptor.getTypeParameters().size() == typeArgCount) {
if (FunctionDescriptorUtil.getMinimumArity(functionDescriptor) <= valueArgCount && valueArgCount <= FunctionDescriptorUtil.getMaximumArity(functionDescriptor)) {
if (FunctionDescriptorUtil.getMinimumArity(functionDescriptor) <= valueArgCount &&
valueArgCount <= FunctionDescriptorUtil.getMaximumArity(functionDescriptor)) {
result.add(FunctionDescriptorUtil.substituteFunctionDescriptor(typeArguments, functionDescriptor));
}
}
......
......@@ -11,6 +11,7 @@ import java.util.List;
*/
public interface FunctionGroup extends Named {
FunctionGroup EMPTY = new FunctionGroup() {
@NotNull
@Override
public String getName() {
return "<empty>";
......@@ -19,7 +20,8 @@ public interface FunctionGroup extends Named {
@NotNull
@Override
public Collection<FunctionDescriptor> getPossiblyApplicableFunctions(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
return Collections.emptySet();
return Collections.emptyList();
// return OverloadResolutionResult.nameNotFound();
}
@Override
......@@ -35,6 +37,8 @@ public interface FunctionGroup extends Named {
@NotNull
Collection<FunctionDescriptor> getPossiblyApplicableFunctions(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes);
// @NotNull
// OverloadResolutionResult getPossiblyApplicableFunctions(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes);
boolean isEmpty();
}
......@@ -122,7 +122,8 @@ public class JetTypeInferrer {
boolean reportUnresolved) {
OverloadDomain overloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(receiverType, scope, name);
overloadDomain = wrapForTracing(overloadDomain, reference, null, reportUnresolved);
return overloadDomain.getFunctionDescriptorForPositionedArguments(Collections.<JetType>emptyList(), argumentTypes);
OverloadResolutionResult resolutionResult = overloadDomain.getFunctionDescriptorForPositionedArguments(Collections.<JetType>emptyList(), argumentTypes);
return resolutionResult.isSuccess() ? resolutionResult.getFunctionDescriptor() : null;
}
......@@ -209,41 +210,54 @@ public class JetTypeInferrer {
@Nullable final OverloadDomain overloadDomain,
@NotNull final JetReferenceExpression referenceExpression,
@Nullable final PsiElement argumentList,
final boolean reportUnresolved) {
final boolean reportErrors) {
if (overloadDomain == null) return OverloadDomain.EMPTY;
return new OverloadDomain() {
@NotNull
@Override
public FunctionDescriptor getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForNamedArguments(typeArguments, valueArgumentTypes, functionLiteralArgumentType);
if (descriptor != null) {
trace.recordReferenceResolution(referenceExpression, descriptor);
}
else {
reportError();
}
return descriptor;
public OverloadResolutionResult getFunctionDescriptorForNamedArguments(@NotNull List<JetType> typeArguments, @NotNull Map<String, JetType> valueArgumentTypes, @Nullable JetType functionLiteralArgumentType) {
OverloadResolutionResult resolutionResult = overloadDomain.getFunctionDescriptorForNamedArguments(typeArguments, valueArgumentTypes, functionLiteralArgumentType);
report(resolutionResult);
return resolutionResult;
}
@NotNull
@Override
public FunctionDescriptor getFunctionDescriptorForPositionedArguments(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
FunctionDescriptor descriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes);
if (descriptor != null) {
trace.recordReferenceResolution(referenceExpression, descriptor);
}
else {
reportError();
}
return descriptor;
public OverloadResolutionResult getFunctionDescriptorForPositionedArguments(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
OverloadResolutionResult resolutionResult = overloadDomain.getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes);
report(resolutionResult);
return resolutionResult;
}
private void reportError() {
if (reportUnresolved) {
if (overloadDomain.isEmpty() || argumentList == null) {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
else {
// TODO : More helpful message. NOTE: there's a separate handling for this for constructors
semanticServices.getErrorHandler().genericError(argumentList.getNode(), "No overload found for these arguments");
private void report(OverloadResolutionResult resolutionResult) {
if (resolutionResult.isSuccess() || resolutionResult.singleFunction()) {
trace.recordReferenceResolution(referenceExpression, resolutionResult.getFunctionDescriptor());
}
if (reportErrors) {
switch (resolutionResult.getResultCode()) {
case NAME_NOT_FOUND:
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
break;
case SINGLE_FUNCTION_ARGUMENT_MISMATCH:
if (argumentList != null) {
// TODO : More helpful message. NOTE: there's a separate handling for this for constructors
semanticServices.getErrorHandler().genericError(argumentList.getNode(), "Arguments do not match " + resolutionResult.getFunctionDescriptor());
}
else {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
break;
case AMBIGUITY:
if (argumentList != null) {
// TODO : More helpful message. NOTE: there's a separate handling for this for constructors
semanticServices.getErrorHandler().genericError(argumentList.getNode(), "Overload ambiguity [TODO : more helpful message]");
}
else {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
break;
default:
// Not a success
}
}
}
......@@ -693,7 +707,9 @@ public class JetTypeInferrer {
}
}
else {
semanticServices.getErrorHandler().genericError(typeElement.getNode(), "Calling a constructor is only supported for ordinary classes"); // TODO : Better message
if (typeElement != null) {
semanticServices.getErrorHandler().genericError(typeElement.getNode(), "Calling a constructor is only supported for ordinary classes"); // TODO : Better message
}
}
}
}
......@@ -799,7 +815,10 @@ public class JetTypeInferrer {
List<JetExpression> positionedValueArguments = new ArrayList<JetExpression>();
for (JetArgument argument : valueArguments) {
positionedValueArguments.add(argument.getArgumentExpression());
JetExpression argumentExpression = argument.getArgumentExpression();
if (argumentExpression != null) {
positionedValueArguments.add(argumentExpression);
}
}
positionedValueArguments.addAll(functionLiteralArguments);
......@@ -809,9 +828,9 @@ public class JetTypeInferrer {
valueArgumentTypes.add(safeGetType(scope, valueArgument, false));
}
FunctionDescriptor functionDescriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(types, valueArgumentTypes);
if (functionDescriptor != null) {
return functionDescriptor.getUnsubstitutedReturnType();
OverloadResolutionResult resolutionResult = overloadDomain.getFunctionDescriptorForPositionedArguments(types, valueArgumentTypes);
if (resolutionResult.isSuccess()) {
return resolutionResult.getFunctionDescriptor().getUnsubstitutedReturnType();
}
}
return null;
......
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public interface Named {
@NotNull
String getName();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册