added different errors instead of ERROR_COMPILE_TIME_VALUE with different text

check type for constants in DataFlowUtils
This commit is contained in:
Svetlana Isakova
2013-09-12 17:25:59 +04:00
parent d556ceedc1
commit 96db2ecabd
30 changed files with 258 additions and 158 deletions
@@ -462,7 +462,8 @@ public class JetControlFlowProcessor {
} }
boolean conditionIsTrueConstant = false; boolean conditionIsTrueConstant = false;
if (condition instanceof JetConstantExpression && condition.getNode().getElementType() == JetNodeTypes.BOOLEAN_CONSTANT) { if (condition instanceof JetConstantExpression && condition.getNode().getElementType() == JetNodeTypes.BOOLEAN_CONSTANT) {
if (BooleanValue.TRUE == new CompileTimeConstantResolver().getBooleanValue(condition.getText(), KotlinBuiltIns.getInstance().getBooleanType())) { if (BooleanValue.TRUE == new CompileTimeConstantResolver().getBooleanValue(
(JetConstantExpression) condition, KotlinBuiltIns.getInstance().getBooleanType())) {
conditionIsTrueConstant = true; conditionIsTrueConstant = true;
} }
} }
@@ -462,7 +462,14 @@ public interface Errors {
// Compile-time values // Compile-time values
DiagnosticFactory1<PsiElement, String> ERROR_COMPILE_TIME_VALUE = DiagnosticFactory1.create(ERROR); DiagnosticFactory0<JetConstantExpression> INT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetConstantExpression> FLOAT_LITERAL_OUT_OF_RANGE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory2<JetConstantExpression, String, JetType> CONSTANT_EXPECTED_TYPE_MISMATCH = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<JetConstantExpression> INCORRECT_CHARACTER_LITERAL = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetConstantExpression> EMPTY_CHARACTER_LITERAL = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<JetConstantExpression, JetConstantExpression> TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<JetElement, JetElement> ILLEGAL_ESCAPE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<JetConstantExpression, JetType> NULL_FOR_NONNULL_TYPE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<JetEscapeStringTemplateEntry> ILLEGAL_ESCAPE_SEQUENCE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<JetEscapeStringTemplateEntry> ILLEGAL_ESCAPE_SEQUENCE = DiagnosticFactory0.create(ERROR);
// Casts and is-checks // Casts and is-checks
@@ -292,7 +292,15 @@ public class DefaultErrorMessages {
MAP.put(CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS, "Class object upper bounds of {0} have empty intersection", NAME); MAP.put(CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS, "Class object upper bounds of {0} have empty intersection", NAME);
MAP.put(TOO_MANY_ARGUMENTS, "Too many arguments for {0}", DescriptorRenderer.TEXT); MAP.put(TOO_MANY_ARGUMENTS, "Too many arguments for {0}", DescriptorRenderer.TEXT);
MAP.put(ERROR_COMPILE_TIME_VALUE, "{0}", TO_STRING);
MAP.put(CONSTANT_EXPECTED_TYPE_MISMATCH, "An {0} literal does not conform to the expected type {1}", TO_STRING, RENDER_TYPE);
MAP.put(INT_LITERAL_OUT_OF_RANGE, "The value is out of range");
MAP.put(FLOAT_LITERAL_OUT_OF_RANGE, "The value is out of range");
MAP.put(INCORRECT_CHARACTER_LITERAL, "Incorrect character literal");
MAP.put(EMPTY_CHARACTER_LITERAL, "Empty character literal");
MAP.put(TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL, "Too many characters in a character literal ''{0}''", ELEMENT_TEXT);
MAP.put(ILLEGAL_ESCAPE, "Illegal escape: ''{0}''", ELEMENT_TEXT);
MAP.put(NULL_FOR_NONNULL_TYPE, "Null can not be a value of a non-null type {0}", RENDER_TYPE);
MAP.put(ELSE_MISPLACED_IN_WHEN, "'else' entry must be the last one in a when-expression"); MAP.put(ELSE_MISPLACED_IN_WHEN, "'else' entry must be the last one in a when-expression");
@@ -42,7 +42,6 @@ import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer;
import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
import org.jetbrains.jet.lang.resolve.constants.ErrorValue;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
@@ -441,14 +440,6 @@ public class CandidateResolver {
JetExpression expression = argument.getArgumentExpression(); JetExpression expression = argument.getArgumentExpression();
if (expression == null) return; if (expression == null) return;
if (expression instanceof JetConstantExpression && !KotlinBuiltIns.getInstance().isUnit(context.expectedType)) {
CompileTimeConstant<?> value =
new CompileTimeConstantResolver().getCompileTimeConstant((JetConstantExpression) expression, context.expectedType);
if (value instanceof ErrorValue) {
context.trace.report(ERROR_COMPILE_TIME_VALUE.on(expression, ((ErrorValue) value).getMessage()));
}
return;
}
DataFlowInfo dataFlowInfoForValueArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(argument); DataFlowInfo dataFlowInfoForValueArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(argument);
ResolutionContext<?> newContext = context.replaceExpectedType(context.expectedType).replaceDataFlowInfo(dataFlowInfoForValueArgument); ResolutionContext<?> newContext = context.replaceExpectedType(context.expectedType).replaceDataFlowInfo(dataFlowInfoForValueArgument);
DataFlowUtils.checkType(type, expression, newContext); DataFlowUtils.checkType(type, expression, newContext);
@@ -17,11 +17,15 @@
package org.jetbrains.jet.lang.resolve.constants; package org.jetbrains.jet.lang.resolve.constants;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Sets;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.diagnostics.AbstractDiagnosticFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.JetConstantExpression;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor; import org.jetbrains.jet.lang.types.TypeConstructor;
@@ -29,40 +33,58 @@ import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.List; import java.util.Set;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.constants.ErrorValue.ErrorValueWithDiagnostic;
public class CompileTimeConstantResolver { public class CompileTimeConstantResolver {
public static final ErrorValue OUT_OF_RANGE = new ErrorValue("The value is out of range");
private final KotlinBuiltIns builtIns; private final KotlinBuiltIns builtIns;
public CompileTimeConstantResolver() { public CompileTimeConstantResolver() {
this.builtIns = KotlinBuiltIns.getInstance(); this.builtIns = KotlinBuiltIns.getInstance();
} }
@Nullable
public Diagnostic checkConstantExpressionType(
@NotNull JetConstantExpression expression,
@NotNull JetType expectedType
) {
CompileTimeConstant<?> compileTimeConstant = getCompileTimeConstant(expression, expectedType);
Set<AbstractDiagnosticFactory> errorsThatDependOnExpectedType =
Sets.<AbstractDiagnosticFactory>newHashSet(CONSTANT_EXPECTED_TYPE_MISMATCH, NULL_FOR_NONNULL_TYPE);
if (compileTimeConstant instanceof ErrorValueWithDiagnostic) {
Diagnostic diagnostic = ((ErrorValueWithDiagnostic) compileTimeConstant).getDiagnostic();
if (errorsThatDependOnExpectedType.contains(diagnostic.getFactory())) {
return diagnostic;
}
}
return null;
}
@NotNull @NotNull
public CompileTimeConstant<?> getCompileTimeConstant( public CompileTimeConstant<?> getCompileTimeConstant(
@NotNull JetConstantExpression expression, @NotNull JetConstantExpression expression,
@NotNull JetType expectedType @NotNull JetType expectedType
) { ) {
IElementType elementType = expression.getNode().getElementType(); IElementType elementType = expression.getNode().getElementType();
String text = expression.getNode().getText();
CompileTimeConstant<?> value; CompileTimeConstant<?> value;
if (elementType == JetNodeTypes.INTEGER_CONSTANT) { if (elementType == JetNodeTypes.INTEGER_CONSTANT) {
value = getIntegerValue(text, expectedType); value = getIntegerValue(expression, expectedType);
} }
else if (elementType == JetNodeTypes.FLOAT_CONSTANT) { else if (elementType == JetNodeTypes.FLOAT_CONSTANT) {
value = getFloatValue(text, expectedType); value = getFloatValue(expression, expectedType);
} }
else if (elementType == JetNodeTypes.BOOLEAN_CONSTANT) { else if (elementType == JetNodeTypes.BOOLEAN_CONSTANT) {
value = getBooleanValue(text, expectedType); value = getBooleanValue(expression, expectedType);
} }
else if (elementType == JetNodeTypes.CHARACTER_CONSTANT) { else if (elementType == JetNodeTypes.CHARACTER_CONSTANT) {
value = getCharValue(text, expectedType); value = getCharValue(expression, expectedType);
} }
else if (elementType == JetNodeTypes.NULL) { else if (elementType == JetNodeTypes.NULL) {
value = getNullValue(expectedType); value = getNullValue(expression, expectedType);
} }
else { else {
throw new IllegalArgumentException("Unsupported constant: " + expression); throw new IllegalArgumentException("Unsupported constant: " + expression);
@@ -70,16 +92,22 @@ public class CompileTimeConstantResolver {
return value; return value;
} }
@NotNull @NotNull
public CompileTimeConstant<?> getIntegerValue(@NotNull String text, @NotNull JetType expectedType) { public CompileTimeConstant<?> getIntegerValue(
return getIntegerValue(parseLongValue(text), expectedType); @NotNull JetConstantExpression expression, @NotNull JetType expectedType
) {
String text = expression.getText();
return getIntegerValue(parseLongValue(text), expectedType, expression);
} }
@NotNull @NotNull
public CompileTimeConstant<?> getIntegerValue(@Nullable Long value, @NotNull JetType expectedType) { public CompileTimeConstant<?> getIntegerValue(
@Nullable Long value,
@NotNull JetType expectedType,
@NotNull JetConstantExpression expression
) {
if (value == null) { if (value == null) {
return OUT_OF_RANGE; return ErrorValue.create(INT_LITERAL_OUT_OF_RANGE.on(expression));
} }
if (noExpectedTypeOrUnitOrError(expectedType)) { if (noExpectedTypeOrUnitOrError(expectedType)) {
if (Integer.MIN_VALUE <= value && value <= Integer.MAX_VALUE) { if (Integer.MIN_VALUE <= value && value <= Integer.MAX_VALUE) {
@@ -116,20 +144,20 @@ public class CompileTimeConstantResolver {
JetType intType = builtIns.getIntType(); JetType intType = builtIns.getIntType();
JetType longType = builtIns.getLongType(); JetType longType = builtIns.getLongType();
if (typeChecker.isSubtypeOf(intType, expectedType)) { if (typeChecker.isSubtypeOf(intType, expectedType)) {
return getIntegerValue(value, intType); return getIntegerValue(value, intType, expression);
} }
else if (typeChecker.isSubtypeOf(longType, expectedType)) { else if (typeChecker.isSubtypeOf(longType, expectedType)) {
return getIntegerValue(value, longType); return getIntegerValue(value, longType, expression);
} }
else { else {
return new ErrorValue("An integer literal does not conform to the expected type " + expectedType); return ErrorValue.create(CONSTANT_EXPECTED_TYPE_MISMATCH.on(expression, "integer", expectedType));
} }
} }
if (value != null && lowerBound <= value && value <= upperBound) { if (value != null && lowerBound <= value && value <= upperBound) {
return create.apply(value); return create.apply(value);
} }
return new ErrorValue("An integer literal does not conform to the expected type " + expectedType); return ErrorValue.create(CONSTANT_EXPECTED_TYPE_MISMATCH.on(expression, "integer", expectedType));
} }
@Nullable @Nullable
@@ -165,41 +193,48 @@ public class CompileTimeConstantResolver {
} }
@NotNull @NotNull
public CompileTimeConstant<?> getFloatValue(@NotNull String text, @NotNull JetType expectedType) { public CompileTimeConstant<?> getFloatValue(
if (noExpectedTypeOrUnitOrError(expectedType) @NotNull JetConstantExpression expression, @NotNull JetType expectedType
|| JetTypeChecker.INSTANCE.isSubtypeOf(builtIns.getDoubleType(), expectedType)) { ) {
try { String text = expression.getText();
try {
if (noExpectedTypeOrUnitOrError(expectedType)
|| JetTypeChecker.INSTANCE.isSubtypeOf(builtIns.getDoubleType(), expectedType)) {
return new DoubleValue(Double.parseDouble(text)); return new DoubleValue(Double.parseDouble(text));
} }
catch (NumberFormatException e) { else if (JetTypeChecker.INSTANCE.isSubtypeOf(builtIns.getFloatType(), expectedType)) {
return OUT_OF_RANGE;
}
}
else if (JetTypeChecker.INSTANCE.isSubtypeOf(builtIns.getFloatType(), expectedType)) {
try {
return new FloatValue(Float.parseFloat(text)); return new FloatValue(Float.parseFloat(text));
} }
catch (NumberFormatException e) { else {
return OUT_OF_RANGE; return ErrorValue.create(CONSTANT_EXPECTED_TYPE_MISMATCH.on(expression, "floating-point", expectedType));
} }
} }
else { catch (NumberFormatException e) {
return new ErrorValue("A floating-point literal does not conform to the expected type " + expectedType); return ErrorValue.create(FLOAT_LITERAL_OUT_OF_RANGE.on(expression));
} }
} }
@Nullable @Nullable
private CompileTimeConstant<?> checkNativeType(String text, JetType expectedType, String title, JetType nativeType) { private CompileTimeConstant<?> checkNativeType(
JetType expectedType,
String title,
JetType nativeType,
JetConstantExpression expression
) {
if (!noExpectedTypeOrUnitOrError(expectedType) if (!noExpectedTypeOrUnitOrError(expectedType)
&& !JetTypeChecker.INSTANCE.isSubtypeOf(nativeType, expectedType)) { && !JetTypeChecker.INSTANCE.isSubtypeOf(nativeType, expectedType)) {
return new ErrorValue("A " + title + " literal " + text + " does not conform to the expected type " + expectedType);
return ErrorValue.create(CONSTANT_EXPECTED_TYPE_MISMATCH.on(expression, title, expectedType));
} }
return null; return null;
} }
@NotNull @NotNull
public CompileTimeConstant<?> getBooleanValue(@NotNull String text, @NotNull JetType expectedType) { public CompileTimeConstant<?> getBooleanValue(
CompileTimeConstant<?> error = checkNativeType(text, expectedType, "boolean", builtIns.getBooleanType()); @NotNull JetConstantExpression expression, @NotNull JetType expectedType
) {
String text = expression.getText();
CompileTimeConstant<?> error = checkNativeType(expectedType, "boolean", builtIns.getBooleanType(), expression);
if (error != null) { if (error != null) {
return error; return error;
} }
@@ -213,20 +248,23 @@ public class CompileTimeConstantResolver {
} }
@NotNull @NotNull
public CompileTimeConstant<?> getCharValue(@NotNull String text, @NotNull JetType expectedType) { public CompileTimeConstant<?> getCharValue(
CompileTimeConstant<?> error = checkNativeType(text, expectedType, "character", builtIns.getCharType()); @NotNull JetConstantExpression expression, @NotNull JetType expectedType
) {
String text = expression.getText();
CompileTimeConstant<?> error = checkNativeType(expectedType, "character", builtIns.getCharType(), expression);
if (error != null) { if (error != null) {
return error; return error;
} }
// Strip the quotes // Strip the quotes
if (text.length() < 2 || text.charAt(0) != '\'' || text.charAt(text.length() - 1) != '\'') { if (text.length() < 2 || text.charAt(0) != '\'' || text.charAt(text.length() - 1) != '\'') {
return new ErrorValue("Incorrect character literal"); return ErrorValue.create(INCORRECT_CHARACTER_LITERAL.on(expression));
} }
text = text.substring(1, text.length() - 1); // now there're no quotes text = text.substring(1, text.length() - 1); // now there're no quotes
if (text.length() == 0) { if (text.length() == 0) {
return new ErrorValue("Empty character literal"); return ErrorValue.create(EMPTY_CHARACTER_LITERAL.on(expression));
} }
if (text.charAt(0) != '\\') { if (text.charAt(0) != '\\') {
@@ -234,13 +272,16 @@ public class CompileTimeConstantResolver {
if (text.length() == 1) { if (text.length() == 1) {
return new CharValue(text.charAt(0)); return new CharValue(text.charAt(0));
} }
return new ErrorValue("Too many characters in a character literal '" + text + "'"); return ErrorValue.create(TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL.on(expression, expression));
} }
return escapedStringToCharValue(text); return escapedStringToCharValue(text, expression);
} }
@NotNull @NotNull
public static CompileTimeConstant<?> escapedStringToCharValue(@NotNull String text) { public static CompileTimeConstant<?> escapedStringToCharValue(
@NotNull String text,
@NotNull JetElement expression
) {
assert text.length() > 0 && text.charAt(0) == '\\' : "Only escaped sequences must be passed to this routine: " + text; assert text.length() > 0 && text.charAt(0) == '\\' : "Only escaped sequences must be passed to this routine: " + text;
// Escape // Escape
@@ -248,12 +289,12 @@ public class CompileTimeConstantResolver {
switch (escape.length()) { switch (escape.length()) {
case 0: case 0:
// bare slash // bare slash
return illegalEscape(text); return illegalEscape(expression);
case 1: case 1:
// one-char escape // one-char escape
Character escaped = translateEscape(escape.charAt(0)); Character escaped = translateEscape(escape.charAt(0));
if (escaped == null) { if (escaped == null) {
return illegalEscape(text); return illegalEscape(expression);
} }
return new CharValue(escaped); return new CharValue(escaped);
case 5: case 5:
@@ -268,11 +309,14 @@ public class CompileTimeConstantResolver {
} }
break; break;
} }
return illegalEscape(text); return illegalEscape(expression);
} }
private static ErrorValue illegalEscape(String text) { @NotNull
return new ErrorValue("Illegal escape: " + text); private static CompileTimeConstant<?> illegalEscape(
@NotNull JetElement expression
) {
return ErrorValue.create(ILLEGAL_ESCAPE.on(expression, expression));
} }
@Nullable @Nullable
@@ -299,11 +343,13 @@ public class CompileTimeConstantResolver {
} }
@NotNull @NotNull
public CompileTimeConstant<?> getNullValue(@NotNull JetType expectedType) { public CompileTimeConstant<?> getNullValue(
@NotNull JetConstantExpression expression, @NotNull JetType expectedType
) {
if (noExpectedTypeOrUnitOrError(expectedType) || expectedType.isNullable()) { if (noExpectedTypeOrUnitOrError(expectedType) || expectedType.isNullable()) {
return NullValue.NULL; return NullValue.NULL;
} }
return new ErrorValue("Null can not be a value of a non-null type " + expectedType); return ErrorValue.create(NULL_FOR_NONNULL_TYPE.on(expression, expectedType));
} }
private static boolean noExpectedTypeOrUnitOrError(JetType expectedType) { private static boolean noExpectedTypeOrUnitOrError(JetType expectedType) {
@@ -18,16 +18,13 @@ package org.jetbrains.jet.lang.resolve.constants;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.rendering.DefaultErrorMessages;
import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
public class ErrorValue implements CompileTimeConstant<Void> { public abstract class ErrorValue implements CompileTimeConstant<Void> {
private final String message;
public ErrorValue(@NotNull String message) {
this.message = message;
}
@Override @Override
@Deprecated // Should not be called, for this is not a real value, but a indication of an error @Deprecated // Should not be called, for this is not a real value, but a indication of an error
@@ -35,24 +32,62 @@ public class ErrorValue implements CompileTimeConstant<Void> {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@NotNull
@Override
public JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns) {
return ErrorUtils.createErrorType(message);
}
@Override @Override
public <R, D> R accept(AnnotationArgumentVisitor<R, D> visitor, D data) { public <R, D> R accept(AnnotationArgumentVisitor<R, D> visitor, D data) {
return visitor.visitErrorValue(this, data); return visitor.visitErrorValue(this, data);
} }
@NotNull public static ErrorValue create(@NotNull String message) {
public String getMessage() { return new ErrorValueWithMessage(message);
return message;
} }
@Override public static ErrorValue create(@NotNull Diagnostic diagnostic) {
public String toString() { return new ErrorValueWithDiagnostic(diagnostic);
return message; }
public static class ErrorValueWithMessage extends ErrorValue {
private final String message;
public ErrorValueWithMessage(@NotNull String message) {
this.message = message;
}
public String getMessage() {
return message;
}
@NotNull
@Override
public JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns) {
return ErrorUtils.createErrorType(message);
}
@Override
public String toString() {
return getMessage();
}
}
public static class ErrorValueWithDiagnostic extends ErrorValue {
private final Diagnostic diagnostic;
public ErrorValueWithDiagnostic(@NotNull Diagnostic diagnostic) {
this.diagnostic = diagnostic;
}
public Diagnostic getDiagnostic() {
return diagnostic;
}
@NotNull
@Override
public JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns) {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
return DefaultErrorMessages.RENDERER.render(diagnostic);
}
} }
} }
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorUtil; import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorUtil;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.*;
@@ -68,6 +69,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getStaticNestedClassesScope; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getStaticNestedClassesScope;
import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.DEPENDENT; import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.DEPENDENT;
import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.INDEPENDENT; import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.INDEPENDENT;
import static org.jetbrains.jet.lang.resolve.constants.ErrorValue.ErrorValueWithDiagnostic;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType; import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType;
@@ -145,10 +147,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
CompileTimeConstant<?> value = compileTimeConstantResolver.getCompileTimeConstant(expression, context.expectedType); CompileTimeConstant<?> value = compileTimeConstantResolver.getCompileTimeConstant(expression, context.expectedType);
if (value instanceof ErrorValue) { if (value instanceof ErrorValue) {
// 'checkType' for 'ContextDependency.DEPENDENT' will take place in 'completeInferenceForArgument' assert value instanceof ErrorValueWithDiagnostic;
if (context.contextDependency == INDEPENDENT) { //noinspection CastConflictsWithInstanceof
context.trace.report(ERROR_COMPILE_TIME_VALUE.on(expression, ((ErrorValue) value).getMessage())); context.trace.report(((ErrorValueWithDiagnostic)value).getDiagnostic());
}
return JetTypeInfo.create(getDefaultType(elementType), context.dataFlowInfo); return JetTypeInfo.create(getDefaultType(elementType), context.dataFlowInfo);
} }
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, value); context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, value);
@@ -1106,9 +1107,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
public JetTypeInfo visitStringTemplateExpression(JetStringTemplateExpression expression, ExpressionTypingContext contextWithExpectedType) { public JetTypeInfo visitStringTemplateExpression(JetStringTemplateExpression expression, ExpressionTypingContext contextWithExpectedType) {
final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT); final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
final CompileTimeConstant<?>[] value = new CompileTimeConstant<?>[1]; final boolean[] isCompileTimeValue = new boolean[] { true };
final DataFlowInfo[] dataFlowInfo = new DataFlowInfo[1]; final DataFlowInfo[] dataFlowInfo = new DataFlowInfo[] { context.dataFlowInfo };
dataFlowInfo[0] = context.dataFlowInfo;
for (JetStringTemplateEntry entry : expression.getEntries()) { for (JetStringTemplateEntry entry : expression.getEntries()) {
entry.accept(new JetVisitorVoid() { entry.accept(new JetVisitorVoid() {
@@ -1120,7 +1120,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetTypeInfo typeInfo = facade.getTypeInfo(entryExpression, context.replaceDataFlowInfo(dataFlowInfo[0])); JetTypeInfo typeInfo = facade.getTypeInfo(entryExpression, context.replaceDataFlowInfo(dataFlowInfo[0]));
dataFlowInfo[0] = typeInfo.getDataFlowInfo(); dataFlowInfo[0] = typeInfo.getDataFlowInfo();
} }
value[0] = CompileTimeConstantResolver.OUT_OF_RANGE; isCompileTimeValue[0] = false;
} }
@Override @Override
@@ -1130,12 +1130,12 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override @Override
public void visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry) { public void visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry) {
String text = entry.getText(); CompileTimeConstant<?> character = CompileTimeConstantResolver.escapedStringToCharValue(entry.getText(), entry);
CompileTimeConstant<?> character = CompileTimeConstantResolver.escapedStringToCharValue(text);
if (character instanceof ErrorValue) { if (character instanceof ErrorValue) {
context.trace.report(ILLEGAL_ESCAPE_SEQUENCE.on(entry)); assert character instanceof ErrorValueWithDiagnostic;
value[0] = CompileTimeConstantResolver.OUT_OF_RANGE; //noinspection CastConflictsWithInstanceof
context.trace.report(((ErrorValueWithDiagnostic) character).getDiagnostic());
isCompileTimeValue[0] = false;
} }
else { else {
builder.append(((CharValue) character).getValue()); builder.append(((CharValue) character).getValue());
@@ -1143,7 +1143,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
}); });
} }
if (value[0] != CompileTimeConstantResolver.OUT_OF_RANGE) { if (isCompileTimeValue[0]) {
context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new StringValue(builder.toString())); context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new StringValue(builder.toString()));
} }
return DataFlowUtils.checkType(KotlinBuiltIns.getInstance().getStringType(), expression, contextWithExpectedType, dataFlowInfo[0]); return DataFlowUtils.checkType(KotlinBuiltIns.getInstance().getStringType(), expression, contextWithExpectedType, dataFlowInfo[0]);
@@ -20,13 +20,16 @@ import com.intellij.openapi.util.Ref;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency;
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.lang.types.JetTypeInfo;
@@ -168,6 +171,15 @@ public class DataFlowUtils {
return expressionType; return expressionType;
} }
if (expression instanceof JetConstantExpression) {
Diagnostic diagnostic =
new CompileTimeConstantResolver().checkConstantExpressionType((JetConstantExpression) expression, expectedType);
if (diagnostic != null) {
trace.report(diagnostic);
}
return expressionType;
}
DataFlowValue dataFlowValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(expression, expressionType, trace.getBindingContext()); DataFlowValue dataFlowValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(expression, expressionType, trace.getBindingContext());
for (JetType possibleType : dataFlowInfo.getPossibleTypes(dataFlowValue)) { for (JetType possibleType : dataFlowInfo.getPossibleTypes(dataFlowValue)) {
if (JetTypeChecker.INSTANCE.isSubtypeOf(possibleType, expectedType)) { if (JetTypeChecker.INSTANCE.isSubtypeOf(possibleType, expectedType)) {
@@ -462,7 +462,7 @@ public class ExpressionTypingUtils {
@Override @Override
public void report(@NotNull Diagnostic diagnostic) { public void report(@NotNull Diagnostic diagnostic) {
AbstractDiagnosticFactory factory = diagnostic.getFactory(); AbstractDiagnosticFactory factory = diagnostic.getFactory();
if ((factory == TYPE_MISMATCH || factory == ERROR_COMPILE_TIME_VALUE) if ((factory == TYPE_MISMATCH || factory == CONSTANT_EXPECTED_TYPE_MISMATCH)
&& diagnostic.getPsiElement() == expressionToWatch) { && diagnostic.getPsiElement() == expressionToWatch) {
mismatchFound[0] = true; mismatchFound[0] = true;
} }
@@ -1,13 +1,13 @@
fun test(<!UNUSED_PARAMETER!>c<!> : Char) { fun test(<!UNUSED_PARAMETER!>c<!> : Char) {
test(<!ERROR_COMPILE_TIME_VALUE!>''<!>) test(<!EMPTY_CHARACTER_LITERAL!>''<!>)
test('a') test('a')
test(<!ERROR_COMPILE_TIME_VALUE!>'aa'<!>) test(<!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>'aa'<!>)
test(<!ERROR_COMPILE_TIME_VALUE!>'a)<!> test(<!INCORRECT_CHARACTER_LITERAL!>'a)<!>
<!UNRESOLVED_REFERENCE!>test<!>(<!ERROR_COMPILE_TIME_VALUE!>'<!> <!UNRESOLVED_REFERENCE!>test<!>(<!INCORRECT_CHARACTER_LITERAL!>'<!>
<!UNRESOLVED_REFERENCE!>test<!>(0<!SYNTAX!><!SYNTAX!><!>'<!> <!UNRESOLVED_REFERENCE!>test<!>(0<!SYNTAX!><!SYNTAX!><!>'<!>
test('\n') test('\n')
test('\\') test('\\')
test(<!ERROR_COMPILE_TIME_VALUE!>''<!><!SYNTAX!>''<!><!SYNTAX!>)<!> test(<!EMPTY_CHARACTER_LITERAL!>''<!><!SYNTAX!>''<!><!SYNTAX!>)<!>
test('\'') test('\'')
test('\"') test('\"')
} }
@@ -25,20 +25,20 @@ fun test() {
1e5: Double 1e5: Double
1e-5: Float 1e-5: Float
<!ERROR_COMPILE_TIME_VALUE!>1<!>: Double <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>: Double
<!ERROR_COMPILE_TIME_VALUE!>1<!>: Float <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>: Float
1 <!USELESS_CAST!>as<!> Byte 1 <!USELESS_CAST!>as<!> Byte
1 <!USELESS_CAST!>as<!> Int 1 <!USELESS_CAST!>as<!> Int
0xff <!USELESS_CAST!>as<!> Long 0xff <!USELESS_CAST!>as<!> Long
<!ERROR_COMPILE_TIME_VALUE!>1.1<!> <!CAST_NEVER_SUCCEEDS!>as<!> Int <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.1<!> <!CAST_NEVER_SUCCEEDS!>as<!> Int
<!ERROR_COMPILE_TIME_VALUE!>1.1<!>: Int <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.1<!>: Int
varargByte(0x77, 1, 3, <!ERROR_COMPILE_TIME_VALUE!>200<!>, 0b111) varargByte(0x77, 1, 3, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>200<!>, 0b111)
varargShort(0x777, 1, 2, 3, <!ERROR_COMPILE_TIME_VALUE!>200000<!>, 0b111) varargShort(0x777, 1, 2, 3, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>200000<!>, 0b111)
varargInt(0x77777777, <!ERROR_COMPILE_TIME_VALUE!>0x7777777777<!>, 1, 2, 3, 2000000000, 0b111) varargInt(0x77777777, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>0x7777777777<!>, 1, 2, 3, 2000000000, 0b111)
varargLong(0x777777777777, 1, 2, 3, 200000, 0b111) varargLong(0x777777777777, 1, 2, 3, 200000, 0b111)
varargFloat(<!ERROR_COMPILE_TIME_VALUE!>1<!>, 1.0, <!TYPE_MISMATCH!>-0.1<!>, 1e4, 1e-4, <!TYPE_MISMATCH!>-1e4<!>) varargFloat(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, 1.0, <!TYPE_MISMATCH!>-0.1<!>, 1e4, 1e-4, <!TYPE_MISMATCH!>-1e4<!>)
varargDouble(<!ERROR_COMPILE_TIME_VALUE!>1<!>, 1.0, -0.1, 1e4, 1e-4, -1e4) varargDouble(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, 1.0, -0.1, 1e4, 1e-4, -1e4)
} }
@@ -2,11 +2,11 @@
// KT-451 Incorrect character literals cause assertion failures // KT-451 Incorrect character literals cause assertion failures
fun ff() { fun ff() {
val <!UNUSED_VARIABLE!>b<!> = <!ERROR_COMPILE_TIME_VALUE!>''<!> val <!UNUSED_VARIABLE!>b<!> = <!EMPTY_CHARACTER_LITERAL!>''<!>
val <!UNUSED_VARIABLE!>c<!> = <!ERROR_COMPILE_TIME_VALUE!>'23'<!> val <!UNUSED_VARIABLE!>c<!> = <!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>'23'<!>
val <!UNUSED_VARIABLE!>d<!> = <!ERROR_COMPILE_TIME_VALUE!>'a<!> val <!UNUSED_VARIABLE!>d<!> = <!INCORRECT_CHARACTER_LITERAL!>'a<!>
val <!UNUSED_VARIABLE!>e<!> = <!ERROR_COMPILE_TIME_VALUE!>'ab<!> val <!UNUSED_VARIABLE!>e<!> = <!INCORRECT_CHARACTER_LITERAL!>'ab<!>
val <!UNUSED_VARIABLE!>f<!> = <!ERROR_COMPILE_TIME_VALUE!>'\'<!> val <!UNUSED_VARIABLE!>f<!> = <!ILLEGAL_ESCAPE!>'\'<!>
} }
fun test() { fun test() {
@@ -19,19 +19,19 @@ fun test() {
<!UNUSED_EXPRESSION!>'\''<!> <!UNUSED_EXPRESSION!>'\''<!>
<!UNUSED_EXPRESSION!>'\\'<!> <!UNUSED_EXPRESSION!>'\\'<!>
<!UNUSED_EXPRESSION!>'\$'<!> <!UNUSED_EXPRESSION!>'\$'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\x'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\x'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\123'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\123'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\ra'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\ra'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\000'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\000'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\000'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\000'<!>
<!UNUSED_EXPRESSION!>'\u0000'<!> <!UNUSED_EXPRESSION!>'\u0000'<!>
<!UNUSED_EXPRESSION!>'\u000a'<!> <!UNUSED_EXPRESSION!>'\u000a'<!>
<!UNUSED_EXPRESSION!>'\u000A'<!> <!UNUSED_EXPRESSION!>'\u000A'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\u'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\u'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\u0'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\u0'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\u00'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\u00'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\u000'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\u000'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\u000z'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\u000z'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\\u000'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\\u000'<!>
<!ERROR_COMPILE_TIME_VALUE, UNUSED_EXPRESSION!>'\'<!> <!ILLEGAL_ESCAPE, UNUSED_EXPRESSION!>'\'<!>
} }
@@ -24,7 +24,7 @@ fun test(<!UNUSED_PARAMETER!>l<!> : <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>java.util
Collections.<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>emptyList<!>() Collections.<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>emptyList<!>()
Collections.singleton<Int>(1) : Set<Int>? Collections.singleton<Int>(1) : Set<Int>?
Collections.singleton<Int>(<!ERROR_COMPILE_TIME_VALUE!>1.0<!>) Collections.singleton<Int>(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!>)
<!UNRESOLVED_REFERENCE!>List<!><Int> <!UNRESOLVED_REFERENCE!>List<!><Int>
@@ -11,12 +11,12 @@ fun demo() {
<!UNUSED_EXPRESSION!>"$"<!> <!UNUSED_EXPRESSION!>"$"<!>
<!UNUSED_EXPRESSION!>"$.$.asdf$\t"<!> <!UNUSED_EXPRESSION!>"$.$.asdf$\t"<!>
<!UNUSED_EXPRESSION!>"asd\$"<!> <!UNUSED_EXPRESSION!>"asd\$"<!>
<!UNUSED_EXPRESSION!>"asd$a<!ILLEGAL_ESCAPE_SEQUENCE!>\x<!>"<!> <!UNUSED_EXPRESSION!>"asd$a<!ILLEGAL_ESCAPE!>\x<!>"<!>
<!UNUSED_EXPRESSION!>"asd$a$asd$ $<!UNRESOLVED_REFERENCE!>xxx<!>"<!> <!UNUSED_EXPRESSION!>"asd$a$asd$ $<!UNRESOLVED_REFERENCE!>xxx<!>"<!>
<!UNUSED_EXPRESSION!>"fosdfasdo${1 + bar + 100}}sdsdfgdsfsdf"<!> <!UNUSED_EXPRESSION!>"fosdfasdo${1 + bar + 100}}sdsdfgdsfsdf"<!>
<!UNUSED_EXPRESSION!>"foo${bar + map {foo}}sdfsdf"<!> <!UNUSED_EXPRESSION!>"foo${bar + map {foo}}sdfsdf"<!>
<!UNUSED_EXPRESSION!>"foo${bar + map { "foo" }}sdfsdf"<!> <!UNUSED_EXPRESSION!>"foo${bar + map { "foo" }}sdfsdf"<!>
<!UNUSED_EXPRESSION!>"foo${bar + map { <!UNUSED_EXPRESSION!>"foo${bar + map {
"foo$sdf${ buzz{}}" }}sdfsdf"<!> "foo$sdf${ buzz{}}" }}sdfsdf"<!>
<!UNUSED_EXPRESSION!>"a<!ILLEGAL_ESCAPE_SEQUENCE!>\u<!> <!ILLEGAL_ESCAPE_SEQUENCE!>\u<!>0 <!ILLEGAL_ESCAPE_SEQUENCE!>\u<!>00 <!ILLEGAL_ESCAPE_SEQUENCE!>\u<!>000 \u0000 \u0AaA <!ILLEGAL_ESCAPE_SEQUENCE!>\u<!>0AAz.length( ) + \u0022b"<!> <!UNUSED_EXPRESSION!>"a<!ILLEGAL_ESCAPE!>\u<!> <!ILLEGAL_ESCAPE!>\u<!>0 <!ILLEGAL_ESCAPE!>\u<!>00 <!ILLEGAL_ESCAPE!>\u<!>000 \u0000 \u0AaA <!ILLEGAL_ESCAPE!>\u<!>0AAz.length( ) + \u0022b"<!>
} }
@@ -10,7 +10,7 @@ fun test() {
v1() v1()
v1({}) v1({})
v1({}, {}) v1({}, {})
v1({}, <!ERROR_COMPILE_TIME_VALUE!>1<!>, {}) v1({}, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, {})
v1({}, {}, {it}) v1({}, {}, {it})
v1({}) <!VARARG_OUTSIDE_PARENTHESES, DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED!>{}<!> v1({}) <!VARARG_OUTSIDE_PARENTHESES, DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED!>{}<!>
v1 <!VARARG_OUTSIDE_PARENTHESES, DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED!>{}<!> v1 <!VARARG_OUTSIDE_PARENTHESES, DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED!>{}<!>
@@ -12,17 +12,17 @@ fun test() {
bar <!TOO_MANY_ARGUMENTS, DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED!>{ }<!> bar <!TOO_MANY_ARGUMENTS, DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED!>{ }<!>
foo(<!TYPE_MISMATCH!>""<!>, <!ERROR_COMPILE_TIME_VALUE!>1<!>, <!UNRESOLVED_REFERENCE, TOO_MANY_ARGUMENTS!>xx<!>) foo(<!TYPE_MISMATCH!>""<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, <!UNRESOLVED_REFERENCE, TOO_MANY_ARGUMENTS!>xx<!>)
foo(<!NAMED_PARAMETER_NOT_FOUND!>r<!> = <!UNRESOLVED_REFERENCE!>xx<!>, i = <!TYPE_MISMATCH!>""<!>, s = "") foo(<!NAMED_PARAMETER_NOT_FOUND!>r<!> = <!UNRESOLVED_REFERENCE!>xx<!>, i = <!TYPE_MISMATCH!>""<!>, s = "")
foo(i = 1, <!ARGUMENT_PASSED_TWICE!>i<!> = 1, s = <!ERROR_COMPILE_TIME_VALUE!>11<!>) foo(i = 1, <!ARGUMENT_PASSED_TWICE!>i<!> = 1, s = <!CONSTANT_EXPECTED_TYPE_MISMATCH!>11<!>)
foo(<!TYPE_MISMATCH!>""<!>, s = <!ERROR_COMPILE_TIME_VALUE!>2<!>) foo(<!TYPE_MISMATCH!>""<!>, s = <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>)
foo(i = <!TYPE_MISMATCH!>""<!>, s = <!ERROR_COMPILE_TIME_VALUE!>2<!>, <!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>33<!>) foo(i = <!TYPE_MISMATCH!>""<!>, s = <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>, <!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>33<!>)
foo(<!TYPE_MISMATCH!>""<!>, <!ERROR_COMPILE_TIME_VALUE!>1<!>) <!TOO_MANY_ARGUMENTS!>{}<!> foo(<!TYPE_MISMATCH!>""<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>) <!TOO_MANY_ARGUMENTS!>{}<!>
foo(<!TYPE_MISMATCH!>""<!>, <!ERROR_COMPILE_TIME_VALUE!>1<!>) <!TOO_MANY_ARGUMENTS!>{}<!> <!MANY_FUNCTION_LITERAL_ARGUMENTS!>{}<!> foo(<!TYPE_MISMATCH!>""<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>) <!TOO_MANY_ARGUMENTS!>{}<!> <!MANY_FUNCTION_LITERAL_ARGUMENTS!>{}<!>
} }
@@ -6,7 +6,7 @@ fun bar<T>(a: T, b: Map<T, String>) = b.get(a)
fun test(a: Int) { fun test(a: Int) {
foo(a, null) foo(a, null)
bar(a, <!ERROR_COMPILE_TIME_VALUE!>null<!>) bar(a, <!NULL_FOR_NONNULL_TYPE!>null<!>)
} }
fun test1(a: Int) { fun test1(a: Int) {
<!UNREACHABLE_CODE!>foo(a, throw Exception())<!> <!UNREACHABLE_CODE!>foo(a, throw Exception())<!>
@@ -18,6 +18,6 @@ public class Y extends X<String> {
fun main() { fun main() {
Y().fooN() : Any Y().fooN() : Any
Y().barN(<!ERROR_COMPILE_TIME_VALUE!>null<!>); Y().barN(<!NULL_FOR_NONNULL_TYPE!>null<!>);
} }
@@ -18,6 +18,6 @@ public class Y extends X<A> {
fun main() { fun main() {
Y().fooN() : Any Y().fooN() : Any
Y().barN(<!ERROR_COMPILE_TIME_VALUE!>null<!>); Y().barN(<!NULL_FOR_NONNULL_TYPE!>null<!>);
} }
@@ -5,12 +5,12 @@ fun foo(i: Int) = i
fun bar(l: Long) = l fun bar(l: Long) = l
fun main(args: Array<String>) { fun main(args: Array<String>) {
val <!UNUSED_VARIABLE!>i<!> = <!ERROR_COMPILE_TIME_VALUE!>111111111111111777777777777777<!> val <!UNUSED_VARIABLE!>i<!> = <!INT_LITERAL_OUT_OF_RANGE!>111111111111111777777777777777<!>
//todo add diagnostic text messages //todo add diagnostic text messages
//report only 'The value is out of range' //report only 'The value is out of range'
//not 'An integer literal does not conform to the expected type Int/Long' //not 'An integer literal does not conform to the expected type Int/Long'
val <!UNUSED_VARIABLE!>l<!>: Long = <!ERROR_COMPILE_TIME_VALUE!>1111111111111117777777777777777<!> val <!UNUSED_VARIABLE!>l<!>: Long = <!INT_LITERAL_OUT_OF_RANGE!>1111111111111117777777777777777<!>
foo(<!ERROR_COMPILE_TIME_VALUE!>11111111111111177777777777777<!>) foo(<!INT_LITERAL_OUT_OF_RANGE!>11111111111111177777777777777<!>)
bar(<!ERROR_COMPILE_TIME_VALUE!>11111111111111177777777777777<!>) bar(<!INT_LITERAL_OUT_OF_RANGE!>11111111111111177777777777777<!>)
} }
@@ -26,9 +26,9 @@ fun test() {
val <!UNUSED_VARIABLE!>g<!>: Byte = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>either<!>(1, 300) val <!UNUSED_VARIABLE!>g<!>: Byte = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>either<!>(1, 300)
other(<!ERROR_COMPILE_TIME_VALUE!>11<!>) other(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>11<!>)
<!TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH!>otherGeneric<!>(<!ERROR_COMPILE_TIME_VALUE!>1<!>) <!TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH!>otherGeneric<!>(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
val r = either(1, "") val r = either(1, "")
<!TYPE_MISMATCH!>r<!>: Int <!TYPE_MISMATCH!>r<!>: Int
@@ -8,9 +8,9 @@ fun main(args : Array<String>) {
val <!UNUSED_VARIABLE!>h<!> : String = <!TYPE_MISMATCH!>v--<!>; val <!UNUSED_VARIABLE!>h<!> : String = <!TYPE_MISMATCH!>v--<!>;
val <!UNUSED_VARIABLE!>h1<!> : String = <!TYPE_MISMATCH!>--v<!>; val <!UNUSED_VARIABLE!>h1<!> : String = <!TYPE_MISMATCH!>--v<!>;
val <!UNUSED_VARIABLE!>i<!> : String = <!TYPE_MISMATCH!>!true<!>; val <!UNUSED_VARIABLE!>i<!> : String = <!TYPE_MISMATCH!>!true<!>;
val <!UNUSED_VARIABLE!>j<!> : String = <!TYPE_MISMATCH!>@foo <!ERROR_COMPILE_TIME_VALUE!>true<!><!>; val <!UNUSED_VARIABLE!>j<!> : String = <!TYPE_MISMATCH!>@foo <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!><!>;
val <!UNUSED_VARIABLE!>j1<!> : String = <!TYPE_MISMATCH!>@ <!ERROR_COMPILE_TIME_VALUE!>true<!><!>; val <!UNUSED_VARIABLE!>j1<!> : String = <!TYPE_MISMATCH!>@ <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!><!>;
val <!UNUSED_VARIABLE!>j2<!> : String = <!TYPE_MISMATCH!>@@ <!ERROR_COMPILE_TIME_VALUE!>true<!><!>; val <!UNUSED_VARIABLE!>j2<!> : String = <!TYPE_MISMATCH!>@@ <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!><!>;
val <!UNUSED_VARIABLE!>k<!> : String = <!TYPE_MISMATCH!>-1<!>; val <!UNUSED_VARIABLE!>k<!> : String = <!TYPE_MISMATCH!>-1<!>;
val <!UNUSED_VARIABLE!>l<!> : String = <!TYPE_MISMATCH!>+1<!>; val <!UNUSED_VARIABLE!>l<!> : String = <!TYPE_MISMATCH!>+1<!>;
} }
@@ -35,7 +35,7 @@ fun t3() : String {
<!RETURN_NOT_ALLOWED!>return@t3 "1"<!> <!RETURN_NOT_ALLOWED!>return@t3 "1"<!>
} }
else { else {
<!RETURN_NOT_ALLOWED!>return <!ERROR_COMPILE_TIME_VALUE!>2<!><!> <!RETURN_NOT_ALLOWED!>return <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!><!>
} }
<!RETURN_NOT_ALLOWED_EXPLICIT_RETURN_TYPE_REQUIRED!>return@ 0<!> <!RETURN_NOT_ALLOWED_EXPLICIT_RETURN_TYPE_REQUIRED!>return@ 0<!>
} }
@@ -189,7 +189,7 @@ public class CheckerTestUtilTest extends JetLiteFixture {
private final List<DiagnosticData> diagnostics = Lists.newArrayList( private final List<DiagnosticData> diagnostics = Lists.newArrayList(
new DiagnosticData(0, 0, "UNUSED_PARAMETER", 8, 9), new DiagnosticData(0, 0, "UNUSED_PARAMETER", 8, 9),
new DiagnosticData(1, 1, "TYPE_MISMATCH", 56, 57), new DiagnosticData(1, 1, "CONSTANT_EXPECTED_TYPE_MISMATCH", 56, 57),
new DiagnosticData(2, 2, "UNUSED_VARIABLE", 67, 68), new DiagnosticData(2, 2, "UNUSED_VARIABLE", 67, 68),
new DiagnosticData(3, 3, "TYPE_MISMATCH", 98, 99), new DiagnosticData(3, 3, "TYPE_MISMATCH", 98, 99),
new DiagnosticData(4, 4, "NONE_APPLICABLE", 120, 121), new DiagnosticData(4, 4, "NONE_APPLICABLE", 120, 121),
@@ -172,7 +172,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
@Override @Override
public void visit(String name, Object value) { public void visit(String name, Object value) {
CompileTimeConstant<?> argument = JavaAnnotationArgumentResolver.resolveCompileTimeConstantValue(value, null); CompileTimeConstant<?> argument = JavaAnnotationArgumentResolver.resolveCompileTimeConstantValue(value, null);
setArgumentValueByName(name, argument != null ? argument : new ErrorValue("Unsupported annotation argument: " + name)); setArgumentValueByName(name, argument != null ? argument : ErrorValue.create("Unsupported annotation argument: " + name));
} }
@Override @Override
@@ -196,7 +196,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
} }
} }
} }
return new ErrorValue("Unresolved enum entry: " + enumFqName + "." + name); return ErrorValue.create("Unresolved enum entry: " + enumFqName + "." + name);
} }
@Override @Override
@@ -164,7 +164,7 @@ public class JetPsiChecker implements Annotator {
return; return;
} }
if (diagnostic.getFactory() == Errors.ILLEGAL_ESCAPE_SEQUENCE) { if (diagnostic.getFactory() == Errors.ILLEGAL_ESCAPE) {
for (TextRange textRange : diagnostic.getTextRanges()) { for (TextRange textRange : diagnostic.getTextRanges()) {
Annotation annotation = holder.createErrorAnnotation(textRange, getDefaultMessage(diagnostic)); Annotation annotation = holder.createErrorAnnotation(textRange, getDefaultMessage(diagnostic));
annotation.setTooltip(getMessage(diagnostic)); annotation.setTooltip(getMessage(diagnostic));
@@ -1,5 +1,5 @@
// "Change 'prop' type to 'Int'" "true" // "Change 'prop' type to 'Int'" "true"
// ERROR: Null can not be a value of a non-null type Int // ERROR: Null can not be a value of a non-null type jet.Int
trait Test<T> { trait Test<T> {
val prop : T val prop : T
} }
@@ -1,5 +1,5 @@
// "Change 'prop' type to 'Int'" "true" // "Change 'prop' type to 'Int'" "true"
// ERROR: Null can not be a value of a non-null type Int // ERROR: Null can not be a value of a non-null type jet.Int
trait Test<T> { trait Test<T> {
val prop : T val prop : T
} }
@@ -1,5 +1,5 @@
// "Change 'A.component2' function return type to 'Unit'" "true" // "Change 'A.component2' function return type to 'Unit'" "true"
// ERROR: <html>Type mismatch.<table><tr><td>Required:</td><td>jet.Unit</td></tr><tr><td>Found:</td><td>jet.Int</td></tr></table></html> // ERROR: An integer literal does not conform to the expected type jet.Unit
abstract class A { abstract class A {
abstract fun component1(): Int abstract fun component1(): Int
fun component2(): Unit = 42 fun component2(): Unit = 42
@@ -1,5 +1,5 @@
// "Change 'A.component2' function return type to 'Unit'" "true" // "Change 'A.component2' function return type to 'Unit'" "true"
// ERROR: <html>Type mismatch.<table><tr><td>Required:</td><td>jet.Unit</td></tr><tr><td>Found:</td><td>jet.Int</td></tr></table></html> // ERROR: An integer literal does not conform to the expected type jet.Unit
abstract class A { abstract class A {
abstract fun component1(): Int abstract fun component1(): Int
fun component2() = 42 fun component2() = 42