"compiler" folder created

This commit is contained in:
Andrey Breslav
2011-09-09 21:47:21 +04:00
parent 443c342725
commit 116f35c650
375 changed files with 3 additions and 11 deletions
@@ -0,0 +1,158 @@
package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.JetScope;
import org.jetbrains.jet.lang.resolve.SubstitutingScope;
import org.jetbrains.jet.lang.types.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @author abreslav
*/
public class JavaClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor {
private TypeConstructor typeConstructor;
private JavaClassMembersScope unsubstitutedMemberScope;
private JetType classObjectType;
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
private Modality modality;
private JetType superclassType;
private final ClassKind kind;
public JavaClassDescriptor(DeclarationDescriptor containingDeclaration, @NotNull ClassKind kind) {
super(containingDeclaration);
this.kind = kind;
}
public void setTypeConstructor(TypeConstructor typeConstructor) {
this.typeConstructor = typeConstructor;
}
public void setModality(Modality modality) {
this.modality = modality;
}
public void setUnsubstitutedMemberScope(JavaClassMembersScope memberScope) {
this.unsubstitutedMemberScope = memberScope;
}
public void setClassObjectMemberScope(JavaClassMembersScope memberScope) {
classObjectType = new JetTypeImpl(
new TypeConstructorImpl(
JavaDescriptorResolver.JAVA_CLASS_OBJECT,
Collections.<AnnotationDescriptor>emptyList(),
true,
"Class object emulation for " + getName(),
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<JetType>emptyList()
),
memberScope
);
}
public void addConstructor(ConstructorDescriptor constructorDescriptor) {
this.constructors.addFunction(constructorDescriptor);
}
private TypeSubstitutor createTypeSubstitutor(List<TypeProjection> typeArguments) {
List<TypeParameterDescriptor> parameters = getTypeConstructor().getParameters();
Map<TypeConstructor, TypeProjection> context = TypeUtils.buildSubstitutionContext(parameters, typeArguments);
return TypeSubstitutor.create(context);
}
@NotNull
@Override
public JetScope getMemberScope(List<TypeProjection> typeArguments) {
assert typeArguments.size() == typeConstructor.getParameters().size();
if (typeArguments.isEmpty()) return unsubstitutedMemberScope;
TypeSubstitutor substitutor = createTypeSubstitutor(typeArguments);
return new SubstitutingScope(unsubstitutedMemberScope, substitutor);
}
@NotNull
@Override
public JetType getSuperclassType() {
return superclassType;
}
public void setSuperclassType(@NotNull JetType superclassType) {
this.superclassType = superclassType;
}
@NotNull
@Override
public FunctionGroup getConstructors() {
// assert typeArguments.size() == typeConstructor.getParameters().size();
// if (typeArguments.isEmpty()) return constructors;
// return new LazySubstitutingFunctionGroup(createTypeSubstitutor(typeArguments), constructors);
return constructors;
}
@Override
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
return null;
}
@Override
public boolean hasConstructors() {
return !constructors.isEmpty();
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
return typeConstructor;
}
@NotNull
@Override
public JetType getDefaultType() {
return TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope);
}
@NotNull
@Override
public ClassDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public JetType getClassObjectType() {
return classObjectType;
}
@Override
public boolean isClassObjectAValue() {
return false;
}
@NotNull
@Override
public ClassKind getKind() {
return kind;
}
@Override
@NotNull
public Modality getModality() {
return modality;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitClassDescriptor(this, data);
}
@Override
public String toString() {
return "java class " + typeConstructor;
}
}
@@ -0,0 +1,155 @@
package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.JetScope;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.Collection;
import java.util.Map;
/**
* @author abreslav
*/
public class JavaClassMembersScope implements JetScope {
private final PsiClass psiClass;
private final JavaSemanticServices semanticServices;
private final boolean staticMembers;
private final DeclarationDescriptor containingDeclaration;
private final Map<String, FunctionGroup> functionGroups = Maps.newHashMap();
private final Map<String, VariableDescriptor> variables = Maps.newHashMap();
private final Map<String, ClassifierDescriptor> classifiers = Maps.newHashMap();
private Collection<DeclarationDescriptor> allDescriptors;
public JavaClassMembersScope(@NotNull DeclarationDescriptor classDescriptor, PsiClass psiClass, JavaSemanticServices semanticServices, boolean staticMembers) {
this.containingDeclaration = classDescriptor;
this.psiClass = psiClass;
this.semanticServices = semanticServices;
this.staticMembers = staticMembers;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return containingDeclaration;
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getDeclarationsByLabel(String labelName) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName) {
return null;
}
@Override
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
throw new UnsupportedOperationException();
}
@Override
public ClassifierDescriptor getClassifier(@NotNull String name) {
ClassifierDescriptor classifierDescriptor = classifiers.get(name);
if (classifierDescriptor == null) {
classifierDescriptor = doGetClassifierDescriptor(name);
classifiers.put(name, classifierDescriptor);
}
return classifierDescriptor;
}
@Override
public Collection<DeclarationDescriptor> getAllDescriptors() {
if (allDescriptors == null) {
allDescriptors = Sets.newHashSet();
TypeSubstitutor substitutorForGenericSupertypes;
if (containingDeclaration instanceof ClassDescriptor) {
substitutorForGenericSupertypes = semanticServices.getDescriptorResolver().createSubstitutorForGenericSupertypes((ClassDescriptor) containingDeclaration);
}
else {
substitutorForGenericSupertypes = TypeSubstitutor.EMPTY;
}
for (HierarchicalMethodSignature signature : psiClass.getVisibleSignatures()) {
PsiMethod method = signature.getMethod();
if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
continue;
}
FunctionDescriptor functionDescriptor = semanticServices.getDescriptorResolver().resolveMethodToFunctionDescriptor(containingDeclaration, psiClass, substitutorForGenericSupertypes, method);
if (functionDescriptor != null) {
allDescriptors.add(functionDescriptor);
}
}
for (PsiField field : psiClass.getAllFields()) {
VariableDescriptor variableDescriptor = semanticServices.getDescriptorResolver().resolveFieldToVariableDescriptor(containingDeclaration, field);
allDescriptors.add(variableDescriptor);
}
}
return allDescriptors;
}
private ClassifierDescriptor doGetClassifierDescriptor(String name) {
// TODO : suboptimal, walk the list only once
for (PsiClass innerClass : psiClass.getAllInnerClasses()) {
if (name.equals(innerClass.getName())) {
if (innerClass.hasModifierProperty(PsiModifier.STATIC) != staticMembers) return null;
return semanticServices.getDescriptorResolver().resolveClass(innerClass);
}
}
return null;
}
@Override
public VariableDescriptor getVariable(@NotNull String name) {
VariableDescriptor variableDescriptor = variables.get(name);
if (variableDescriptor == null) {
variableDescriptor = doGetVariable(name);
variables.put(name, variableDescriptor);
}
return variableDescriptor;
}
private VariableDescriptor doGetVariable(String name) {
PsiField field = psiClass.findFieldByName(name, true);
if (field == null) return null;
if (field.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
return null;
}
return semanticServices.getDescriptorResolver().resolveFieldToVariableDescriptor((ClassDescriptor) containingDeclaration, field);
}
@NotNull
@Override
public FunctionGroup getFunctionGroup(@NotNull String name) {
FunctionGroup functionGroup = functionGroups.get(name);
if (functionGroup == null) {
functionGroup = semanticServices.getDescriptorResolver().resolveFunctionGroup(
containingDeclaration,
psiClass,
staticMembers ? null : (ClassDescriptor) containingDeclaration,
name,
staticMembers);
functionGroups.put(name, functionGroup);
}
return functionGroup;
}
@Override
public NamespaceDescriptor getNamespace(@NotNull String name) {
return null;
}
@NotNull
@Override
public JetType getThisType() {
return null;
}
}
@@ -0,0 +1,23 @@
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.ImportingStrategy;
import org.jetbrains.jet.lang.resolve.WritableScope;
/**
* @author abreslav
*/
public class JavaDefaultImports {
public static final ImportingStrategy JAVA_DEFAULT_IMPORTS = new ImportingStrategy() {
@Override
public void addImports(Project project, JetSemanticServices semanticServices, BindingTrace trace, WritableScope rootScope) {
// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("").getMemberScope());
// scope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace("java.lang").getMemberScope());
JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, semanticServices, trace);
rootScope.importScope(new JavaPackageScope("", null, javaSemanticServices));
rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
}
};
}
@@ -0,0 +1,371 @@
package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.*;
import java.util.*;
/**
* @author abreslav
*/
public class JavaDescriptorResolver {
/*package*/ static final DeclarationDescriptor JAVA_ROOT = new DeclarationDescriptorImpl(null, Collections.<AnnotationDescriptor>emptyList(), "<java_root>") {
@NotNull
@Override
public DeclarationDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitDeclarationDescriptor(this, data);
}
};
/*package*/ static final DeclarationDescriptor JAVA_CLASS_OBJECT = new DeclarationDescriptorImpl(null, Collections.<AnnotationDescriptor>emptyList(), "<java_class_object_emulation>") {
@NotNull
@Override
public DeclarationDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitDeclarationDescriptor(this, data);
}
};
protected final Map<String, ClassDescriptor> classDescriptorCache = new HashMap<String, ClassDescriptor>();
protected final Map<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap();
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
protected final Map<String, NamespaceDescriptor> namespaceDescriptorCache = new HashMap<String, NamespaceDescriptor>();
protected final JavaPsiFacade javaFacade;
protected final GlobalSearchScope javaSearchScope;
protected final JavaSemanticServices semanticServices;
public JavaDescriptorResolver(Project project, JavaSemanticServices semanticServices) {
this.javaFacade = JavaPsiFacade.getInstance(project);
this.javaSearchScope = GlobalSearchScope.allScope(project);
this.semanticServices = semanticServices;
}
@NotNull
public ClassDescriptor resolveClass(@NotNull PsiClass psiClass) {
String qualifiedName = psiClass.getQualifiedName();
ClassDescriptor classDescriptor = classDescriptorCache.get(qualifiedName);
if (classDescriptor == null) {
classDescriptor = createJavaClassDescriptor(psiClass);
classDescriptorCache.put(qualifiedName, classDescriptor);
}
return classDescriptor;
}
@Nullable
public ClassDescriptor resolveClass(@NotNull String qualifiedName) {
ClassDescriptor classDescriptor = classDescriptorCache.get(qualifiedName);
if (classDescriptor == null) {
PsiClass psiClass = javaFacade.findClass(qualifiedName, javaSearchScope);
if (psiClass == null) {
return null;
}
classDescriptor = createJavaClassDescriptor(psiClass);
}
return classDescriptor;
}
private ClassDescriptor createJavaClassDescriptor(@NotNull final PsiClass psiClass) {
assert !classDescriptorCache.containsKey(psiClass.getQualifiedName()) : psiClass.getQualifiedName();
classDescriptorCache.put(psiClass.getQualifiedName(), null); // TODO
String name = psiClass.getName();
JavaClassDescriptor classDescriptor = new JavaClassDescriptor(
JAVA_ROOT, psiClass.isInterface() ? ClassKind.TRAIT : ClassKind.CLASS
);
classDescriptor.setName(name);
List<JetType> supertypes = new ArrayList<JetType>();
List<TypeParameterDescriptor> typeParameters = resolveTypeParameters(classDescriptor, psiClass.getTypeParameters());
classDescriptor.setTypeConstructor(new TypeConstructorImpl(
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(), // TODO
// TODO
psiClass.hasModifierProperty(PsiModifier.FINAL),
name,
typeParameters,
supertypes
));
classDescriptor.setModality(Modality.convertFromFlags(
psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
!psiClass.hasModifierProperty(PsiModifier.FINAL))
);
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
classDescriptor.setClassObjectMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, true));
// UGLY HACK
supertypes.addAll(getSupertypes(psiClass));
if (psiClass.isInterface()) {
classDescriptor.setSuperclassType(JetStandardClasses.getAnyType()); // TODO : Make it java.lang.Object
}
else {
PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
assert extendsListTypes.length == 0 || extendsListTypes.length == 1;
JetType superclassType = extendsListTypes.length == 0
? JetStandardClasses.getAnyType()
: semanticServices.getTypeTransformer().transformToType(extendsListTypes[0]);
classDescriptor.setSuperclassType(superclassType);
}
PsiMethod[] psiConstructors = psiClass.getConstructors();
if (psiConstructors.length == 0) {
if (!psiClass.hasModifierProperty(PsiModifier.ABSTRACT) && !psiClass.isInterface()) {
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
false);
constructorDescriptor.initialize(typeParameters, Collections.<ValueParameterDescriptor>emptyList(), Modality.FINAL);
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
classDescriptor.addConstructor(constructorDescriptor);
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor);
}
}
else {
for (PsiMethod constructor : psiConstructors) {
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(), // TODO
false);
constructorDescriptor.initialize(typeParameters, resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()), Modality.FINAL);
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
classDescriptor.addConstructor(constructorDescriptor);
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, constructor, constructorDescriptor);
}
}
semanticServices.getTrace().record(BindingContext.CLASS, psiClass, classDescriptor);
return classDescriptor;
}
private List<TypeParameterDescriptor> resolveTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) {
List<TypeParameterDescriptor> result = Lists.newArrayList();
for (PsiTypeParameter typeParameter : typeParameters) {
TypeParameterDescriptor typeParameterDescriptor = resolveTypeParameter(containingDeclaration, typeParameter);
result.add(typeParameterDescriptor);
}
return result;
}
private TypeParameterDescriptor createJavaTypeParameterDescriptor(@NotNull DeclarationDescriptor owner, @NotNull PsiTypeParameter typeParameter) {
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
owner,
Collections.<AnnotationDescriptor>emptyList(), // TODO
Variance.INVARIANT,
typeParameter.getName(),
typeParameter.getIndex()
);
typeParameterDescriptorCache.put(typeParameter, typeParameterDescriptor);
PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes();
if (referencedTypes.length == 0){
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
}
else if (referencedTypes.length == 1) {
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0]));
}
else {
for (PsiClassType referencedType : referencedTypes) {
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType));
}
}
return typeParameterDescriptor;
}
@NotNull
public TypeParameterDescriptor resolveTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorCache.get(psiTypeParameter);
if (typeParameterDescriptor == null) {
typeParameterDescriptor = createJavaTypeParameterDescriptor(containingDeclaration, psiTypeParameter);
// This is done inside the method: typeParameterDescriptorCache.put(psiTypeParameter, typeParameterDescriptor);
}
return typeParameterDescriptor;
}
private Collection<? extends JetType> getSupertypes(PsiClass psiClass) {
List<JetType> result = new ArrayList<JetType>();
result.add(JetStandardClasses.getAnyType());
transformSupertypeList(result, psiClass.getExtendsListTypes());
transformSupertypeList(result, psiClass.getImplementsListTypes());
return result;
}
private void transformSupertypeList(List<JetType> result, PsiClassType[] extendsListTypes) {
for (PsiClassType type : extendsListTypes) {
JetType transform = semanticServices.getTypeTransformer().transformToType(type);
result.add(TypeUtils.makeNotNullable(transform));
}
}
public NamespaceDescriptor resolveNamespace(String qualifiedName) {
NamespaceDescriptor namespaceDescriptor = namespaceDescriptorCache.get(qualifiedName);
if (namespaceDescriptor == null) {
// TODO : packages
// PsiClass psiClass = javaFacade.findClass(qualifiedName, javaSearchScope);
// if (psiClass != null) {
// namespaceDescriptor = createJavaNamespaceDescriptor(psiClass);
// }
// else {
PsiPackage psiPackage = javaFacade.findPackage(qualifiedName);
if (psiPackage == null) {
return null;
}
namespaceDescriptor = createJavaNamespaceDescriptor(psiPackage);
// }
namespaceDescriptorCache.put(qualifiedName, namespaceDescriptor);
}
return namespaceDescriptor;
}
private NamespaceDescriptor createJavaNamespaceDescriptor(PsiPackage psiPackage) {
JavaNamespaceDescriptor namespaceDescriptor = new JavaNamespaceDescriptor(
JAVA_ROOT,
Collections.<AnnotationDescriptor>emptyList(), // TODO
psiPackage.getName()
);
namespaceDescriptor.setMemberScope(new JavaPackageScope(psiPackage.getQualifiedName(), namespaceDescriptor, semanticServices));
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiPackage, namespaceDescriptor);
return namespaceDescriptor;
}
private NamespaceDescriptor createJavaNamespaceDescriptor(@NotNull final PsiClass psiClass) {
JavaNamespaceDescriptor namespaceDescriptor = new JavaNamespaceDescriptor(
JAVA_ROOT,
Collections.<AnnotationDescriptor>emptyList(), // TODO
psiClass.getName()
);
namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceDescriptor, psiClass, semanticServices, true));
semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceDescriptor);
return namespaceDescriptor;
}
public List<ValueParameterDescriptor> resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) {
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) {
PsiParameter parameter = parameters[i];
String name = parameter.getName();
result.add(new ValueParameterDescriptorImpl(
containingDeclaration,
i,
Collections.<AnnotationDescriptor>emptyList(), // TODO
name == null ? "p" + i : name,
null, // TODO : review
semanticServices.getTypeTransformer().transformToType(parameter.getType()),
false,
parameter.isVarArgs()
));
}
return result;
}
public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) {
VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field);
if (variableDescriptor != null) {
return variableDescriptor;
}
JetType type = semanticServices.getTypeTransformer().transformToType(field.getType());
boolean isFinal = field.hasModifierProperty(PsiModifier.FINAL);
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
!isFinal,
null,
field.getName(),
isFinal ? null : type,
type);
semanticServices.getTrace().record(BindingContext.VARIABLE, field, propertyDescriptor);
fieldDescriptorCache.put(field, propertyDescriptor);
return propertyDescriptor;
}
@NotNull
public FunctionGroup resolveFunctionGroup(@NotNull DeclarationDescriptor owner, @NotNull PsiClass psiClass, @Nullable ClassDescriptor classDescriptor, @NotNull String methodName, boolean staticMembers) {
WritableFunctionGroup writableFunctionGroup = new WritableFunctionGroup(methodName);
final Collection<HierarchicalMethodSignature> signatures = psiClass.getVisibleSignatures();
TypeSubstitutor typeSubstitutor = createSubstitutorForGenericSupertypes(classDescriptor);
for (HierarchicalMethodSignature signature: signatures) {
PsiMethod method = signature.getMethod();
if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
continue;
}
if (!methodName.equals(method.getName())) {
continue;
}
FunctionDescriptor substitutedFunctionDescriptor = resolveMethodToFunctionDescriptor(owner, psiClass, typeSubstitutor, method);
if (substitutedFunctionDescriptor != null) {
writableFunctionGroup.addFunction(substitutedFunctionDescriptor);
}
}
return writableFunctionGroup;
}
public TypeSubstitutor createSubstitutorForGenericSupertypes(ClassDescriptor classDescriptor) {
TypeSubstitutor typeSubstitutor;
if (classDescriptor != null) {
typeSubstitutor = TypeUtils.buildDeepSubstitutor(classDescriptor.getDefaultType());
}
else {
typeSubstitutor = TypeSubstitutor.EMPTY;
}
return typeSubstitutor;
}
@Nullable
public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod method) {
PsiType returnType = method.getReturnType();
if (returnType == null) {
return null;
}
FunctionDescriptor functionDescriptor = methodDescriptorCache.get(method);
if (functionDescriptor != null) {
if (method.getContainingClass() != psiClass) {
functionDescriptor = functionDescriptor.substitute(typeSubstitutorForGenericSuperclasses);
}
return functionDescriptor;
}
PsiParameter[] parameters = method.getParameterList().getParameters();
FunctionDescriptorImpl functionDescriptorImpl = new FunctionDescriptorImpl(
owner,
Collections.<AnnotationDescriptor>emptyList(), // TODO
method.getName()
);
methodDescriptorCache.put(method, functionDescriptorImpl);
functionDescriptorImpl.initialize(
null,
resolveTypeParameters(functionDescriptorImpl, method.getTypeParameters()),
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters),
semanticServices.getTypeTransformer().transformToType(returnType),
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL))
);
semanticServices.getTrace().record(BindingContext.FUNCTION, method, functionDescriptorImpl);
FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl;
if (method.getContainingClass() != psiClass) {
substitutedFunctionDescriptor = functionDescriptorImpl.substitute(typeSubstitutorForGenericSuperclasses);
}
return substitutedFunctionDescriptor;
}
}
@@ -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.annotations.AnnotationDescriptor;
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<AnnotationDescriptor> 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,52 @@
package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.JetScopeImpl;
/**
* @author abreslav
*/
public class JavaPackageScope extends JetScopeImpl {
private final JavaSemanticServices semanticServices;
private final DeclarationDescriptor containingDescriptor;
private final String packagePrefix;
public JavaPackageScope(@NotNull String packageFQN, DeclarationDescriptor containingDescriptor, JavaSemanticServices semanticServices) {
this.semanticServices = semanticServices;
this.packagePrefix = packageFQN.isEmpty() ? "" : packageFQN + ".";
this.containingDescriptor = containingDescriptor;
}
@Override
public ClassifierDescriptor getClassifier(@NotNull String name) {
return semanticServices.getDescriptorResolver().resolveClass(getQualifiedName(name));
}
@Override
public NamespaceDescriptor getNamespace(@NotNull String name) {
return semanticServices.getDescriptorResolver().resolveNamespace(getQualifiedName(name));
}
@NotNull
@Override
public FunctionGroup getFunctionGroup(@NotNull String name) {
// ClassifierDescriptor classifier = getClassifier(name);
// if (classifier instanceof ClassDescriptor) {
// ClassDescriptor classDescriptor = (ClassDescriptor) classifier;
// return classDescriptor.getConstructors();
// }
return FunctionGroup.EMPTY;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return containingDescriptor;
}
private String getQualifiedName(String name) {
return packagePrefix + name;
}
}
@@ -0,0 +1,42 @@
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.resolve.BindingTrace;
/**
* @author abreslav
*/
public class JavaSemanticServices {
private final JavaTypeTransformer typeTransformer;
private final JavaDescriptorResolver descriptorResolver;
private final BindingTrace trace;
private final JetSemanticServices jetSemanticServices;
public JavaSemanticServices(Project project, JetSemanticServices jetSemanticServices, BindingTrace trace) {
this.trace = trace;
this.descriptorResolver = new JavaDescriptorResolver(project, this);
this.typeTransformer = new JavaTypeTransformer(jetSemanticServices.getStandardLibrary(), descriptorResolver);
this.jetSemanticServices = jetSemanticServices;
}
@NotNull
public JavaTypeTransformer getTypeTransformer() {
return typeTransformer;
}
@NotNull
public JavaDescriptorResolver getDescriptorResolver() {
return descriptorResolver;
}
@NotNull
public BindingTrace getTrace() {
return trace;
}
public JetSemanticServices getJetSemanticServices() {
return jetSemanticServices;
}
}
@@ -0,0 +1,168 @@
package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Lists;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.types.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author abreslav
*/
public class JavaTypeTransformer {
private final JavaDescriptorResolver resolver;
private final JetStandardLibrary standardLibrary;
private Map<String, JetType> primitiveTypesMap;
private Map<String, JetType> classTypesMap;
public JavaTypeTransformer(JetStandardLibrary standardLibrary, JavaDescriptorResolver resolver) {
this.resolver = resolver;
this.standardLibrary = standardLibrary;
}
@NotNull
public TypeProjection transformToTypeProjection(@NotNull final PsiType javaType, @NotNull final TypeParameterDescriptor typeParameterDescriptor) {
TypeProjection result = javaType.accept(new PsiTypeVisitor<TypeProjection>() {
@Override
public TypeProjection visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public TypeProjection visitWildcardType(PsiWildcardType wildcardType) {
if (!wildcardType.isBounded()) {
return TypeUtils.makeStarProjection(typeParameterDescriptor);
}
Variance variance = wildcardType.isExtends() ? Variance.OUT_VARIANCE : Variance.IN_VARIANCE;
PsiType bound = wildcardType.getBound();
assert bound != null;
return new TypeProjection(variance, transformToType(bound));
}
@Override
public TypeProjection visitType(PsiType type) {
return new TypeProjection(transformToType(type));
}
});
return result;
}
@NotNull
public JetType transformToType(@NotNull PsiType javaType) {
return javaType.accept(new PsiTypeVisitor<JetType>() {
@Override
public JetType visitClassType(PsiClassType classType) {
PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics();
PsiClass psiClass = classResolveResult.getElement();
if (psiClass == null) {
return ErrorUtils.createErrorType("Unresolved java class: " + classType.getPresentableText());
}
if (psiClass instanceof PsiTypeParameter) {
PsiTypeParameter typeParameter = (PsiTypeParameter) psiClass;
TypeParameterDescriptor typeParameterDescriptor = resolver.resolveTypeParameter(JavaDescriptorResolver.JAVA_ROOT, typeParameter);
return typeParameterDescriptor.getDefaultType();
}
else {
JetType jetAnalog = getClassTypesMap().get(psiClass.getQualifiedName());
if (jetAnalog != null) {
return jetAnalog;
}
ClassDescriptor descriptor = resolver.resolveClass(psiClass);
List<TypeProjection> arguments = Lists.newArrayList();
if (classType.isRaw()) {
List<TypeParameterDescriptor> parameters = descriptor.getTypeConstructor().getParameters();
for (TypeParameterDescriptor parameter : parameters) {
arguments.add(TypeUtils.makeStarProjection(parameter));
}
} else {
PsiType[] psiArguments = classType.getParameters();
for (int i = 0, psiArgumentsLength = psiArguments.length; i < psiArgumentsLength; i++) {
PsiType psiArgument = psiArguments[i];
TypeParameterDescriptor typeParameterDescriptor = descriptor.getTypeConstructor().getParameters().get(i);
arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor));
}
}
return new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(),
descriptor.getTypeConstructor(),
true,
arguments,
descriptor.getMemberScope(arguments));
}
}
@Override
public JetType visitPrimitiveType(PsiPrimitiveType primitiveType) {
String canonicalText = primitiveType.getCanonicalText();
JetType type = getPrimitiveTypesMap().get(canonicalText);
assert type != null : canonicalText;
return type;
}
@Override
public JetType visitArrayType(PsiArrayType arrayType) {
JetType type = transformToType(arrayType.getComponentType());
return TypeUtils.makeNullable(standardLibrary.getArrayType(type));
}
@Override
public JetType visitType(PsiType type) {
throw new UnsupportedOperationException("Unsupported type: " + type.getPresentableText()); // TODO
}
});
}
public Map<String, JetType> getPrimitiveTypesMap() {
if (primitiveTypesMap == null) {
primitiveTypesMap = new HashMap<String, JetType>();
primitiveTypesMap.put("byte", standardLibrary.getByteType());
primitiveTypesMap.put("short", standardLibrary.getShortType());
primitiveTypesMap.put("char", standardLibrary.getCharType());
primitiveTypesMap.put("int", standardLibrary.getIntType());
primitiveTypesMap.put("long", standardLibrary.getLongType());
primitiveTypesMap.put("float", standardLibrary.getFloatType());
primitiveTypesMap.put("double", standardLibrary.getDoubleType());
primitiveTypesMap.put("boolean", standardLibrary.getBooleanType());
primitiveTypesMap.put("void", JetStandardClasses.getUnitType());
primitiveTypesMap.put("java.lang.Byte", TypeUtils.makeNullable(standardLibrary.getByteType()));
primitiveTypesMap.put("java.lang.Short", TypeUtils.makeNullable(standardLibrary.getShortType()));
primitiveTypesMap.put("java.lang.Character", TypeUtils.makeNullable(standardLibrary.getCharType()));
primitiveTypesMap.put("java.lang.Integer", TypeUtils.makeNullable(standardLibrary.getIntType()));
primitiveTypesMap.put("java.lang.Long", TypeUtils.makeNullable(standardLibrary.getLongType()));
primitiveTypesMap.put("java.lang.Float", TypeUtils.makeNullable(standardLibrary.getFloatType()));
primitiveTypesMap.put("java.lang.Double", TypeUtils.makeNullable(standardLibrary.getDoubleType()));
primitiveTypesMap.put("java.lang.Boolean", TypeUtils.makeNullable(standardLibrary.getBooleanType()));
}
return primitiveTypesMap;
}
public Map<String, JetType> getClassTypesMap() {
if (classTypesMap == null) {
classTypesMap = new HashMap<String, JetType>();
classTypesMap.put("java.lang.Byte", TypeUtils.makeNullable(standardLibrary.getByteType()));
classTypesMap.put("java.lang.Short", TypeUtils.makeNullable(standardLibrary.getShortType()));
classTypesMap.put("java.lang.Character", TypeUtils.makeNullable(standardLibrary.getCharType()));
classTypesMap.put("java.lang.Integer", TypeUtils.makeNullable(standardLibrary.getIntType()));
classTypesMap.put("java.lang.Long", TypeUtils.makeNullable(standardLibrary.getLongType()));
classTypesMap.put("java.lang.Float", TypeUtils.makeNullable(standardLibrary.getFloatType()));
classTypesMap.put("java.lang.Double", TypeUtils.makeNullable(standardLibrary.getDoubleType()));
classTypesMap.put("java.lang.Boolean", TypeUtils.makeNullable(standardLibrary.getBooleanType()));
classTypesMap.put("java.lang.Object", JetStandardClasses.getNullableAnyType());
classTypesMap.put("java.lang.String", standardLibrary.getNullableStringType());
}
return classTypesMap;
}
}