Basic support for resolving top-level SAM interfaces.
This commit is contained in:
+15
-13
@@ -19,10 +19,7 @@ package org.jetbrains.jet.lang.resolve.java.provider;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.lang.resolve.java.PsiClassFinder;
|
||||
import org.jetbrains.jet.lang.resolve.java.TypeSource;
|
||||
import org.jetbrains.jet.lang.resolve.java.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.java.prop.PropertyNameUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.prop.PropertyParseResult;
|
||||
@@ -73,27 +70,28 @@ public final class MembersCache {
|
||||
|
||||
//TODO:
|
||||
List<PsiClass> classes = psiPackage != null ? finder.findPsiClasses(psiPackage) : finder.findInnerPsiClasses(psiClass);
|
||||
membersCache.new ObjectClassProcessor(classes).process();
|
||||
membersCache.new ExtraPackageMembersProcessor(classes).process();
|
||||
return membersCache;
|
||||
}
|
||||
|
||||
private class ObjectClassProcessor {
|
||||
private class ExtraPackageMembersProcessor { // 'extra' means that PSI elements for these members are not just top-level classes
|
||||
@NotNull
|
||||
private final List<PsiClass> psiClasses;
|
||||
|
||||
private ObjectClassProcessor(@NotNull List<PsiClass> classes) {
|
||||
private ExtraPackageMembersProcessor(@NotNull List<PsiClass> classes) {
|
||||
psiClasses = classes;
|
||||
}
|
||||
|
||||
private void process() {
|
||||
for (PsiClass psiClass : psiClasses) {
|
||||
if (!psiClass.isPhysical()) { // to filter out JetLightClasses
|
||||
continue;
|
||||
if (!(psiClass instanceof JetJavaMirrorMarker)) { // to filter out JetLightClasses
|
||||
if (JetClassAnnotation.get(psiClass).kind() == JvmStdlibNames.FLAG_CLASS_KIND_OBJECT) {
|
||||
processObjectClass(psiClass);
|
||||
}
|
||||
if (!DescriptorResolverUtils.isKotlinClass(psiClass) && psiClass.isInterface()) {
|
||||
processFunctionalInterface(psiClass);
|
||||
}
|
||||
}
|
||||
if (JetClassAnnotation.get(psiClass).kind() != JvmStdlibNames.FLAG_CLASS_KIND_OBJECT) {
|
||||
continue;
|
||||
}
|
||||
processObjectClass(psiClass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +104,10 @@ public final class MembersCache {
|
||||
namedMembers.addPropertyAccessor(new PropertyPsiDataElement(new PsiFieldWrapper(instanceField), type, null));
|
||||
}
|
||||
}
|
||||
|
||||
private void processFunctionalInterface(@NotNull PsiClass psiClass) {
|
||||
getOrCreateEmpty(Name.identifier(psiClass.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
private class ClassMemberProcessor {
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java.sam;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class SingleAbstractMethodUtils {
|
||||
public static boolean isFunctionalInterface(@NotNull ClassDescriptor klass) {
|
||||
if (klass.getKind() != ClassKind.TRAIT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<CallableMemberDescriptor> abstractMembers = getAbstractMembers(klass);
|
||||
return abstractMembers.size() == 1 && abstractMembers.get(0) instanceof SimpleFunctionDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<CallableMemberDescriptor> getAbstractMembers(@NotNull ClassDescriptor klass) {
|
||||
List<CallableMemberDescriptor> abstractMembers = Lists.newArrayList();
|
||||
for (DeclarationDescriptor member : klass.getDefaultType().getMemberScope().getAllDescriptors()) {
|
||||
if (member instanceof CallableMemberDescriptor && ((CallableMemberDescriptor) member).getModality() == Modality.ABSTRACT) {
|
||||
abstractMembers.add((CallableMemberDescriptor) member);
|
||||
}
|
||||
}
|
||||
return abstractMembers;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetType getFunctionalTypeForFunction(@NotNull FunctionDescriptor function) {
|
||||
// TODO substitute type parameters of class
|
||||
// TODO substitute type parameters of function with star projections
|
||||
JetType returnType = function.getReturnType();
|
||||
assert returnType != null : "function is not initialized: " + function;
|
||||
List<JetType> parameterTypes = Lists.newArrayList();
|
||||
for (ValueParameterDescriptor parameter : function.getValueParameters()) {
|
||||
parameterTypes.add(parameter.getType());
|
||||
}
|
||||
return KotlinBuiltIns.getInstance().getFunctionType(Collections.<AnnotationDescriptor>emptyList(), null, parameterTypes, returnType);
|
||||
}
|
||||
|
||||
public static SimpleFunctionDescriptor createConstructorFunction(@NotNull ClassDescriptor klass) {
|
||||
SimpleFunctionDescriptorImpl result = new SimpleFunctionDescriptorImpl(
|
||||
klass.getContainingDeclaration(),
|
||||
klass.getAnnotations(),
|
||||
klass.getName(),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
);
|
||||
|
||||
JetType parameterType = getFunctionalTypeForFunction((SimpleFunctionDescriptor) getAbstractMembers(klass).get(0));
|
||||
ValueParameterDescriptor parameter = new ValueParameterDescriptorImpl(
|
||||
result, 0, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("function"), parameterType, false, null);
|
||||
|
||||
result.initialize(
|
||||
null,
|
||||
null,
|
||||
Lists.<TypeParameterDescriptor>newArrayList(), // TODO recreate type parameters of class
|
||||
Arrays.asList(parameter),
|
||||
klass.getDefaultType(), // TODO substitute type parameters of class
|
||||
Modality.FINAL,
|
||||
klass.getVisibility(),
|
||||
false
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private SingleAbstractMethodUtils() {
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -18,10 +18,12 @@ package org.jetbrains.jet.lang.resolve.java.scope;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.resolve.java.provider.PackagePsiDeclarationProvider;
|
||||
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
@@ -42,7 +44,15 @@ public final class JavaPackageScopeWithoutMembers extends JavaPackageScope {
|
||||
@Override
|
||||
@NotNull
|
||||
protected Set<FunctionDescriptor> computeFunctionDescriptor(@NotNull Name name) {
|
||||
return Collections.emptySet();
|
||||
ClassifierDescriptor classifier = getClassifier(name);
|
||||
if (classifier instanceof ClassDescriptor && SingleAbstractMethodUtils.isFunctionalInterface((ClassDescriptor) classifier)) {
|
||||
|
||||
FunctionDescriptor constructorFunction = SingleAbstractMethodUtils.createConstructorFunction((ClassDescriptor) classifier);
|
||||
|
||||
return Collections.singleton(constructorFunction);
|
||||
}
|
||||
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user