diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java index 5b2281ea730..b0c3247ef03 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java @@ -5,16 +5,11 @@ import com.google.common.collect.HashBiMap; import com.google.common.collect.Maps; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.resolve.BindingTrace; -import org.jetbrains.jet.lang.resolve.JetScope; -import org.jetbrains.jet.lang.resolve.WritableScope; -import org.jetbrains.jet.lang.resolve.WritableScopeImpl; +import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.types.*; import java.util.*; -import static org.jetbrains.jet.lang.types.TypeSubstitutor.TypeSubstitution; - /** * @author abreslav */ @@ -97,7 +92,7 @@ public class FunctionDescriptorUtil { @NotNull public static JetScope getFunctionInnerScope(@NotNull JetScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) { - WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, trace).setDebugName("Function inner scope"); + WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Function inner scope"); JetType receiverType = descriptor.getReceiverType(); if (receiverType != null) { parameterScope.setThisType(receiverType); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index dd6ef1366fb..f39d8e11a7b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -40,9 +40,10 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, ClassKind kind) { super(containingDeclaration); - this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, trace).setDebugName("MemberLookup"); - this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, trace).setDebugName("SupertypeResolution"); - this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, trace).setDebugName("MemberResolution"); + TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace); + this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler).setDebugName("MemberLookup"); + this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler).setDebugName("SupertypeResolution"); + this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler).setDebugName("MemberResolution"); this.kind = kind; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement1.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement1.java index efc03f41cdf..8d10286885c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement1.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement1.java @@ -1,9 +1,7 @@ package org.jetbrains.jet.lang.diagnostics; import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; /** @@ -29,11 +27,11 @@ public abstract class DiagnosticFactoryWithPsiElement1 @NotNull public Diagnostic on(@NotNull T element, @NotNull ASTNode node, @NotNull A argument) { - return new DiagnosticWithPsiElement(this, severity, makeMessage(argument), element, node.getTextRange()); + return new DiagnosticWithPsiElementImpl(this, severity, makeMessage(argument), element, node.getTextRange()); } @NotNull public Diagnostic on(@NotNull T element, @NotNull PsiElement psiElement, @NotNull A argument) { - return new DiagnosticWithPsiElement(this, severity, makeMessage(argument), element, psiElement.getTextRange()); + return new DiagnosticWithPsiElementImpl(this, severity, makeMessage(argument), element, psiElement.getTextRange()); } } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement2.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement2.java index 669090b4a50..dc4ea2218f2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement2.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement2.java @@ -33,6 +33,6 @@ public abstract class DiagnosticFactoryWithPsiElement2(this, severity, makeMessage(a, b), element, node.getTextRange()); + return new DiagnosticWithPsiElementImpl(this, severity, makeMessage(a, b), element, node.getTextRange()); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithPsiElement.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithPsiElement.java index 034ef8de822..30b4aac5aff 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithPsiElement.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithPsiElement.java @@ -1,27 +1,12 @@ package org.jetbrains.jet.lang.diagnostics; -import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; /** - * @author svtk + * @author abreslav */ -public class DiagnosticWithPsiElement extends GenericDiagnostic { - private final T psiElement; - - public DiagnosticWithPsiElement(DiagnosticFactory factory, Severity severity, String message, T psiElement) { - this(factory, severity, message, psiElement, psiElement.getTextRange()); - } - - public DiagnosticWithPsiElement(DiagnosticFactory factory, Severity severity, String message, T psiElement, @NotNull TextRange textRange) { - super(factory, severity, message, psiElement.getContainingFile(), textRange); - this.psiElement = psiElement; - } - +public interface DiagnosticWithPsiElement extends DiagnosticWithTextRange { @NotNull - public T getPsiElement() { - return psiElement; - } + T getPsiElement(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithPsiElementImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithPsiElementImpl.java new file mode 100644 index 00000000000..4c9914d4967 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithPsiElementImpl.java @@ -0,0 +1,27 @@ +package org.jetbrains.jet.lang.diagnostics; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +/** + * @author svtk + */ +public class DiagnosticWithPsiElementImpl extends GenericDiagnostic implements DiagnosticWithPsiElement { + private final T psiElement; + + public DiagnosticWithPsiElementImpl(DiagnosticFactory factory, Severity severity, String message, T psiElement) { + this(factory, severity, message, psiElement, psiElement.getTextRange()); + } + + public DiagnosticWithPsiElementImpl(DiagnosticFactory factory, Severity severity, String message, T psiElement, @NotNull TextRange textRange) { + super(factory, severity, message, psiElement.getContainingFile(), textRange); + this.psiElement = psiElement; + } + + @Override + @NotNull + public T getPsiElement() { + return psiElement; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ParameterizedDiagnosticFactory3.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ParameterizedDiagnosticFactory3.java index dd80fb14dc5..fafff17af01 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ParameterizedDiagnosticFactory3.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ParameterizedDiagnosticFactory3.java @@ -46,6 +46,6 @@ public class ParameterizedDiagnosticFactory3 extends DiagnosticFactoryW @NotNull public Diagnostic on(@NotNull PsiElement element, @NotNull A a, @NotNull B b, @NotNull C c) { - return new DiagnosticWithPsiElement(this, severity, makeMessage(a, b, c), element); + return new DiagnosticWithPsiElementImpl(this, severity, makeMessage(a, b, c), element); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnostic.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnostic.java index 9fbb737d3b1..eafe8595cab 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnostic.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnostic.java @@ -1,46 +1,79 @@ package org.jetbrains.jet.lang.diagnostics; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.resolve.BindingContext; import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR; /** -* @author abreslav -*/ -public class RedeclarationDiagnostic implements Diagnostic { + * @author abreslav + */ +public interface RedeclarationDiagnostic extends DiagnosticWithPsiElement { + public class SimpleRedeclarationDiagnostic extends DiagnosticWithPsiElementImpl implements RedeclarationDiagnostic { - private final DeclarationDescriptor a; - private final DeclarationDescriptor b; - - public RedeclarationDiagnostic(DeclarationDescriptor a, DeclarationDescriptor b) { - this.a = a; - this.b = b; + public SimpleRedeclarationDiagnostic(@NotNull PsiElement psiElement) { + super(RedeclarationDiagnosticFactory.INSTANCE, ERROR, "Redeclaration", psiElement); + } } - public DeclarationDescriptor getA() { - return a; + public class RedeclarationDiagnosticWithDeferredResolution implements RedeclarationDiagnostic { + + private final DeclarationDescriptor duplicatingDescriptor; + private final BindingContext contextToResolveToDeclaration; + private PsiElement element; + + public RedeclarationDiagnosticWithDeferredResolution(@NotNull DeclarationDescriptor duplicatingDescriptor, @NotNull BindingContext contextToResolveToDeclaration) { + this.duplicatingDescriptor = duplicatingDescriptor; + this.contextToResolveToDeclaration = contextToResolveToDeclaration; + } + + private PsiElement resolve() { + if (element == null) { + element = contextToResolveToDeclaration.get(BindingContext.DESCRIPTOR_TO_DECLARATION, duplicatingDescriptor); + assert element != null : "No element for descriptor: " + duplicatingDescriptor; + } + return element; + } + + @NotNull + @Override + public PsiElement getPsiElement() { + return resolve(); + } + + @NotNull + @Override + public TextRange getTextRange() { + return resolve().getTextRange(); + } + + @NotNull + @Override + public PsiFile getPsiFile() { + return resolve().getContainingFile(); + } + + @NotNull + @Override + public DiagnosticFactory getFactory() { + return Errors.REDECLARATION; + } + + @NotNull + @Override + public String getMessage() { + return "Redeclaration"; + } + + @NotNull + @Override + public Severity getSeverity() { + return ERROR; + } } - public DeclarationDescriptor getB() { - return b; - } - - @NotNull - @Override - public DiagnosticFactory getFactory() { - return RedeclarationDiagnosticFactory.INSTANCE; - } - - @NotNull - @Override - public String getMessage() { - return "Redeclaration"; - } - - @NotNull - @Override - public Severity getSeverity() { - return ERROR; - } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnosticFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnosticFactory.java index 5ebd2be9fb5..a44f5dfad57 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnosticFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/RedeclarationDiagnosticFactory.java @@ -1,9 +1,11 @@ package org.jetbrains.jet.lang.diagnostics; import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.resolve.BindingContext; /** * @author abreslav @@ -14,8 +16,12 @@ public class RedeclarationDiagnosticFactory implements DiagnosticFactory { public RedeclarationDiagnosticFactory() {} - public RedeclarationDiagnostic on(DeclarationDescriptor a, DeclarationDescriptor b) { - return new RedeclarationDiagnostic(a, b); + public RedeclarationDiagnostic on(@NotNull PsiElement duplicatingElement) { + return new RedeclarationDiagnostic.SimpleRedeclarationDiagnostic(duplicatingElement); + } + + public Diagnostic on(DeclarationDescriptor duplicatingDescriptor, BindingContext contextToResolveToDeclaration) { + return new RedeclarationDiagnostic.RedeclarationDiagnosticWithDeferredResolution(duplicatingDescriptor, contextToResolveToDeclaration); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/SimpleDiagnosticFactoryWithPsiElement.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/SimpleDiagnosticFactoryWithPsiElement.java index 4d8a7d4b7ee..89c1929ca7a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/SimpleDiagnosticFactoryWithPsiElement.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/SimpleDiagnosticFactoryWithPsiElement.java @@ -18,7 +18,7 @@ public abstract class SimpleDiagnosticFactoryWithPsiElement(this, severity, message, element, node.getTextRange()); + return new DiagnosticWithPsiElementImpl(this, severity, message, element, node.getTextRange()); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/UnresolvedReferenceDiagnostic.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/UnresolvedReferenceDiagnostic.java index ebe70e62ed3..3e41219d46a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/UnresolvedReferenceDiagnostic.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/UnresolvedReferenceDiagnostic.java @@ -8,7 +8,7 @@ import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR; /** * @author abreslav */ -public class UnresolvedReferenceDiagnostic extends DiagnosticWithPsiElement { +public class UnresolvedReferenceDiagnostic extends DiagnosticWithPsiElementImpl { public UnresolvedReferenceDiagnostic(JetReferenceExpression referenceExpression) { super(Errors.UNRESOLVED_REFERENCE, ERROR, "Unresolved reference", referenceExpression); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index 3ca2ef052c1..1d582977156 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -69,7 +69,7 @@ public class AnalyzingUtils { JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope(); ModuleDescriptor owner = new ModuleDescriptor(""); - final WritableScope scope = new WritableScopeImpl(libraryScope, owner, bindingTraceContext).setDebugName("Root scope in analyzeNamespace"); + final WritableScope scope = new WritableScopeImpl(libraryScope, owner, new TraceBasedRedeclarationHandler(bindingTraceContext)).setDebugName("Root scope in analyzeNamespace"); importingStrategy.addImports(project, semanticServices, bindingTraceContext, scope); TopDownAnalyzer.process(semanticServices, bindingTraceContext, scope, new NamespaceLike.Adapter(owner) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 2da0eb2866b..ee68f236761 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -500,7 +500,7 @@ public class BodyResolver { @NotNull private JetScope getInnerScopeForConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull JetScope declaringScope, boolean primary) { - WritableScope constructorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), context.getTrace()).setDebugName("Inner scope for constructor"); + WritableScope constructorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Inner scope for constructor"); for (PropertyDescriptor propertyDescriptor : ((MutableClassDescriptor) descriptor.getContainingDeclaration()).getProperties()) { constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor); } @@ -567,7 +567,7 @@ public class BodyResolver { } private JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull PropertyDescriptor propertyDescriptor) { - WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, context.getTrace()).setDebugName("Property declaration inner scope"); + WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Property declaration inner scope"); for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) { result.addTypeParameterDescriptor(typeParameterDescriptor); } @@ -581,7 +581,7 @@ public class BodyResolver { private void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor, JetScope declaringScope) { BindingTraceAdapter fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor); - WritableScope accessorScope = new WritableScopeImpl(getPropertyDeclarationInnerScope(declaringScope, propertyDescriptor), declaringScope.getContainingDeclaration(), context.getTrace()).setDebugName("Accessor scope"); + WritableScope accessorScope = new WritableScopeImpl(getPropertyDeclarationInnerScope(declaringScope, propertyDescriptor), declaringScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Accessor scope"); accessorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor); JetPropertyAccessor getter = property.getGetter(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index 122108346c5..e3785895486 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -142,7 +142,7 @@ public class ClassDescriptorResolver { annotationResolver.resolveAnnotations(scope, function.getModifierList()), JetPsiUtil.safeName(function.getName()) ); - WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, trace).setDebugName("Function descriptor header scope"); + WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Function descriptor header scope"); innerScope.addLabeledDeclaration(functionDescriptor); List typeParameterDescriptors = resolveTypeParameters(functionDescriptor, innerScope, function.getTypeParameters()); @@ -451,7 +451,7 @@ public class ClassDescriptorResolver { typeParameterDescriptors = Collections.emptyList(); } else { - WritableScope writableScope = new WritableScopeImpl(scope, containingDeclaration, trace).setDebugName("Scope with type parameters of a property"); + WritableScope writableScope = new WritableScopeImpl(scope, containingDeclaration, new TraceBasedRedeclarationHandler(trace)).setDebugName("Scope with type parameters of a property"); typeParameterDescriptors = resolveTypeParameters(containingDeclaration, writableScope, typeParameters); resolveGenericBounds(property, writableScope, typeParameterDescriptors); scopeWithTypeParameters = writableScope; @@ -659,7 +659,7 @@ public class ClassDescriptorResolver { typeParameters, resolveValueParameters( constructorDescriptor, - new WritableScopeImpl(scope, classDescriptor, trace).setDebugName("Scope with value parameters of a constructor"), + new WritableScopeImpl(scope, classDescriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Scope with value parameters of a constructor"), valueParameters), Modality.FINAL); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/RedeclarationHandler.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/RedeclarationHandler.java new file mode 100644 index 00000000000..b2574aaa20d --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/RedeclarationHandler.java @@ -0,0 +1,23 @@ +package org.jetbrains.jet.lang.resolve; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; + +/** + * @author abreslav + */ +public interface RedeclarationHandler { + RedeclarationHandler DO_NOTHING = new RedeclarationHandler() { + @Override + public void handleRedeclaration(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) { + } + }; + RedeclarationHandler THROW_EXCEPTION = new RedeclarationHandler() { + @Override + public void handleRedeclaration(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) { + throw new IllegalStateException("Redeclaration: " + first + " and " + second + "(no line info available)"); + } + }; + + void handleRedeclaration(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TraceBasedRedeclarationHandler.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TraceBasedRedeclarationHandler.java new file mode 100644 index 00000000000..5b3438de5d9 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TraceBasedRedeclarationHandler.java @@ -0,0 +1,34 @@ +package org.jetbrains.jet.lang.resolve; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; + +import static org.jetbrains.jet.lang.diagnostics.Errors.REDECLARATION; + +/** + * @author abreslav + */ +public class TraceBasedRedeclarationHandler implements RedeclarationHandler { + private final BindingTrace trace; + + public TraceBasedRedeclarationHandler(@NotNull BindingTrace trace) { + this.trace = trace; + } + + @Override + public void handleRedeclaration(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) { + report(first); + report(second); + } + + private void report(DeclarationDescriptor first) { + PsiElement firstElement = trace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, first); + if (firstElement != null) { + trace.report(REDECLARATION.on(firstElement)); + } + else { + trace.report(REDECLARATION.on(first, trace.getBindingContext())); + } + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 48e6a50b829..89a3940cb28 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -71,13 +71,13 @@ public class TypeHierarchyResolver { Collections.emptyList(), // TODO: annotations name ); - namespaceDescriptor.initialize(new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, context.getTrace()).setDebugName("Namespace member scope")); + namespaceDescriptor.initialize(new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Namespace member scope")); owner.addNamespace(namespaceDescriptor); context.getTrace().record(BindingContext.NAMESPACE, namespace, namespaceDescriptor); } context.getNamespaceDescriptors().put(namespace, namespaceDescriptor); - WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), context.getTrace()); + WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), new TraceBasedRedeclarationHandler(context.getTrace())); context.getNamespaceScopes().put(namespace, namespaceScope); processImports(namespace, namespaceScope, outerScope); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeImpl.java index 6d6065cc7c0..48e1e88ae8d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeImpl.java @@ -6,13 +6,10 @@ import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; import org.jetbrains.jet.lang.types.JetType; import java.util.*; -import static org.jetbrains.jet.lang.diagnostics.Errors.REDECLARATION; - /** * @author abreslav */ @@ -40,8 +37,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { private List variableDescriptors; - public WritableScopeImpl(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner, @NotNull DiagnosticHolder diagnosticHolder) { - super(scope, diagnosticHolder); + public WritableScopeImpl(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner, @NotNull RedeclarationHandler redeclarationHandler) { + super(scope, redeclarationHandler); this.ownerDeclarationDescriptor = owner; } @@ -139,7 +136,7 @@ public class WritableScopeImpl extends WritableScopeWithImports { Map variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); DeclarationDescriptor existingDescriptor = variableClassOrNamespaceDescriptors.get(variableDescriptor.getName()); if (existingDescriptor != null) { - diagnosticHolder.report(REDECLARATION.on(existingDescriptor, variableDescriptor)); + redeclarationHandler.handleRedeclaration(existingDescriptor, variableDescriptor); } // TODO : Should this always happen? variableClassOrNamespaceDescriptors.put(variableDescriptor.getName(), variableDescriptor); @@ -230,7 +227,7 @@ public class WritableScopeImpl extends WritableScopeWithImports { Map variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); DeclarationDescriptor originalDescriptor = variableClassOrNamespaceDescriptors.get(name); if (originalDescriptor != null) { - diagnosticHolder.report(REDECLARATION.on(originalDescriptor, classifierDescriptor)); + redeclarationHandler.handleRedeclaration(originalDescriptor, classifierDescriptor); } variableClassOrNamespaceDescriptors.put(name, classifierDescriptor); allDescriptors.add(classifierDescriptor); @@ -262,7 +259,7 @@ public class WritableScopeImpl extends WritableScopeWithImports { Map variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors(); DeclarationDescriptor oldValue = variableClassOrNamespaceDescriptors.put(namespaceDescriptor.getName(), namespaceDescriptor); if (oldValue != null) { - diagnosticHolder.report(REDECLARATION.on(oldValue, namespaceDescriptor)); + redeclarationHandler.handleRedeclaration(oldValue, namespaceDescriptor); } allDescriptors.add(namespaceDescriptor); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeWithImports.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeWithImports.java index 6151d0f708a..1a03d1e5d46 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeWithImports.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeWithImports.java @@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; import java.util.ArrayList; import java.util.List; @@ -18,11 +17,11 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement @Nullable private List imports; private WritableScope currentIndividualImportScope; - protected final DiagnosticHolder diagnosticHolder; + protected final RedeclarationHandler redeclarationHandler; - public WritableScopeWithImports(@NotNull JetScope scope, @NotNull DiagnosticHolder diagnosticHolder) { + public WritableScopeWithImports(@NotNull JetScope scope, @NotNull RedeclarationHandler redeclarationHandler) { super(scope); - this.diagnosticHolder = diagnosticHolder; + this.redeclarationHandler = redeclarationHandler; } public WritableScopeWithImports setDebugName(@NotNull String debugName) { @@ -97,7 +96,7 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement public void importClassifierAlias(@NotNull String importedClassifierName, @NotNull ClassifierDescriptor classifierDescriptor) { if (currentIndividualImportScope == null) { - WritableScopeImpl writableScope = new WritableScopeImpl(JetScope.EMPTY, getContainingDeclaration(), DiagnosticHolder.DO_NOTHING).setDebugName("Individual import scope"); + WritableScopeImpl writableScope = new WritableScopeImpl(JetScope.EMPTY, getContainingDeclaration(), RedeclarationHandler.DO_NOTHING).setDebugName("Individual import scope"); importScope(writableScope); currentIndividualImportScope = writableScope; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WriteThroughScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WriteThroughScope.java index 3018808e29e..74c029e7b43 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WriteThroughScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WriteThroughScope.java @@ -4,7 +4,6 @@ import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; import org.jetbrains.jet.lang.types.JetType; import java.util.Collection; @@ -16,8 +15,8 @@ public class WriteThroughScope extends WritableScopeWithImports { private final WritableScope writableWorker; private Collection allDescriptors; - public WriteThroughScope(@NotNull JetScope outerScope, @NotNull WritableScope scope, @NotNull DiagnosticHolder diagnosticHolder) { - super(outerScope, diagnosticHolder); + public WriteThroughScope(@NotNull JetScope outerScope, @NotNull WritableScope scope, @NotNull RedeclarationHandler redeclarationHandler) { + super(outerScope, redeclarationHandler); this.writableWorker = scope; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index f307299eb96..2e30c1a0e38 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -6,11 +6,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; -import org.jetbrains.jet.lang.resolve.JetScope; -import org.jetbrains.jet.lang.resolve.JetScopeImpl; -import org.jetbrains.jet.lang.resolve.WritableScope; -import org.jetbrains.jet.lang.resolve.WritableScopeImpl; +import org.jetbrains.jet.lang.resolve.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -198,7 +194,7 @@ public class JetStandardClasses { /*package*/ static final JetScope STANDARD_CLASSES; static { - WritableScope writableScope = new WritableScopeImpl(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE, DiagnosticHolder.DO_NOTHING).setDebugName("JetStandardClasses.STANDARD_CLASSES"); + WritableScope writableScope = new WritableScopeImpl(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE, RedeclarationHandler.DO_NOTHING).setDebugName("JetStandardClasses.STANDARD_CLASSES"); STANDARD_CLASSES = writableScope; writableScope.addClassifierAlias("Unit", getTuple(0)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index e1c19b1a575..1ab9f99ebb4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -9,7 +9,6 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionGroup; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.plugin.JetFileType; @@ -99,7 +98,7 @@ public class JetStandardLibrary { JetSemanticServices bootstrappingSemanticServices = JetSemanticServices.createSemanticServices(this); BindingTraceContext bindingTraceContext = new BindingTraceContext(); - WritableScopeImpl writableScope = new WritableScopeImpl(JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, DiagnosticHolder.THROW_EXCEPTION).setDebugName("Root bootstrap scope"); + WritableScopeImpl writableScope = new WritableScopeImpl(JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, RedeclarationHandler.THROW_EXCEPTION).setDebugName("Root bootstrap scope"); // this.libraryScope = bootstrappingTDA.process(JetStandardClasses.STANDARD_CLASSES, file.getRootNamespace().getDeclarations()); // bootstrappingTDA.process(writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace().getDeclarations()); TopDownAnalyzer.processStandardLibraryNamespace(bootstrappingSemanticServices, bindingTraceContext, writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 6950b92af0f..0427ba0b237 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -367,7 +367,7 @@ public class JetTypeInferrer { } DeclarationDescriptor containingDescriptor = outerScope.getContainingDeclaration(); - WritableScope scope = new WritableScopeImpl(outerScope, containingDescriptor, context.trace).setDebugName("getBlockReturnedType"); + WritableScope scope = new WritableScopeImpl(outerScope, containingDescriptor, new TraceBasedRedeclarationHandler(context.trace)).setDebugName("getBlockReturnedType"); return getBlockReturnedTypeWithWritableScope(scope, block, coercionStrategyForLastExpression, context); } @@ -1814,7 +1814,7 @@ public class JetTypeInferrer { } protected WritableScopeImpl newWritableScopeImpl(JetScope scope, BindingTrace trace) { - return new WritableScopeImpl(scope, scope.getContainingDeclaration(), trace); + return new WritableScopeImpl(scope, scope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace)); } @Override diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java b/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java index 02bf994dfba..75fae7ffed9 100644 --- a/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java +++ b/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java @@ -13,7 +13,6 @@ import com.intellij.psi.MultiRangeReference; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.diagnostics.*; @@ -52,7 +51,7 @@ public class JetPsiChecker implements Annotator { if (errorReportingEnabled) { Collection diagnostics = bindingContext.getDiagnostics(); - Set redeclarations = Sets.newHashSet(); + Set redeclarations = Sets.newHashSet(); for (Diagnostic diagnostic : diagnostics) { Annotation annotation = null; if (diagnostic.getSeverity() == Severity.ERROR) { @@ -72,8 +71,7 @@ public class JetPsiChecker implements Annotator { } else if (diagnostic instanceof RedeclarationDiagnostic) { RedeclarationDiagnostic redeclarationDiagnostic = (RedeclarationDiagnostic) diagnostic; - markRedeclaration(redeclarations, redeclarationDiagnostic.getA(), bindingContext, holder); - markRedeclaration(redeclarations, redeclarationDiagnostic.getB(), bindingContext, holder); + markRedeclaration(redeclarations, redeclarationDiagnostic.getPsiElement(), holder); } else { annotation = holder.createErrorAnnotation(diagnostic.getFactory().getTextRange(diagnostic), getMessage(diagnostic)); @@ -82,7 +80,7 @@ public class JetPsiChecker implements Annotator { else if (diagnostic.getSeverity() == Severity.WARNING) { annotation = holder.createWarningAnnotation(diagnostic.getFactory().getTextRange(diagnostic), getMessage(diagnostic)); } - if (annotation != null && diagnostic instanceof DiagnosticWithPsiElement) { + if (annotation != null && diagnostic instanceof DiagnosticWithPsiElementImpl) { DiagnosticWithPsiElement diagnosticWithPsiElement = (DiagnosticWithPsiElement) diagnostic; if (diagnostic.getFactory() instanceof PsiElementOnlyDiagnosticFactory) { PsiElementOnlyDiagnosticFactory factory = (PsiElementOnlyDiagnosticFactory) diagnostic.getFactory(); @@ -135,17 +133,16 @@ public class JetPsiChecker implements Annotator { return diagnostic.getMessage(); } - private void markRedeclaration(Set redeclarations, DeclarationDescriptor redeclaration, BindingContext bindingContext, AnnotationHolder holder) { + private void markRedeclaration(Set redeclarations, @NotNull PsiElement redeclaration, AnnotationHolder holder) { if (!redeclarations.add(redeclaration)) return; - PsiElement declarationPsiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, redeclaration); - if (declarationPsiElement instanceof JetNamedDeclaration) { - PsiElement nameIdentifier = ((JetNamedDeclaration) declarationPsiElement).getNameIdentifier(); + if (redeclaration instanceof JetNamedDeclaration) { + PsiElement nameIdentifier = ((JetNamedDeclaration) redeclaration).getNameIdentifier(); if (nameIdentifier != null) { holder.createErrorAnnotation(nameIdentifier, "Redeclaration"); } } - else if (declarationPsiElement != null) { - holder.createErrorAnnotation(declarationPsiElement, "Redeclaration"); + else { + holder.createErrorAnnotation(redeclaration, "Redeclaration"); } } diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index 2b2cee7886a..a647c7a4d8f 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -13,7 +13,6 @@ import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.java.JavaPackageScope; @@ -527,7 +526,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { } private WritableScopeImpl addImports(JetScope scope) { - WritableScopeImpl writableScope = new WritableScopeImpl(scope, scope.getContainingDeclaration(), DiagnosticHolder.DO_NOTHING); + WritableScopeImpl writableScope = new WritableScopeImpl(scope, scope.getContainingDeclaration(), RedeclarationHandler.DO_NOTHING); writableScope.importScope(library.getLibraryScope()); JavaSemanticServices javaSemanticServices = new JavaSemanticServices(getProject(), semanticServices, JetTestUtils.DUMMY_TRACE); writableScope.importScope(new JavaPackageScope("", null, javaSemanticServices)); @@ -637,7 +636,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { trace.record(BindingContext.CLASS, classElement, classDescriptor); - final WritableScope parameterScope = new WritableScopeImpl(scope, classDescriptor, trace); + final WritableScope parameterScope = new WritableScopeImpl(scope, classDescriptor, new TraceBasedRedeclarationHandler(trace)); // This call has side-effects on the parameterScope (fills it in) List typeParameters @@ -656,7 +655,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { // } boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD); - final WritableScope memberDeclarations = new WritableScopeImpl(JetScope.EMPTY, classDescriptor, trace); + final WritableScope memberDeclarations = new WritableScopeImpl(JetScope.EMPTY, classDescriptor, new TraceBasedRedeclarationHandler(trace)); List declarations = classElement.getDeclarations(); for (JetDeclaration declaration : declarations) {