Namespace types are only allowed in appropriate contexts

This commit is contained in:
Andrey Breslav
2011-04-25 19:54:48 +04:00
parent 43742828c4
commit 9059dae673
6 changed files with 82 additions and 19 deletions
@@ -1,13 +1,14 @@
package org.jetbrains.jet.lang.resolve;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.types.NamespaceType;
/**
* @author abreslav
*/
public class JetModuleUtil {
public static JetScope getRootNamespaceScope(JetElement expression) {
public static NamespaceType getRootNamespaceType(JetElement expression) {
// TODO: this is a stub: at least the modules' root namespaces must be indexed here
return JetScope.EMPTY;
return new NamespaceType("<namespace_root>", JetScope.EMPTY);
}
}
@@ -114,7 +114,7 @@ public class TopDownAnalyzer {
if (importDirective.isAllUnder()) {
JetExpression importedReference = importDirective.getImportedReference();
if (importedReference != null) {
JetType type = semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.THROW_EXCEPTION).getType(namespaceScope, importedReference, false);
JetType type = semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.THROW_EXCEPTION).getTypeWithNamespaces(namespaceScope, importedReference, false);
if (type != null) {
namespaceScope.importScope(type.getMemberScope());
}
@@ -202,9 +202,9 @@ public class TypeResolver {
if (referencedName == null) {
return null;
}
ClassifierDescriptor classifierDescriptor = null;
ClassifierDescriptor classifierDescriptor;
if (userType.isAbsoluteInRootNamespace()) {
classifierDescriptor = JetModuleUtil.getRootNamespaceScope(userType).getClassifier(referencedName);
classifierDescriptor = JetModuleUtil.getRootNamespaceType(userType).getMemberScope().getClassifier(referencedName);
}
else {
JetUserType qualifier = userType.getQualifier();
@@ -238,7 +238,7 @@ public class TypeResolver {
@Nullable
private NamespaceDescriptor resolveNamespace(JetScope scope, JetUserType userType) {
if (userType.isAbsoluteInRootNamespace()) {
return resolveNamespace(JetModuleUtil.getRootNamespaceScope(userType), userType);
return resolveNamespace(JetModuleUtil.getRootNamespaceType(userType).getMemberScope(), userType);
}
JetUserType qualifier = userType.getQualifier();
@@ -150,7 +150,8 @@ public class ErrorUtils {
}
public static boolean isErrorType(JetType type) {
return type instanceof ErrorTypeImpl || isError(type.getConstructor());
return type instanceof ErrorTypeImpl ||
isError(type.getConstructor());
}
private static class ErrorTypeImpl implements JetType {
@@ -92,6 +92,10 @@ public class JetTypeInferrer {
return new TypeInferrerVisitor(scope, preferBlock).getType(expression);
}
public JetType getTypeWithNamespaces(@NotNull final JetScope scope, @NotNull JetExpression expression, final boolean preferBlock) {
return new TypeInferrerVisitorWithNamespaces(scope, preferBlock).getType(expression);
}
@Nullable
private List<JetType> getTypes(JetScope scope, List<JetExpression> indexExpressions) {
List<JetType> argumentTypes = new ArrayList<JetType>();
@@ -557,7 +561,7 @@ public class JetTypeInferrer {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private class TypeInferrerVisitor extends JetVisitor {
private final JetScope scope;
protected final JetScope scope;
private final boolean preferBlock;
protected JetType result;
@@ -574,13 +578,18 @@ public class JetTypeInferrer {
visitor = this;
}
else {
visitor = new TypeInferrerVisitor(scope, preferBlock);
visitor = createNew(scope, preferBlock);
}
JetType type = visitor.getType(expression);
visitor.result = null;
return type;
}
@NotNull
public TypeInferrerVisitor createNew(JetScope scope, boolean preferBlock) {
return new TypeInferrerVisitor(scope, preferBlock);
}
@Nullable
public JetType getType(@NotNull JetExpression expression) {
assert result == null;
@@ -640,19 +649,33 @@ public class JetTypeInferrer {
semanticServices.getErrorHandler().genericError(expression.getNode(), "This variable is not readable in this context");
}
return;
} else {
NamespaceDescriptor namespace = scope.getNamespace(referencedName);
if (namespace != null) {
trace.recordReferenceResolution(expression, namespace);
result = namespace.getNamespaceType();
return;
}
} else if (furtherNameLookup(expression, referencedName)) {
return;
}
semanticServices.getErrorHandler().unresolvedReference(expression);
}
}
}
protected boolean furtherNameLookup(@NotNull JetSimpleNameExpression expression, @NotNull String referencedName) {
NamespaceType namespaceType = lookupNamespaceType(expression, referencedName);
if (namespaceType != null) {
semanticServices.getErrorHandler().genericError(expression.getNode(), "Expression expected, but a namespace name found");
return true;
}
return false;
}
@Nullable
protected NamespaceType lookupNamespaceType(@NotNull JetSimpleNameExpression expression, @NotNull String referencedName) {
NamespaceDescriptor namespace = scope.getNamespace(referencedName);
if (namespace == null) {
return null;
}
trace.recordReferenceResolution(expression, namespace);
return namespace.getNamespaceType();
}
@Override
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
if (preferBlock && !expression.hasParameterSpecification()) {
@@ -1164,7 +1187,7 @@ public class JetTypeInferrer {
// TODO : functions
JetExpression selectorExpression = expression.getSelectorExpression();
JetExpression receiverExpression = expression.getReceiverExpression();
JetType receiverType = getType(scope, receiverExpression, false);
JetType receiverType = new TypeInferrerVisitorWithNamespaces(scope, false).getType(receiverExpression);
if (receiverType != null) {
checkNullSafety(receiverType, expression);
JetType selectorReturnType = getSelectorReturnType(receiverType, selectorExpression);
@@ -1467,9 +1490,39 @@ public class JetTypeInferrer {
}
@Override
public void visitJetElement(JetElement elem) {
semanticServices.getErrorHandler().genericError(elem.getNode(), "Unsupported element: " + elem + " " + elem.getClass().getCanonicalName());
public void visitRootNamespaceExpression(JetRootNamespaceExpression expression) {
semanticServices.getErrorHandler().genericError(expression.getNode(), "'namespace' is not an expression");
result = null;
}
@Override
public void visitJetElement(JetElement elem) {
semanticServices.getErrorHandler().genericError(elem.getNode(), "[JetTypeInferrer] Unsupported element: " + elem + " " + elem.getClass().getCanonicalName());
}
}
private class TypeInferrerVisitorWithNamespaces extends TypeInferrerVisitor {
private TypeInferrerVisitorWithNamespaces(@NotNull JetScope scope, boolean preferBlock) {
super(scope, preferBlock);
}
@NotNull
@Override
public TypeInferrerVisitor createNew(JetScope scope, boolean preferBlock) {
return new TypeInferrerVisitorWithNamespaces(scope, preferBlock);
}
@Override
public void visitRootNamespaceExpression(JetRootNamespaceExpression expression) {
result = JetModuleUtil.getRootNamespaceType(expression);
}
@Override
protected boolean furtherNameLookup(@NotNull JetSimpleNameExpression expression, @NotNull String referencedName) {
result = lookupNamespaceType(expression, referencedName);
return result != null;
}
}
private class TypeInferrerVisitorWithWritableScope extends TypeInferrerVisitor {
@@ -0,0 +1,8 @@
namespace root
namespace a {
}
val x = <error>a</error>
val y2 = <error>namespace</error>