Initial stub version of resolve for types
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
package org.jetbrains.jet.lang.modules;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface JetModule extends NamespaceDomain {
|
||||||
|
Collection<JetModule> getImports();
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.jetbrains.jet.lang.modules;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.types.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.ExtensionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.MethodDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.PropertyDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface MemberDomain {
|
||||||
|
@Nullable
|
||||||
|
MethodDescriptor getMethods(String name);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
ClassDescriptor getClass(String name);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
PropertyDescriptor getProperty(String name);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
ExtensionDescriptor getExtension(String name);
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.jetbrains.jet.lang.modules;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.types.NamespaceDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface NamespaceDomain {
|
||||||
|
@Nullable
|
||||||
|
NamespaceDescriptor getNamespace(String namespaceName);
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ package org.jetbrains.jet.lang.psi;
|
|||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
@@ -11,6 +13,19 @@ public class JetReferenceExpression extends JetExpression {
|
|||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAbsoluteInRootNamespace() {
|
||||||
|
return findChildByType(JetTokens.NAMESPACE_KEYWORD) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JetReferenceExpression getQualifier() {
|
||||||
|
return findChildByClass(JetReferenceExpression.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReferencedName() {
|
||||||
|
return getNode().findChildByType(JetTokens.IDENTIFIER).getText();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(JetVisitor visitor) {
|
public void accept(JetVisitor visitor) {
|
||||||
visitor.visitReferenceExpression(this);
|
visitor.visitReferenceExpression(this);
|
||||||
|
|||||||
@@ -2,12 +2,7 @@ package org.jetbrains.jet.lang.psi;
|
|||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
@@ -22,34 +17,7 @@ public class JetUserType extends JetTypeElement {
|
|||||||
visitor.visitUserType(this);
|
visitor.visitUserType(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAbsoluteInRootNamespace() {
|
public JetReferenceExpression getReferenceExpression() {
|
||||||
return findChildByType(JetTokens.NAMESPACE_KEYWORD) != null;
|
return (JetReferenceExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION);
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public JetUserType getQualifierType() {
|
|
||||||
return (JetUserType) findChildByType(JetNodeTypes.USER_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable @IfNotParsed
|
|
||||||
public ASTNode getTypeNameNode() {
|
|
||||||
return getNode().findChildByType(JetNodeTypes.REFERENCE_EXPRESSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable @IfNotParsed
|
|
||||||
public String getReferencedName() {
|
|
||||||
ASTNode nameNode = getTypeNameNode();
|
|
||||||
return nameNode != null ? nameNode.getText() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public JetTypeArgumentList getTypeArgumentList() {
|
|
||||||
return (JetTypeArgumentList) findChildByType(JetNodeTypes.TYPE_ARGUMENT_LIST);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public List<JetTypeReference> getTypeArguments() {
|
|
||||||
JetTypeArgumentList list = getTypeArgumentList();
|
|
||||||
return list != null ? list.getArguments() : Collections.<JetTypeReference>emptyList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class JetModuleUtil {
|
||||||
|
public static JetScope getRootNamespaceScope(JetElement expression) {
|
||||||
|
// TODO: this is a stub: at least the modules' root namespaces must be indexed here
|
||||||
|
return JetScope.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.modules.MemberDomain;
|
||||||
|
import org.jetbrains.jet.lang.modules.NamespaceDomain;
|
||||||
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface JetScope extends NamespaceDomain, MemberDomain {
|
||||||
|
JetScope EMPTY = new JetScopeImpl() {};
|
||||||
|
|
||||||
|
abstract class JetScopeImpl implements JetScope {
|
||||||
|
@Override
|
||||||
|
public MethodDescriptor getMethods(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassDescriptor getClass(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyDescriptor getProperty(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtensionDescriptor getExtension(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor getNamespace(String namespaceName) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.modules.MemberDomain;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetUserType;
|
||||||
|
import org.jetbrains.jet.lang.types.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.NamespaceDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class TypeResolver {
|
||||||
|
|
||||||
|
public static final TypeResolver INSTANCE = new TypeResolver();
|
||||||
|
|
||||||
|
private TypeResolver() {}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ClassDescriptor resolveClass(JetScope scope, JetUserType userType) {
|
||||||
|
return resolveClass(scope, userType.getReferenceExpression());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ClassDescriptor resolveClass(JetScope scope, JetReferenceExpression expression) {
|
||||||
|
if (expression.isAbsoluteInRootNamespace()) {
|
||||||
|
return resolveClass(JetModuleUtil.getRootNamespaceScope(expression), expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
JetReferenceExpression qualifier = expression.getQualifier();
|
||||||
|
if (qualifier != null) {
|
||||||
|
// TODO: this is slow. The faster way would be to start with the first item in the quilified name
|
||||||
|
// TODO: priorities: class of namespace first?
|
||||||
|
MemberDomain domain = resolveClass(scope, qualifier);
|
||||||
|
if (domain == null) {
|
||||||
|
domain = resolveNamespace(scope, qualifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domain != null) {
|
||||||
|
return domain.getClass(expression.getReferencedName());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert qualifier == null;
|
||||||
|
|
||||||
|
return scope.getClass(expression.getReferencedName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private NamespaceDescriptor resolveNamespace(JetScope scope, JetReferenceExpression expression) {
|
||||||
|
if (expression.isAbsoluteInRootNamespace()) {
|
||||||
|
return resolveNamespace(JetModuleUtil.getRootNamespaceScope(expression), expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
JetReferenceExpression qualifier = expression.getQualifier();
|
||||||
|
if (qualifier != null) {
|
||||||
|
NamespaceDescriptor domain = resolveNamespace(scope, qualifier);
|
||||||
|
if (domain == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return domain.getNamespace(expression.getReferencedName());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert qualifier == null;
|
||||||
|
|
||||||
|
return scope.getNamespace(expression.getReferencedName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.modules.MemberDomain;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -7,7 +9,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class ClassDescriptor extends MemberDescriptorImpl {
|
public class ClassDescriptor extends MemberDescriptorImpl implements MemberDomain {
|
||||||
private final TypeConstructor typeConstructor;
|
private final TypeConstructor typeConstructor;
|
||||||
|
|
||||||
public ClassDescriptor(
|
public ClassDescriptor(
|
||||||
@@ -26,4 +28,23 @@ public class ClassDescriptor extends MemberDescriptorImpl {
|
|||||||
public TypeConstructor getTypeConstructor() {
|
public TypeConstructor getTypeConstructor() {
|
||||||
return typeConstructor;
|
return typeConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClassDescriptor getClass(String referencedName) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodDescriptor getMethods(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyDescriptor getProperty(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtensionDescriptor getExtension(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class ExtensionDescriptor {
|
||||||
|
}
|
||||||
@@ -64,7 +64,7 @@ public class JetTypeChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSubtypeOf(Type subtype, Type supertype) {
|
public boolean isSubtypeOf(Type subtype, Type supertype) {
|
||||||
|
// subtype.getConstructor().getSupertypes()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class MethodDescriptor {
|
||||||
|
}
|
||||||
@@ -1,7 +1,34 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.modules.MemberDomain;
|
||||||
|
import org.jetbrains.jet.lang.modules.NamespaceDomain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class NamespaceDescriptor {
|
public class NamespaceDescriptor implements NamespaceDomain, MemberDomain {
|
||||||
|
@Override
|
||||||
|
public ClassDescriptor getClass(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodDescriptor getMethods(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyDescriptor getProperty(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtensionDescriptor getExtension(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor getNamespace(String namespaceName) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class PropertyDescriptor {
|
||||||
|
}
|
||||||
@@ -4,9 +4,9 @@ import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
|||||||
import com.intellij.openapi.application.PathManager;
|
import com.intellij.openapi.application.PathManager;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardTypes;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||||
import org.jetbrains.jet.lang.types.Type;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -17,6 +17,30 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||||
|
|
||||||
|
private static final JetScope BASIC_SCOPE = new JetScope.JetScopeImpl() {
|
||||||
|
@Override
|
||||||
|
public ClassDescriptor getClass(String name) {
|
||||||
|
if ("Int".equals(name)) {
|
||||||
|
return JetStandardClasses.getInt();
|
||||||
|
} else if ("Boolean".equals(name)) {
|
||||||
|
return JetStandardClasses.getInt();
|
||||||
|
} else if ("Byte".equals(name)) {
|
||||||
|
return JetStandardClasses.getInt();
|
||||||
|
} else if ("Char".equals(name)) {
|
||||||
|
return JetStandardClasses.getInt();
|
||||||
|
} else if ("Short".equals(name)) {
|
||||||
|
return JetStandardClasses.getInt();
|
||||||
|
} else if ("Long".equals(name)) {
|
||||||
|
return JetStandardClasses.getInt();
|
||||||
|
} else if ("Float".equals(name)) {
|
||||||
|
return JetStandardClasses.getInt();
|
||||||
|
} else if ("Double".equals(name)) {
|
||||||
|
return JetStandardClasses.getInt();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getTestDataPath() {
|
protected String getTestDataPath() {
|
||||||
return getHomeDirectory() + "/idea/testData";
|
return getHomeDirectory() + "/idea/testData";
|
||||||
@@ -111,30 +135,36 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
JetTypeElement typeElement = typeNode.getTypeElement();
|
JetTypeElement typeElement = typeNode.getTypeElement();
|
||||||
List<JetTypeReference> typeArguments = typeNode.getTypeArguments();
|
List<JetTypeReference> typeArguments = typeNode.getTypeArguments();
|
||||||
|
|
||||||
typeElement.accept(new JetVisitor());
|
final Type[] result = new Type[1];
|
||||||
|
typeElement.accept(new JetVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visitUserType(JetUserType type) {
|
||||||
|
result[0] = new ClassType(TypeResolver.INSTANCE.resolveClass(BASIC_SCOPE, type));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
return result[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testImplicitConversions() throws Exception {
|
public void testImplicitConversions() throws Exception {
|
||||||
assertConvertibleTo("1", JetStandardTypes.getByte());
|
assertConvertibleTo("1", JetStandardTypes.getByte());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertConvertibleTo(String expression, Type type) {
|
private static void assertConvertibleTo(String expression, Type type) {
|
||||||
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
||||||
assertTrue(
|
assertTrue(
|
||||||
expression + " must be convertible to " + type,
|
expression + " must be convertible to " + type,
|
||||||
new JetTypeChecker().isConvertibleTo(jetExpression, type));
|
new JetTypeChecker().isConvertibleTo(jetExpression, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertNotConvertibleTo(String expression, Type type) {
|
private static void assertNotConvertibleTo(String expression, Type type) {
|
||||||
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
||||||
assertFalse(
|
assertFalse(
|
||||||
expression + " must not be convertible to " + type,
|
expression + " must not be convertible to " + type,
|
||||||
new JetTypeChecker().isConvertibleTo(jetExpression, type));
|
new JetTypeChecker().isConvertibleTo(jetExpression, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertType(String expression, Type expectedType) {
|
private static void assertType(String expression, Type expectedType) {
|
||||||
Project project = getProject();
|
Project project = getProject();
|
||||||
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
||||||
Type type = new JetTypeChecker().getType(jetExpression);
|
Type type = new JetTypeChecker().getType(jetExpression);
|
||||||
|
|||||||
Reference in New Issue
Block a user