Navigation improved a little
This commit is contained in:
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.annotations;
|
|||||||
|
|
||||||
import com.intellij.lang.annotation.AnnotationHolder;
|
import com.intellij.lang.annotation.AnnotationHolder;
|
||||||
import com.intellij.lang.annotation.Annotator;
|
import com.intellij.lang.annotation.Annotator;
|
||||||
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
@@ -20,24 +21,31 @@ public class JetPsiChecker implements Annotator {
|
|||||||
if (element instanceof JetFile) {
|
if (element instanceof JetFile) {
|
||||||
JetFile file = (JetFile) element;
|
JetFile file = (JetFile) element;
|
||||||
JetSemanticServices semanticServices = new JetSemanticServices(element.getProject());
|
JetSemanticServices semanticServices = new JetSemanticServices(element.getProject());
|
||||||
final BindingContext bindingContext = new TopDownAnalyzer(semanticServices).process(semanticServices.getStandardLibrary().getLibraryScope(), file.getRootNamespace().getDeclarations());
|
try {
|
||||||
file.getRootNamespace().accept(new JetVisitor() {
|
final BindingContext bindingContext = new TopDownAnalyzer(semanticServices).process(semanticServices.getStandardLibrary().getLibraryScope(), file.getRootNamespace().getDeclarations());
|
||||||
@Override
|
file.getRootNamespace().accept(new JetVisitor() {
|
||||||
public void visitClass(JetClass klass) {
|
@Override
|
||||||
for (JetDelegationSpecifier specifier : klass.getDelegationSpecifiers()) {
|
public void visitClass(JetClass klass) {
|
||||||
JetTypeReference typeReference = specifier.getTypeReference();
|
for (JetDelegationSpecifier specifier : klass.getDelegationSpecifiers()) {
|
||||||
Type type = bindingContext.resolveTypeReference(typeReference);
|
JetTypeReference typeReference = specifier.getTypeReference();
|
||||||
holder.createWeakWarningAnnotation(typeReference, type.toString());
|
Type type = bindingContext.resolveTypeReference(typeReference);
|
||||||
|
holder.createWeakWarningAnnotation(typeReference, type.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitNamespace(JetNamespace namespace) {
|
public void visitNamespace(JetNamespace namespace) {
|
||||||
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
||||||
declaration.accept(this);
|
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
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String getCanonicalText() {
|
public String getCanonicalText() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
return getReferencedName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new IncorrectOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new IncorrectOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReferenceTo(PsiElement element) {
|
public boolean isReferenceTo(PsiElement element) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Object[] getVariants() {
|
public Object[] getVariants() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
return EMPTY_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSoft() {
|
public boolean isSoft() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public class ClassDescriptorResolver {
|
|||||||
returnType = semanticServices.getTypeInferrer().getType(parameterScope, bodyExpression, function.hasBlockBody());
|
returnType = semanticServices.getTypeInferrer().getType(parameterScope, bodyExpression, function.hasBlockBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FunctionDescriptorImpl(
|
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(
|
||||||
function,
|
function,
|
||||||
null,
|
null,
|
||||||
AttributeResolver.INSTANCE.resolveAttributes(function.getModifierList()),
|
AttributeResolver.INSTANCE.resolveAttributes(function.getModifierList()),
|
||||||
@@ -148,6 +148,9 @@ public class ClassDescriptorResolver {
|
|||||||
valueParameterDescriptors,
|
valueParameterDescriptors,
|
||||||
returnType
|
returnType
|
||||||
);
|
);
|
||||||
|
|
||||||
|
trace.recordDeclarationResolution(function, functionDescriptor);
|
||||||
|
return functionDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ValueParameterDescriptor> resolveValueParameters(WritableScope parameterScope, List<JetParameter> valueParameters) {
|
private List<ValueParameterDescriptor> resolveValueParameters(WritableScope parameterScope, List<JetParameter> valueParameters) {
|
||||||
|
|||||||
@@ -30,22 +30,22 @@ public class TopDownAnalyzer {
|
|||||||
this.semanticServices = semanticServices;
|
this.semanticServices = semanticServices;
|
||||||
this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, new BindingTrace() {
|
this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, new BindingTrace() {
|
||||||
@Override
|
@Override
|
||||||
public void recordExpressionType(JetExpression expression, Type type) {
|
public void recordExpressionType(@NotNull JetExpression expression, @NotNull Type type) {
|
||||||
expressionTypes.put(expression, type);
|
expressionTypes.put(expression, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recordReferenceResolution(JetReferenceExpression expression, DeclarationDescriptor descriptor) {
|
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
|
||||||
resolutionResults.put(expression, descriptor);
|
resolutionResults.put(expression, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recordTypeResolution(JetTypeReference typeReference, Type type) {
|
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull Type type) {
|
||||||
types.put(typeReference, type);
|
types.put(typeReference, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recordDeclarationResolution(JetDeclaration declaration, DeclarationDescriptor descriptor) {
|
public void recordDeclarationResolution(@NotNull JetDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||||
descriptorToDeclarations.put(descriptor, declaration);
|
descriptorToDeclarations.put(descriptor, declaration);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -245,22 +245,22 @@ public class TopDownAnalyzer {
|
|||||||
private void resolveExpression(@NotNull JetScope scope, JetExpression expression, boolean preferBlock) {
|
private void resolveExpression(@NotNull JetScope scope, JetExpression expression, boolean preferBlock) {
|
||||||
semanticServices.getTypeInferrer(new BindingTrace() {
|
semanticServices.getTypeInferrer(new BindingTrace() {
|
||||||
@Override
|
@Override
|
||||||
public void recordExpressionType(JetExpression expression, Type type) {
|
public void recordExpressionType(@NotNull JetExpression expression, @NotNull Type type) {
|
||||||
expressionTypes.put(expression, type);
|
expressionTypes.put(expression, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recordReferenceResolution(JetReferenceExpression expression, DeclarationDescriptor descriptor) {
|
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
|
||||||
resolutionResults.put(expression, descriptor);
|
resolutionResults.put(expression, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recordTypeResolution(JetTypeReference typeReference, Type type) {
|
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull Type type) {
|
||||||
types.put(typeReference, type);
|
types.put(typeReference, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recordDeclarationResolution(JetDeclaration declaration, DeclarationDescriptor descriptor) {
|
public void recordDeclarationResolution(@NotNull JetDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}).getType(scope, expression, preferBlock);
|
}).getType(scope, expression, preferBlock);
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ public class TypeResolver {
|
|||||||
@Override
|
@Override
|
||||||
public void visitUserType(JetUserType type) {
|
public void visitUserType(JetUserType type) {
|
||||||
ClassDescriptor classDescriptor = resolveClass(scope, type);
|
ClassDescriptor classDescriptor = resolveClass(scope, type);
|
||||||
trace.recordReferenceResolution(type.getReferenceExpression(), classDescriptor);
|
|
||||||
if (classDescriptor != null) {
|
if (classDescriptor != null) {
|
||||||
|
trace.recordReferenceResolution(type.getReferenceExpression(), classDescriptor);
|
||||||
TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
|
TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
|
||||||
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
|
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
|
||||||
result[0] = new TypeImpl(
|
result[0] = new TypeImpl(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||||
@@ -11,18 +12,18 @@ import org.jetbrains.jet.lang.psi.JetTypeReference;
|
|||||||
public class BindingTrace {
|
public class BindingTrace {
|
||||||
public static final BindingTrace DUMMY = new 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user