Navigation improved a little

This commit is contained in:
Andrey Breslav
2011-03-01 14:27:58 +03:00
parent ecc2300f79
commit 8c77e38c67
7 changed files with 156 additions and 35 deletions
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.annotations;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.JetSemanticServices;
@@ -20,24 +21,31 @@ public class JetPsiChecker implements Annotator {
if (element instanceof JetFile) {
JetFile file = (JetFile) element;
JetSemanticServices semanticServices = new JetSemanticServices(element.getProject());
final BindingContext bindingContext = new TopDownAnalyzer(semanticServices).process(semanticServices.getStandardLibrary().getLibraryScope(), file.getRootNamespace().getDeclarations());
file.getRootNamespace().accept(new JetVisitor() {
@Override
public void visitClass(JetClass klass) {
for (JetDelegationSpecifier specifier : klass.getDelegationSpecifiers()) {
JetTypeReference typeReference = specifier.getTypeReference();
Type type = bindingContext.resolveTypeReference(typeReference);
holder.createWeakWarningAnnotation(typeReference, type.toString());
try {
final BindingContext bindingContext = new TopDownAnalyzer(semanticServices).process(semanticServices.getStandardLibrary().getLibraryScope(), file.getRootNamespace().getDeclarations());
file.getRootNamespace().accept(new JetVisitor() {
@Override
public void visitClass(JetClass klass) {
for (JetDelegationSpecifier specifier : klass.getDelegationSpecifiers()) {
JetTypeReference typeReference = specifier.getTypeReference();
Type type = bindingContext.resolveTypeReference(typeReference);
holder.createWeakWarningAnnotation(typeReference, type.toString());
}
}
}
@Override
public void visitNamespace(JetNamespace namespace) {
for (JetDeclaration declaration : namespace.getDeclarations()) {
declaration.accept(this);
@Override
public void visitNamespace(JetNamespace namespace) {
for (JetDeclaration declaration : namespace.getDeclarations()) {
declaration.accept(this);
}
}
}
});
});
}
catch (Throwable e) {
// TODO
holder.createErrorAnnotation(new TextRange(0, 1), e.getClass().getCanonicalName() + ": " + e.getMessage());
e.printStackTrace();
}
}
}
}
@@ -74,33 +74,33 @@ public class JetReferenceExpression extends JetExpression {
@NotNull
@Override
public String getCanonicalText() {
throw new UnsupportedOperationException(); // TODO
return getReferencedName();
}
@Override
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
throw new UnsupportedOperationException(); // TODO
throw new IncorrectOperationException();
}
@Override
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
throw new UnsupportedOperationException(); // TODO
throw new IncorrectOperationException();
}
@Override
public boolean isReferenceTo(PsiElement element) {
throw new UnsupportedOperationException(); // TODO
return false;
}
@NotNull
@Override
public Object[] getVariants() {
throw new UnsupportedOperationException(); // TODO
return EMPTY_ARRAY;
}
@Override
public boolean isSoft() {
throw new UnsupportedOperationException(); // TODO
return false;
}
};
}
@@ -139,7 +139,7 @@ public class ClassDescriptorResolver {
returnType = semanticServices.getTypeInferrer().getType(parameterScope, bodyExpression, function.hasBlockBody());
}
return new FunctionDescriptorImpl(
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(
function,
null,
AttributeResolver.INSTANCE.resolveAttributes(function.getModifierList()),
@@ -148,6 +148,9 @@ public class ClassDescriptorResolver {
valueParameterDescriptors,
returnType
);
trace.recordDeclarationResolution(function, functionDescriptor);
return functionDescriptor;
}
private List<ValueParameterDescriptor> resolveValueParameters(WritableScope parameterScope, List<JetParameter> valueParameters) {
@@ -30,22 +30,22 @@ public class TopDownAnalyzer {
this.semanticServices = semanticServices;
this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, new BindingTrace() {
@Override
public void recordExpressionType(JetExpression expression, Type type) {
public void recordExpressionType(@NotNull JetExpression expression, @NotNull Type type) {
expressionTypes.put(expression, type);
}
@Override
public void recordReferenceResolution(JetReferenceExpression expression, DeclarationDescriptor descriptor) {
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
resolutionResults.put(expression, descriptor);
}
@Override
public void recordTypeResolution(JetTypeReference typeReference, Type type) {
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull Type type) {
types.put(typeReference, type);
}
@Override
public void recordDeclarationResolution(JetDeclaration declaration, DeclarationDescriptor descriptor) {
public void recordDeclarationResolution(@NotNull JetDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
descriptorToDeclarations.put(descriptor, declaration);
}
});
@@ -245,22 +245,22 @@ public class TopDownAnalyzer {
private void resolveExpression(@NotNull JetScope scope, JetExpression expression, boolean preferBlock) {
semanticServices.getTypeInferrer(new BindingTrace() {
@Override
public void recordExpressionType(JetExpression expression, Type type) {
public void recordExpressionType(@NotNull JetExpression expression, @NotNull Type type) {
expressionTypes.put(expression, type);
}
@Override
public void recordReferenceResolution(JetReferenceExpression expression, DeclarationDescriptor descriptor) {
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
resolutionResults.put(expression, descriptor);
}
@Override
public void recordTypeResolution(JetTypeReference typeReference, Type type) {
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull Type type) {
types.put(typeReference, type);
}
@Override
public void recordDeclarationResolution(JetDeclaration declaration, DeclarationDescriptor descriptor) {
public void recordDeclarationResolution(@NotNull JetDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
throw new IllegalStateException();
}
}).getType(scope, expression, preferBlock);
@@ -37,8 +37,8 @@ public class TypeResolver {
@Override
public void visitUserType(JetUserType type) {
ClassDescriptor classDescriptor = resolveClass(scope, type);
trace.recordReferenceResolution(type.getReferenceExpression(), classDescriptor);
if (classDescriptor != null) {
trace.recordReferenceResolution(type.getReferenceExpression(), classDescriptor);
TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
result[0] = new TypeImpl(
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
@@ -11,18 +12,18 @@ import org.jetbrains.jet.lang.psi.JetTypeReference;
public class BindingTrace {
public static final BindingTrace DUMMY = new BindingTrace();
public void recordExpressionType(JetExpression expression, Type type) {
public void recordExpressionType(@NotNull JetExpression expression, @NotNull Type type) {
}
public void recordReferenceResolution(JetReferenceExpression expression, DeclarationDescriptor descriptor) {
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
}
public void recordDeclarationResolution(JetDeclaration declaration, DeclarationDescriptor descriptor) {
public void recordDeclarationResolution(@NotNull JetDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
}
public void recordTypeResolution(JetTypeReference typeReference, Type type) {
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull Type type) {
}
}
@@ -0,0 +1,109 @@
package org.jetbrains.jet.checkers;
import com.intellij.codeHighlighting.Pass;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.testFramework.ExpectedHighlightingData;
import com.intellij.testFramework.FileTreeAccessFilter;
import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
/**
* @author abreslav
*/
public abstract class ExtensibleHighlightingTestCase extends LightCodeInsightTestCase {
private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
@Override
protected void setUp() throws Exception {
super.setUp();
((DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(getProject())).prepareForTest(true);
DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
}
@Override
protected void tearDown() throws Exception {
((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(true); // has to cleanup by hand since light project does not get disposed any time soon
super.tearDown();
}
@Override
protected void runTest() throws Throwable {
final Throwable[] throwable = {null};
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
@Override
public void run() {
try {
doRunTest();
}
catch (Throwable t) {
throwable[0] = t;
}
}
}, "", null);
if (throwable[0] != null) {
throw throwable[0];
}
}
protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkInfos) throws Exception {
configureByFile(filePath);
doTestConfiguredFile(checkWarnings, checkInfos);
}
protected void doTestConfiguredFile(boolean checkWarnings, boolean checkInfos) {
getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
ExpectedHighlightingData expectedData = new ExpectedHighlightingData(getEditor().getDocument(),checkWarnings, checkInfos) {
@Override
protected void initAdditionalHighlightingTypes() {
// this.this.put();
}
};
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
getFile().getText(); //to load text
myJavaFilesFilter.allowTreeAccessForFile(getVFile());
getJavaFacade().setAssertOnFileLoadingFilter(myJavaFilesFilter); // check repository work
Collection<HighlightInfo> infos = doHighlighting();
getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
expectedData.checkResult(infos, getEditor().getDocument().getText());
}
@NotNull
protected List<HighlightInfo> doHighlighting() {
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
int[] toIgnore = doFolding() ? ArrayUtil.EMPTY_INT_ARRAY : new int[]{Pass.UPDATE_FOLDING};
Editor editor = getEditor();
PsiFile file = getFile();
if (editor instanceof EditorWindow) {
editor = ((EditorWindow)editor).getDelegate();
file = InjectedLanguageUtil.getTopLevelFile(file);
}
return CodeInsightTestFixtureImpl.instantiateAndRun(file, editor, toIgnore, false);
}
protected boolean doFolding() {
return false;
}
}