diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 504a55ede81..3e306817c2d 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -27,5 +27,6 @@
+
diff --git a/idea/src/org/jetbrains/jet/lang/ErrorHandler.java b/idea/src/org/jetbrains/jet/lang/ErrorHandler.java
index 5d76edf11ea..ef64fa6c773 100644
--- a/idea/src/org/jetbrains/jet/lang/ErrorHandler.java
+++ b/idea/src/org/jetbrains/jet/lang/ErrorHandler.java
@@ -14,38 +14,38 @@ public class ErrorHandler {
public static final ErrorHandler DO_NOTHING = new ErrorHandler();
public static final ErrorHandler THROW_EXCEPTION = new ErrorHandler() {
@Override
- public void unresolvedReference(JetReferenceExpression referenceExpression) {
+ public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) {
throw new IllegalStateException("Unresolved reference: " + referenceExpression.getText());
}
@Override
- public void genericError(@NotNull ASTNode node, String errorMessage) {
+ public void genericError(@NotNull ASTNode node, @NotNull String errorMessage) {
throw new IllegalStateException(errorMessage);
}
@Override
- public void typeMismatch(JetExpression expression, JetType expectedType, JetType actualType) {
+ public void typeMismatch(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull JetType actualType) {
throw new IllegalStateException("Type mismatch: inferred type is " + actualType + " but " + expectedType + " was expected");
}
@Override
- public void redeclaration(DeclarationDescriptor existingDescriptor, DeclarationDescriptor redeclaredDescriptor) {
+ public void redeclaration(@NotNull DeclarationDescriptor existingDescriptor, @NotNull DeclarationDescriptor redeclaredDescriptor) {
throw new IllegalStateException("Redeclaration: " + existingDescriptor.getName());
}
};
- public void unresolvedReference(JetReferenceExpression referenceExpression) {
+ public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) {
}
- public void typeMismatch(JetExpression expression, JetType expectedType, JetType actualType) {
+ public void typeMismatch(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull JetType actualType) {
}
- public void redeclaration(DeclarationDescriptor existingDescriptor, DeclarationDescriptor redeclaredDescriptor) {
+ public void redeclaration(@NotNull DeclarationDescriptor existingDescriptor, @NotNull DeclarationDescriptor redeclaredDescriptor) {
}
- public void genericError(@NotNull ASTNode node, String errorMessage) {
+ public void genericError(@NotNull ASTNode node, @NotNull String errorMessage) {
}
- public void genericWarning(ASTNode node, String message) {
+ public void genericWarning(@NotNull ASTNode node, @NotNull String message) {
}
}
diff --git a/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java b/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java
new file mode 100644
index 00000000000..6d3ffacef6c
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java
@@ -0,0 +1,96 @@
+package org.jetbrains.jet.lang;
+
+import com.intellij.lang.ASTNode;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.jet.lang.psi.JetExpression;
+import org.jetbrains.jet.lang.psi.JetReferenceExpression;
+import org.jetbrains.jet.lang.types.DeclarationDescriptor;
+import org.jetbrains.jet.lang.types.JetType;
+
+/**
+ * @author abreslav
+ */
+public abstract class JetDiagnostic {
+
+ public static class UnresolvedReferenceError extends JetDiagnostic {
+
+ private final JetReferenceExpression referenceExpression;
+
+ public UnresolvedReferenceError(@NonNls JetReferenceExpression referenceExpression) {
+ this.referenceExpression = referenceExpression;
+ }
+
+ @Override
+ public void acceptHandler(@NonNls ErrorHandler handler) {
+ handler.unresolvedReference(referenceExpression);
+ }
+ }
+
+ public static class GenericError extends JetDiagnostic {
+
+ private final ASTNode node;
+ private final String message;
+
+ public GenericError(@NonNls ASTNode node, @NonNls String message) {
+ this.node = node;
+ this.message = message;
+ }
+
+ @Override
+ public void acceptHandler(@NonNls ErrorHandler handler) {
+ handler.genericError(node, message);
+ }
+ }
+
+ public static class TypeMismatchError extends JetDiagnostic {
+
+ private final JetExpression expression;
+ private final JetType expectedType;
+ private final JetType actualType;
+
+ public TypeMismatchError(@NonNls JetExpression expression, @NonNls JetType expectedType, @NonNls JetType actualType) {
+ this.expression = expression;
+ this.expectedType = expectedType;
+ this.actualType = actualType;
+ }
+
+ @Override
+ public void acceptHandler(@NonNls ErrorHandler handler) {
+ handler.typeMismatch(expression, expectedType, actualType);
+ }
+ }
+
+ public static class RedeclarationError extends JetDiagnostic {
+
+ private final DeclarationDescriptor existingDescriptor;
+ private final DeclarationDescriptor redeclaredDescriptor;
+
+ public RedeclarationError(@NonNls DeclarationDescriptor existingDescriptor, @NonNls DeclarationDescriptor redeclaredDescriptor) {
+ this.existingDescriptor = existingDescriptor;
+ this.redeclaredDescriptor = redeclaredDescriptor;
+ }
+
+ @Override
+ public void acceptHandler(@NonNls ErrorHandler handler) {
+ handler.redeclaration(existingDescriptor, redeclaredDescriptor);
+ }
+ }
+
+ public static class GenericWarning extends JetDiagnostic {
+
+ private final ASTNode node;
+ private final String message;
+
+ public GenericWarning(@NonNls ASTNode node, @NonNls String message) {
+ this.message = message;
+ this.node = node;
+ }
+
+ @Override
+ public void acceptHandler(@NonNls ErrorHandler handler) {
+ handler.genericWarning(node, message);
+ }
+ }
+
+ public abstract void acceptHandler(@NonNls ErrorHandler handler);
+}
diff --git a/idea/src/org/jetbrains/jet/lang/annotations/JetLineMarkerProvider.java b/idea/src/org/jetbrains/jet/lang/annotations/JetLineMarkerProvider.java
new file mode 100644
index 00000000000..7ce86b44a06
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/lang/annotations/JetLineMarkerProvider.java
@@ -0,0 +1,107 @@
+package org.jetbrains.jet.lang.annotations;
+
+import com.google.common.collect.Lists;
+import com.intellij.codeHighlighting.Pass;
+import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
+import com.intellij.codeInsight.daemon.LineMarkerInfo;
+import com.intellij.codeInsight.daemon.LineMarkerProvider;
+import com.intellij.codeInsight.hint.HintUtil;
+import com.intellij.codeInsight.navigation.NavigationUtil;
+import com.intellij.ide.util.DefaultPsiElementCellRenderer;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.util.IconLoader;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.util.Function;
+import com.intellij.util.PsiNavigateUtil;
+import org.jetbrains.jet.lang.ErrorHandler;
+import org.jetbrains.jet.lang.psi.JetFile;
+import org.jetbrains.jet.lang.psi.JetFunction;
+import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
+import org.jetbrains.jet.lang.resolve.BindingContext;
+import org.jetbrains.jet.lang.types.FunctionDescriptor;
+
+import javax.swing.*;
+import java.awt.event.MouseEvent;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author abreslav
+ */
+public class JetLineMarkerProvider implements LineMarkerProvider {
+
+ public static final Icon OVERRIDING_FUNCTION = IconLoader.getIcon("/general/overridingMethod.png");
+
+ @Override
+ public LineMarkerInfo getLineMarkerInfo(PsiElement element) {
+ if (element instanceof JetFunction) {
+ JetFunction jetFunction = (JetFunction) element;
+
+ JetFile file = PsiTreeUtil.getParentOfType(element, JetFile.class);
+ assert file != null;
+ final BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, ErrorHandler.DO_NOTHING);
+ FunctionDescriptor functionDescriptor = bindingContext.getFunctionDescriptor(jetFunction);
+ final Set extends FunctionDescriptor> overriddenFunctions = functionDescriptor.getOverriddenFunctions();
+ if (!overriddenFunctions.isEmpty()) {
+ return new LineMarkerInfo(
+ jetFunction, jetFunction.getTextOffset(), OVERRIDING_FUNCTION, Pass.UPDATE_ALL,
+ new Function() {
+ @Override
+ public String fun(JetFunction jetFunction) {
+ return overriddenFunctions.toString();
+ }
+ },
+ new GutterIconNavigationHandler() {
+ @Override
+ public void navigate(MouseEvent event, JetFunction elt) {
+ final List list = Lists.newArrayList();
+ for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
+ PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(overriddenFunction);
+ list.add(declarationPsiElement);
+ }
+ if (list.isEmpty()) {
+ String myEmptyText = "empty text";
+ if (myEmptyText != null) {
+ final JComponent renderer = HintUtil.createErrorLabel(myEmptyText);
+ final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(renderer, renderer).createPopup();
+ if (event != null) {
+ popup.show(new RelativePoint(event));
+ }
+ }
+ return;
+ }
+ if (list.size() == 1) {
+ PsiNavigateUtil.navigate(list.iterator().next());
+ }
+ else {
+ final JBPopup popup = NavigationUtil.getPsiElementPopup(PsiUtilBase.toPsiElementArray(list), new DefaultPsiElementCellRenderer() {
+ @Override
+ public String getElementText(PsiElement element) {
+ if (element instanceof JetFunction) {
+ JetFunction function = (JetFunction) element;
+ return bindingContext.getFunctionDescriptor(function).toString();
+ }
+ return super.getElementText(element);
+ }
+ }, "title");
+ if (event != null) {
+ popup.show(new RelativePoint(event));
+ }
+ }
+ }
+ }
+ );
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void collectSlowLineMarkers(List elements, Collection result) {
+ }
+}
diff --git a/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java b/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java
index e83a6c5045b..ee6544d6e0b 100644
--- a/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java
+++ b/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java
@@ -12,6 +12,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ErrorHandler;
+import org.jetbrains.jet.lang.JetDiagnostic;
import org.jetbrains.jet.lang.JetHighlighter;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
@@ -21,8 +22,8 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.PropertyDescriptor;
import org.jetbrains.jet.lang.types.VariableDescriptor;
-import java.util.Collection;
import java.util.HashSet;
+import java.util.Set;
/**
* @author abreslav
@@ -36,47 +37,57 @@ public class JetPsiChecker implements Annotator {
JetFile file = (JetFile) element;
try {
- final Collection redeclarations = new HashSet();
- final BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, new ErrorHandler() {
+ final BindingContext bindingContext = AnalyzingUtils.analyzeFile(file);
+
+ ErrorHandler errorHandler = new ErrorHandler() {
+ private final Set redeclarations = new HashSet();
+
@Override
- public void unresolvedReference(JetReferenceExpression referenceExpression) {
+ public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) {
PsiReference reference = referenceExpression.getReference();
if (reference instanceof MultiRangeReference) {
MultiRangeReference mrr = (MultiRangeReference) reference;
for (TextRange range : mrr.getRanges()) {
holder.createErrorAnnotation(range.shiftRight(referenceExpression.getTextOffset()), "Unresolved").setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
}
- } else {
+ }
+ else {
holder.createErrorAnnotation(referenceExpression, "Unresolved").setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
}
}
@Override
- public void typeMismatch(JetExpression expression, JetType expectedType, JetType actualType) {
+ public void typeMismatch(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull JetType actualType) {
holder.createErrorAnnotation(expression, "Type mismatch: inferred type is " + actualType + " but " + expectedType + " was expected");
}
@Override
- public void redeclaration(DeclarationDescriptor existingDescriptor, DeclarationDescriptor redeclaredDescriptor) {
- redeclarations.add(existingDescriptor);
- redeclarations.add(redeclaredDescriptor);
+ public void redeclaration(@NotNull DeclarationDescriptor existingDescriptor, @NotNull DeclarationDescriptor redeclaredDescriptor) {
+ markRedeclaration(existingDescriptor);
+ markRedeclaration(redeclaredDescriptor);
+ }
+
+ private void markRedeclaration(DeclarationDescriptor redeclaration) {
+ if (!redeclarations.add(redeclaration)) return;
+ PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(redeclaration);
+ if (declarationPsiElement != null) {
+ holder.createErrorAnnotation(declarationPsiElement, "Redeclaration");
+ }
}
@Override
- public void genericError(@NotNull ASTNode node, String errorMessage) {
+ public void genericError(@NotNull ASTNode node, @NotNull String errorMessage) {
holder.createErrorAnnotation(node, errorMessage);
}
@Override
- public void genericWarning(ASTNode node, String message) {
+ public void genericWarning(@NotNull ASTNode node, @NotNull String message) {
holder.createWarningAnnotation(node, message);
}
- });
- for (DeclarationDescriptor redeclaration : redeclarations) {
- PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(redeclaration);
- if (declarationPsiElement != null) {
- holder.createErrorAnnotation(declarationPsiElement, "Redeclaration");
- }
+ };
+
+ for (JetDiagnostic diagnostic : bindingContext.getDiagnostics()) {
+ diagnostic.acceptHandler(errorHandler);
}
highlightBackingFields(holder, file, bindingContext);
@@ -92,6 +103,7 @@ public class JetPsiChecker implements Annotator {
}
}
+
private void highlightBackingFields(final AnnotationHolder holder, JetFile file, final BindingContext bindingContext) {
file.acceptChildren(new JetVisitor() {
@Override
diff --git a/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java
index 201c3a91e49..f275ee93ec8 100644
--- a/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java
+++ b/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java
@@ -1,11 +1,17 @@
package org.jetbrains.jet.lang.resolve;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiErrorElement;
+import com.intellij.psi.util.CachedValue;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.psi.util.PsiModificationTracker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ErrorHandler;
+import org.jetbrains.jet.lang.JetDiagnostic;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -18,6 +24,48 @@ import org.jetbrains.jet.lang.types.ModuleDescriptor;
* @author abreslav
*/
public class AnalyzingUtils {
+ private final static Key> BINDING_CONTEXT = Key.create("BINDING_CONTEXT");
+
+ public static BindingContext analyzeFile(@NotNull final JetFile file) {
+ // TODO : Synchronization?
+ // TODO : Error handler may be ignored
+ CachedValue bindingContextCachedValue = file.getUserData(BINDING_CONTEXT);
+ if (bindingContextCachedValue == null) {
+ bindingContextCachedValue = CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider() {
+ @Override
+ public Result compute() {
+ JetNamespace rootNamespace = file.getRootNamespace();
+ BindingContext bindingContext = analyzeNamespace(rootNamespace, JetControlFlowDataTraceFactory.EMPTY);
+ return new Result(bindingContext, PsiModificationTracker.MODIFICATION_COUNT);
+ }
+ }, false);
+ file.putUserData(BINDING_CONTEXT, bindingContextCachedValue);
+ }
+ return bindingContextCachedValue.getValue();
+ }
+
+ public static BindingContext analyzeNamespace(@NotNull JetNamespace namespace) {
+ return analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY);
+ }
+
+ public static BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
+ Project project = namespace.getProject();
+
+ BindingTraceContext bindingTraceContext = new BindingTraceContext();
+ JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project, bindingTraceContext.getErrorHandler());
+ JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, semanticServices, bindingTraceContext);
+
+ JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope();
+ WritableScope scope = semanticServices.createWritableScope(libraryScope, new ModuleDescriptor(""));
+// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("").getMemberScope());
+// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("java.lang").getMemberScope());
+ scope.importScope(new JavaPackageScope("", null, javaSemanticServices));
+ scope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
+
+ new TopDownAnalyzer(semanticServices, bindingTraceContext, flowDataTraceFactory).process(scope, namespace);
+ return bindingTraceContext;
+ }
+
public static void checkForSyntacticErrors(@NotNull PsiElement root) {
root.acceptChildren(new PsiElementVisitor() {
@Override
@@ -32,30 +80,21 @@ public class AnalyzingUtils {
});
}
- public static BindingContext analyzeFile(@NotNull JetFile file, @NotNull ErrorHandler errorHandler) {
- JetNamespace rootNamespace = file.getRootNamespace();
- return analyzeNamespace(rootNamespace, errorHandler, JetControlFlowDataTraceFactory.EMPTY);
- }
-
public static BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull ErrorHandler errorHandler) {
- return analyzeNamespace(namespace, errorHandler, JetControlFlowDataTraceFactory.EMPTY);
+ BindingContext bindingContext = analyzeNamespace(namespace);
+ applyHandler(errorHandler, bindingContext);
+ return bindingContext;
}
- public static BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull ErrorHandler errorHandler, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
- Project project = namespace.getProject();
- JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project, errorHandler);
+ private static void applyHandler(@NotNull ErrorHandler errorHandler, @NotNull BindingContext bindingContext) {
+ for (JetDiagnostic jetDiagnostic : bindingContext.getDiagnostics()) {
+ jetDiagnostic.acceptHandler(errorHandler);
+ }
+ }
- BindingTraceContext bindingTraceContext = new BindingTraceContext();
- JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, semanticServices, bindingTraceContext);
-
- JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope();
- WritableScope scope = semanticServices.createWritableScope(libraryScope, new ModuleDescriptor(""));
-// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("").getMemberScope());
-// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("java.lang").getMemberScope());
- scope.importScope(new JavaPackageScope("", null, javaSemanticServices));
- scope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
-
- new TopDownAnalyzer(semanticServices, bindingTraceContext, flowDataTraceFactory).process(scope, namespace);
- return bindingTraceContext;
+ public static BindingContext analyzeFile(@NotNull JetFile file, @NotNull ErrorHandler errorHandler) {
+ BindingContext bindingContext = analyzeFile(file);
+ applyHandler(errorHandler, bindingContext);
+ return bindingContext;
}
}
diff --git a/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java
index 935299c75e8..7908c2d4aac 100644
--- a/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java
+++ b/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java
@@ -2,9 +2,12 @@ package org.jetbrains.jet.lang.resolve;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ClassCodegen;
+import org.jetbrains.jet.lang.JetDiagnostic;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.*;
+import java.util.Collection;
+
/**
* @author abreslav
*/
@@ -38,4 +41,6 @@ public interface BindingContext {
boolean hasBackingField(PropertyDescriptor propertyDescriptor);
ConstructorDescriptor resolveSuperConstructor(JetDelegatorToSuperCall superCall, ClassCodegen classCodegen);
+
+ Collection getDiagnostics();
}
diff --git a/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java b/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java
index d351025cd2f..368cbaee399 100644
--- a/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java
+++ b/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java
@@ -1,17 +1,18 @@
package org.jetbrains.jet.lang.resolve;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ClassCodegen;
+import org.jetbrains.jet.lang.ErrorHandler;
+import org.jetbrains.jet.lang.JetDiagnostic;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.*;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
/**
* @author abreslav
@@ -30,10 +31,43 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
private final Set statements = new HashSet();
private final Set backingFieldRequired = new HashSet();
+ private Collection 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 JetScope toplevelScope;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ @NotNull
+ public ErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
@Override
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
expressionTypes.put(expression, type);
@@ -250,4 +284,9 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
DeclarationDescriptor descriptor = resolveReferenceExpression(((JetUserType) typeElement).getReferenceExpression());
return descriptor instanceof ConstructorDescriptor ? (ConstructorDescriptor) descriptor : null;
}
+
+ @Override
+ public Collection getDiagnostics() {
+ return diagnostics;
+ }
}
diff --git a/idea/src/org/jetbrains/jet/lang/resolve/MutableClassDescriptor.java b/idea/src/org/jetbrains/jet/lang/resolve/MutableClassDescriptor.java
index 67cc96b3649..e44908012b9 100644
--- a/idea/src/org/jetbrains/jet/lang/resolve/MutableClassDescriptor.java
+++ b/idea/src/org/jetbrains/jet/lang/resolve/MutableClassDescriptor.java
@@ -14,13 +14,16 @@ import java.util.Set;
* @author abreslav
*/
public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor {
- private final WritableFunctionGroup constructors = new WritableFunctionGroup("");
- private final WritableScope classHeaderScope;
- private final WritableScope writableMemberScope;
- private final Set properties = Sets.newHashSet();
private ConstructorDescriptor primaryConstructor;
+ private final WritableFunctionGroup constructors = new WritableFunctionGroup("");
+ private final Set functions = Sets.newHashSet();
+ private final Set properties = Sets.newHashSet();
+ private final Set classes = Sets.newHashSet();
private TypeConstructor typeConstructor;
+
+ private final WritableScope classHeaderScope;
+ private final WritableScope writableMemberScope;
private JetScope unsubstitutedMemberScope;
public MutableClassDescriptor(@NotNull JetSemanticServices semanticServices, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
@@ -32,6 +35,12 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
properties.add(descriptor);
return null;
}
+
+ @Override
+ public Void visitFunctionDescriptor(FunctionDescriptor descriptor, WritableScope data) {
+ functions.add(descriptor);
+ return null;
+ }
});
this.unsubstitutedMemberScope = this.writableMemberScope;
}
@@ -42,6 +51,45 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
this.writableMemberScope = null;
}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
+ assert this.primaryConstructor == null : "Primary constructor assigned twice " + this;
+ this.primaryConstructor = constructorDescriptor;
+ addConstructor(constructorDescriptor);
+ }
+
+ @Override
+ @Nullable
+ public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
+ return primaryConstructor;
+ }
+
+ public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
+ assert constructorDescriptor.getContainingDeclaration() == this;
+ constructors.addFunction(constructorDescriptor);
+ }
+
+ public void addProperty(@NotNull PropertyDescriptor propertyDescriptor) {
+ properties.add(propertyDescriptor);
+ }
+
+ @NotNull
+ public Set getProperties() {
+ return properties;
+ }
+
+ public void addFunction(@NotNull FunctionDescriptor functionDescriptor) {
+ functions.add(functionDescriptor);
+ }
+
+ @NotNull
+ public Set getFunctions() {
+ return functions;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
public void setUnsubstitutedMemberScope(@NotNull JetScope unsubstitutedMemberScope) {
assert writableMemberScope == null;
this.unsubstitutedMemberScope = unsubstitutedMemberScope;
@@ -57,10 +105,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
this.typeConstructor = typeConstructor;
}
- public Set getProperties() {
- return properties;
- }
-
@NotNull
@Override
public JetScope getMemberScope(List typeArguments) {
@@ -79,11 +123,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
return TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope);
}
- public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
- assert constructorDescriptor.getContainingDeclaration() == this;
- constructors.addFunction(constructorDescriptor);
- }
-
@NotNull
@Override
public FunctionGroup getConstructors(List typeArguments) {
@@ -118,18 +157,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
return visitor.visitClassDescriptor(this, data);
}
- public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
- assert this.primaryConstructor == null : "Primary constructor assigned twice " + this;
- this.primaryConstructor = constructorDescriptor;
- addConstructor(constructorDescriptor);
- }
-
- @Override
- @Nullable
- public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
- return primaryConstructor;
- }
-
@Override
public boolean hasConstructors() {
return !constructors.isEmpty();
diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java
index b6340625519..6ed91f4c930 100644
--- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java
+++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java
@@ -7,6 +7,7 @@ import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor;
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
@@ -314,6 +315,40 @@ public class TopDownAnalyzer {
resolveSecondaryConstructorBodies();
resolveFunctionBodies();
+ checkIfPrimaryConstructorIsNecessary();
+
+ bindOverrides();
+ }
+
+ private void bindOverrides() {
+ for (Map.Entry entry : classes.entrySet()) {
+ MutableClassDescriptor classDescriptor = entry.getValue();
+// JetClass jetClass = entry.getKey();
+
+ for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) {
+ for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
+ FunctionDescriptor overridden = findFunctionOverridableBy(declaredFunction, supertype);
+ if (overridden != null) {
+ ((FunctionDescriptorImpl) declaredFunction).addOverriddenFunction(overridden);
+ }
+ }
+ }
+ }
+
+ }
+
+ @Nullable
+ private FunctionDescriptor findFunctionOverridableBy(@NotNull FunctionDescriptor declaredFunction, @NotNull JetType supertype) {
+ FunctionGroup functionGroup = supertype.getMemberScope().getFunctionGroup(declaredFunction.getName());
+ for (FunctionDescriptor functionDescriptor : functionGroup.getFunctionDescriptors()) {
+ if (FunctionDescriptorUtil.isOverridableBy(semanticServices.getTypeChecker(), functionDescriptor, declaredFunction).isSuccess()) {
+ return functionDescriptor;
+ }
+ }
+ return null;
+ }
+
+ private void checkIfPrimaryConstructorIsNecessary() {
for (Map.Entry entry : classes.entrySet()) {
MutableClassDescriptor classDescriptor = entry.getValue();
JetClass jetClass = entry.getKey();
diff --git a/idea/src/org/jetbrains/jet/lang/resolve/WritableFunctionGroup.java b/idea/src/org/jetbrains/jet/lang/resolve/WritableFunctionGroup.java
index a1249333de1..f4557447971 100644
--- a/idea/src/org/jetbrains/jet/lang/resolve/WritableFunctionGroup.java
+++ b/idea/src/org/jetbrains/jet/lang/resolve/WritableFunctionGroup.java
@@ -1,20 +1,19 @@
package org.jetbrains.jet.lang.resolve;
+import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jet.lang.types.FunctionDescriptor;
-import org.jetbrains.jet.lang.types.FunctionDescriptorUtil;
-import org.jetbrains.jet.lang.types.FunctionGroup;
-import org.jetbrains.jet.lang.types.JetType;
+import org.jetbrains.jet.lang.types.*;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
/**
* @author abreslav
*/
public class WritableFunctionGroup implements FunctionGroup {
private final String name;
- private List functionDescriptors;
+ private Set functionDescriptors;
public WritableFunctionGroup(String name) {
this.name = name;
@@ -38,9 +37,9 @@ public class WritableFunctionGroup implements FunctionGroup {
}
@NotNull
- private List getFunctionDescriptors() {
+ public Set getFunctionDescriptors() {
if (functionDescriptors == null) {
- functionDescriptors = new ArrayList();
+ functionDescriptors = Sets.newLinkedHashSet();
}
return functionDescriptors;
}
@@ -48,7 +47,7 @@ public class WritableFunctionGroup implements FunctionGroup {
@NotNull
@Override
public OverloadResolutionResult getPossiblyApplicableFunctions(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes) {
- List functionDescriptors = getFunctionDescriptors();
+ Set functionDescriptors = getFunctionDescriptors();
if (functionDescriptors.isEmpty()) return OverloadResolutionResult.nameNotFound();
int typeArgCount = typeArguments.size();
@@ -68,7 +67,7 @@ public class WritableFunctionGroup implements FunctionGroup {
if (result.isEmpty()) {
assert !functionDescriptors.isEmpty();
if (functionDescriptors.size() == 1) {
- return OverloadResolutionResult.singleFunctionArgumentMismatch(functionDescriptors.get(0));
+ return OverloadResolutionResult.singleFunctionArgumentMismatch(functionDescriptors.iterator().next());
}
}
if (result.size() == 1) {
diff --git a/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptorImpl.java
index 071ff21cdf3..83444e5f2d0 100644
--- a/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptorImpl.java
+++ b/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptorImpl.java
@@ -1,9 +1,11 @@
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
/**
* @author abreslav
@@ -61,6 +63,17 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
return Collections.emptyList();
}
+ @NotNull
+ @Override
+ public Set extends FunctionDescriptor> getOverriddenFunctions() {
+ return null;
+ }
+
+ @Override
+ public void addOverriddenFunction(@NotNull FunctionDescriptor overriddenFunction) {
+ throw new UnsupportedOperationException("Constructors cannot override anything");
+ }
+
@Override
protected FunctionDescriptorImpl createSubstitutedCopy() {
return new ConstructorDescriptorImpl(
diff --git a/idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java
index 6a80d9074f3..4aeccda9fb3 100644
--- a/idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java
+++ b/idea/src/org/jetbrains/jet/lang/types/ErrorUtils.java
@@ -78,6 +78,12 @@ public class ErrorUtils {
public boolean isEmpty() {
return false;
}
+
+ @NotNull
+ @Override
+ public Set getFunctionDescriptors() {
+ return Collections.singleton(createErrorFunction(0, Collections.emptyList()));
+ }
};
private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.emptyList(), "");
diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptor.java
index cfa54413384..4478f225dba 100644
--- a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptor.java
+++ b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptor.java
@@ -3,11 +3,16 @@ package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import java.util.List;
+import java.util.Set;
/**
* @author abreslav
*/
public interface FunctionDescriptor extends DeclarationDescriptor {
+ @Override
+ @NotNull
+ DeclarationDescriptor getContainingDeclaration();
+
@NotNull
List getTypeParameters();
@@ -20,10 +25,9 @@ public interface FunctionDescriptor extends DeclarationDescriptor {
@NotNull
FunctionDescriptor getOriginal();
- @Override
- @NotNull
- DeclarationDescriptor getContainingDeclaration();
-
@Override
FunctionDescriptor substitute(TypeSubstitutor substitutor);
+
+ @NotNull
+ Set extends FunctionDescriptor> getOverriddenFunctions();
}
diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorImpl.java
index a9e8e8916da..82e7e4b96b2 100644
--- a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorImpl.java
+++ b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorImpl.java
@@ -1,10 +1,12 @@
package org.jetbrains.jet.lang.types;
+import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
/**
* @author abreslav
@@ -12,10 +14,11 @@ import java.util.List;
public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements MutableFunctionDescriptor {
private List typeParameters;
-
private List unsubstitutedValueParameters;
-
private JetType unsubstitutedReturnType;
+
+ private final Set overriddenFunctions = Sets.newHashSet();
+
private final FunctionDescriptor original;
public FunctionDescriptorImpl(
@@ -44,6 +47,16 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
return this;
}
+ @NotNull
+ @Override
+ public Set extends FunctionDescriptor> getOverriddenFunctions() {
+ return overriddenFunctions;
+ }
+
+ public void addOverriddenFunction(@NotNull FunctionDescriptor overriddenFunction) {
+ overriddenFunctions.add(overriddenFunction);
+ }
+
@Override
public void setUnsubstitutedReturnType(@NotNull JetType unsubstitutedReturnType) {
this.unsubstitutedReturnType = unsubstitutedReturnType;
diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java
index ab224271be5..9cc2eaf2a05 100644
--- a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java
+++ b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java
@@ -156,8 +156,8 @@ public class FunctionDescriptorUtil {
this.message = message;
}
- public boolean isError() {
- return isError;
+ public boolean isSuccess() {
+ return !isError;
}
public String getMessage() {
@@ -166,7 +166,7 @@ public class FunctionDescriptorUtil {
}
@NotNull
- public static OverrideCompatibilityInfo isOverridableWith(@NotNull JetTypeChecker typeChecker, @NotNull FunctionDescriptor superFunction, @NotNull FunctionDescriptor subFunction) {
+ public static OverrideCompatibilityInfo isOverridableBy(@NotNull JetTypeChecker typeChecker, @NotNull FunctionDescriptor superFunction, @NotNull FunctionDescriptor subFunction) {
if (!superFunction.getName().equals(subFunction.getName())) {
return OverrideCompatibilityInfo.nameMismatch();
}
diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionGroup.java b/idea/src/org/jetbrains/jet/lang/types/FunctionGroup.java
index bd91cf6c892..da064c219af 100644
--- a/idea/src/org/jetbrains/jet/lang/types/FunctionGroup.java
+++ b/idea/src/org/jetbrains/jet/lang/types/FunctionGroup.java
@@ -3,7 +3,9 @@ package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.OverloadResolutionResult;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
/**
* @author abreslav
@@ -26,6 +28,12 @@ public interface FunctionGroup extends Named {
public boolean isEmpty() {
return true;
}
+
+ @NotNull
+ @Override
+ public Set getFunctionDescriptors() {
+ return Collections.emptySet();
+ }
};
@@ -37,4 +45,7 @@ public interface FunctionGroup extends Named {
OverloadResolutionResult getPossiblyApplicableFunctions(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes);
boolean isEmpty();
+
+ @NotNull
+ Set getFunctionDescriptors();
}
diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java
index 09ba03e0aba..fd1300b92b4 100644
--- a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java
+++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java
@@ -10,6 +10,8 @@ import java.util.*;
*/
public class JetTypeChecker {
+ public static final JetTypeChecker INSTANCE = new JetTypeChecker(null);
+
private final Map> conversionMap = new HashMap>();
private final JetStandardLibrary standardLibrary;
diff --git a/idea/src/org/jetbrains/jet/lang/types/LazySubstitutingFunctionGroup.java b/idea/src/org/jetbrains/jet/lang/types/LazySubstitutingFunctionGroup.java
index faef947f4e9..757ee041c99 100644
--- a/idea/src/org/jetbrains/jet/lang/types/LazySubstitutingFunctionGroup.java
+++ b/idea/src/org/jetbrains/jet/lang/types/LazySubstitutingFunctionGroup.java
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.types;
+import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.OverloadResolutionResult;
@@ -7,6 +8,7 @@ import org.jetbrains.jet.lang.resolve.OverloadResolutionResult;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Set;
/**
* @author abreslav
@@ -14,6 +16,7 @@ import java.util.List;
public class LazySubstitutingFunctionGroup implements FunctionGroup {
private final TypeSubstitutor substitutor;
private final FunctionGroup functionGroup;
+ private Set functionDescriptors;
public LazySubstitutingFunctionGroup(TypeSubstitutor substitutor, FunctionGroup functionGroup) {
this.substitutor = substitutor;
@@ -54,4 +57,16 @@ public class LazySubstitutingFunctionGroup implements FunctionGroup {
public boolean isEmpty() {
return functionGroup.isEmpty();
}
+
+ @NotNull
+ @Override
+ public Set getFunctionDescriptors() {
+ if (functionDescriptors == null) {
+ functionDescriptors = Sets.newHashSet();
+ for (FunctionDescriptor descriptor : functionGroup.getFunctionDescriptors()) {
+ functionDescriptors.add(descriptor.substitute(substitutor));
+ }
+ }
+ return functionDescriptors;
+ }
}
diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyGetterDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/PropertyGetterDescriptor.java
index 0123da6bb86..84fe74ae3e6 100644
--- a/idea/src/org/jetbrains/jet/lang/types/PropertyGetterDescriptor.java
+++ b/idea/src/org/jetbrains/jet/lang/types/PropertyGetterDescriptor.java
@@ -1,15 +1,18 @@
package org.jetbrains.jet.lang.types;
+import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
/**
* @author abreslav
*/
public class PropertyGetterDescriptor extends PropertyAccessorDescriptor implements MutableFunctionDescriptor {
+ private final Set overriddenGetters = Sets.newHashSet();
private JetType returnType;
public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List annotations, @Nullable JetType returnType, boolean hasBody) {
@@ -17,6 +20,16 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor impleme
this.returnType = returnType == null ? correspondingProperty.getOutType() : returnType;
}
+ @NotNull
+ @Override
+ public Set extends FunctionDescriptor> getOverriddenFunctions() {
+ return overriddenGetters;
+ }
+
+ public void addOverriddenFunction(@NotNull PropertyGetterDescriptor overriddenGetter) {
+ overriddenGetters.add(overriddenGetter);
+ }
+
@NotNull
@Override
public List getUnsubstitutedValueParameters() {
diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertySetterDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/PropertySetterDescriptor.java
index eaa59216d23..fa938abdbc0 100644
--- a/idea/src/org/jetbrains/jet/lang/types/PropertySetterDescriptor.java
+++ b/idea/src/org/jetbrains/jet/lang/types/PropertySetterDescriptor.java
@@ -1,9 +1,11 @@
package org.jetbrains.jet.lang.types;
+import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
/**
* @author abreslav
@@ -11,6 +13,7 @@ import java.util.List;
public class PropertySetterDescriptor extends PropertyAccessorDescriptor implements MutableFunctionDescriptor {
private MutableValueParameterDescriptor parameter;
+ private final Set overriddenSetters = Sets.newHashSet();
public PropertySetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List annotations, boolean hasBody) {
super(correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody);
@@ -25,6 +28,16 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor impleme
parameter.setType(type);
}
+ @NotNull
+ @Override
+ public Set extends FunctionDescriptor> getOverriddenFunctions() {
+ return overriddenSetters;
+ }
+
+ public void setOverriddenFunction(@NotNull PropertySetterDescriptor overriddenSetter) {
+ overriddenSetters.add(overriddenSetter);
+ }
+
@NotNull
@Override
public List getUnsubstitutedValueParameters() {
diff --git a/idea/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java b/idea/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java
index 26a9277cc8a..39e18d69871 100644
--- a/idea/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java
+++ b/idea/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java
@@ -8,10 +8,9 @@ import junit.framework.Test;
import junit.framework.TestSuite;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBase;
-import org.jetbrains.jet.lang.ErrorHandler;
import org.jetbrains.jet.lang.cfg.pseudocode.Instruction;
-import org.jetbrains.jet.lang.cfg.pseudocode.JetPseudocodeTrace;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
+import org.jetbrains.jet.lang.cfg.pseudocode.JetPseudocodeTrace;
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -62,7 +61,7 @@ public class JetControlFlowTest extends JetTestCaseBase {
};
- AnalyzingUtils.analyzeNamespace(file.getRootNamespace(), ErrorHandler.DO_NOTHING, new JetControlFlowDataTraceFactory() {
+ AnalyzingUtils.analyzeNamespace(file.getRootNamespace(), new JetControlFlowDataTraceFactory() {
@NotNull
@Override
public JetPseudocodeTrace createTrace(JetElement element) {
diff --git a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java
index 09865c6779e..cd79a07bf47 100644
--- a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java
+++ b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java
@@ -4,6 +4,7 @@ import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ErrorHandler;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.psi.*;
@@ -82,7 +83,7 @@ public class ExpectedResolveData {
final Set unresolvedReferences = new HashSet();
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(file.getProject(), new ErrorHandler() {
@Override
- public void unresolvedReference(JetReferenceExpression referenceExpression) {
+ public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) {
unresolvedReferences.add(referenceExpression);
}
});
diff --git a/idea/tests/org/jetbrains/jet/types/JetOverridingTest.java b/idea/tests/org/jetbrains/jet/types/JetOverridingTest.java
index 3d621203191..10485f38026 100644
--- a/idea/tests/org/jetbrains/jet/types/JetOverridingTest.java
+++ b/idea/tests/org/jetbrains/jet/types/JetOverridingTest.java
@@ -136,8 +136,8 @@ public class JetOverridingTest extends LightDaemonAnalyzerTestCase {
private void assertOverridabilityRelation(String superFun, String subFun, boolean expectedIsError) {
FunctionDescriptor a = makeFunction(superFun);
FunctionDescriptor b = makeFunction(subFun);
- FunctionDescriptorUtil.OverrideCompatibilityInfo overridableWith = FunctionDescriptorUtil.isOverridableWith(semanticServices.getTypeChecker(), a, b);
- assertEquals(overridableWith.getMessage(), expectedIsError, overridableWith.isError());
+ FunctionDescriptorUtil.OverrideCompatibilityInfo overridableWith = FunctionDescriptorUtil.isOverridableBy(semanticServices.getTypeChecker(), a, b);
+ assertEquals(overridableWith.getMessage(), expectedIsError, !overridableWith.isSuccess());
}
private FunctionDescriptor makeFunction(String funDecl) {