Redeclarations reported in the editor
This commit is contained in:
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang;
|
||||
import com.intellij.lang.ASTNode;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -25,6 +26,11 @@ public class ErrorHandler {
|
||||
public void typeMismatch(JetExpression expression, JetType expectedType, JetType actualType) {
|
||||
throw new IllegalStateException("Type mismatch: inferred type is " + actualType + " but " + expectedType + " was expected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redeclaration(DeclarationDescriptor existingDescriptor, DeclarationDescriptor redeclaredDescriptor) {
|
||||
throw new IllegalStateException("Redeclaration: " + existingDescriptor.getName());
|
||||
}
|
||||
};
|
||||
|
||||
public void unresolvedReference(JetReferenceExpression referenceExpression) {
|
||||
@@ -35,4 +41,7 @@ public class ErrorHandler {
|
||||
|
||||
public void typeMismatch(JetExpression expression, JetType expectedType, JetType actualType) {
|
||||
}
|
||||
|
||||
public void redeclaration(DeclarationDescriptor existingDescriptor, DeclarationDescriptor redeclaredDescriptor) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,10 @@ package org.jetbrains.jet.lang;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.ClassDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
||||
import org.jetbrains.jet.lang.types.BindingTrace;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.JetTypeInferrer;
|
||||
import org.jetbrains.jet.lang.resolve.WritableScope;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -63,4 +62,9 @@ public class JetSemanticServices {
|
||||
public OverloadResolver getOverloadResolver() {
|
||||
return overloadResolver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WritableScope createWritableScope(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner) {
|
||||
return new WritableScope(scope, owner, errorHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,17 @@ 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.psi.*;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
@@ -29,6 +35,7 @@ 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() {
|
||||
@Override
|
||||
public void unresolvedReference(JetReferenceExpression referenceExpression) {
|
||||
@@ -52,24 +59,19 @@ public class JetPsiChecker implements Annotator {
|
||||
public void typeMismatch(JetExpression expression, JetType expectedType, JetType actualType) {
|
||||
holder.createErrorAnnotation(expression, "Type mismatch: inferred type is " + actualType + " but " + expectedType + " was expected");
|
||||
}
|
||||
});
|
||||
file.getRootNamespace().accept(new JetVisitor() {
|
||||
@Override
|
||||
public void visitClass(JetClass klass) {
|
||||
for (JetDelegationSpecifier specifier : klass.getDelegationSpecifiers()) {
|
||||
JetTypeReference typeReference = specifier.getTypeReference();
|
||||
JetType type = bindingContext.resolveTypeReference(typeReference);
|
||||
holder.createWeakWarningAnnotation(typeReference, type.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNamespace(JetNamespace namespace) {
|
||||
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
||||
declaration.accept(this);
|
||||
}
|
||||
public void redeclaration(DeclarationDescriptor existingDescriptor, DeclarationDescriptor redeclaredDescriptor) {
|
||||
redeclarations.add(existingDescriptor);
|
||||
redeclarations.add(redeclaredDescriptor);
|
||||
}
|
||||
});
|
||||
for (DeclarationDescriptor redeclaration : redeclarations) {
|
||||
PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(redeclaration);
|
||||
if (declarationPsiElement != null) {
|
||||
holder.createErrorAnnotation(declarationPsiElement, "Redeclaration");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
|
||||
@@ -27,7 +27,7 @@ public class AnalyzingUtils {
|
||||
JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, semanticServices, bindingTraceContext);
|
||||
|
||||
JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope();
|
||||
WritableScope scope = new WritableScope(libraryScope, new ModuleDescriptor("<module>"));
|
||||
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));
|
||||
|
||||
@@ -30,7 +30,7 @@ public class ClassDescriptorResolver {
|
||||
scope.getContainingDeclaration(),
|
||||
AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()),
|
||||
classElement.getName());
|
||||
WritableScope parameterScope = new WritableScope(scope, classDescriptor);
|
||||
WritableScope parameterScope = semanticServices.createWritableScope(scope, classDescriptor);
|
||||
|
||||
// This call has side-effects on the parameterScope (fills it in)
|
||||
List<TypeParameterDescriptor> typeParameters
|
||||
@@ -100,7 +100,7 @@ public class ClassDescriptorResolver {
|
||||
final JetScope typeParameterScope,
|
||||
final Collection<? extends JetType> supertypes) {
|
||||
|
||||
final WritableScope memberDeclarations = new WritableScope(typeParameterScope, classDescriptor);
|
||||
final WritableScope memberDeclarations = semanticServices.createWritableScope(typeParameterScope, classDescriptor);
|
||||
|
||||
List<JetDeclaration> declarations = classElement.getDeclarations();
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
@@ -142,7 +142,7 @@ public class ClassDescriptorResolver {
|
||||
AttributeResolver.INSTANCE.resolveAttributes(function.getModifierList()),
|
||||
function.getName()
|
||||
);
|
||||
WritableScope parameterScope = new WritableScope(scope, functionDescriptor);
|
||||
WritableScope parameterScope = semanticServices.createWritableScope(scope, functionDescriptor);
|
||||
|
||||
// The two calls below have side-effects on parameterScope
|
||||
List<TypeParameterDescriptor> typeParameterDescriptors = resolveTypeParameters(functionDescriptor, parameterScope, function.getTypeParameters());
|
||||
|
||||
@@ -7,9 +7,10 @@ import org.jetbrains.jet.lang.types.*;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class JetScopeAdapter implements JetScope {
|
||||
@NotNull
|
||||
private final JetScope scope;
|
||||
|
||||
public JetScopeAdapter(JetScope scope) {
|
||||
public JetScopeAdapter(@NotNull JetScope scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.List;
|
||||
@@ -13,9 +14,9 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
||||
private final WritableScope unsubstitutedMemberScope;
|
||||
private TypeConstructor typeConstructor;
|
||||
|
||||
public MutableClassDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
|
||||
public MutableClassDescriptor(@NotNull JetSemanticServices semanticServices, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
|
||||
super(containingDeclaration);
|
||||
this.unsubstitutedMemberScope = new WritableScope(outerScope, this);
|
||||
this.unsubstitutedMemberScope = semanticServices.createWritableScope(outerScope, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -32,7 +32,7 @@ public class TopDownAnalyzer {
|
||||
}
|
||||
|
||||
public void process(@NotNull JetScope outerScope, @NotNull List<JetDeclaration> declarations) {
|
||||
final WritableScope toplevelScope = new WritableScope(outerScope, outerScope.getContainingDeclaration()); // TODO ?!
|
||||
final WritableScope toplevelScope = semanticServices.createWritableScope(outerScope, outerScope.getContainingDeclaration()); // TODO ?!
|
||||
trace.setToplevelScope(toplevelScope); // TODO : this is a hack
|
||||
collectTypeDeclarators(toplevelScope, declarations);
|
||||
resolveTypeDeclarations();
|
||||
@@ -69,7 +69,7 @@ public class TopDownAnalyzer {
|
||||
trace.recordDeclarationResolution(namespace, namespaceDescriptor);
|
||||
}
|
||||
|
||||
WritableScope namespaceScope = new WritableScope(declaringScope, namespaceDescriptor);
|
||||
WritableScope namespaceScope = semanticServices.createWritableScope(declaringScope, namespaceDescriptor);
|
||||
namespaceScopes.put(namespace, namespaceScope);
|
||||
|
||||
for (JetImportDirective importDirective : importDirectives) {
|
||||
@@ -104,7 +104,7 @@ public class TopDownAnalyzer {
|
||||
}
|
||||
|
||||
private WritableScope processClass(@NotNull WritableScope declaringScope, JetClass klass) {
|
||||
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(declaringScope.getContainingDeclaration(), declaringScope);
|
||||
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(semanticServices, declaringScope.getContainingDeclaration(), declaringScope);
|
||||
mutableClassDescriptor.setName(klass.getName());
|
||||
|
||||
declaringScope.addClassDescriptor(mutableClassDescriptor);
|
||||
@@ -204,7 +204,7 @@ public class TopDownAnalyzer {
|
||||
WritableScope declaringScope = declaringScopes.get(function);
|
||||
assert declaringScope != null;
|
||||
|
||||
WritableScope parameterScope = new WritableScope(declaringScope, descriptor);
|
||||
WritableScope parameterScope = semanticServices.createWritableScope(declaringScope, descriptor);
|
||||
for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
|
||||
parameterScope.addTypeParameterDescriptor(typeParameter);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -13,6 +14,9 @@ import java.util.Map;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class WritableScope extends JetScopeAdapter {
|
||||
@NotNull
|
||||
private final ErrorHandler errorHandler;
|
||||
|
||||
@Nullable
|
||||
private Map<String, PropertyDescriptor> propertyDescriptors;
|
||||
@Nullable
|
||||
@@ -31,9 +35,10 @@ public class WritableScope extends JetScopeAdapter {
|
||||
@NotNull
|
||||
private final DeclarationDescriptor ownerDeclarationDescriptor;
|
||||
|
||||
public WritableScope(JetScope scope, @NotNull DeclarationDescriptor owner) {
|
||||
public WritableScope(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner, @NotNull ErrorHandler errorHandler) {
|
||||
super(scope);
|
||||
this.ownerDeclarationDescriptor = owner;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -42,7 +47,7 @@ public class WritableScope extends JetScopeAdapter {
|
||||
return ownerDeclarationDescriptor;
|
||||
}
|
||||
|
||||
public void importScope(JetScope imported) {
|
||||
public void importScope(@NotNull JetScope imported) {
|
||||
getImports().add(0, imported);
|
||||
}
|
||||
|
||||
@@ -64,9 +69,11 @@ public class WritableScope extends JetScopeAdapter {
|
||||
|
||||
public void addPropertyDescriptor(PropertyDescriptor propertyDescriptor) {
|
||||
Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors();
|
||||
if (propertyDescriptors.containsKey(propertyDescriptor.getName())) {
|
||||
throw new UnsupportedOperationException("Property redeclared: " + propertyDescriptor.getName());
|
||||
PropertyDescriptor existingDescriptor = propertyDescriptors.get(propertyDescriptor.getName());
|
||||
if (existingDescriptor != null) {
|
||||
errorHandler.redeclaration(existingDescriptor, propertyDescriptor);
|
||||
}
|
||||
// TODO : Should this always happen?
|
||||
propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.WritableScope;
|
||||
|
||||
@@ -160,7 +161,7 @@ public class JetStandardClasses {
|
||||
/*package*/ static final JetScope STANDARD_CLASSES;
|
||||
|
||||
static {
|
||||
WritableScope writableScope = new WritableScope(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE);
|
||||
WritableScope writableScope = new WritableScope(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE, ErrorHandler.DO_NOTHING);
|
||||
STANDARD_CLASSES = writableScope;
|
||||
writableScope.addClassAlias("Unit", getTuple(0));
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -274,7 +273,7 @@ public class JetTypeChecker {
|
||||
handler.afterChildren(current);
|
||||
}
|
||||
|
||||
public boolean isConvertibleTo(JetType actual, JetType expected) {
|
||||
public boolean isConvertibleTo(@NotNull JetType actual, @NotNull JetType expected) {
|
||||
if (isSubtypeOf(actual, expected)) return true;
|
||||
if (expected.getConstructor().equals(JetStandardClasses.getTuple(0).getTypeConstructor())) {
|
||||
return true;
|
||||
|
||||
@@ -25,7 +25,7 @@ public class JetTypeInferrer {
|
||||
this.trace = trace;
|
||||
this.semanticServices = semanticServices;
|
||||
this.typeResolver = new TypeResolver(trace, semanticServices);
|
||||
this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, trace);
|
||||
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -168,7 +168,7 @@ public class JetTypeInferrer {
|
||||
return JetStandardClasses.getUnitType();
|
||||
} else {
|
||||
DeclarationDescriptor containingDescriptor = outerScope.getContainingDeclaration();
|
||||
WritableScope scope = new WritableScope(outerScope, containingDescriptor);
|
||||
WritableScope scope = semanticServices.createWritableScope(outerScope, containingDescriptor);
|
||||
for (JetElement statement : block) {
|
||||
// TODO: consider other declarations
|
||||
if (statement instanceof JetProperty) {
|
||||
@@ -181,7 +181,7 @@ public class JetTypeInferrer {
|
||||
getType(scope, (JetExpression) statement, true);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
throw new UnsupportedOperationException(statement.getClass().getCanonicalName()); // TODO
|
||||
}
|
||||
}
|
||||
JetElement lastElement = block.get(block.size() - 1);
|
||||
@@ -278,7 +278,7 @@ public class JetTypeInferrer {
|
||||
if (returnTypeRef != null) {
|
||||
returnType = typeResolver.resolveType(scope, returnTypeRef);
|
||||
} else {
|
||||
WritableScope writableScope = new WritableScope(scope, functionDescriptor);
|
||||
WritableScope writableScope = semanticServices.createWritableScope(scope, functionDescriptor);
|
||||
for (PropertyDescriptor propertyDescriptor : parameterDescriptors.values()) {
|
||||
writableScope.addPropertyDescriptor(propertyDescriptor);
|
||||
}
|
||||
@@ -689,8 +689,8 @@ public class JetTypeInferrer {
|
||||
}
|
||||
|
||||
private JetType getTypeForBinaryCall(JetScope scope, JetExpression left, JetSimpleNameExpression operationSign, @NotNull JetExpression right, String name, boolean reportUnresolved) {
|
||||
JetType leftType = getType(scope, left, false);
|
||||
JetType rightType = getType(scope, right, false);
|
||||
JetType leftType = safeGetType(scope, left, false);
|
||||
JetType rightType = safeGetType(scope, right, false);
|
||||
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, name, leftType, Collections.singletonList(rightType), reportUnresolved);
|
||||
if (functionDescriptor != null) {
|
||||
return functionDescriptor.getUnsubstitutedReturnType();
|
||||
|
||||
Reference in New Issue
Block a user