Autocasts implemented
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package org.jetbrains.jet.lang;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CollectingErrorHandler extends ErrorHandler {
|
||||
private final List<JetDiagnostic> diagnostics;
|
||||
|
||||
public CollectingErrorHandler() {
|
||||
this(Lists.<JetDiagnostic>newArrayList());
|
||||
}
|
||||
|
||||
public CollectingErrorHandler(List<JetDiagnostic> diagnostics) {
|
||||
this.diagnostics = diagnostics;
|
||||
}
|
||||
|
||||
public List<JetDiagnostic> getDiagnostics() {
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) {
|
||||
diagnostics.add(new JetDiagnostic.UnresolvedReferenceError(referenceExpression));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void typeMismatch(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull JetType actualType) {
|
||||
diagnostics.add(new JetDiagnostic.TypeMismatchError(expression, expectedType, actualType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redeclaration(@NotNull DeclarationDescriptor existingDescriptor, @NotNull DeclarationDescriptor redeclaredDescriptor) {
|
||||
diagnostics.add(new JetDiagnostic.RedeclarationError(existingDescriptor, redeclaredDescriptor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genericError(@NotNull ASTNode node, @NotNull String errorMessage) {
|
||||
diagnostics.add(new JetDiagnostic.GenericError(node, errorMessage));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genericWarning(@NotNull ASTNode node, @NotNull String message) {
|
||||
diagnostics.add(new JetDiagnostic.GenericWarning(node, message));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.jetbrains.jet.lang;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ErrorHandlerAdapter extends ErrorHandler {
|
||||
protected ErrorHandler worker;
|
||||
|
||||
public ErrorHandlerAdapter(ErrorHandler worker) {
|
||||
this.worker = worker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) {
|
||||
worker.unresolvedReference(referenceExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void typeMismatch(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull JetType actualType) {
|
||||
worker.typeMismatch(expression, expectedType, actualType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redeclaration(@NotNull DeclarationDescriptor existingDescriptor, @NotNull DeclarationDescriptor redeclaredDescriptor) {
|
||||
worker.redeclaration(existingDescriptor, redeclaredDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genericError(@NotNull ASTNode node, @NotNull String errorMessage) {
|
||||
worker.genericError(node, errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genericWarning(@NotNull ASTNode node, @NotNull String message) {
|
||||
worker.genericWarning(node, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.jetbrains.jet.lang;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ErrorHandlerWithRegions extends ErrorHandler {
|
||||
|
||||
public class DiagnosticsRegion {
|
||||
private final CollectingErrorHandler errorHandler;
|
||||
private boolean committed = false;
|
||||
|
||||
private DiagnosticsRegion(CollectingErrorHandler errorHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
public CollectingErrorHandler getErrorHandler() {
|
||||
assert !committed;
|
||||
return errorHandler;
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
assert !committed;
|
||||
AnalyzingUtils.applyHandler(parent, errorHandler.getDiagnostics());
|
||||
committed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private final ErrorHandler parent;
|
||||
private final Stack<CollectingErrorHandler> workers;
|
||||
private ErrorHandler worker;
|
||||
|
||||
public ErrorHandlerWithRegions(ErrorHandler parent) {
|
||||
this.parent = parent;
|
||||
this.worker = parent;
|
||||
this.workers = new Stack<CollectingErrorHandler>();
|
||||
}
|
||||
|
||||
public void openRegion() {
|
||||
CollectingErrorHandler newWorker = new CollectingErrorHandler();
|
||||
workers.push(newWorker);
|
||||
worker = newWorker;
|
||||
}
|
||||
|
||||
public void closeAndCommitCurrentRegion() {
|
||||
assert !workers.isEmpty();
|
||||
CollectingErrorHandler region = workers.pop();
|
||||
AnalyzingUtils.applyHandler(parent, region.getDiagnostics());
|
||||
|
||||
setWorker();
|
||||
}
|
||||
|
||||
public DiagnosticsRegion closeAndReturnCurrentRegion() {
|
||||
assert !workers.isEmpty();
|
||||
CollectingErrorHandler currentWorker = workers.pop();
|
||||
setWorker();
|
||||
return new DiagnosticsRegion(currentWorker);
|
||||
}
|
||||
|
||||
private void setWorker() {
|
||||
worker = workers.isEmpty() ? parent : workers.peek();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) {
|
||||
worker.unresolvedReference(referenceExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void typeMismatch(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull JetType actualType) {
|
||||
worker.typeMismatch(expression, expectedType, actualType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redeclaration(@NotNull DeclarationDescriptor existingDescriptor, @NotNull DeclarationDescriptor redeclaredDescriptor) {
|
||||
worker.redeclaration(existingDescriptor, redeclaredDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genericError(@NotNull ASTNode node, @NotNull String errorMessage) {
|
||||
worker.genericError(node, errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genericWarning(@NotNull ASTNode node, @NotNull String message) {
|
||||
worker.genericWarning(node, message);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.editor.HighlighterColors;
|
||||
import com.intellij.openapi.editor.SyntaxHighlighterColors;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -14,6 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lexer.JetLexer;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -54,7 +56,7 @@ public class JetHighlighter extends SyntaxHighlighterBase {
|
||||
SyntaxHighlighterColors.NUMBER.getDefaultAttributes()
|
||||
);
|
||||
|
||||
private static final TextAttributesKey JET_STRING = TextAttributesKey.createTextAttributesKey(
|
||||
public static final TextAttributesKey JET_STRING = TextAttributesKey.createTextAttributesKey(
|
||||
"JET.STRING",
|
||||
SyntaxHighlighterColors.STRING.getDefaultAttributes()
|
||||
);
|
||||
@@ -69,6 +71,14 @@ public class JetHighlighter extends SyntaxHighlighterBase {
|
||||
HighlighterColors.BAD_CHARACTER.getDefaultAttributes()
|
||||
);
|
||||
|
||||
public static final TextAttributesKey JET_AUTO_CAST_EXPRESSION;
|
||||
static {
|
||||
TextAttributes clone = SyntaxHighlighterColors.STRING.getDefaultAttributes().clone();
|
||||
clone.setFontType(Font.PLAIN);
|
||||
// TODO: proper attributes
|
||||
JET_AUTO_CAST_EXPRESSION = TextAttributesKey.createTextAttributesKey("JET.AUTO.CAST.EXPRESSION", clone);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Lexer getHighlightingLexer() {
|
||||
return new JetLexer();
|
||||
|
||||
@@ -88,6 +88,22 @@ public class JetPsiChecker implements Annotator {
|
||||
AnalyzingUtils.applyHandler(errorHandler, bindingContext);
|
||||
|
||||
highlightBackingFields(holder, file, bindingContext);
|
||||
|
||||
file.acceptChildren(new JetVisitor() {
|
||||
@Override
|
||||
public void visitExpression(JetExpression expression) {
|
||||
JetType autoCast = bindingContext.getAutoCastType(expression);
|
||||
if (autoCast != null) {
|
||||
holder.createInfoAnnotation(expression, "Automatically cast to " + autoCast).setTextAttributes(JetHighlighter.JET_AUTO_CAST_EXPRESSION);
|
||||
}
|
||||
expression.acceptChildren(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJetElement(JetElement element) {
|
||||
element.acceptChildren(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaPackageScope;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
@@ -115,7 +116,12 @@ public class AnalyzingUtils {
|
||||
}
|
||||
|
||||
public static void applyHandler(@NotNull ErrorHandler errorHandler, @NotNull BindingContext bindingContext) {
|
||||
for (JetDiagnostic jetDiagnostic : bindingContext.getDiagnostics()) {
|
||||
Collection<JetDiagnostic> diagnostics = bindingContext.getDiagnostics();
|
||||
applyHandler(errorHandler, diagnostics);
|
||||
}
|
||||
|
||||
public static void applyHandler(@NotNull ErrorHandler errorHandler, @NotNull Collection<JetDiagnostic> diagnostics) {
|
||||
for (JetDiagnostic jetDiagnostic : diagnostics) {
|
||||
jetDiagnostic.acceptHandler(errorHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.JetDiagnostic;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -41,5 +43,8 @@ public interface BindingContext {
|
||||
|
||||
ConstructorDescriptor resolveSuperConstructor(JetDelegatorToSuperCall superCall);
|
||||
|
||||
@Nullable
|
||||
JetType getAutoCastType(@NotNull JetExpression expression);
|
||||
|
||||
Collection<JetDiagnostic> getDiagnostics();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.ErrorHandlerWithRegions;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -35,8 +35,10 @@ public interface BindingTrace {
|
||||
|
||||
void requireBackingField(@NotNull PropertyDescriptor propertyDescriptor);
|
||||
|
||||
void recordAutoCast(@NotNull JetExpression expression, @NotNull JetType type);
|
||||
|
||||
@NotNull
|
||||
ErrorHandler getErrorHandler();
|
||||
ErrorHandlerWithRegions getErrorHandler();
|
||||
|
||||
boolean isProcessed(@NotNull JetExpression expression);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.ErrorHandlerWithRegions;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -14,6 +14,11 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
public class BindingTraceAdapter implements BindingTrace {
|
||||
private final BindingTrace originalTrace;
|
||||
|
||||
@Override
|
||||
public void recordAutoCast(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||
originalTrace.recordAutoCast(expression, type);
|
||||
}
|
||||
|
||||
public BindingTraceAdapter(BindingTrace originalTrace) {
|
||||
this.originalTrace = originalTrace;
|
||||
}
|
||||
@@ -63,7 +68,7 @@ public class BindingTraceAdapter implements BindingTrace {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ErrorHandler getErrorHandler() {
|
||||
public ErrorHandlerWithRegions getErrorHandler() {
|
||||
return originalTrace.getErrorHandler();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ package org.jetbrains.jet.lang.resolve;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.CollectingErrorHandler;
|
||||
import org.jetbrains.jet.lang.ErrorHandlerWithRegions;
|
||||
import org.jetbrains.jet.lang.JetDiagnostic;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -32,39 +32,15 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
||||
private final Set<JetElement> statements = new HashSet<JetElement>();
|
||||
private final Set<PropertyDescriptor> backingFieldRequired = new HashSet<PropertyDescriptor>();
|
||||
private final Set<JetExpression> processed = Sets.newHashSet();
|
||||
private final Map<JetExpression, JetType> autoCasts = Maps.newHashMap();
|
||||
|
||||
private Collection<JetDiagnostic> diagnostics = Lists.newArrayList();
|
||||
private ErrorHandler errorHandler = new ErrorHandler() {
|
||||
@Override
|
||||
public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) {
|
||||
diagnostics.add(new JetDiagnostic.UnresolvedReferenceError(referenceExpression));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void typeMismatch(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull JetType actualType) {
|
||||
diagnostics.add(new JetDiagnostic.TypeMismatchError(expression, expectedType, actualType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redeclaration(@NotNull DeclarationDescriptor existingDescriptor, @NotNull DeclarationDescriptor redeclaredDescriptor) {
|
||||
diagnostics.add(new JetDiagnostic.RedeclarationError(existingDescriptor, redeclaredDescriptor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genericError(@NotNull ASTNode node, @NotNull String errorMessage) {
|
||||
diagnostics.add(new JetDiagnostic.GenericError(node, errorMessage));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genericWarning(@NotNull ASTNode node, @NotNull String message) {
|
||||
diagnostics.add(new JetDiagnostic.GenericWarning(node, message));
|
||||
}
|
||||
};
|
||||
private final List<JetDiagnostic> diagnostics = Lists.newArrayList();
|
||||
private final ErrorHandlerWithRegions errorHandler = new ErrorHandlerWithRegions(new CollectingErrorHandler(diagnostics));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@NotNull
|
||||
public ErrorHandler getErrorHandler() {
|
||||
public ErrorHandlerWithRegions getErrorHandler() {
|
||||
return errorHandler;
|
||||
}
|
||||
|
||||
@@ -133,6 +109,11 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
||||
backingFieldRequired.add(propertyDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordAutoCast(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||
safePut(autoCasts, expression, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordBlock(JetFunctionLiteralExpression expression) {
|
||||
blocks.add(expression);
|
||||
@@ -281,6 +262,11 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
||||
return descriptor instanceof ConstructorDescriptor ? (ConstructorDescriptor) descriptor : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetType getAutoCastType(@NotNull JetExpression expression) {
|
||||
return autoCasts.get(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<JetDiagnostic> getDiagnostics() {
|
||||
return diagnostics;
|
||||
|
||||
@@ -14,10 +14,10 @@ import java.util.*;
|
||||
public class DataFlowInfo {
|
||||
|
||||
private static DataFlowInfo EMPTY = new DataFlowInfo(ImmutableMap.<VariableDescriptor, NullabilityFlags>of(), Multimaps.forMap(Collections.<VariableDescriptor, JetType>emptyMap()));
|
||||
public static final Supplier<SortedSet<JetType>> SORTED_SET_SUPPLIER = new Supplier<SortedSet<JetType>>() {
|
||||
public static final Supplier<List<JetType>> ARRAY_LIST_SUPPLIER = new Supplier<List<JetType>>() {
|
||||
@Override
|
||||
public SortedSet<JetType> get() {
|
||||
return new TreeSet<JetType>();
|
||||
public List<JetType> get() {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -83,7 +83,7 @@ public class DataFlowInfo {
|
||||
public DataFlowInfo isInstanceOf(@NotNull VariableDescriptor variableDescriptor, @NotNull JetType type) {
|
||||
Multimap<VariableDescriptor, JetType> newTypeInfo = copyTypeInfo();
|
||||
newTypeInfo.put(variableDescriptor, type);
|
||||
return new DataFlowInfo(getEqualsToNullMap(variableDescriptor, false), newTypeInfo);
|
||||
return new DataFlowInfo(getEqualsToNullMap(variableDescriptor, !type.isNullable()), newTypeInfo);
|
||||
}
|
||||
|
||||
public DataFlowInfo and(DataFlowInfo other) {
|
||||
@@ -107,7 +107,7 @@ public class DataFlowInfo {
|
||||
}
|
||||
|
||||
private Multimap<VariableDescriptor, JetType> copyTypeInfo() {
|
||||
Multimap<VariableDescriptor, JetType> newTypeInfo = Multimaps.newSortedSetMultimap(Maps.<VariableDescriptor, Collection<JetType>>newHashMap(), SORTED_SET_SUPPLIER);
|
||||
Multimap<VariableDescriptor, JetType> newTypeInfo = Multimaps.newListMultimap(Maps.<VariableDescriptor, Collection<JetType>>newHashMap(), ARRAY_LIST_SUPPLIER);
|
||||
newTypeInfo.putAll(typeInfo);
|
||||
return newTypeInfo;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
import org.jetbrains.jet.lang.ErrorHandlerWithRegions;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -1346,12 +1347,14 @@ public class JetTypeInferrer {
|
||||
condition.accept(new JetVisitor() {
|
||||
@Override
|
||||
public void visitIsExpression(JetIsExpression expression) {
|
||||
VariableDescriptor variableDescriptor = getVariableDescriptorFromSimpleName(expression.getLeftHandSide());
|
||||
if (variableDescriptor != null) {
|
||||
JetPattern pattern = expression.getPattern();
|
||||
if (pattern instanceof JetTypePattern) {
|
||||
JetTypePattern jetTypePattern = (JetTypePattern) pattern;
|
||||
result[0] = dataFlowInfo.isInstanceOf(variableDescriptor, trace.getBindingContext().resolveTypeReference(jetTypePattern.getTypeReference()));
|
||||
if (conditionValue) {
|
||||
VariableDescriptor variableDescriptor = getVariableDescriptorFromSimpleName(expression.getLeftHandSide());
|
||||
if (variableDescriptor != null) {
|
||||
JetPattern pattern = expression.getPattern();
|
||||
if (pattern instanceof JetTypePattern) {
|
||||
JetTypePattern jetTypePattern = (JetTypePattern) pattern;
|
||||
result[0] = dataFlowInfo.isInstanceOf(variableDescriptor, trace.getBindingContext().resolveTypeReference(jetTypePattern.getTypeReference()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1642,25 +1645,37 @@ public class JetTypeInferrer {
|
||||
JetExpression receiverExpression = expression.getReceiverExpression();
|
||||
JetType receiverType = new TypeInferrerVisitorWithNamespaces(scope, false, dataFlowInfo).getType(receiverExpression);
|
||||
if (receiverType != null) {
|
||||
ErrorHandlerWithRegions errorHandler = trace.getErrorHandler();
|
||||
errorHandler.openRegion();
|
||||
JetType selectorReturnType = getSelectorReturnType(receiverType, selectorExpression);
|
||||
|
||||
if (selectorReturnType == null) {
|
||||
|
||||
if (selectorReturnType != null) {
|
||||
errorHandler.closeAndCommitCurrentRegion();
|
||||
}
|
||||
else {
|
||||
ErrorHandlerWithRegions.DiagnosticsRegion regionToCommit = errorHandler.closeAndReturnCurrentRegion();
|
||||
|
||||
VariableDescriptor variableDescriptor = getVariableDescriptorFromSimpleName(receiverExpression);
|
||||
if (variableDescriptor != null) {
|
||||
Collection<JetType> possibleTypes = dataFlowInfo.getPossibleTypes(variableDescriptor);
|
||||
for (JetType possibleType : possibleTypes) {
|
||||
errorHandler.openRegion();
|
||||
selectorReturnType = getSelectorReturnType(possibleType, selectorExpression);
|
||||
if (selectorReturnType != null) {
|
||||
regionToCommit = errorHandler.closeAndReturnCurrentRegion();
|
||||
trace.recordAutoCast(receiverExpression, possibleType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
regionToCommit.commit();
|
||||
}
|
||||
|
||||
if (expression.getOperationSign() == JetTokens.QUEST) {
|
||||
if (selectorReturnType != null && !isBoolean(selectorReturnType) && selectorExpression != null) {
|
||||
// TODO : more comprehensible error message
|
||||
trace.getErrorHandler().typeMismatch(selectorExpression, semanticServices.getStandardLibrary().getBooleanType(), selectorReturnType);
|
||||
errorHandler.typeMismatch(selectorExpression, semanticServices.getStandardLibrary().getBooleanType(), selectorReturnType);
|
||||
}
|
||||
result = TypeUtils.makeNullable(receiverType);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
class A() {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
class B() : A() {
|
||||
fun bar() {}
|
||||
}
|
||||
|
||||
fun f9() {
|
||||
val a : A?
|
||||
a?.foo()
|
||||
a?.<error>bar</error>()
|
||||
if (a is B) {
|
||||
<info descr="Automatically cast to B">a</info>.bar()
|
||||
a.foo()
|
||||
}
|
||||
a?.foo()
|
||||
a?.<error>bar</error>()
|
||||
if (!(a is B)) {
|
||||
a?.<error>bar</error>()
|
||||
a?.foo()
|
||||
}
|
||||
if (!(a is B) || <info descr="Automatically cast to B">a</info>.bar() == ()) {
|
||||
a?.<error>bar</error>()
|
||||
}
|
||||
if (!(a is B)) {
|
||||
return;
|
||||
}
|
||||
<info descr="Automatically cast to B">a</info>.bar()
|
||||
a.foo()
|
||||
}
|
||||
|
||||
fun f10() {
|
||||
val a : A?
|
||||
if (!(a is B)) {
|
||||
return;
|
||||
}
|
||||
if (!(a is B)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.ErrorHandlerWithRegions;
|
||||
import org.jetbrains.jet.lang.JetDiagnostic;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -63,10 +64,15 @@ public class JetTestUtils {
|
||||
public void requireBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordAutoCast(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ErrorHandler getErrorHandler() {
|
||||
return ErrorHandler.DO_NOTHING;
|
||||
public ErrorHandlerWithRegions getErrorHandler() {
|
||||
return new ErrorHandlerWithRegions(ErrorHandler.DO_NOTHING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,6 +184,11 @@ public class JetTestUtils {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetType getAutoCastType(@NotNull JetExpression expression) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<JetDiagnostic> getDiagnostics() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
|
||||
Reference in New Issue
Block a user