JET-25 Support method overriding: overrides are bound together (and displayed in the editor)
This commit is contained in:
@@ -27,5 +27,6 @@
|
||||
<annotator language="jet" implementationClass="org.jetbrains.jet.lang.annotations.JetPsiChecker"/>
|
||||
<documentationProvider implementation="org.jetbrains.jet.plugin.JetQuickDocumentationProvider"/>
|
||||
<configurationType implementation="org.jetbrains.jet.run.JetRunConfigurationType"/>
|
||||
<codeInsight.lineMarkerProvider language="jet" implementationClass="org.jetbrains.jet.lang.annotations.JetLineMarkerProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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, jetFunction.getTextOffset(), OVERRIDING_FUNCTION, Pass.UPDATE_ALL,
|
||||
new Function<JetFunction, String>() {
|
||||
@Override
|
||||
public String fun(JetFunction jetFunction) {
|
||||
return overriddenFunctions.toString();
|
||||
}
|
||||
},
|
||||
new GutterIconNavigationHandler<JetFunction>() {
|
||||
@Override
|
||||
public void navigate(MouseEvent event, JetFunction elt) {
|
||||
final List<PsiElement> 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<PsiElement> elements, Collection<LineMarkerInfo> result) {
|
||||
}
|
||||
}
|
||||
@@ -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<DeclarationDescriptor> redeclarations = new HashSet<DeclarationDescriptor>();
|
||||
final BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, new ErrorHandler() {
|
||||
final BindingContext bindingContext = AnalyzingUtils.analyzeFile(file);
|
||||
|
||||
ErrorHandler errorHandler = new ErrorHandler() {
|
||||
private final Set<DeclarationDescriptor> redeclarations = new HashSet<DeclarationDescriptor>();
|
||||
|
||||
@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
|
||||
|
||||
@@ -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<CachedValue<BindingContext>> BINDING_CONTEXT = Key.create("BINDING_CONTEXT");
|
||||
|
||||
public static BindingContext analyzeFile(@NotNull final JetFile file) {
|
||||
// TODO : Synchronization?
|
||||
// TODO : Error handler may be ignored
|
||||
CachedValue<BindingContext> bindingContextCachedValue = file.getUserData(BINDING_CONTEXT);
|
||||
if (bindingContextCachedValue == null) {
|
||||
bindingContextCachedValue = CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider<BindingContext>() {
|
||||
@Override
|
||||
public Result<BindingContext> compute() {
|
||||
JetNamespace rootNamespace = file.getRootNamespace();
|
||||
BindingContext bindingContext = analyzeNamespace(rootNamespace, JetControlFlowDataTraceFactory.EMPTY);
|
||||
return new Result<BindingContext>(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("<module>"));
|
||||
// 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("<module>"));
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<JetDiagnostic> getDiagnostics();
|
||||
}
|
||||
|
||||
@@ -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<JetElement> statements = new HashSet<JetElement>();
|
||||
private final Set<PropertyDescriptor> backingFieldRequired = new HashSet<PropertyDescriptor>();
|
||||
|
||||
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 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<JetDiagnostic> getDiagnostics() {
|
||||
return diagnostics;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,16 @@ import java.util.Set;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor {
|
||||
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
||||
private final WritableScope classHeaderScope;
|
||||
private final WritableScope writableMemberScope;
|
||||
private final Set<PropertyDescriptor> properties = Sets.newHashSet();
|
||||
private ConstructorDescriptor primaryConstructor;
|
||||
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
||||
private final Set<FunctionDescriptor> functions = Sets.newHashSet();
|
||||
private final Set<PropertyDescriptor> properties = Sets.newHashSet();
|
||||
private final Set<MutableClassDescriptor> 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<PropertyDescriptor> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void addFunction(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
functions.add(functionDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<FunctionDescriptor> 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<PropertyDescriptor> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetScope getMemberScope(List<TypeProjection> 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<TypeProjection> 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();
|
||||
|
||||
@@ -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<JetClass, MutableClassDescriptor> 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<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
||||
MutableClassDescriptor classDescriptor = entry.getValue();
|
||||
JetClass jetClass = entry.getKey();
|
||||
|
||||
@@ -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<FunctionDescriptor> functionDescriptors;
|
||||
private Set<FunctionDescriptor> functionDescriptors;
|
||||
|
||||
public WritableFunctionGroup(String name) {
|
||||
this.name = name;
|
||||
@@ -38,9 +37,9 @@ public class WritableFunctionGroup implements FunctionGroup {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<FunctionDescriptor> getFunctionDescriptors() {
|
||||
public Set<FunctionDescriptor> getFunctionDescriptors() {
|
||||
if (functionDescriptors == null) {
|
||||
functionDescriptors = new ArrayList<FunctionDescriptor>();
|
||||
functionDescriptors = Sets.newLinkedHashSet();
|
||||
}
|
||||
return functionDescriptors;
|
||||
}
|
||||
@@ -48,7 +47,7 @@ public class WritableFunctionGroup implements FunctionGroup {
|
||||
@NotNull
|
||||
@Override
|
||||
public OverloadResolutionResult getPossiblyApplicableFunctions(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
|
||||
List<FunctionDescriptor> functionDescriptors = getFunctionDescriptors();
|
||||
Set<FunctionDescriptor> 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) {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -78,6 +78,12 @@ public class ErrorUtils {
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<FunctionDescriptor> getFunctionDescriptors() {
|
||||
return Collections.singleton(createErrorFunction(0, Collections.<JetType>emptyList()));
|
||||
}
|
||||
};
|
||||
|
||||
private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.<Annotation>emptyList(), "<ERROR CLASS>");
|
||||
|
||||
@@ -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<TypeParameterDescriptor> 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();
|
||||
}
|
||||
|
||||
@@ -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<TypeParameterDescriptor> typeParameters;
|
||||
|
||||
private List<ValueParameterDescriptor> unsubstitutedValueParameters;
|
||||
|
||||
private JetType unsubstitutedReturnType;
|
||||
|
||||
private final Set<FunctionDescriptor> 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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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<FunctionDescriptor> getFunctionDescriptors() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -37,4 +45,7 @@ public interface FunctionGroup extends Named {
|
||||
OverloadResolutionResult getPossiblyApplicableFunctions(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes);
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
@NotNull
|
||||
Set<FunctionDescriptor> getFunctionDescriptors();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import java.util.*;
|
||||
*/
|
||||
public class JetTypeChecker {
|
||||
|
||||
public static final JetTypeChecker INSTANCE = new JetTypeChecker(null);
|
||||
|
||||
private final Map<TypeConstructor, Set<TypeConstructor>> conversionMap = new HashMap<TypeConstructor, Set<TypeConstructor>>();
|
||||
private final JetStandardLibrary standardLibrary;
|
||||
|
||||
|
||||
@@ -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<FunctionDescriptor> 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<FunctionDescriptor> getFunctionDescriptors() {
|
||||
if (functionDescriptors == null) {
|
||||
functionDescriptors = Sets.newHashSet();
|
||||
for (FunctionDescriptor descriptor : functionGroup.getFunctionDescriptors()) {
|
||||
functionDescriptors.add(descriptor.substitute(substitutor));
|
||||
}
|
||||
}
|
||||
return functionDescriptors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<PropertyGetterDescriptor> overriddenGetters = Sets.newHashSet();
|
||||
private JetType returnType;
|
||||
|
||||
public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Annotation> 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<ValueParameterDescriptor> getUnsubstitutedValueParameters() {
|
||||
|
||||
@@ -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<PropertySetterDescriptor> overriddenSetters = Sets.newHashSet();
|
||||
|
||||
public PropertySetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Annotation> 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<ValueParameterDescriptor> getUnsubstitutedValueParameters() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<PsiElement> unresolvedReferences = new HashSet<PsiElement>();
|
||||
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(file.getProject(), new ErrorHandler() {
|
||||
@Override
|
||||
public void unresolvedReference(JetReferenceExpression referenceExpression) {
|
||||
public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) {
|
||||
unresolvedReferences.add(referenceExpression);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user