Converted 2 more JetScope implementations to Kotlin
This commit is contained in:
-291
@@ -1,291 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.lazy.descriptors;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.Function0;
|
||||
import kotlin.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
|
||||
import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetScriptInfo;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProvider;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.storage.MemoizedFunctionToNotNull;
|
||||
import org.jetbrains.jet.storage.NotNullLazyValue;
|
||||
import org.jetbrains.jet.storage.StorageManager;
|
||||
import org.jetbrains.jet.utils.Printer;
|
||||
import org.jetbrains.jet.utils.UtilsPackage;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, DP extends DeclarationProvider> implements JetScope {
|
||||
protected final ResolveSession resolveSession;
|
||||
protected final BindingTrace trace;
|
||||
protected final DP declarationProvider;
|
||||
protected final D thisDescriptor;
|
||||
|
||||
private final MemoizedFunctionToNotNull<Name, List<ClassDescriptor>> classDescriptors;
|
||||
|
||||
private final MemoizedFunctionToNotNull<Name, Collection<FunctionDescriptor>> functionDescriptors;
|
||||
private final MemoizedFunctionToNotNull<Name, Collection<VariableDescriptor>> propertyDescriptors;
|
||||
|
||||
private final NotNullLazyValue<Collection<DeclarationDescriptor>> descriptorsFromDeclaredElements;
|
||||
private final NotNullLazyValue<Collection<DeclarationDescriptor>> extraDescriptors;
|
||||
|
||||
protected AbstractLazyMemberScope(
|
||||
@NotNull ResolveSession resolveSession,
|
||||
@NotNull DP declarationProvider,
|
||||
@NotNull D thisDescriptor,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
this.resolveSession = resolveSession;
|
||||
this.trace = trace;
|
||||
this.declarationProvider = declarationProvider;
|
||||
this.thisDescriptor = thisDescriptor;
|
||||
|
||||
StorageManager storageManager = resolveSession.getStorageManager();
|
||||
this.classDescriptors = storageManager.createMemoizedFunction(new Function1<Name, List<ClassDescriptor>>() {
|
||||
@Override
|
||||
public List<ClassDescriptor> invoke(Name name) {
|
||||
return resolveClassDescriptor(name);
|
||||
}
|
||||
});
|
||||
|
||||
this.functionDescriptors = storageManager.createMemoizedFunction(new Function1<Name, Collection<FunctionDescriptor>>() {
|
||||
@Override
|
||||
public Collection<FunctionDescriptor> invoke(Name name) {
|
||||
return doGetFunctions(name);
|
||||
}
|
||||
});
|
||||
this.propertyDescriptors = storageManager.createMemoizedFunction(new Function1<Name, Collection<VariableDescriptor>>() {
|
||||
@Override
|
||||
public Collection<VariableDescriptor> invoke(Name name) {
|
||||
return doGetProperties(name);
|
||||
}
|
||||
});
|
||||
|
||||
this.descriptorsFromDeclaredElements = storageManager.createLazyValue(new Function0<Collection<DeclarationDescriptor>>() {
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> invoke() {
|
||||
return computeDescriptorsFromDeclaredElements();
|
||||
}
|
||||
});
|
||||
this.extraDescriptors = storageManager.createLazyValue(new Function0<Collection<DeclarationDescriptor>>() {
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> invoke() {
|
||||
return computeExtraDescriptors();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private List<ClassDescriptor> resolveClassDescriptor(@NotNull final Name name) {
|
||||
Collection<JetClassLikeInfo> classOrObjectDeclarations = declarationProvider.getClassOrObjectDeclarations(name);
|
||||
|
||||
return UtilsPackage.toReadOnlyList(ContainerUtil.mapNotNull(classOrObjectDeclarations, new Function<JetClassLikeInfo, ClassDescriptor>() {
|
||||
@Override
|
||||
public ClassDescriptor fun(JetClassLikeInfo classLikeInfo) {
|
||||
// SCRIPT: Creating a script class
|
||||
if (classLikeInfo instanceof JetScriptInfo) {
|
||||
return new LazyScriptClassDescriptor(resolveSession, thisDescriptor, name, (JetScriptInfo) classLikeInfo);
|
||||
}
|
||||
return new LazyClassDescriptor(resolveSession, thisDescriptor, name, classLikeInfo);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassifierDescriptor getClassifier(@NotNull Name name) {
|
||||
return first(classDescriptors.invoke(name));
|
||||
}
|
||||
|
||||
private static <T> T first(@NotNull List<T> list) {
|
||||
if (list.isEmpty()) return null;
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
|
||||
return functionDescriptors.invoke(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<FunctionDescriptor> doGetFunctions(@NotNull Name name) {
|
||||
Set<FunctionDescriptor> result = Sets.newLinkedHashSet();
|
||||
|
||||
Collection<JetNamedFunction> declarations = declarationProvider.getFunctionDeclarations(name);
|
||||
for (JetNamedFunction functionDeclaration : declarations) {
|
||||
JetScope resolutionScope = getScopeForMemberDeclarationResolution(functionDeclaration);
|
||||
result.add(resolveSession.getDescriptorResolver().resolveFunctionDescriptorWithAnnotationArguments(
|
||||
thisDescriptor, resolutionScope,
|
||||
functionDeclaration,
|
||||
trace,
|
||||
// this relies on the assumption that a lazily resolved declaration is not a local one,
|
||||
// thus doesn't have a surrounding data flow
|
||||
DataFlowInfo.EMPTY)
|
||||
);
|
||||
}
|
||||
|
||||
getNonDeclaredFunctions(name, result);
|
||||
|
||||
return UtilsPackage.toReadOnlyList(result);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration);
|
||||
|
||||
protected abstract void getNonDeclaredFunctions(@NotNull Name name, @NotNull Set<FunctionDescriptor> result);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<VariableDescriptor> getProperties(@NotNull Name name) {
|
||||
return propertyDescriptors.invoke(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<VariableDescriptor> doGetProperties(@NotNull Name name) {
|
||||
Set<VariableDescriptor> result = Sets.newLinkedHashSet();
|
||||
|
||||
Collection<JetProperty> declarations = declarationProvider.getPropertyDeclarations(name);
|
||||
for (JetProperty propertyDeclaration : declarations) {
|
||||
JetScope resolutionScope = getScopeForMemberDeclarationResolution(propertyDeclaration);
|
||||
PropertyDescriptor propertyDescriptor =
|
||||
resolveSession.getDescriptorResolver().resolvePropertyDescriptor(
|
||||
thisDescriptor, resolutionScope,
|
||||
propertyDeclaration,
|
||||
trace,
|
||||
// this relies on the assumption that a lazily resolved declaration is not a local one,
|
||||
// thus doesn't have a surrounding data flow
|
||||
DataFlowInfo.EMPTY
|
||||
);
|
||||
result.add(propertyDescriptor);
|
||||
AnnotationResolver.resolveAnnotationsArguments(propertyDescriptor.getAnnotations(), trace);
|
||||
}
|
||||
|
||||
getNonDeclaredProperties(name, result);
|
||||
|
||||
return UtilsPackage.toReadOnlyList(result);
|
||||
}
|
||||
|
||||
protected abstract void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result);
|
||||
|
||||
@Override
|
||||
public VariableDescriptor getLocalVariable(@NotNull Name name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DeclarationDescriptor getContainingDeclaration() {
|
||||
return thisDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull Name labelName) {
|
||||
// A member scope has no labels
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
Collection<DeclarationDescriptor> result = new LinkedHashSet<DeclarationDescriptor>(descriptorsFromDeclaredElements.invoke());
|
||||
result.addAll(extraDescriptors.invoke());
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<DeclarationDescriptor> computeDescriptorsFromDeclaredElements() {
|
||||
List<JetDeclaration> declarations = declarationProvider.getAllDeclarations();
|
||||
ArrayList<DeclarationDescriptor> result = new ArrayList<DeclarationDescriptor>(declarations.size());
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
if (declaration instanceof JetClassOrObject) {
|
||||
JetClassOrObject classOrObject = (JetClassOrObject) declaration;
|
||||
result.addAll(classDescriptors.invoke(classOrObject.getNameAsSafeName()));
|
||||
}
|
||||
else if (declaration instanceof JetFunction) {
|
||||
JetFunction function = (JetFunction) declaration;
|
||||
result.addAll(getFunctions(function.getNameAsSafeName()));
|
||||
}
|
||||
else if (declaration instanceof JetProperty) {
|
||||
JetProperty property = (JetProperty) declaration;
|
||||
result.addAll(getProperties(property.getNameAsSafeName()));
|
||||
}
|
||||
else if (declaration instanceof JetParameter) {
|
||||
JetParameter parameter = (JetParameter) declaration;
|
||||
result.addAll(getProperties(parameter.getNameAsSafeName()));
|
||||
}
|
||||
else if (declaration instanceof JetScript) {
|
||||
result.addAll(classDescriptors.invoke(ScriptNameUtil.classNameForScript((JetScript) declaration).shortName()));
|
||||
}
|
||||
else if (declaration instanceof JetTypedef || declaration instanceof JetMultiDeclaration) {
|
||||
// Do nothing for typedefs as they are not supported.
|
||||
// MultiDeclarations are not supported on global level too.
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unsupported declaration kind: " + declaration);
|
||||
}
|
||||
}
|
||||
|
||||
return UtilsPackage.toReadOnlyList(result);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract Collection<DeclarationDescriptor> computeExtraDescriptors();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// Do not change this, override in concrete subclasses:
|
||||
// it is very easy to compromise laziness of this class, and fail all the debugging
|
||||
// a generic implementation can't do this properly
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
|
||||
return getAllDescriptors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printScopeStructure(@NotNull Printer p) {
|
||||
p.println(getClass().getSimpleName(), " {");
|
||||
p.pushIndent();
|
||||
|
||||
p.println("thisDescriptor = ", thisDescriptor);
|
||||
|
||||
p.popIndent();
|
||||
p.println("}");
|
||||
}
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.lazy.descriptors
|
||||
|
||||
import com.google.common.collect.Sets
|
||||
import com.intellij.util.Function
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.jet.lang.descriptors.*
|
||||
import org.jetbrains.jet.lang.psi.*
|
||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace
|
||||
import org.jetbrains.jet.lang.resolve.ScriptNameUtil
|
||||
import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo
|
||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetScriptInfo
|
||||
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProvider
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import org.jetbrains.jet.storage.MemoizedFunctionToNotNull
|
||||
import org.jetbrains.jet.storage.NotNullLazyValue
|
||||
import org.jetbrains.jet.utils.Printer
|
||||
|
||||
import java.util.*
|
||||
import org.jetbrains.jet.utils.toReadOnlyList
|
||||
|
||||
public abstract class AbstractLazyMemberScope<D : DeclarationDescriptor, DP : DeclarationProvider> protected(
|
||||
protected val resolveSession: ResolveSession,
|
||||
protected val declarationProvider: DP,
|
||||
protected val thisDescriptor: D,
|
||||
protected val trace: BindingTrace) : JetScope {
|
||||
|
||||
private val classDescriptors: MemoizedFunctionToNotNull<Name, List<ClassDescriptor>>
|
||||
|
||||
private val functionDescriptors: MemoizedFunctionToNotNull<Name, Collection<FunctionDescriptor>>
|
||||
private val propertyDescriptors: MemoizedFunctionToNotNull<Name, Collection<VariableDescriptor>>
|
||||
|
||||
private val descriptorsFromDeclaredElements: NotNullLazyValue<Collection<DeclarationDescriptor>>
|
||||
private val extraDescriptors: NotNullLazyValue<Collection<DeclarationDescriptor>>
|
||||
|
||||
{
|
||||
val storageManager = resolveSession.getStorageManager()
|
||||
this.classDescriptors = storageManager.createMemoizedFunction { resolveClassDescriptor(it) }
|
||||
this.functionDescriptors = storageManager.createMemoizedFunction<Name, Collection<FunctionDescriptor>> { doGetFunctions(it) }
|
||||
this.propertyDescriptors = storageManager.createMemoizedFunction<Name, Collection<VariableDescriptor>> { doGetProperties(it) }
|
||||
this.descriptorsFromDeclaredElements = storageManager.createLazyValue<Collection<DeclarationDescriptor>> { computeDescriptorsFromDeclaredElements() }
|
||||
this.extraDescriptors = storageManager.createLazyValue<Collection<DeclarationDescriptor>> { computeExtraDescriptors() }
|
||||
}
|
||||
|
||||
private fun resolveClassDescriptor(name: Name): List<ClassDescriptor> {
|
||||
val classOrObjectDeclarations = declarationProvider.getClassOrObjectDeclarations(name)
|
||||
|
||||
return ContainerUtil.mapNotNull<JetClassLikeInfo, ClassDescriptor>(classOrObjectDeclarations, object : Function<JetClassLikeInfo, ClassDescriptor> {
|
||||
override fun `fun`(classLikeInfo: JetClassLikeInfo): ClassDescriptor {
|
||||
// SCRIPT: Creating a script class
|
||||
if (classLikeInfo is JetScriptInfo) {
|
||||
return LazyScriptClassDescriptor(resolveSession, thisDescriptor, name, classLikeInfo)
|
||||
}
|
||||
return LazyClassDescriptor(resolveSession, thisDescriptor, name, classLikeInfo)
|
||||
}
|
||||
}).toReadOnlyList()
|
||||
}
|
||||
|
||||
override fun getContainingDeclaration() = thisDescriptor
|
||||
|
||||
override fun getClassifier(name: Name) = classDescriptors(name).firstOrNull()
|
||||
|
||||
override fun getFunctions(name: Name) = functionDescriptors(name)
|
||||
|
||||
private fun doGetFunctions(name: Name): Collection<FunctionDescriptor> {
|
||||
val result = Sets.newLinkedHashSet<FunctionDescriptor>()
|
||||
|
||||
val declarations = declarationProvider.getFunctionDeclarations(name)
|
||||
for (functionDeclaration in declarations) {
|
||||
val resolutionScope = getScopeForMemberDeclarationResolution(functionDeclaration)
|
||||
result.add(resolveSession.getDescriptorResolver().resolveFunctionDescriptorWithAnnotationArguments(
|
||||
thisDescriptor,
|
||||
resolutionScope,
|
||||
functionDeclaration,
|
||||
trace,
|
||||
// this relies on the assumption that a lazily resolved declaration is not a local one,
|
||||
// thus doesn't have a surrounding data flow
|
||||
DataFlowInfo.EMPTY))
|
||||
}
|
||||
|
||||
getNonDeclaredFunctions(name, result)
|
||||
|
||||
return result.toReadOnlyList()
|
||||
}
|
||||
|
||||
protected abstract fun getScopeForMemberDeclarationResolution(declaration: JetDeclaration): JetScope
|
||||
|
||||
protected abstract fun getNonDeclaredFunctions(name: Name, result: MutableSet<FunctionDescriptor>)
|
||||
|
||||
override fun getProperties(name: Name) = propertyDescriptors(name)
|
||||
|
||||
public fun doGetProperties(name: Name): Collection<VariableDescriptor> {
|
||||
val result = Sets.newLinkedHashSet<VariableDescriptor>()
|
||||
|
||||
val declarations = declarationProvider.getPropertyDeclarations(name)
|
||||
for (propertyDeclaration in declarations) {
|
||||
val resolutionScope = getScopeForMemberDeclarationResolution(propertyDeclaration)
|
||||
val propertyDescriptor = resolveSession.getDescriptorResolver().resolvePropertyDescriptor(
|
||||
thisDescriptor,
|
||||
resolutionScope,
|
||||
propertyDeclaration,
|
||||
trace,
|
||||
// this relies on the assumption that a lazily resolved declaration is not a local one,
|
||||
// thus doesn't have a surrounding data flow
|
||||
DataFlowInfo.EMPTY)
|
||||
result.add(propertyDescriptor)
|
||||
AnnotationResolver.resolveAnnotationsArguments(propertyDescriptor.getAnnotations(), trace)
|
||||
}
|
||||
|
||||
getNonDeclaredProperties(name, result)
|
||||
|
||||
return result.toReadOnlyList()
|
||||
}
|
||||
|
||||
protected abstract fun getNonDeclaredProperties(name: Name, result: MutableSet<VariableDescriptor>)
|
||||
|
||||
override fun getLocalVariable(name: Name): VariableDescriptor? = null
|
||||
|
||||
override fun getDeclarationsByLabel(labelName: Name) = setOf<DeclarationDescriptor>()
|
||||
|
||||
override fun getAllDescriptors(): Collection<DeclarationDescriptor> {
|
||||
val result = LinkedHashSet(descriptorsFromDeclaredElements())
|
||||
result.addAll(extraDescriptors())
|
||||
return result
|
||||
}
|
||||
|
||||
private fun computeDescriptorsFromDeclaredElements(): Collection<DeclarationDescriptor> {
|
||||
val declarations = declarationProvider.getAllDeclarations()
|
||||
val result = ArrayList<DeclarationDescriptor>(declarations.size())
|
||||
for (declaration in declarations) {
|
||||
if (declaration is JetClassOrObject) {
|
||||
result.addAll(classDescriptors.invoke(declaration.getNameAsSafeName()))
|
||||
}
|
||||
else if (declaration is JetFunction) {
|
||||
result.addAll(getFunctions(declaration.getNameAsSafeName()))
|
||||
}
|
||||
else if (declaration is JetProperty) {
|
||||
result.addAll(getProperties(declaration.getNameAsSafeName()))
|
||||
}
|
||||
else if (declaration is JetParameter) {
|
||||
result.addAll(getProperties(declaration.getNameAsSafeName()))
|
||||
}
|
||||
else if (declaration is JetScript) {
|
||||
result.addAll(classDescriptors(ScriptNameUtil.classNameForScript(declaration).shortName()))
|
||||
}
|
||||
else if (declaration is JetTypedef || declaration is JetMultiDeclaration) {
|
||||
// Do nothing for typedefs as they are not supported.
|
||||
// MultiDeclarations are not supported on global level too.
|
||||
}
|
||||
else {
|
||||
throw IllegalArgumentException("Unsupported declaration kind: " + declaration)
|
||||
}
|
||||
}
|
||||
return result.toReadOnlyList()
|
||||
}
|
||||
|
||||
protected abstract fun computeExtraDescriptors(): Collection<DeclarationDescriptor>
|
||||
|
||||
override fun getImplicitReceiversHierarchy() = listOf<ReceiverParameterDescriptor>()
|
||||
|
||||
// Do not change this, override in concrete subclasses:
|
||||
// it is very easy to compromise laziness of this class, and fail all the debugging
|
||||
// a generic implementation can't do this properly
|
||||
abstract override fun toString(): String
|
||||
|
||||
override fun getOwnDeclaredDescriptors() = getAllDescriptors()
|
||||
|
||||
override fun printScopeStructure(p: Printer) {
|
||||
p.println(javaClass.getSimpleName(), " {")
|
||||
p.pushIndent()
|
||||
|
||||
p.println("thisDescriptor = ", thisDescriptor)
|
||||
|
||||
p.popIndent()
|
||||
p.println("}")
|
||||
}
|
||||
}
|
||||
-401
@@ -1,401 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.lazy.descriptors;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import kotlin.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.dataClassUtils.DataClassUtilsPackage;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.declarations.ClassMemberDeclarationProvider;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.DeferredType;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.storage.NullableLazyValue;
|
||||
import org.jetbrains.jet.utils.UtilsPackage;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.DELEGATION;
|
||||
import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
|
||||
import static org.jetbrains.jet.lang.resolve.DelegationResolver.generateDelegatedMembers;
|
||||
|
||||
public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescriptor, ClassMemberDeclarationProvider> {
|
||||
|
||||
@NotNull
|
||||
private static final Set<ClassKind> GENERATE_CONSTRUCTORS_FOR =
|
||||
ImmutableSet.of(ClassKind.CLASS, ClassKind.ANNOTATION_CLASS, ClassKind.OBJECT,
|
||||
ClassKind.ENUM_CLASS, ClassKind.ENUM_ENTRY, ClassKind.CLASS_OBJECT);
|
||||
|
||||
private interface MemberExtractor<T extends CallableMemberDescriptor> {
|
||||
MemberExtractor<FunctionDescriptor> EXTRACT_FUNCTIONS = new MemberExtractor<FunctionDescriptor>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<FunctionDescriptor> extract(@NotNull JetType extractFrom, @NotNull Name name) {
|
||||
return extractFrom.getMemberScope().getFunctions(name);
|
||||
}
|
||||
};
|
||||
|
||||
MemberExtractor<PropertyDescriptor> EXTRACT_PROPERTIES = new MemberExtractor<PropertyDescriptor>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PropertyDescriptor> extract(@NotNull JetType extractFrom, @NotNull Name name) {
|
||||
//noinspection unchecked
|
||||
return (Collection) extractFrom.getMemberScope().getProperties(name);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
Collection<T> extract(@NotNull JetType extractFrom, @NotNull Name name);
|
||||
}
|
||||
|
||||
private final NullableLazyValue<ConstructorDescriptor> primaryConstructor;
|
||||
|
||||
public LazyClassMemberScope(
|
||||
@NotNull ResolveSession resolveSession,
|
||||
@NotNull ClassMemberDeclarationProvider declarationProvider,
|
||||
@NotNull LazyClassDescriptor thisClass,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
super(resolveSession, declarationProvider, thisClass, trace);
|
||||
this.primaryConstructor = resolveSession.getStorageManager().createNullableLazyValue(new Function0<ConstructorDescriptor>() {
|
||||
@Override
|
||||
public ConstructorDescriptor invoke() {
|
||||
return resolvePrimaryConstructor();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
return thisDescriptor.getScopeForInitializerResolution();
|
||||
}
|
||||
return thisDescriptor.getScopeForMemberDeclarationResolution();
|
||||
}
|
||||
|
||||
private <D extends CallableMemberDescriptor> void generateFakeOverrides(
|
||||
@NotNull Name name,
|
||||
@NotNull Collection<D> fromSupertypes,
|
||||
@NotNull final Collection<D> result,
|
||||
@NotNull final Class<? extends D> exactDescriptorClass
|
||||
) {
|
||||
OverridingUtil.generateOverridesInFunctionGroup(
|
||||
name,
|
||||
fromSupertypes,
|
||||
Lists.newArrayList(result),
|
||||
thisDescriptor,
|
||||
new OverridingUtil.DescriptorSink() {
|
||||
@Override
|
||||
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
||||
assert exactDescriptorClass.isInstance(fakeOverride) : "Wrong descriptor type in an override: " +
|
||||
fakeOverride +
|
||||
" while expecting " +
|
||||
exactDescriptorClass.getSimpleName();
|
||||
//noinspection unchecked
|
||||
result.add((D) fakeOverride);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
|
||||
JetDeclaration declaration = (JetDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(fromCurrent);
|
||||
assert declaration != null : "fromCurrent can not be a fake override";
|
||||
trace.report(Errors.CONFLICTING_OVERLOADS
|
||||
.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().asString()));
|
||||
}
|
||||
}
|
||||
);
|
||||
OverrideResolver.resolveUnknownVisibilities(result, trace);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
|
||||
// TODO: this should be handled by lazy function descriptors
|
||||
Collection<FunctionDescriptor> functions = super.getFunctions(name);
|
||||
resolveUnknownVisibilitiesForMembers(functions);
|
||||
return functions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getNonDeclaredFunctions(@NotNull Name name, @NotNull Set<FunctionDescriptor> result) {
|
||||
Collection<FunctionDescriptor> fromSupertypes = Lists.newArrayList();
|
||||
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
|
||||
fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name));
|
||||
}
|
||||
result.addAll(generateDelegatingDescriptors(name, MemberExtractor.EXTRACT_FUNCTIONS, result));
|
||||
generateDataClassMethods(result, name);
|
||||
generateFakeOverrides(name, fromSupertypes, result, FunctionDescriptor.class);
|
||||
}
|
||||
|
||||
private void generateDataClassMethods(@NotNull Collection<FunctionDescriptor> result, @NotNull Name name) {
|
||||
if (!KotlinBuiltIns.getInstance().isData(thisDescriptor)) return;
|
||||
|
||||
ConstructorDescriptor constructor = getPrimaryConstructor();
|
||||
if (constructor == null) return;
|
||||
|
||||
List<? extends JetParameter> primaryConstructorParameters = declarationProvider.getOwnerInfo().getPrimaryConstructorParameters();
|
||||
assert constructor.getValueParameters().size() == primaryConstructorParameters.size()
|
||||
: "From descriptor: " + constructor.getValueParameters().size() + " but from PSI: " + primaryConstructorParameters.size();
|
||||
|
||||
if (DataClassUtilsPackage.isComponentLike(name)) {
|
||||
int componentIndex = 0;
|
||||
|
||||
for (ValueParameterDescriptor parameter : constructor.getValueParameters()) {
|
||||
if (parameter.getType().isError()) continue;
|
||||
if (!primaryConstructorParameters.get(parameter.getIndex()).hasValOrVarNode()) continue;
|
||||
|
||||
Collection<VariableDescriptor> properties = getProperties(parameter.getName());
|
||||
if (properties.isEmpty()) continue;
|
||||
|
||||
assert properties.size() == 1 :
|
||||
"A constructor parameter is resolved to more than one (" + properties.size() + ") property: " + parameter;
|
||||
|
||||
PropertyDescriptor property = (PropertyDescriptor) properties.iterator().next();
|
||||
if (property == null) continue;
|
||||
|
||||
++componentIndex;
|
||||
|
||||
if (name.equals(DataClassUtilsPackage.createComponentName(componentIndex))) {
|
||||
SimpleFunctionDescriptor functionDescriptor = DescriptorResolver.createComponentFunctionDescriptor(
|
||||
componentIndex, property, parameter, thisDescriptor, trace);
|
||||
result.add(functionDescriptor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name.equals(DescriptorResolver.COPY_METHOD_NAME)) {
|
||||
for (ValueParameterDescriptor parameter : constructor.getValueParameters()) {
|
||||
// force properties resolution to fill BindingContext.VALUE_PARAMETER_AS_PROPERTY slice
|
||||
getProperties(parameter.getName());
|
||||
}
|
||||
|
||||
SimpleFunctionDescriptor copyFunctionDescriptor =
|
||||
DescriptorResolver.createCopyFunctionDescriptor(constructor.getValueParameters(), thisDescriptor, trace);
|
||||
result.add(copyFunctionDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<VariableDescriptor> getProperties(@NotNull Name name) {
|
||||
// TODO: this should be handled by lazy property descriptors
|
||||
Collection<VariableDescriptor> properties = super.getProperties(name);
|
||||
resolveUnknownVisibilitiesForMembers((Collection) properties);
|
||||
return properties;
|
||||
}
|
||||
|
||||
private void resolveUnknownVisibilitiesForMembers(@NotNull Collection<? extends CallableMemberDescriptor> descriptors) {
|
||||
for (CallableMemberDescriptor descriptor : descriptors) {
|
||||
if (descriptor.getKind() != FAKE_OVERRIDE && descriptor.getKind() != DELEGATION) {
|
||||
OverridingUtil.resolveUnknownVisibilityForMember(descriptor, OverrideResolver.createCannotInferVisibilityReporter(trace));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
|
||||
createPropertiesFromPrimaryConstructorParameters(name, result);
|
||||
|
||||
// Members from supertypes
|
||||
Collection<PropertyDescriptor> fromSupertypes = Lists.newArrayList();
|
||||
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
|
||||
fromSupertypes.addAll((Collection) supertype.getMemberScope().getProperties(name));
|
||||
}
|
||||
result.addAll(generateDelegatingDescriptors(name, MemberExtractor.EXTRACT_PROPERTIES, result));
|
||||
generateFakeOverrides(name, fromSupertypes, (Collection) result, PropertyDescriptor.class);
|
||||
}
|
||||
|
||||
protected void createPropertiesFromPrimaryConstructorParameters(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
|
||||
JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
|
||||
|
||||
// From primary constructor parameters
|
||||
ConstructorDescriptor primaryConstructor = getPrimaryConstructor();
|
||||
if (primaryConstructor == null) return;
|
||||
|
||||
List<ValueParameterDescriptor> valueParameterDescriptors = primaryConstructor.getValueParameters();
|
||||
List<? extends JetParameter> primaryConstructorParameters = classInfo.getPrimaryConstructorParameters();
|
||||
assert valueParameterDescriptors.size() == primaryConstructorParameters.size()
|
||||
: "From descriptor: " + valueParameterDescriptors.size() + " but from PSI: " + primaryConstructorParameters.size();
|
||||
|
||||
for (ValueParameterDescriptor valueParameterDescriptor : valueParameterDescriptors) {
|
||||
if (!name.equals(valueParameterDescriptor.getName())) continue;
|
||||
|
||||
JetParameter parameter = primaryConstructorParameters.get(valueParameterDescriptor.getIndex());
|
||||
if (parameter.hasValOrVarNode()) {
|
||||
PropertyDescriptor propertyDescriptor =
|
||||
resolveSession.getDescriptorResolver().resolvePrimaryConstructorParameterToAProperty(
|
||||
thisDescriptor,
|
||||
valueParameterDescriptor,
|
||||
thisDescriptor.getScopeForClassHeaderResolution(),
|
||||
parameter, trace
|
||||
);
|
||||
result.add(propertyDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <T extends CallableMemberDescriptor> Collection<T> generateDelegatingDescriptors(
|
||||
@NotNull final Name name,
|
||||
@NotNull final MemberExtractor<T> extractor,
|
||||
@NotNull Collection<? extends CallableDescriptor> existingDescriptors
|
||||
) {
|
||||
JetClassOrObject classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject();
|
||||
if (classOrObject == null) {
|
||||
// Enum class objects do not have delegated members
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
DelegationResolver.TypeResolver lazyTypeResolver = new DelegationResolver.TypeResolver() {
|
||||
@Nullable
|
||||
@Override
|
||||
public JetType resolve(@NotNull JetTypeReference reference) {
|
||||
return resolveSession.getTypeResolver().resolveType(
|
||||
thisDescriptor.getScopeForClassHeaderResolution(),
|
||||
reference,
|
||||
trace,
|
||||
false);
|
||||
}
|
||||
};
|
||||
DelegationResolver.MemberExtractor<T> lazyMemberExtractor = new DelegationResolver.MemberExtractor<T>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<T> getMembersByType(@NotNull JetType type) {
|
||||
return extractor.extract(type, name);
|
||||
}
|
||||
};
|
||||
return generateDelegatedMembers(classOrObject, thisDescriptor, existingDescriptors, trace, lazyMemberExtractor,
|
||||
lazyTypeResolver);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected Collection<DeclarationDescriptor> computeExtraDescriptors() {
|
||||
List<DeclarationDescriptor> result = new ArrayList<DeclarationDescriptor>();
|
||||
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
|
||||
for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
result.addAll(getFunctions(descriptor.getName()));
|
||||
}
|
||||
else if (descriptor instanceof PropertyDescriptor) {
|
||||
result.addAll(getProperties(descriptor.getName()));
|
||||
}
|
||||
// Nothing else is inherited
|
||||
}
|
||||
}
|
||||
|
||||
addDataClassMethods(result);
|
||||
|
||||
return UtilsPackage.toReadOnlyList(result);
|
||||
}
|
||||
|
||||
private void addDataClassMethods(@NotNull Collection<DeclarationDescriptor> result) {
|
||||
if (!KotlinBuiltIns.getInstance().isData(thisDescriptor)) return;
|
||||
|
||||
ConstructorDescriptor constructor = getPrimaryConstructor();
|
||||
if (constructor == null) return;
|
||||
|
||||
// Generate componentN functions until there's no such function for some n
|
||||
int n = 1;
|
||||
while (true) {
|
||||
Name componentName = DataClassUtilsPackage.createComponentName(n);
|
||||
Collection<FunctionDescriptor> functions = getFunctions(componentName);
|
||||
if (functions.isEmpty()) break;
|
||||
|
||||
result.addAll(functions);
|
||||
|
||||
n++;
|
||||
}
|
||||
result.addAll(getFunctions(Name.identifier("copy")));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PackageViewDescriptor getPackage(@NotNull Name name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<ConstructorDescriptor> getConstructors() {
|
||||
ConstructorDescriptor constructor = getPrimaryConstructor();
|
||||
return constructor == null ? Collections.<ConstructorDescriptor>emptySet() : Collections.singleton(constructor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ConstructorDescriptor getPrimaryConstructor() {
|
||||
return primaryConstructor.invoke();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected ConstructorDescriptor resolvePrimaryConstructor() {
|
||||
if (GENERATE_CONSTRUCTORS_FOR.contains(thisDescriptor.getKind())) {
|
||||
JetClassLikeInfo ownerInfo = declarationProvider.getOwnerInfo();
|
||||
JetClassOrObject classOrObject = ownerInfo.getCorrespondingClassOrObject();
|
||||
if (!thisDescriptor.getKind().isSingleton()) {
|
||||
JetClass jetClass = (JetClass) classOrObject;
|
||||
assert jetClass != null : "No JetClass for " + thisDescriptor;
|
||||
ConstructorDescriptorImpl constructor = resolveSession.getDescriptorResolver()
|
||||
.resolvePrimaryConstructorDescriptor(thisDescriptor.getScopeForClassHeaderResolution(),
|
||||
thisDescriptor,
|
||||
jetClass,
|
||||
trace);
|
||||
assert constructor != null : "No constructor created for " + thisDescriptor;
|
||||
setDeferredReturnType(constructor);
|
||||
return constructor;
|
||||
}
|
||||
else {
|
||||
ConstructorDescriptorImpl constructor =
|
||||
DescriptorResolver.createAndRecordPrimaryConstructorForObject(classOrObject, thisDescriptor, trace);
|
||||
setDeferredReturnType(constructor);
|
||||
return constructor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void setDeferredReturnType(@NotNull ConstructorDescriptorImpl descriptor) {
|
||||
descriptor.setReturnType(DeferredType.create(resolveSession.getStorageManager(), trace,
|
||||
new Function0<JetType>() {
|
||||
@Override
|
||||
public JetType invoke() {
|
||||
return thisDescriptor.getDefaultType();
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// Do not add details here, they may compromise the laziness during debugging
|
||||
return "lazy scope for class " + thisDescriptor.getName();
|
||||
}
|
||||
}
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.lazy.descriptors
|
||||
|
||||
import com.google.common.collect.Lists
|
||||
import org.jetbrains.jet.lang.descriptors.*
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors
|
||||
import org.jetbrains.jet.lang.psi.*
|
||||
import org.jetbrains.jet.lang.resolve.*
|
||||
import org.jetbrains.jet.lang.resolve.dataClassUtils.*
|
||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.jet.lang.resolve.lazy.declarations.ClassMemberDeclarationProvider
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import org.jetbrains.jet.lang.types.DeferredType
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.storage.NullableLazyValue
|
||||
|
||||
import java.util.*
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.DELEGATION
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
import org.jetbrains.jet.lang.resolve.DelegationResolver.generateDelegatedMembers
|
||||
|
||||
public open class LazyClassMemberScope(resolveSession: ResolveSession,
|
||||
declarationProvider: ClassMemberDeclarationProvider,
|
||||
thisClass: LazyClassDescriptor,
|
||||
trace: BindingTrace)
|
||||
: AbstractLazyMemberScope<LazyClassDescriptor, ClassMemberDeclarationProvider>(resolveSession, declarationProvider, thisClass, trace) {
|
||||
|
||||
private trait MemberExtractor<T : CallableMemberDescriptor> {
|
||||
|
||||
public fun extract(extractFrom: JetType, name: Name): Collection<T>
|
||||
|
||||
}
|
||||
|
||||
private val primaryConstructor: NullableLazyValue<ConstructorDescriptor>
|
||||
= resolveSession.getStorageManager().createNullableLazyValue { resolvePrimaryConstructor() }
|
||||
|
||||
override fun getScopeForMemberDeclarationResolution(declaration: JetDeclaration): JetScope {
|
||||
if (declaration is JetProperty) {
|
||||
return thisDescriptor.getScopeForInitializerResolution()
|
||||
}
|
||||
return thisDescriptor.getScopeForMemberDeclarationResolution()
|
||||
}
|
||||
|
||||
private fun <D : CallableMemberDescriptor> generateFakeOverrides(name: Name, fromSupertypes: Collection<D>, result: MutableCollection<D>, exactDescriptorClass: Class<out D>) {
|
||||
OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, ArrayList(result), thisDescriptor, object : OverridingUtil.DescriptorSink {
|
||||
override fun addToScope(fakeOverride: CallableMemberDescriptor) {
|
||||
assert(exactDescriptorClass.isInstance(fakeOverride)) { "Wrong descriptor type in an override: " + fakeOverride + " while expecting " + exactDescriptorClass.getSimpleName() }
|
||||
[suppress("UNCHECKED_CAST")]
|
||||
result.add(fakeOverride as D)
|
||||
}
|
||||
|
||||
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
|
||||
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(fromCurrent) as JetDeclaration?
|
||||
assert(declaration != null, "fromCurrent can not be a fake override")
|
||||
trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().asString()))
|
||||
}
|
||||
})
|
||||
OverrideResolver.resolveUnknownVisibilities(result, trace)
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name): Collection<FunctionDescriptor> {
|
||||
// TODO: this should be handled by lazy function descriptors
|
||||
val functions = super.getFunctions(name)
|
||||
resolveUnknownVisibilitiesForMembers(functions)
|
||||
return functions
|
||||
}
|
||||
|
||||
protected override fun getNonDeclaredFunctions(name: Name, result: MutableSet<FunctionDescriptor>) {
|
||||
val fromSupertypes = Lists.newArrayList<FunctionDescriptor>()
|
||||
for (supertype in thisDescriptor.getTypeConstructor().getSupertypes()) {
|
||||
fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name))
|
||||
}
|
||||
result.addAll(generateDelegatingDescriptors(name, EXTRACT_FUNCTIONS, result))
|
||||
generateDataClassMethods(result, name)
|
||||
generateFakeOverrides(name, fromSupertypes, result, javaClass<FunctionDescriptor>())
|
||||
}
|
||||
|
||||
private fun generateDataClassMethods(result: MutableCollection<FunctionDescriptor>, name: Name) {
|
||||
if (!KotlinBuiltIns.getInstance().isData(thisDescriptor)) return
|
||||
|
||||
val constructor = getPrimaryConstructor()
|
||||
if (constructor == null) return
|
||||
|
||||
val primaryConstructorParameters = declarationProvider.getOwnerInfo().getPrimaryConstructorParameters()
|
||||
assert(constructor.getValueParameters().size() == primaryConstructorParameters.size()) { "From descriptor: " + constructor.getValueParameters().size() + " but from PSI: " + primaryConstructorParameters.size() }
|
||||
|
||||
if (isComponentLike(name)) {
|
||||
var componentIndex = 0
|
||||
|
||||
for (parameter in constructor.getValueParameters()) {
|
||||
if (parameter.getType().isError()) continue
|
||||
if (!primaryConstructorParameters.get(parameter.getIndex()).hasValOrVarNode()) continue
|
||||
|
||||
val properties = getProperties(parameter.getName())
|
||||
if (properties.isEmpty()) continue
|
||||
|
||||
assert(properties.size() == 1) { "A constructor parameter is resolved to more than one (" + properties.size() + ") property: " + parameter }
|
||||
|
||||
val property = properties.iterator().next() as PropertyDescriptor
|
||||
|
||||
++componentIndex
|
||||
|
||||
if (name == createComponentName(componentIndex)) {
|
||||
val functionDescriptor = DescriptorResolver.createComponentFunctionDescriptor(componentIndex, property, parameter, thisDescriptor, trace)
|
||||
result.add(functionDescriptor)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name == DescriptorResolver.COPY_METHOD_NAME) {
|
||||
for (parameter in constructor.getValueParameters()) {
|
||||
// force properties resolution to fill BindingContext.VALUE_PARAMETER_AS_PROPERTY slice
|
||||
getProperties(parameter.getName())
|
||||
}
|
||||
|
||||
val copyFunctionDescriptor = DescriptorResolver.createCopyFunctionDescriptor(constructor.getValueParameters(), thisDescriptor, trace)
|
||||
result.add(copyFunctionDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getProperties(name: Name): Collection<VariableDescriptor> {
|
||||
// TODO: this should be handled by lazy property descriptors
|
||||
val properties = super.getProperties(name)
|
||||
resolveUnknownVisibilitiesForMembers(properties as Collection<CallableMemberDescriptor>)
|
||||
return properties
|
||||
}
|
||||
|
||||
private fun resolveUnknownVisibilitiesForMembers(descriptors: Collection<CallableMemberDescriptor>) {
|
||||
for (descriptor in descriptors) {
|
||||
if (descriptor.getKind() != FAKE_OVERRIDE && descriptor.getKind() != DELEGATION) {
|
||||
OverridingUtil.resolveUnknownVisibilityForMember(descriptor, OverrideResolver.createCannotInferVisibilityReporter(trace))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[suppress("UNCHECKED_CAST")]
|
||||
protected override fun getNonDeclaredProperties(name: Name, result: MutableSet<VariableDescriptor>) {
|
||||
createPropertiesFromPrimaryConstructorParameters(name, result)
|
||||
|
||||
// Members from supertypes
|
||||
val fromSupertypes = ArrayList<PropertyDescriptor>()
|
||||
for (supertype in thisDescriptor.getTypeConstructor().getSupertypes()) {
|
||||
fromSupertypes.addAll(supertype.getMemberScope().getProperties(name) as Collection<PropertyDescriptor>)
|
||||
}
|
||||
result.addAll(generateDelegatingDescriptors(name, EXTRACT_PROPERTIES, result))
|
||||
generateFakeOverrides(name, fromSupertypes, result as MutableCollection<PropertyDescriptor>, javaClass<PropertyDescriptor>())
|
||||
}
|
||||
|
||||
protected open fun createPropertiesFromPrimaryConstructorParameters(name: Name, result: MutableSet<VariableDescriptor>) {
|
||||
val classInfo = declarationProvider.getOwnerInfo()
|
||||
|
||||
// From primary constructor parameters
|
||||
val primaryConstructor = getPrimaryConstructor() ?: return
|
||||
|
||||
val valueParameterDescriptors = primaryConstructor.getValueParameters()
|
||||
val primaryConstructorParameters = classInfo.getPrimaryConstructorParameters()
|
||||
assert(valueParameterDescriptors.size() == primaryConstructorParameters.size()) {
|
||||
"From descriptor: ${valueParameterDescriptors.size} but from PSI: ${primaryConstructorParameters.size}"
|
||||
}
|
||||
|
||||
for (valueParameterDescriptor in valueParameterDescriptors) {
|
||||
if (name != valueParameterDescriptor.getName()) continue
|
||||
|
||||
val parameter = primaryConstructorParameters.get(valueParameterDescriptor.getIndex())
|
||||
if (parameter.hasValOrVarNode()) {
|
||||
val propertyDescriptor = resolveSession.getDescriptorResolver().resolvePrimaryConstructorParameterToAProperty(
|
||||
thisDescriptor, valueParameterDescriptor, thisDescriptor.getScopeForClassHeaderResolution(), parameter, trace)
|
||||
result.add(propertyDescriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : CallableMemberDescriptor> generateDelegatingDescriptors(name: Name, extractor: MemberExtractor<T>, existingDescriptors: Collection<CallableDescriptor>): Collection<T> {
|
||||
val classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject()
|
||||
?: return setOf() // Enum class objects do not have delegated members
|
||||
|
||||
val lazyTypeResolver = DelegationResolver.TypeResolver { reference ->
|
||||
resolveSession.getTypeResolver().resolveType(thisDescriptor.getScopeForClassHeaderResolution(), reference, trace, false)
|
||||
}
|
||||
val lazyMemberExtractor = DelegationResolver.MemberExtractor<T> {
|
||||
type -> extractor.extract(type, name)
|
||||
}
|
||||
return generateDelegatedMembers(classOrObject, thisDescriptor, existingDescriptors, trace, lazyMemberExtractor, lazyTypeResolver)
|
||||
}
|
||||
|
||||
override fun computeExtraDescriptors(): Collection<DeclarationDescriptor> {
|
||||
val result = ArrayList<DeclarationDescriptor>()
|
||||
for (supertype in thisDescriptor.getTypeConstructor().getSupertypes()) {
|
||||
for (descriptor in supertype.getMemberScope().getAllDescriptors()) {
|
||||
if (descriptor is FunctionDescriptor) {
|
||||
result.addAll(getFunctions(descriptor.getName()))
|
||||
}
|
||||
else if (descriptor is PropertyDescriptor) {
|
||||
result.addAll(getProperties(descriptor.getName()))
|
||||
}
|
||||
// Nothing else is inherited
|
||||
}
|
||||
}
|
||||
|
||||
addDataClassMethods(result)
|
||||
|
||||
result.trimToSize()
|
||||
return result
|
||||
}
|
||||
|
||||
private fun addDataClassMethods(result: MutableCollection<DeclarationDescriptor>) {
|
||||
if (!KotlinBuiltIns.getInstance().isData(thisDescriptor)) return
|
||||
|
||||
if (getPrimaryConstructor() == null) return
|
||||
|
||||
// Generate componentN functions until there's no such function for some n
|
||||
var n = 1
|
||||
while (true) {
|
||||
val componentName = createComponentName(n)
|
||||
val functions = getFunctions(componentName)
|
||||
if (functions.isEmpty()) break
|
||||
|
||||
result.addAll(functions)
|
||||
|
||||
n++
|
||||
}
|
||||
result.addAll(getFunctions(Name.identifier("copy")))
|
||||
}
|
||||
|
||||
override fun getPackage(name: Name): PackageViewDescriptor? = null
|
||||
|
||||
public fun getConstructors(): Set<ConstructorDescriptor> {
|
||||
val constructor = getPrimaryConstructor()
|
||||
return if (constructor != null) setOf(constructor) else setOf()
|
||||
}
|
||||
|
||||
public fun getPrimaryConstructor(): ConstructorDescriptor? = primaryConstructor()
|
||||
|
||||
protected open fun resolvePrimaryConstructor(): ConstructorDescriptor? {
|
||||
if (GENERATE_CONSTRUCTORS_FOR.contains(thisDescriptor.getKind())) {
|
||||
val ownerInfo = declarationProvider.getOwnerInfo()
|
||||
val classOrObject = ownerInfo.getCorrespondingClassOrObject()
|
||||
if (!thisDescriptor.getKind().isSingleton()) {
|
||||
assert(classOrObject is JetClass) { "No JetClass for $thisDescriptor" }
|
||||
classOrObject as JetClass
|
||||
val constructor = resolveSession.getDescriptorResolver().resolvePrimaryConstructorDescriptor(
|
||||
thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor, classOrObject, trace)
|
||||
assert(constructor != null) { "No constructor created for $thisDescriptor" }
|
||||
setDeferredReturnType(constructor)
|
||||
return constructor
|
||||
}
|
||||
else {
|
||||
val constructor = DescriptorResolver.createAndRecordPrimaryConstructorForObject(classOrObject, thisDescriptor, trace)
|
||||
setDeferredReturnType(constructor)
|
||||
return constructor
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
protected fun setDeferredReturnType(descriptor: ConstructorDescriptorImpl) {
|
||||
descriptor.setReturnType(DeferredType.create(resolveSession.getStorageManager(), trace, { thisDescriptor.getDefaultType() }))
|
||||
}
|
||||
|
||||
// Do not add details here, they may compromise the laziness during debugging
|
||||
override fun toString() = "lazy scope for class ${thisDescriptor.getName()}"
|
||||
|
||||
class object {
|
||||
private val GENERATE_CONSTRUCTORS_FOR = setOf(ClassKind.CLASS,
|
||||
ClassKind.ANNOTATION_CLASS,
|
||||
ClassKind.OBJECT,
|
||||
ClassKind.ENUM_CLASS,
|
||||
ClassKind.ENUM_ENTRY,
|
||||
ClassKind.CLASS_OBJECT)
|
||||
|
||||
private val EXTRACT_FUNCTIONS: MemberExtractor<FunctionDescriptor> = object : MemberExtractor<FunctionDescriptor> {
|
||||
override fun extract(extractFrom: JetType, name: Name): Collection<FunctionDescriptor> {
|
||||
return extractFrom.getMemberScope().getFunctions(name)
|
||||
}
|
||||
}
|
||||
|
||||
private val EXTRACT_PROPERTIES: MemberExtractor<PropertyDescriptor> = object : MemberExtractor<PropertyDescriptor> {
|
||||
override fun extract(extractFrom: JetType, name: Name): Collection<PropertyDescriptor> {
|
||||
[suppress("UNCHECKED_CAST")]
|
||||
return extractFrom.getMemberScope().getProperties(name) as Collection<PropertyDescriptor>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -46,7 +46,7 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope<PackageFragm
|
||||
@NotNull
|
||||
@Override
|
||||
protected JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration) {
|
||||
return resolveSession.getScopeProvider().getFileScope(declaration.getContainingJetFile());
|
||||
return getResolveSession().getScopeProvider().getFileScope(declaration.getContainingJetFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,6 +68,6 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope<PackageFragm
|
||||
@Override
|
||||
public String toString() {
|
||||
// Do not add details here, they may compromise the laziness during debugging
|
||||
return "lazy scope for package " + thisDescriptor.getName();
|
||||
return "lazy scope for package " + getThisDescriptor().getName();
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -51,9 +51,9 @@ public class LazyScriptClassMemberScope extends LazyClassMemberScope {
|
||||
new Function0<PropertyDescriptor>() {
|
||||
@Override
|
||||
public PropertyDescriptor invoke() {
|
||||
JetScriptInfo scriptInfo = (JetScriptInfo) declarationProvider.getOwnerInfo();
|
||||
JetScriptInfo scriptInfo = (JetScriptInfo) getDeclarationProvider().getOwnerInfo();
|
||||
|
||||
return ScriptDescriptorImpl.createScriptResultProperty(resolveSession.getScriptDescriptor(scriptInfo.getScript()));
|
||||
return ScriptDescriptorImpl.createScriptResultProperty(getResolveSession().getScriptDescriptor(scriptInfo.getScript()));
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -99,7 +99,7 @@ public class LazyScriptClassMemberScope extends LazyClassMemberScope {
|
||||
|
||||
@Override
|
||||
protected void createPropertiesFromPrimaryConstructorParameters(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
|
||||
JetScriptInfo scriptInfo = (JetScriptInfo) declarationProvider.getOwnerInfo();
|
||||
JetScriptInfo scriptInfo = (JetScriptInfo) getDeclarationProvider().getOwnerInfo();
|
||||
|
||||
// From primary constructor parameters
|
||||
ConstructorDescriptor primaryConstructor = getPrimaryConstructor();
|
||||
@@ -110,7 +110,7 @@ public class LazyScriptClassMemberScope extends LazyClassMemberScope {
|
||||
|
||||
result.add(
|
||||
ScriptDescriptorImpl.createPropertyFromScriptParameter(
|
||||
resolveSession.getScriptDescriptor(scriptInfo.getScript()),
|
||||
getResolveSession().getScriptDescriptor(scriptInfo.getScript()),
|
||||
valueParameterDescriptor
|
||||
)
|
||||
);
|
||||
@@ -120,8 +120,8 @@ public class LazyScriptClassMemberScope extends LazyClassMemberScope {
|
||||
@Override
|
||||
@Nullable
|
||||
protected ConstructorDescriptor resolvePrimaryConstructor() {
|
||||
JetScriptInfo scriptInfo = (JetScriptInfo) declarationProvider.getOwnerInfo();
|
||||
ScriptDescriptor scriptDescriptor = resolveSession.getScriptDescriptor(scriptInfo.getScript());
|
||||
JetScriptInfo scriptInfo = (JetScriptInfo) getDeclarationProvider().getOwnerInfo();
|
||||
ScriptDescriptor scriptDescriptor = getResolveSession().getScriptDescriptor(scriptInfo.getScript());
|
||||
ConstructorDescriptorImpl constructor = ScriptDescriptorImpl.createConstructor(scriptDescriptor,
|
||||
scriptDescriptor.getScriptCodeDescriptor()
|
||||
.getValueParameters());
|
||||
|
||||
Reference in New Issue
Block a user