KT-762 Wrong highlighting in imports (No errors reported on unresolved imports)

This commit is contained in:
Andrey Breslav
2011-12-07 17:26:28 +04:00
parent 6e7082ca5e
commit 40937e438b
3 changed files with 119 additions and 79 deletions
@@ -0,0 +1,108 @@
package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import java.util.List;
import static org.jetbrains.jet.lang.diagnostics.Errors.UNRESOLVED_REFERENCE;
import static org.jetbrains.jet.lang.diagnostics.Errors.UNSUPPORTED;
/**
* @author abreslav
*/
public class ImportsResolver {
private final TopDownAnalysisContext context;
public ImportsResolver(@NotNull TopDownAnalysisContext context) {
this.context = context;
}
public void processTypeImports() {
for (JetNamespace jetNamespace : context.getNamespaceDescriptors().keySet()) {
processImports(jetNamespace, context.getNamespaceScopes().get(jetNamespace), context.getDeclaringScopes().get(jetNamespace));
}
}
private void processImports(@NotNull JetNamespace namespace, @NotNull WritableScope namespaceScope, @NotNull JetScope outerScope) {
context.getConfiguration().addDefaultImports(context.getTrace(), namespaceScope);
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
for (JetImportDirective importDirective : importDirectives) {
if (importDirective.isAbsoluteInRootNamespace()) {
context.getTrace().report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
continue;
}
if (importDirective.isAllUnder()) {
JetExpression importedReference = importDirective.getImportedReference();
if (importedReference != null) {
ExpressionTypingServices typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace());
JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference);
if (type != null) {
namespaceScope.importScope(type.getMemberScope());
}
}
}
else {
ClassifierDescriptor classifierDescriptor = null;
NamespaceDescriptor namespaceDescriptor = null;
JetSimpleNameExpression referenceExpression = null;
JetExpression importedReference = importDirective.getImportedReference();
if (importedReference instanceof JetDotQualifiedExpression) {
JetDotQualifiedExpression reference = (JetDotQualifiedExpression) importedReference;
JetType type = context.getSemanticServices().getTypeInferrerServices(context.getTrace()).getTypeWithNamespaces(namespaceScope, reference.getReceiverExpression());
JetExpression selectorExpression = reference.getSelectorExpression();
if (selectorExpression != null) {
referenceExpression = (JetSimpleNameExpression) selectorExpression;
String referencedName = referenceExpression.getReferencedName();
if (type != null && referencedName != null) {
classifierDescriptor = type.getMemberScope().getClassifier(referencedName);
namespaceDescriptor = type.getMemberScope().getNamespace(referencedName);
}
}
}
else {
assert importedReference instanceof JetSimpleNameExpression;
referenceExpression = (JetSimpleNameExpression) importedReference;
String referencedName = referenceExpression.getReferencedName();
if (referencedName != null) {
classifierDescriptor = outerScope.getClassifier(referencedName);
namespaceDescriptor = outerScope.getNamespace(referencedName);
if (classifierDescriptor == null && namespaceDescriptor == null) {
context.getTrace().report(UNRESOLVED_REFERENCE.on(referenceExpression));
}
}
}
String aliasName = importDirective.getAliasName();
if (aliasName == null) {
aliasName = referenceExpression != null ? referenceExpression.getReferencedName() : null;
}
if (classifierDescriptor != null) {
context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor);
if (aliasName != null) {
namespaceScope.importClassifierAlias(aliasName, classifierDescriptor);
}
}
if (namespaceDescriptor != null) {
if (classifierDescriptor == null) {
context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, namespaceDescriptor);
}
if (aliasName != null) {
namespaceScope.importNamespaceAlias(aliasName, namespaceDescriptor);
}
}
}
}
}
}
@@ -15,7 +15,10 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lexer.JetTokens;
@@ -30,17 +33,19 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*;
*/
public class TypeHierarchyResolver {
private final TopDownAnalysisContext context;
private final ImportsResolver importsResolver;
private LinkedList<MutableClassDescriptor> topologicalOrder;
public TypeHierarchyResolver(TopDownAnalysisContext context) {
this.context = context;
this.importsResolver = new ImportsResolver(context);
}
public void process(@NotNull JetScope outerScope, @NotNull NamespaceLike owner, @NotNull Collection<? extends JetDeclaration> declarations) {
collectNamespacesAndClassifiers(outerScope, outerScope, owner, declarations); // namespaceScopes, classes
processTypeImports();
importsResolver.processTypeImports();
createTypeConstructors(); // create type constructors for classes and generic parameters, supertypes are not filled in
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
@@ -75,7 +80,6 @@ public class TypeHierarchyResolver {
WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), new TraceBasedRedeclarationHandler(context.getTrace()));
namespaceScope.changeLockLevel(WritableScope.LockLevel.BOTH);
context.getConfiguration().addDefaultImports(context.getTrace(), namespaceScope);
context.getNamespaceScopes().put(namespace, namespaceScope);
context.getDeclaringScopes().put(namespace, outerScope);
@@ -233,82 +237,6 @@ public class TypeHierarchyResolver {
return ClassKind.CLASS;
}
private void processTypeImports() {
for (JetNamespace jetNamespace : context.getNamespaceDescriptors().keySet()) {
processImports(jetNamespace, context.getNamespaceScopes().get(jetNamespace), context.getDeclaringScopes().get(jetNamespace));
}
}
private void processImports(@NotNull JetNamespace namespace, @NotNull WritableScope namespaceScope, @NotNull JetScope outerScope) {
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
for (JetImportDirective importDirective : importDirectives) {
if (importDirective.isAbsoluteInRootNamespace()) {
context.getTrace().report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
continue;
}
if (importDirective.isAllUnder()) {
JetExpression importedReference = importDirective.getImportedReference();
if (importedReference != null) {
ExpressionTypingServices typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace());
JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference);
if (type != null) {
namespaceScope.importScope(type.getMemberScope());
}
}
}
else {
ClassifierDescriptor classifierDescriptor = null;
NamespaceDescriptor namespaceDescriptor = null;
JetSimpleNameExpression referenceExpression = null;
JetExpression importedReference = importDirective.getImportedReference();
if (importedReference instanceof JetDotQualifiedExpression) {
JetDotQualifiedExpression reference = (JetDotQualifiedExpression) importedReference;
JetType type = context.getSemanticServices().getTypeInferrerServices(context.getTrace()).getTypeWithNamespaces(namespaceScope, reference.getReceiverExpression());
JetExpression selectorExpression = reference.getSelectorExpression();
if (selectorExpression != null) {
referenceExpression = (JetSimpleNameExpression) selectorExpression;
String referencedName = referenceExpression.getReferencedName();
if (type != null && referencedName != null) {
classifierDescriptor = type.getMemberScope().getClassifier(referencedName);
namespaceDescriptor = type.getMemberScope().getNamespace(referencedName);
}
}
}
else {
assert importedReference instanceof JetSimpleNameExpression;
referenceExpression = (JetSimpleNameExpression) importedReference;
String referencedName = referenceExpression.getReferencedName();
if (referencedName != null) {
classifierDescriptor = outerScope.getClassifier(referencedName);
namespaceDescriptor = outerScope.getNamespace(referencedName);
}
}
String aliasName = importDirective.getAliasName();
if (aliasName == null) {
aliasName = referenceExpression != null ? referenceExpression.getReferencedName() : null;
}
if (classifierDescriptor != null) {
context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor);
if (aliasName != null) {
namespaceScope.importClassifierAlias(aliasName, classifierDescriptor);
}
}
if (namespaceDescriptor != null) {
if (classifierDescriptor == null) {
context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, namespaceDescriptor);
}
if (aliasName != null) {
namespaceScope.importNamespaceAlias(aliasName, namespaceDescriptor);
}
}
}
}
}
private void createTypeConstructors() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey();
@@ -0,0 +1,4 @@
//KT-762 Wrong highlighting in imports (No errors reported on unresolved imports)
import <!UNRESOLVED_REFERENCE!>aaa<!> // must be an error
fun main(args : Array<String>) {}