Namespace types are only allowed in appropriate contexts
This commit is contained in:
@@ -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>
|
||||
Reference in New Issue
Block a user