Restrict scope of local declarations

This commit is contained in:
Alexey Sedunov
2013-10-23 18:33:09 +04:00
parent c3c0925de1
commit b20a18cf38
4 changed files with 31 additions and 18 deletions
@@ -18,12 +18,13 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.stubs.IStubElementType; import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.NamedStub; import com.intellij.psi.stubs.NamedStub;
import com.intellij.util.IncorrectOperationException; import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
@@ -80,4 +81,15 @@ abstract class JetNamedDeclarationStub<T extends NamedStub> extends JetDeclarati
PsiElement identifier = getNameIdentifier(); PsiElement identifier = getNameIdentifier();
return identifier != null ? identifier.getTextRange().getStartOffset() : getTextRange().getStartOffset(); return identifier != null ? identifier.getTextRange().getStartOffset() : getTextRange().getStartOffset();
} }
@NotNull
@Override
public SearchScope getUseScope() {
JetElement enclosingBlock = JetPsiUtil.getEnclosingBlockForLocalDeclaration(this);
if (enclosingBlock != null) {
return new LocalSearchScope(enclosingBlock);
}
return super.getUseScope();
}
} }
@@ -17,6 +17,8 @@
package org.jetbrains.jet.lang.psi; package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class JetObjectDeclarationName extends JetNamedDeclarationNotStubbed { public class JetObjectDeclarationName extends JetNamedDeclarationNotStubbed {
@@ -34,4 +36,11 @@ public class JetObjectDeclarationName extends JetNamedDeclarationNotStubbed {
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) { public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitObjectDeclarationName(this, data); return visitor.visitObjectDeclarationName(this, data);
} }
@NotNull
@Override
public SearchScope getUseScope() {
JetObjectDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(this, JetObjectDeclaration.class);
return objectDeclaration != null ? objectDeclaration.getUseScope() : super.getUseScope();
}
} }
@@ -89,16 +89,6 @@ public class JetProperty extends JetTypeParameterListOwnerStub<PsiJetPropertyStu
return getParent() instanceof JetFile; return getParent() instanceof JetFile;
} }
@NotNull
@Override
public SearchScope getUseScope() {
if (isLocal()) {
@SuppressWarnings("unchecked") PsiElement block = PsiTreeUtil.getParentOfType(this, JetBlockExpression.class, JetClassInitializer.class);
if (block == null) return super.getUseScope();
else return new LocalSearchScope(block);
} else return super.getUseScope();
}
@Nullable @Nullable
@Override @Override
public JetParameterList getValueParameterList() { public JetParameterList getValueParameterList() {
@@ -1007,16 +1007,18 @@ public class JetPsiUtil {
return header != null ? header.getQualifiedName() : null; return header != null ? header.getQualifiedName() : null;
} }
public static JetElement getEnclosingBlockForLocalDeclaration(@NotNull JetNamedDeclaration declaration) { @Nullable
//noinspection unchecked public static JetElement getEnclosingBlockForLocalDeclaration(@Nullable JetNamedDeclaration declaration) {
JetDeclaration container = if (declaration instanceof JetTypeParameter || declaration instanceof JetParameter) {
PsiTreeUtil.getParentOfType(declaration, JetNamedFunction.class, JetPropertyAccessor.class, JetClassInitializer.class); declaration = PsiTreeUtil.getParentOfType(declaration, JetNamedDeclaration.class);
}
//noinspection unchecked
JetElement container =
PsiTreeUtil.getParentOfType(declaration, JetBlockExpression.class, JetClassInitializer.class);
if (container == null) return null; if (container == null) return null;
return (container instanceof JetClassInitializer) return (container instanceof JetClassInitializer) ? ((JetClassInitializer) container).getBody() : container;
? ((JetClassInitializer) container).getBody()
: ((JetDeclarationWithBody) container).getBodyExpression();
} }
public static boolean isLocal(@NotNull JetNamedDeclaration declaration) { public static boolean isLocal(@NotNull JetNamedDeclaration declaration) {