JET-26 Check bounds in generic types: fixed substitution problems
This commit is contained in:
+10
-11
@@ -7,7 +7,7 @@ class TypeInfo<T> {
|
|||||||
|
|
||||||
class Iterator<out T> {
|
class Iterator<out T> {
|
||||||
fun next() : T
|
fun next() : T
|
||||||
val hasNext : Boolean
|
abstract val hasNext : Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class Iterable<out T> {
|
class Iterable<out T> {
|
||||||
@@ -38,7 +38,7 @@ class Boolean : Comparable<Boolean> {
|
|||||||
fun equals(other : Any?) : Boolean
|
fun equals(other : Any?) : Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class String : Comparable<String> {
|
class String() : Comparable<String> {
|
||||||
fun get(index : Int) : Char
|
fun get(index : Int) : Char
|
||||||
val length : Int
|
val length : Int
|
||||||
|
|
||||||
@@ -50,19 +50,18 @@ class Range<in T : Comparable<T>> {
|
|||||||
fun contains(item : T) : Boolean
|
fun contains(item : T) : Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class IntRange<T> : Range<T>, Iterable<T> {
|
class IntRange<T : Comparable<T>> : Range<T>, Iterable<T> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Number : Hashable {
|
class Number : Hashable {
|
||||||
val dbl : Double
|
abstract val dbl : Double
|
||||||
val flt : Float
|
abstract val flt : Float
|
||||||
val lng : Long
|
abstract val lng : Long
|
||||||
val int : Int
|
abstract val int : Int
|
||||||
val chr : Char
|
abstract val chr : Char
|
||||||
val sht : Short
|
abstract val sht : Short
|
||||||
val byt : Byte
|
abstract val byt : Byte
|
||||||
|
|
||||||
// fun equals(other : Double) : Boolean
|
// fun equals(other : Double) : Boolean
|
||||||
// fun equals(other : Float) : Boolean
|
// fun equals(other : Float) : Boolean
|
||||||
// fun equals(other : Long) : Boolean
|
// fun equals(other : Long) : Boolean
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isStatic = descriptor.getContainingDeclaration() instanceof NamespaceDescriptor;
|
boolean isStatic = descriptor.getContainingDeclaration() instanceof NamespaceDescriptorImpl;
|
||||||
final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
|
final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
|
||||||
final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField);
|
final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField);
|
||||||
if (!isStatic) {
|
if (!isStatic) {
|
||||||
@@ -482,7 +482,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public StackValue intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean directToField) {
|
public StackValue intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean directToField) {
|
||||||
boolean isStatic = propertyDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor;
|
boolean isStatic = propertyDescriptor.getContainingDeclaration() instanceof NamespaceDescriptorImpl;
|
||||||
final JetType outType = propertyDescriptor.getOutType();
|
final JetType outType = propertyDescriptor.getOutType();
|
||||||
boolean isInsideClass = propertyDescriptor.getContainingDeclaration() == contextType;
|
boolean isInsideClass = propertyDescriptor.getContainingDeclaration() == contextType;
|
||||||
Method getter;
|
Method getter;
|
||||||
@@ -572,7 +572,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
methodDescriptor = typeMapper.mapSignature((JetFunction) declarationPsiElement);
|
methodDescriptor = typeMapper.mapSignature((JetFunction) declarationPsiElement);
|
||||||
if (functionParent instanceof NamespaceDescriptor && declarationPsiElement instanceof JetFunction) {
|
if (functionParent instanceof NamespaceDescriptorImpl && declarationPsiElement instanceof JetFunction) {
|
||||||
pushMethodArguments(expression, methodDescriptor);
|
pushMethodArguments(expression, methodDescriptor);
|
||||||
final String owner = NamespaceCodegen.getJVMClassName(DescriptorUtil.getFQName(functionParent));
|
final String owner = NamespaceCodegen.getJVMClassName(DescriptorUtil.getFQName(functionParent));
|
||||||
v.invokestatic(owner, methodDescriptor.getName(), methodDescriptor.getDescriptor());
|
v.invokestatic(owner, methodDescriptor.getName(), methodDescriptor.getDescriptor());
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
static String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
|
static String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
|
||||||
String owner;
|
String owner;
|
||||||
if (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
if (descriptor.getContainingDeclaration() instanceof NamespaceDescriptorImpl) {
|
||||||
owner = jvmName((NamespaceDescriptor) descriptor.getContainingDeclaration());
|
owner = jvmName((NamespaceDescriptor) descriptor.getContainingDeclaration());
|
||||||
}
|
}
|
||||||
else if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
else if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||||
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public abstract class AbstractNamespaceDescriptorImpl extends DeclarationDescriptorImpl implements NamespaceDescriptor {
|
||||||
|
private NamespaceType namespaceType;
|
||||||
|
|
||||||
|
public AbstractNamespaceDescriptorImpl(DeclarationDescriptor containingDeclaration, List<Annotation> annotations, String name) {
|
||||||
|
super(containingDeclaration, annotations, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public NamespaceType getNamespaceType() {
|
||||||
|
if (namespaceType == null) {
|
||||||
|
namespaceType = new NamespaceType(getName(), getMemberScope());
|
||||||
|
}
|
||||||
|
return namespaceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor substitute(TypeSubstitutor substitutor) {
|
||||||
|
throw new UnsupportedOperationException("This operation does not make sense for a namespace");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
||||||
|
return visitor.visitNamespaceDescriptor(this, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ import java.util.Set;
|
|||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor {
|
public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLike {
|
||||||
private ConstructorDescriptor primaryConstructor;
|
private ConstructorDescriptor primaryConstructor;
|
||||||
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
||||||
private final Set<FunctionDescriptor> functions = Sets.newHashSet();
|
private final Set<FunctionDescriptor> functions = Sets.newHashSet();
|
||||||
@@ -71,7 +71,8 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
|||||||
constructors.addFunction(constructorDescriptor);
|
constructors.addFunction(constructorDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addProperty(@NotNull PropertyDescriptor propertyDescriptor) {
|
@Override
|
||||||
|
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||||
properties.add(propertyDescriptor);
|
properties.add(propertyDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +81,8 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
|||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFunction(@NotNull FunctionDescriptor functionDescriptor) {
|
@Override
|
||||||
|
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
functions.add(functionDescriptor);
|
functions.add(functionDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +91,21 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
|||||||
return functions;
|
return functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptorImpl getNamespace(String name) {
|
||||||
|
throw new UnsupportedOperationException("Classes do not define namespaces");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||||
|
throw new UnsupportedOperationException("Classes do not define namespaces");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
|
||||||
|
classes.add(classDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void setUnsubstitutedMemberScope(@NotNull JetScope unsubstitutedMemberScope) {
|
public void setUnsubstitutedMemberScope(@NotNull JetScope unsubstitutedMemberScope) {
|
||||||
@@ -99,6 +116,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public TypeConstructor getTypeConstructor() {
|
public TypeConstructor getTypeConstructor() {
|
||||||
|
assert typeConstructor != null : "Type constructor is not set for " + getName();
|
||||||
return typeConstructor;
|
return typeConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,51 +1,16 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class NamespaceDescriptor extends DeclarationDescriptorImpl {
|
public interface NamespaceDescriptor extends Annotated, Named, DeclarationDescriptor {
|
||||||
private NamespaceType namespaceType;
|
@NotNull
|
||||||
|
JetScope getMemberScope();
|
||||||
private JetScope memberScope;
|
|
||||||
|
|
||||||
public NamespaceDescriptor(@Nullable DeclarationDescriptor containingDeclaration, @NotNull List<Annotation> annotations, @NotNull String name) {
|
|
||||||
super(containingDeclaration, annotations, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initialize(@NotNull JetScope memberScope) {
|
|
||||||
this.memberScope = memberScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetScope getMemberScope() {
|
NamespaceType getNamespaceType();
|
||||||
return memberScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public NamespaceType getNamespaceType() {
|
|
||||||
if (namespaceType == null) {
|
|
||||||
assert memberScope != null : "Member scope not set";
|
|
||||||
namespaceType = new NamespaceType(getName(), memberScope);
|
|
||||||
}
|
|
||||||
return namespaceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public NamespaceDescriptor substitute(TypeSubstitutor substitutor) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
|
||||||
return visitor.visitNamespaceDescriptor(this, data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.resolve.WritableScope;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl implements NamespaceLike {
|
||||||
|
|
||||||
|
private WritableScope memberScope;
|
||||||
|
|
||||||
|
public NamespaceDescriptorImpl(@Nullable DeclarationDescriptor containingDeclaration, @NotNull List<Annotation> annotations, @NotNull String name) {
|
||||||
|
super(containingDeclaration, annotations, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(@NotNull WritableScope memberScope) {
|
||||||
|
this.memberScope = memberScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public WritableScope getMemberScope() {
|
||||||
|
return memberScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptorImpl getNamespace(String name) {
|
||||||
|
return (NamespaceDescriptorImpl) memberScope.getDeclaredNamespace(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||||
|
memberScope.addNamespace(namespaceDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
|
||||||
|
memberScope.addClassifierDescriptor(classDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
|
memberScope.addFunctionDescriptor(functionDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPropertyDescriptor(@NotNull PropertyDescriptor variableDescriptor) {
|
||||||
|
memberScope.addVariableDescriptor(variableDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,9 +58,13 @@ public interface NamespaceLike extends DeclarationDescriptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
NamespaceDescriptor getNamespace(String name);
|
NamespaceDescriptorImpl getNamespace(String name);
|
||||||
|
|
||||||
void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor);
|
void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor);
|
||||||
|
|
||||||
void addClassifierDescriptor(MutableClassDescriptor classDescriptor);
|
void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor);
|
||||||
|
|
||||||
|
void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor);
|
||||||
|
|
||||||
|
void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,15 @@ import org.jetbrains.jet.lang.ErrorHandler;
|
|||||||
import org.jetbrains.jet.lang.JetDiagnostic;
|
import org.jetbrains.jet.lang.JetDiagnostic;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaPackageScope;
|
import org.jetbrains.jet.lang.resolve.java.JavaPackageScope;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
@@ -51,13 +54,43 @@ public class AnalyzingUtils {
|
|||||||
JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, semanticServices, bindingTraceContext);
|
JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, semanticServices, bindingTraceContext);
|
||||||
|
|
||||||
JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope();
|
JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope();
|
||||||
WritableScope scope = new WritableScopeImpl(libraryScope, new ModuleDescriptor("<module>"), bindingTraceContext.getErrorHandler(), null);
|
ModuleDescriptor owner = new ModuleDescriptor("<module>");
|
||||||
|
final WritableScope scope = new WritableScopeImpl(libraryScope, owner, bindingTraceContext.getErrorHandler(), null);
|
||||||
// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("").getMemberScope());
|
// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("").getMemberScope());
|
||||||
// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("java.lang").getMemberScope());
|
// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("java.lang").getMemberScope());
|
||||||
scope.importScope(new JavaPackageScope("", null, javaSemanticServices));
|
scope.importScope(new JavaPackageScope("", null, javaSemanticServices));
|
||||||
scope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
|
scope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
|
||||||
|
|
||||||
new TopDownAnalyzer(semanticServices, bindingTraceContext, flowDataTraceFactory).process(scope, namespace);
|
TopDownAnalyzer topDownAnalyzer = new TopDownAnalyzer(semanticServices, bindingTraceContext, flowDataTraceFactory);
|
||||||
|
// topDownAnalyzer.process(scope, Collections.<JetDeclaration>singletonList(namespace));
|
||||||
|
// if (false)
|
||||||
|
topDownAnalyzer.process(scope, new NamespaceLike.Adapter(owner) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptorImpl getNamespace(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||||
|
scope.addNamespace(namespaceDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
|
||||||
|
scope.addClassifierDescriptor(classDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
|
scope.addFunctionDescriptor(functionDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||||
|
scope.addVariableDescriptor(propertyDescriptor);
|
||||||
|
}
|
||||||
|
}, Collections.<JetDeclaration>singletonList(namespace));
|
||||||
return bindingTraceContext;
|
return bindingTraceContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class ClassDescriptorResolver {
|
|||||||
// TODO : assuming that the hierarchy is acyclic
|
// TODO : assuming that the hierarchy is acyclic
|
||||||
Collection<JetType> supertypes = delegationSpecifiers.isEmpty()
|
Collection<JetType> supertypes = delegationSpecifiers.isEmpty()
|
||||||
? Collections.singleton(JetStandardClasses.getAnyType())
|
? Collections.singleton(JetStandardClasses.getAnyType())
|
||||||
: resolveDelegationSpecifiers(parameterScope, delegationSpecifiers);
|
: resolveDelegationSpecifiers(parameterScope, delegationSpecifiers, typeResolver);
|
||||||
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
|
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
|
||||||
WritableScope members = resolveMembers(classDescriptor, classElement, typeParameters, scope, parameterScope, supertypes);
|
WritableScope members = resolveMembers(classDescriptor, classElement, typeParameters, scope, parameterScope, supertypes);
|
||||||
|
|
||||||
@@ -124,6 +124,9 @@ public class ClassDescriptorResolver {
|
|||||||
if (extendsBound != null) {
|
if (extendsBound != null) {
|
||||||
typeParameterDescriptor.addUpperBound(typeResolverNotCheckingBounds.resolveType(classDescriptor.getClassHeaderScope(), extendsBound));
|
typeParameterDescriptor.addUpperBound(typeResolverNotCheckingBounds.resolveType(classDescriptor.getClassHeaderScope(), extendsBound));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO : Bounds from with
|
// TODO : Bounds from with
|
||||||
}
|
}
|
||||||
@@ -133,7 +136,7 @@ public class ClassDescriptorResolver {
|
|||||||
// TODO : assuming that the hierarchy is acyclic
|
// TODO : assuming that the hierarchy is acyclic
|
||||||
Collection<? extends JetType> superclasses = delegationSpecifiers.isEmpty()
|
Collection<? extends JetType> superclasses = delegationSpecifiers.isEmpty()
|
||||||
? Collections.singleton(JetStandardClasses.getAnyType())
|
? Collections.singleton(JetStandardClasses.getAnyType())
|
||||||
: resolveDelegationSpecifiers(descriptor.getClassHeaderScope(), delegationSpecifiers);
|
: resolveDelegationSpecifiers(descriptor.getClassHeaderScope(), delegationSpecifiers, typeResolverNotCheckingBounds);
|
||||||
((TypeConstructorImpl) descriptor.getTypeConstructor()).getSupertypes().addAll(superclasses);
|
((TypeConstructorImpl) descriptor.getTypeConstructor()).getSupertypes().addAll(superclasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +167,7 @@ public class ClassDescriptorResolver {
|
|||||||
// TODO : assuming that the hierarchy is acyclic
|
// TODO : assuming that the hierarchy is acyclic
|
||||||
Collection<? extends JetType> superclasses = delegationSpecifiers.isEmpty()
|
Collection<? extends JetType> superclasses = delegationSpecifiers.isEmpty()
|
||||||
? Collections.singleton(JetStandardClasses.getAnyType())
|
? Collections.singleton(JetStandardClasses.getAnyType())
|
||||||
: resolveDelegationSpecifiers(parameterScope, delegationSpecifiers);
|
: resolveDelegationSpecifiers(parameterScope, delegationSpecifiers, typeResolver);
|
||||||
|
|
||||||
// TODO : UGLY HACK
|
// TODO : UGLY HACK
|
||||||
supertypes.addAll(superclasses);
|
supertypes.addAll(superclasses);
|
||||||
@@ -325,7 +328,7 @@ public class ClassDescriptorResolver {
|
|||||||
return typeParameterDescriptor;
|
return typeParameterDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<JetType> resolveDelegationSpecifiers(WritableScope extensibleScope, List<JetDelegationSpecifier> delegationSpecifiers) {
|
private Collection<JetType> resolveDelegationSpecifiers(WritableScope extensibleScope, List<JetDelegationSpecifier> delegationSpecifiers, @NotNull TypeResolver resolver) {
|
||||||
if (delegationSpecifiers.isEmpty()) {
|
if (delegationSpecifiers.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@@ -333,7 +336,7 @@ public class ClassDescriptorResolver {
|
|||||||
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
|
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
|
||||||
JetTypeReference typeReference = delegationSpecifier.getTypeReference();
|
JetTypeReference typeReference = delegationSpecifier.getTypeReference();
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
result.add(typeResolver.resolveType(extensibleScope, typeReference));
|
result.add(resolver.resolveType(extensibleScope, typeReference));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result.add(ErrorUtils.createErrorType("No type reference"));
|
result.add(ErrorUtils.createErrorType("No type reference"));
|
||||||
@@ -489,19 +492,25 @@ public class ClassDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JetType getType(@NotNull JetScope scope, @NotNull JetProperty property) {
|
private JetType getType(@NotNull final JetScope scope, @NotNull JetProperty property) {
|
||||||
// TODO : receiver?
|
// TODO : receiver?
|
||||||
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
|
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
|
||||||
|
|
||||||
JetType type;
|
JetType type;
|
||||||
if (propertyTypeRef == null) {
|
if (propertyTypeRef == null) {
|
||||||
JetExpression initializer = property.getInitializer();
|
final JetExpression initializer = property.getInitializer();
|
||||||
if (initializer == null) {
|
if (initializer == null) {
|
||||||
trace.getErrorHandler().genericError(property.getNode(), "This property must either have a type annotation or be initialized");
|
trace.getErrorHandler().genericError(property.getNode(), "This property must either have a type annotation or be initialized");
|
||||||
type = ErrorUtils.createErrorType("No type, no body");
|
type = ErrorUtils.createErrorType("No type, no body");
|
||||||
} else {
|
} else {
|
||||||
// TODO : ??? Fix-point here: what if we have something like "val a = foo {a.bar()}"
|
// TODO : ??? Fix-point here: what if we have something like "val a = foo {a.bar()}"
|
||||||
type = semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.THROW_EXCEPTION).safeGetType(scope, initializer, false);
|
// TODO : a risk of a memory leak
|
||||||
|
type = new DeferredType(new LazyValue<JetType>() {
|
||||||
|
@Override
|
||||||
|
protected JetType compute() {
|
||||||
|
return semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.THROW_EXCEPTION).safeGetType(scope, initializer, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
type = typeResolver.resolveType(scope, propertyTypeRef);
|
type = typeResolver.resolveType(scope, propertyTypeRef);
|
||||||
@@ -590,6 +599,7 @@ public class ClassDescriptorResolver {
|
|||||||
List<JetTypeReference> typeReferences = typeElement.getTypeArgumentsAsTypes();
|
List<JetTypeReference> typeReferences = typeElement.getTypeArgumentsAsTypes();
|
||||||
assert typeReferences.size() == arguments.size() : typeElement.getText();
|
assert typeReferences.size() == arguments.size() : typeElement.getText();
|
||||||
|
|
||||||
|
TypeSubstitutor substitutor = TypeSubstitutor.create(type);
|
||||||
for (int i = 0, projectionsSize = typeReferences.size(); i < projectionsSize; i++) {
|
for (int i = 0, projectionsSize = typeReferences.size(); i < projectionsSize; i++) {
|
||||||
JetTypeReference argumentTypeReference = typeReferences.get(i);
|
JetTypeReference argumentTypeReference = typeReferences.get(i);
|
||||||
|
|
||||||
@@ -599,14 +609,19 @@ public class ClassDescriptorResolver {
|
|||||||
checkBounds(argumentTypeReference, typeArgument);
|
checkBounds(argumentTypeReference, typeArgument);
|
||||||
|
|
||||||
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
|
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
|
||||||
checkBounds(argumentTypeReference, typeArgument, typeParameterDescriptor);
|
checkBounds(argumentTypeReference, typeArgument, typeParameterDescriptor, substitutor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkBounds(@NotNull JetTypeReference argumentTypeReference, @NotNull JetType typeArgument, @NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
public void checkBounds(
|
||||||
|
@NotNull JetTypeReference argumentTypeReference,
|
||||||
|
@NotNull JetType typeArgument,
|
||||||
|
@NotNull TypeParameterDescriptor typeParameterDescriptor,
|
||||||
|
@NotNull TypeSubstitutor substitutor) {
|
||||||
for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
|
for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
|
||||||
if (!semanticServices.getTypeChecker().isSubtypeOf(typeArgument, bound)) {
|
JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
|
||||||
trace.getErrorHandler().genericError(argumentTypeReference.getNode(), "An upper bound " + bound + " is violated"); // TODO : Message
|
if (!semanticServices.getTypeChecker().isSubtypeOf(typeArgument, substitutedBound)) {
|
||||||
|
trace.getErrorHandler().genericError(argumentTypeReference.getNode(), "An upper bound " + substitutedBound + " is violated"); // TODO : Message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,10 @@ import java.util.*;
|
|||||||
public class TopDownAnalyzer {
|
public class TopDownAnalyzer {
|
||||||
|
|
||||||
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
|
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
|
||||||
private final Map<JetNamespace, WritableScope> namespaceScopes = new LinkedHashMap<JetNamespace, WritableScope>();
|
private final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
|
||||||
private final Map<JetDeclaration, FunctionDescriptorImpl> functions = Maps.newLinkedHashMap();
|
private final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
|
||||||
|
|
||||||
|
private final Map<JetFunction, FunctionDescriptorImpl> functions = Maps.newLinkedHashMap();
|
||||||
private final Map<JetDeclaration, ConstructorDescriptor> constructors = Maps.newLinkedHashMap();
|
private final Map<JetDeclaration, ConstructorDescriptor> constructors = Maps.newLinkedHashMap();
|
||||||
private final Map<JetProperty, PropertyDescriptor> properties = new LinkedHashMap<JetProperty, PropertyDescriptor>();
|
private final Map<JetProperty, PropertyDescriptor> properties = new LinkedHashMap<JetProperty, PropertyDescriptor>();
|
||||||
private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap();
|
private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap();
|
||||||
@@ -82,19 +84,24 @@ public class TopDownAnalyzer {
|
|||||||
this(semanticServices, bindingTrace, JetControlFlowDataTraceFactory.EMPTY);
|
this(semanticServices, bindingTrace, JetControlFlowDataTraceFactory.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process(@NotNull JetScope outerScope, @NotNull JetDeclaration declaration) {
|
// public void process(@NotNull JetScope outerScope, @NotNull JetDeclaration declaration) {
|
||||||
process(outerScope, Collections.singletonList(declaration));
|
// process(outerScope, Collections.singletonList(declaration));
|
||||||
}
|
// }
|
||||||
|
|
||||||
public <T extends NamespaceDescriptor & NamespaceLike> void process(@NotNull WritableScope outerScope, T owner, @NotNull List<JetDeclaration> declarations) {
|
public void process(@NotNull WritableScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
|
||||||
collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes
|
collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes
|
||||||
|
|
||||||
createTypeConstructors(); // create type constructors for classes and generic parameters
|
createTypeConstructors(); // create type constructors for classes and generic parameters
|
||||||
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
|
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
|
||||||
checkGenericBoundsInClassHeaders(); // For the types resolved so far
|
checkGenericBoundsInClassHeaders(); // For the types resolved so far
|
||||||
|
|
||||||
resolveFunctionAndPropertyHeaders(); // TODO : for now, fail fast if something is unknown yet (i.e. some type annotation is omitted)
|
resolveFunctionAndPropertyHeaders(declarations); // TODO : for now, fail fast if something is unknown yet (i.e. some type annotation is omitted)
|
||||||
resolveExecutableCode();
|
resolveExecutableCode();
|
||||||
|
// processBehaviorDeclarators(outerScope, declarations);
|
||||||
|
|
||||||
|
// readyToProcessExpressions = true;
|
||||||
|
// resolveBehaviorDeclarationBodies();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectNamespacesAndClassifiers(
|
private void collectNamespacesAndClassifiers(
|
||||||
@@ -111,10 +118,10 @@ public class TopDownAnalyzer {
|
|||||||
if (name == null) {
|
if (name == null) {
|
||||||
name = "<no name provided>";
|
name = "<no name provided>";
|
||||||
}
|
}
|
||||||
NamespaceDescriptor namespaceDescriptor = owner.getNamespace(name);
|
NamespaceDescriptorImpl namespaceDescriptor = owner.getNamespace(name);
|
||||||
if (namespaceDescriptor == null) {
|
if (namespaceDescriptor == null) {
|
||||||
namespaceDescriptor = new NamespaceDescriptor(
|
namespaceDescriptor = new NamespaceDescriptorImpl(
|
||||||
owner, //declaringScope.getContainingDeclaration(),
|
owner.getOriginal(), //declaringScope.getContainingDeclaration(),
|
||||||
Collections.<Annotation>emptyList(), // TODO
|
Collections.<Annotation>emptyList(), // TODO
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
@@ -122,8 +129,9 @@ public class TopDownAnalyzer {
|
|||||||
owner.addNamespace(namespaceDescriptor);
|
owner.addNamespace(namespaceDescriptor);
|
||||||
trace.recordDeclarationResolution(namespace, namespaceDescriptor);
|
trace.recordDeclarationResolution(namespace, namespaceDescriptor);
|
||||||
}
|
}
|
||||||
|
namespaceDescriptors.put(namespace, namespaceDescriptor);
|
||||||
|
|
||||||
WritableScope namespaceScope = new WritableScopeImpl(outerScope, owner, trace.getErrorHandler(), null);
|
WritableScope namespaceScope = new WriteThroughScope(outerScope, (WritableScope) namespaceDescriptor.getMemberScope());
|
||||||
namespaceScopes.put(namespace, namespaceScope);
|
namespaceScopes.put(namespace, namespaceScope);
|
||||||
|
|
||||||
for (JetImportDirective importDirective : importDirectives) {
|
for (JetImportDirective importDirective : importDirectives) {
|
||||||
@@ -143,23 +151,7 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final NamespaceDescriptor finalNamespaceDescriptor = namespaceDescriptor;
|
collectNamespacesAndClassifiers(namespaceScope, namespaceDescriptor, namespace.getDeclarations());
|
||||||
collectNamespacesAndClassifiers(namespaceScope, new NamespaceLike.Adapter(finalNamespaceDescriptor) {
|
|
||||||
@Override
|
|
||||||
public NamespaceDescriptor getNamespace(String name) {
|
|
||||||
return ((WritableScope) finalNamespaceDescriptor.getMemberScope()).getDeclaredNamespace(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
|
||||||
((WritableScope) namespaceDescriptor.getMemberScope()).addNamespace(namespaceDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addClassifierDescriptor(MutableClassDescriptor classDescriptor) {
|
|
||||||
((WritableScope) finalNamespaceDescriptor.getMemberScope()).addClassifierDescriptor(classDescriptor);
|
|
||||||
}
|
|
||||||
}, namespace.getDeclarations());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -228,12 +220,53 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveFunctionAndPropertyHeaders() {
|
private void resolveFunctionAndPropertyHeaders(@NotNull List<JetDeclaration> declarations) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
for (Map.Entry<JetNamespace, WritableScope> entry : namespaceScopes.entrySet()) {
|
||||||
|
JetNamespace namespace = entry.getKey();
|
||||||
|
final WritableScope namespaceScope = entry.getValue();
|
||||||
|
final NamespaceLike namespaceDescriptor = namespaceDescriptors.get(namespace);
|
||||||
|
|
||||||
|
resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceDescriptor);
|
||||||
|
}
|
||||||
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
||||||
|
JetClass jetClass = entry.getKey();
|
||||||
|
final MutableClassDescriptor classDescriptor = entry.getValue();
|
||||||
|
|
||||||
|
resolveFunctionAndPropertyHeaders(jetClass.getDeclarations(), classDescriptor.getClassHeaderScope(), classDescriptor);
|
||||||
|
processPrimaryConstructor(classDescriptor, jetClass);
|
||||||
|
// processBehaviorDeclarators(classDescriptor.getWritableUnsubstitutedMemberScope(), jetClass.getDeclarations());
|
||||||
|
|
||||||
|
// TODO : Constructors
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO : Extensions
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resolveFunctionAndPropertyHeaders(@NotNull List<JetDeclaration> declarations, final @NotNull JetScope scope, final @NotNull NamespaceLike namespaceLike) {
|
||||||
|
for (JetDeclaration declaration : declarations) {
|
||||||
|
declaration.accept(new JetVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visitFunction(JetFunction function) {
|
||||||
|
FunctionDescriptorImpl functionDescriptor = classDescriptorResolver.resolveFunctionDescriptor(namespaceLike, scope, function);
|
||||||
|
namespaceLike.addFunctionDescriptor(functionDescriptor);
|
||||||
|
functions.put(function, functionDescriptor);
|
||||||
|
declaringScopes.put(function, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitProperty(JetProperty property) {
|
||||||
|
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(namespaceLike, scope, property);
|
||||||
|
namespaceLike.addPropertyDescriptor(propertyDescriptor);
|
||||||
|
properties.put(property, propertyDescriptor);
|
||||||
|
declaringScopes.put(property, scope);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveExecutableCode() {
|
private void resolveExecutableCode() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
readyToProcessExpressions = true;
|
||||||
|
resolveBehaviorDeclarationBodies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -263,9 +296,9 @@ public class TopDownAnalyzer {
|
|||||||
if (name == null) {
|
if (name == null) {
|
||||||
name = "<no name provided>";
|
name = "<no name provided>";
|
||||||
}
|
}
|
||||||
NamespaceDescriptor namespaceDescriptor = declaringScope.getDeclaredNamespace(name);
|
NamespaceDescriptorImpl namespaceDescriptor = (NamespaceDescriptorImpl) declaringScope.getDeclaredNamespace(name);
|
||||||
if (namespaceDescriptor == null) {
|
if (namespaceDescriptor == null) {
|
||||||
namespaceDescriptor = new NamespaceDescriptor(
|
namespaceDescriptor = new NamespaceDescriptorImpl(
|
||||||
declaringScope.getContainingDeclaration(),
|
declaringScope.getContainingDeclaration(),
|
||||||
Collections.<Annotation>emptyList(), // TODO
|
Collections.<Annotation>emptyList(), // TODO
|
||||||
name
|
name
|
||||||
@@ -814,7 +847,7 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resolveFunctionBodies() {
|
private void resolveFunctionBodies() {
|
||||||
for (Map.Entry<JetDeclaration, FunctionDescriptorImpl> entry : functions.entrySet()) {
|
for (Map.Entry<JetFunction, FunctionDescriptorImpl> entry : functions.entrySet()) {
|
||||||
JetDeclaration declaration = entry.getKey();
|
JetDeclaration declaration = entry.getKey();
|
||||||
FunctionDescriptor descriptor = entry.getValue();
|
FunctionDescriptor descriptor = entry.getValue();
|
||||||
|
|
||||||
|
|||||||
@@ -92,17 +92,6 @@ public class TypeResolver {
|
|||||||
trace.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage);
|
trace.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (checkBounds) {
|
|
||||||
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
|
|
||||||
TypeParameterDescriptor parameter = parameters.get(i);
|
|
||||||
JetType argument = arguments.get(i).getType();
|
|
||||||
JetTypeReference typeReference = type.getTypeArguments().get(i).getTypeReference();
|
|
||||||
|
|
||||||
if (typeReference != null) {
|
|
||||||
semanticServices.getClassDescriptorResolver(trace).checkBounds(typeReference, argument, parameter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result[0] = new JetTypeImpl(
|
result[0] = new JetTypeImpl(
|
||||||
annotations,
|
annotations,
|
||||||
typeConstructor,
|
typeConstructor,
|
||||||
@@ -110,6 +99,18 @@ public class TypeResolver {
|
|||||||
arguments,
|
arguments,
|
||||||
classDescriptor.getMemberScope(arguments)
|
classDescriptor.getMemberScope(arguments)
|
||||||
);
|
);
|
||||||
|
if (checkBounds) {
|
||||||
|
TypeSubstitutor substitutor = TypeSubstitutor.create(result[0]);
|
||||||
|
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
|
||||||
|
TypeParameterDescriptor parameter = parameters.get(i);
|
||||||
|
JetType argument = arguments.get(i).getType();
|
||||||
|
JetTypeReference typeReference = type.getTypeArguments().get(i).getTypeReference();
|
||||||
|
|
||||||
|
if (typeReference != null) {
|
||||||
|
semanticServices.getClassDescriptorResolver(trace).checkBounds(typeReference, argument, parameter, substitutor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.ErrorHandler;
|
import org.jetbrains.jet.lang.ErrorHandler;
|
||||||
@@ -244,7 +245,7 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public Map<String, NamespaceDescriptor> getNamespaceDescriptors() {
|
public Map<String, NamespaceDescriptor> getNamespaceDescriptors() {
|
||||||
if (namespaceDescriptors == null) {
|
if (namespaceDescriptors == null) {
|
||||||
namespaceDescriptors = new HashMap<String, NamespaceDescriptor>();
|
namespaceDescriptors = Maps.newHashMap();
|
||||||
}
|
}
|
||||||
return namespaceDescriptors;
|
return namespaceDescriptors;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,23 +189,23 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceDescriptor createJavaNamespaceDescriptor(PsiPackage psiPackage) {
|
private NamespaceDescriptor createJavaNamespaceDescriptor(PsiPackage psiPackage) {
|
||||||
NamespaceDescriptor namespaceDescriptor = new NamespaceDescriptor(
|
JavaNamespaceDescriptor namespaceDescriptor = new JavaNamespaceDescriptor(
|
||||||
JAVA_ROOT,
|
JAVA_ROOT,
|
||||||
Collections.<Annotation>emptyList(), // TODO
|
Collections.<Annotation>emptyList(), // TODO
|
||||||
psiPackage.getName()
|
psiPackage.getName()
|
||||||
);
|
);
|
||||||
namespaceDescriptor.initialize(new JavaPackageScope(psiPackage.getQualifiedName(), namespaceDescriptor, semanticServices));
|
namespaceDescriptor.setMemberScope(new JavaPackageScope(psiPackage.getQualifiedName(), namespaceDescriptor, semanticServices));
|
||||||
semanticServices.getTrace().recordDeclarationResolution(psiPackage, namespaceDescriptor);
|
semanticServices.getTrace().recordDeclarationResolution(psiPackage, namespaceDescriptor);
|
||||||
return namespaceDescriptor;
|
return namespaceDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceDescriptor createJavaNamespaceDescriptor(@NotNull final PsiClass psiClass) {
|
private NamespaceDescriptor createJavaNamespaceDescriptor(@NotNull final PsiClass psiClass) {
|
||||||
NamespaceDescriptor namespaceDescriptor = new NamespaceDescriptor(
|
JavaNamespaceDescriptor namespaceDescriptor = new JavaNamespaceDescriptor(
|
||||||
JAVA_ROOT,
|
JAVA_ROOT,
|
||||||
Collections.<Annotation>emptyList(), // TODO
|
Collections.<Annotation>emptyList(), // TODO
|
||||||
psiClass.getName()
|
psiClass.getName()
|
||||||
);
|
);
|
||||||
namespaceDescriptor.initialize(new JavaClassMembersScope(namespaceDescriptor, psiClass, semanticServices, true));
|
namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceDescriptor, psiClass, semanticServices, true));
|
||||||
semanticServices.getTrace().recordDeclarationResolution(psiClass, namespaceDescriptor);
|
semanticServices.getTrace().recordDeclarationResolution(psiClass, namespaceDescriptor);
|
||||||
return namespaceDescriptor;
|
return namespaceDescriptor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.java;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.AbstractNamespaceDescriptorImpl;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.Annotation;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl {
|
||||||
|
private JetScope memberScope;
|
||||||
|
|
||||||
|
public JavaNamespaceDescriptor(DeclarationDescriptor containingDeclaration, List<Annotation> annotations, String name) {
|
||||||
|
super(containingDeclaration, annotations, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemberScope(@NotNull JetScope memberScope) {
|
||||||
|
this.memberScope = memberScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JetScope getMemberScope() {
|
||||||
|
return memberScope;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.Annotation;
|
||||||
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class DeferredType implements JetType {
|
||||||
|
private final LazyValue<JetType> lazyValue;
|
||||||
|
|
||||||
|
public DeferredType(LazyValue<JetType> lazyValue) {
|
||||||
|
this.lazyValue = lazyValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JetType getActualType() {
|
||||||
|
return lazyValue.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public JetScope getMemberScope() {
|
||||||
|
return getActualType().getMemberScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public TypeConstructor getConstructor() {
|
||||||
|
return getActualType().getConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<TypeProjection> getArguments() {
|
||||||
|
return getActualType().getArguments();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable() {
|
||||||
|
return getActualType().isNullable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Annotation> getAnnotations() {
|
||||||
|
return getActualType().getAnnotations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
try {
|
||||||
|
return getActualType().toString();
|
||||||
|
}
|
||||||
|
catch (ReenteringLazyValueComputationException e) {
|
||||||
|
return "<Failed to compute this type>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ public class JetStandardClasses {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private static NamespaceDescriptor STANDARD_CLASSES_NAMESPACE = new NamespaceDescriptor(null, Collections.<Annotation>emptyList(), "jet");
|
/*package*/ static NamespaceDescriptorImpl STANDARD_CLASSES_NAMESPACE = new NamespaceDescriptorImpl(null, Collections.<Annotation>emptyList(), "jet");
|
||||||
|
|
||||||
private static final ClassDescriptor NOTHING_CLASS = new ClassDescriptorImpl(
|
private static final ClassDescriptor NOTHING_CLASS = new ClassDescriptorImpl(
|
||||||
STANDARD_CLASSES_NAMESPACE,
|
STANDARD_CLASSES_NAMESPACE,
|
||||||
@@ -201,6 +201,7 @@ public class JetStandardClasses {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
STANDARD_CLASSES_NAMESPACE.initialize(writableScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -4,14 +4,13 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.intellij.openapi.util.io.FileUtil;
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
import com.intellij.psi.PsiFileFactory;
|
import com.intellij.psi.PsiFileFactory;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.ErrorHandler;
|
||||||
import org.jetbrains.jet.lang.JetFileType;
|
import org.jetbrains.jet.lang.JetFileType;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.descriptors.Annotation;
|
import org.jetbrains.jet.lang.descriptors.Annotation;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
|
||||||
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -73,7 +72,11 @@ public class JetStandardLibrary {
|
|||||||
JetSemanticServices bootstrappingSemanticServices = JetSemanticServices.createSemanticServices(this);
|
JetSemanticServices bootstrappingSemanticServices = JetSemanticServices.createSemanticServices(this);
|
||||||
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
||||||
TopDownAnalyzer bootstrappingTDA = new TopDownAnalyzer(bootstrappingSemanticServices, bindingTraceContext);
|
TopDownAnalyzer bootstrappingTDA = new TopDownAnalyzer(bootstrappingSemanticServices, bindingTraceContext);
|
||||||
this.libraryScope = bootstrappingTDA.process(JetStandardClasses.STANDARD_CLASSES, file.getRootNamespace().getDeclarations());
|
WritableScopeImpl writableScope = new WritableScopeImpl(JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, ErrorHandler.THROW_EXCEPTION, null);
|
||||||
|
// this.libraryScope = bootstrappingTDA.process(JetStandardClasses.STANDARD_CLASSES, file.getRootNamespace().getDeclarations());
|
||||||
|
bootstrappingTDA.process(writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace().getDeclarations());
|
||||||
|
this.libraryScope = JetStandardClasses.STANDARD_CLASSES_NAMESPACE.getMemberScope();
|
||||||
|
AnalyzingUtils.applyHandler(ErrorHandler.THROW_EXCEPTION, bindingTraceContext);
|
||||||
|
|
||||||
this.byteClass = (ClassDescriptor) libraryScope.getClassifier("Byte");
|
this.byteClass = (ClassDescriptor) libraryScope.getClassifier("Byte");
|
||||||
this.charClass = (ClassDescriptor) libraryScope.getClassifier("Char");
|
this.charClass = (ClassDescriptor) libraryScope.getClassifier("Char");
|
||||||
|
|||||||
@@ -594,13 +594,19 @@ public class JetTypeInferrer {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public JetType getType(@NotNull JetExpression expression) {
|
public JetType getType(@NotNull JetExpression expression) {
|
||||||
assert result == null;
|
assert result == null;
|
||||||
expression.accept(this);
|
try {
|
||||||
if (result != null) {
|
expression.accept(this);
|
||||||
trace.recordExpressionType(expression, result);
|
if (result != null) {
|
||||||
if (JetStandardClasses.isNothing(result) && !result.isNullable()) {
|
trace.recordExpressionType(expression, result);
|
||||||
markDominatedExpressionsAsUnreachable(expression);
|
if (JetStandardClasses.isNothing(result) && !result.isNullable()) {
|
||||||
|
markDominatedExpressionsAsUnreachable(expression);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (ReenteringLazyValueComputationException e) {
|
||||||
|
trace.getErrorHandler().genericError(expression.getNode(), "Type inference has run into a recursive problem"); // TODO : message
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public abstract class LazyValue<T> {
|
||||||
|
|
||||||
|
private enum State {
|
||||||
|
NOT_COMPUTED,
|
||||||
|
BEING_COMPUTED,
|
||||||
|
COMPUTED,
|
||||||
|
ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
private State state = State.NOT_COMPUTED;
|
||||||
|
private T value;
|
||||||
|
|
||||||
|
protected abstract T compute();
|
||||||
|
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public final T get() {
|
||||||
|
switch (state) {
|
||||||
|
case NOT_COMPUTED:
|
||||||
|
state = State.BEING_COMPUTED;
|
||||||
|
value = compute();
|
||||||
|
state = State.COMPUTED;
|
||||||
|
return value;
|
||||||
|
case BEING_COMPUTED:
|
||||||
|
state = State.ERROR;
|
||||||
|
throw new ReenteringLazyValueComputationException();
|
||||||
|
case COMPUTED:
|
||||||
|
return value;
|
||||||
|
case ERROR:
|
||||||
|
throw new ReenteringLazyValueComputationException();
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Unreachable");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class ReenteringLazyValueComputationException extends RuntimeException {
|
||||||
|
public ReenteringLazyValueComputationException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReenteringLazyValueComputationException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReenteringLazyValueComputationException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReenteringLazyValueComputationException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,20 @@
|
|||||||
|
namespace boundsWithSubstitutors {
|
||||||
|
class A<T>
|
||||||
|
class B<X : A<X>>()
|
||||||
|
|
||||||
|
class C : A<C>
|
||||||
|
|
||||||
|
val a = new B<C>()
|
||||||
|
val a1 = new B<<error>Int</error>>()
|
||||||
|
|
||||||
|
class X<A, B : A>()
|
||||||
|
|
||||||
|
val b = new X<Any, X<A<C>, C>>
|
||||||
|
val b0 = new X<Any, <error>Any?</error>>
|
||||||
|
val b1 = new X<Any, X<A<C>, <error>String</error>>>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class A
|
class A
|
||||||
class B<T : A>()
|
class B<T : A>()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user