Preliminary version of lazy resolve
The implementation is incomplete and thus not used anywhere other than the test
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.di;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
|
||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
/* This file is generated by org.jetbrains.jet.di.AllInjectorsGenerator. DO NOT EDIT! */
|
||||
public class InjectorForLazyResolve {
|
||||
|
||||
private final Project project;
|
||||
private DescriptorResolver descriptorResolver;
|
||||
private ExpressionTypingServices expressionTypingServices;
|
||||
private TypeResolver typeResolver;
|
||||
private AnnotationResolver annotationResolver;
|
||||
private CallResolver callResolver;
|
||||
private OverloadingConflictResolver overloadingConflictResolver;
|
||||
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||
|
||||
public InjectorForLazyResolve(
|
||||
@NotNull Project project
|
||||
) {
|
||||
this.project = project;
|
||||
this.descriptorResolver = new DescriptorResolver();
|
||||
this.expressionTypingServices = new ExpressionTypingServices();
|
||||
this.typeResolver = new TypeResolver();
|
||||
this.annotationResolver = new AnnotationResolver();
|
||||
this.callResolver = new CallResolver();
|
||||
this.overloadingConflictResolver = new OverloadingConflictResolver();
|
||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||
|
||||
this.descriptorResolver.setAnnotationResolver(annotationResolver);
|
||||
this.descriptorResolver.setExpressionTypingServices(expressionTypingServices);
|
||||
this.descriptorResolver.setTypeResolver(typeResolver);
|
||||
|
||||
this.expressionTypingServices.setCallResolver(callResolver);
|
||||
this.expressionTypingServices.setDescriptorResolver(descriptorResolver);
|
||||
this.expressionTypingServices.setProject(project);
|
||||
this.expressionTypingServices.setTypeResolver(typeResolver);
|
||||
|
||||
this.typeResolver.setAnnotationResolver(annotationResolver);
|
||||
this.typeResolver.setDescriptorResolver(descriptorResolver);
|
||||
this.typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||
|
||||
annotationResolver.setCallResolver(callResolver);
|
||||
annotationResolver.setExpressionTypingServices(expressionTypingServices);
|
||||
|
||||
callResolver.setDescriptorResolver(descriptorResolver);
|
||||
callResolver.setExpressionTypingServices(expressionTypingServices);
|
||||
callResolver.setOverloadingConflictResolver(overloadingConflictResolver);
|
||||
callResolver.setTypeResolver(typeResolver);
|
||||
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
public DescriptorResolver getDescriptorResolver() {
|
||||
return this.descriptorResolver;
|
||||
}
|
||||
|
||||
public ExpressionTypingServices getExpressionTypingServices() {
|
||||
return this.expressionTypingServices;
|
||||
}
|
||||
|
||||
public TypeResolver getTypeResolver() {
|
||||
return this.typeResolver;
|
||||
}
|
||||
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
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.name.LabelName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, DP extends DeclarationProvider> implements JetScope {
|
||||
protected final ResolveSession resolveSession;
|
||||
protected final DP declarationProvider;
|
||||
protected final D thisDescriptor;
|
||||
|
||||
protected boolean allDescriptorsComputed = false;
|
||||
|
||||
private final Map<Name, ClassDescriptor> classDescriptors = Maps.newHashMap();
|
||||
private final Map<Name, Set<FunctionDescriptor>> functionDescriptors = Maps.newHashMap();
|
||||
private final Map<Name, Set<VariableDescriptor>> propertyDescriptors = Maps.newHashMap();
|
||||
|
||||
protected AbstractLazyMemberScope(
|
||||
@NotNull ResolveSession resolveSession,
|
||||
@NotNull DP declarationProvider,
|
||||
@NotNull D thisDescriptor
|
||||
) {
|
||||
this.resolveSession = resolveSession;
|
||||
this.declarationProvider = declarationProvider;
|
||||
this.thisDescriptor = thisDescriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ClassDescriptor getClassOrObjectDescriptor(@NotNull Name name, boolean object) {
|
||||
ClassDescriptor known = classDescriptors.get(name);
|
||||
if (known != null) return known;
|
||||
|
||||
if (allDescriptorsComputed) return null;
|
||||
|
||||
JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name);
|
||||
if (classOrObjectDeclaration == null) return null;
|
||||
|
||||
if (object != classOrObjectDeclaration instanceof JetObjectDeclaration) return null;
|
||||
|
||||
ClassMemberDeclarationProvider classMemberDeclarationProvider =
|
||||
resolveSession.getDeclarationProviderFactory().getClassMemberDeclarationProvider(classOrObjectDeclaration);
|
||||
ClassDescriptor classDescriptor = new LazyClassDescriptor(resolveSession, thisDescriptor, name, classMemberDeclarationProvider);
|
||||
|
||||
classDescriptors.put(name, classDescriptor);
|
||||
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassifierDescriptor getClassifier(@NotNull Name name) {
|
||||
return getClassOrObjectDescriptor(name, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
|
||||
// TODO: We shouldn't really allow objects in classes...
|
||||
return getClassOrObjectDescriptor(name, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<FunctionDescriptor> getFunctions(@NotNull Name name) {
|
||||
Set<FunctionDescriptor> known = functionDescriptors.get(name);
|
||||
if (known != null) return known;
|
||||
|
||||
// If all descriptors are already computed, we are
|
||||
if (allDescriptorsComputed) return Collections.emptySet();
|
||||
|
||||
Set<FunctionDescriptor> result = Sets.newLinkedHashSet();
|
||||
|
||||
List<JetNamedFunction> declarations = declarationProvider.getFunctionDeclarations(name);
|
||||
for (JetNamedFunction functionDeclaration : declarations) {
|
||||
JetScope resolutionScope = getScopeForMemberDeclarationResolution(functionDeclaration);
|
||||
result.add(resolveSession.getDescriptorResolver().resolveFunctionDescriptor(thisDescriptor, resolutionScope,
|
||||
functionDeclaration, resolveSession.getTrace()));
|
||||
}
|
||||
|
||||
getNonDeclaredFunctions(name, result);
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
functionDescriptors.put(name, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration);
|
||||
|
||||
protected abstract void getNonDeclaredFunctions(@NotNull Name name, @NotNull Set<FunctionDescriptor> result);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<VariableDescriptor> getProperties(@NotNull Name name) {
|
||||
Set<VariableDescriptor> known = propertyDescriptors.get(name);
|
||||
if (known != null) return known;
|
||||
|
||||
// If all descriptors are already computed, we are
|
||||
if (allDescriptorsComputed) return Collections.emptySet();
|
||||
|
||||
Set<VariableDescriptor> result = Sets.newLinkedHashSet();
|
||||
|
||||
List<JetProperty> declarations = declarationProvider.getPropertyDeclarations(name);
|
||||
for (JetProperty propertyDeclaration : declarations) {
|
||||
JetScope resolutionScope = getScopeForMemberDeclarationResolution(propertyDeclaration);
|
||||
result.add(resolveSession.getDescriptorResolver().resolvePropertyDescriptor(thisDescriptor, resolutionScope,
|
||||
propertyDeclaration, resolveSession.getTrace()));
|
||||
}
|
||||
|
||||
getNonDeclaredProperties(name, result);
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
propertyDescriptors.put(name, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<ClassDescriptor> getObjectDescriptors() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableDescriptor getLocalVariable(@NotNull Name name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DeclarationDescriptor getContainingDeclaration() {
|
||||
return thisDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyDescriptor getPropertyByFieldReference(@NotNull Name fieldName) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
allDescriptorsComputed = true;
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
|
||||
ReceiverDescriptor receiver = getImplicitReceiver();
|
||||
if (receiver.exists()) {
|
||||
result.add(receiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface ClassMemberDeclarationProvider extends DeclarationProvider {
|
||||
@NotNull
|
||||
JetClassOrObject getOwnerClassOrObject();
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface DeclarationProvider {
|
||||
List<JetDeclaration> getAllDeclarations();
|
||||
|
||||
@NotNull
|
||||
List<JetNamedFunction> getFunctionDeclarations(@NotNull Name name);
|
||||
|
||||
@NotNull
|
||||
List<JetProperty> getPropertyDeclarations(@NotNull Name name);
|
||||
|
||||
@Nullable
|
||||
JetClassOrObject getClassOrObjectDeclaration(@NotNull Name name);
|
||||
|
||||
boolean isPackageDeclared(@NotNull Name name);
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface DeclarationProviderFactory {
|
||||
@NotNull
|
||||
ClassMemberDeclarationProvider getClassMemberDeclarationProvider(@NotNull JetClassOrObject jetClassOrObject);
|
||||
|
||||
@Nullable
|
||||
DeclarationProvider getPackageMemberDeclarationProvider(@NotNull FqName packageFqName);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Segment;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class IdentitySmartPointer<E extends PsiElement> implements SmartPsiElementPointer<E> {
|
||||
private final E element;
|
||||
|
||||
public IdentitySmartPointer(@NotNull E element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile getContainingFile() {
|
||||
return element.getContainingFile();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Project getProject() {
|
||||
return element.getProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualFile getVirtualFile() {
|
||||
return element.getContainingFile().getVirtualFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Segment getRange() {
|
||||
return element.getTextRange();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDescriptor {
|
||||
|
||||
private final ResolveSession resolveSession;
|
||||
|
||||
private final Name name;
|
||||
private final DeclarationDescriptor containingDeclaration;
|
||||
private final TypeConstructor typeConstructor;
|
||||
private final ClassMemberDeclarationProvider declarationProvider;
|
||||
|
||||
private final LazyClassMemberScope unsubstitutedMemberScope;
|
||||
private final JetScope unsubstitutedInnerClassesScope;
|
||||
private ClassReceiver implicitReceiver;
|
||||
private JetScope scopeForClassHeaderResolution;
|
||||
private JetScope scopeForMemberDeclarationResolution;
|
||||
|
||||
private final Modality modality;
|
||||
private final Visibility visibility;
|
||||
private final ClassKind kind;
|
||||
|
||||
|
||||
public LazyClassDescriptor(
|
||||
@NotNull ResolveSession resolveSession,
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@NotNull Name name,
|
||||
@NotNull ClassMemberDeclarationProvider memberDeclarationProvider
|
||||
) {
|
||||
this.declarationProvider = memberDeclarationProvider;
|
||||
this.resolveSession = resolveSession;
|
||||
this.name = name;
|
||||
this.containingDeclaration = containingDeclaration;
|
||||
this.unsubstitutedMemberScope = new LazyClassMemberScope(resolveSession, memberDeclarationProvider, this);
|
||||
this.unsubstitutedInnerClassesScope = new InnerClassesScopeWrapper(unsubstitutedMemberScope);
|
||||
|
||||
this.typeConstructor = new LazyClassTypeConstructor();
|
||||
|
||||
JetClassOrObject classOrObject = memberDeclarationProvider.getOwnerClassOrObject();
|
||||
this.kind = getClassKind(classOrObject);
|
||||
Modality defaultModality = kind == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
|
||||
JetModifierList modifierList = classOrObject.getModifierList();
|
||||
this.modality = DescriptorResolver.resolveModalityFromModifiers(modifierList, defaultModality);
|
||||
this.visibility = DescriptorResolver.resolveVisibilityFromModifiers(modifierList);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ClassKind getClassKind(@NotNull JetClassOrObject jetClassOrObject) {
|
||||
if (jetClassOrObject instanceof JetClass) {
|
||||
JetClass jetClass = (JetClass) jetClassOrObject;
|
||||
if (jetClass.isTrait()) return ClassKind.TRAIT;
|
||||
if (jetClass.hasModifier(JetTokens.ANNOTATION_KEYWORD)) return ClassKind.ANNOTATION_CLASS;
|
||||
if (jetClass.hasModifier(JetTokens.ENUM_KEYWORD)) return ClassKind.ENUM_CLASS;
|
||||
return ClassKind.CLASS;
|
||||
}
|
||||
if (jetClassOrObject instanceof JetObjectDeclaration) {
|
||||
return ClassKind.OBJECT;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown class or object kind: " + jetClassOrObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JetScope getScopeForMemberLookup() {
|
||||
return unsubstitutedMemberScope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetScope getUnsubstitutedInnerClassesScope() {
|
||||
return unsubstitutedInnerClassesScope;
|
||||
}
|
||||
|
||||
public JetScope getScopeForMemberDeclarationResolution() {
|
||||
if (scopeForMemberDeclarationResolution == null) {
|
||||
WritableScopeImpl scope = new WritableScopeImpl(getScopeForClassHeaderResolution(), this, RedeclarationHandler.DO_NOTHING)
|
||||
.setDebugName("Member Declaration Resolution");
|
||||
|
||||
scope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||
scopeForMemberDeclarationResolution = scope;
|
||||
}
|
||||
return scopeForMemberDeclarationResolution;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetScope getScopeForClassHeaderResolution() {
|
||||
if (scopeForClassHeaderResolution == null) {
|
||||
WritableScopeImpl scope = new WritableScopeImpl(resolveSession.getResolutionScope(declarationProvider.getOwnerClassOrObject()), this, RedeclarationHandler.DO_NOTHING)
|
||||
.setDebugName("Class Header Resolution");
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
|
||||
scope.addClassifierDescriptor(typeParameterDescriptor);
|
||||
}
|
||||
scope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||
scopeForClassHeaderResolution = scope;
|
||||
}
|
||||
return scopeForClassHeaderResolution;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<ConstructorDescriptor> getConstructors() {
|
||||
return unsubstitutedMemberScope.getConstructors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
|
||||
return unsubstitutedMemberScope.getPrimaryConstructor();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DeclarationDescriptor getOriginal() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DeclarationDescriptor getContainingDeclaration() {
|
||||
return containingDeclaration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeConstructor getTypeConstructor() {
|
||||
return typeConstructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetType getClassObjectType() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClassObjectAValue() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassDescriptor getClassObjectDescriptor() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ClassKind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Modality getModality() {
|
||||
return modality;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Visibility getVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
if (implicitReceiver == null) {
|
||||
implicitReceiver = new ClassReceiver(this);
|
||||
}
|
||||
return implicitReceiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AnnotationDescriptor> getAnnotations() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Name getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "lazy class " + getName().toString();
|
||||
}
|
||||
|
||||
private class LazyClassTypeConstructor implements TypeConstructor {
|
||||
private Collection<JetType> supertypes = null;
|
||||
private List<TypeParameterDescriptor> parameters = null;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TypeParameterDescriptor> getParameters() {
|
||||
if (parameters == null) {
|
||||
JetClassOrObject declaration = declarationProvider.getOwnerClassOrObject();
|
||||
if (declaration instanceof JetClass) {
|
||||
JetClass jetClass = (JetClass) declaration;
|
||||
|
||||
List<JetTypeParameter> typeParameters = jetClass.getTypeParameters();
|
||||
parameters = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
|
||||
|
||||
for (int i = 0; i < typeParameters.size(); i++) {
|
||||
parameters.add(new LazyTypeParameterDescriptor(resolveSession, LazyClassDescriptor.this, typeParameters.get(i), i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// It is an object declaration, no type parameters
|
||||
parameters = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<? extends JetType> getSupertypes() {
|
||||
if (supertypes == null) {
|
||||
JetClassOrObject declaration = declarationProvider.getOwnerClassOrObject();
|
||||
this.supertypes = resolveSession.getDescriptorResolver()
|
||||
.resolveSupertypes(getScopeForClassHeaderResolution(),
|
||||
declaration,
|
||||
resolveSession.getTrace());
|
||||
}
|
||||
return supertypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSealed() {
|
||||
return !getModality().isOverridable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassifierDescriptor getDeclarationDescriptor() {
|
||||
return LazyClassDescriptor.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AnnotationDescriptor> getAnnotations() {
|
||||
return Collections.emptyList(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return LazyClassDescriptor.this.getName().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescriptor, ClassMemberDeclarationProvider> {
|
||||
|
||||
public LazyClassMemberScope(
|
||||
@NotNull ResolveSession resolveSession,
|
||||
@NotNull ClassMemberDeclarationProvider declarationProvider,
|
||||
@NotNull LazyClassDescriptor thisClass
|
||||
) {
|
||||
super(resolveSession, declarationProvider, thisClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration) {
|
||||
return thisDescriptor.getScopeForMemberDeclarationResolution();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getNonDeclaredFunctions(@NotNull Name name, @NotNull Set<FunctionDescriptor> result) {
|
||||
JetClassOrObject owner = declarationProvider.getOwnerClassOrObject();
|
||||
//throw new UnsupportedOperationException(); // TODO
|
||||
System.err.println("getNonDeclaredFunctions() should generate fake overrides for a class");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
|
||||
System.err.println("getNonDeclaredProperties() should generate fake overrides for a class");
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceDescriptor getNamespace(@NotNull Name name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
return thisDescriptor.getImplicitReceiver();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<ConstructorDescriptor> getConstructors() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ConstructorDescriptor getPrimaryConstructor() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class LazyDescriptorFactory {
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor createLazyClassDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.AbstractNamespaceDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorParent;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class LazyPackageDescriptor extends AbstractNamespaceDescriptorImpl implements NamespaceDescriptor {
|
||||
private final LazyPackageMemberScope memberScope;
|
||||
|
||||
public LazyPackageDescriptor(
|
||||
@NotNull NamespaceDescriptorParent containingDeclaration,
|
||||
@NotNull Name name,
|
||||
@NotNull ResolveSession resolveSession,
|
||||
@NotNull DeclarationProvider declarationProvider
|
||||
) {
|
||||
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), name);
|
||||
this.memberScope = new LazyPackageMemberScope(resolveSession, declarationProvider, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetScope getMemberScope() {
|
||||
return memberScope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FqName getQualifiedName() {
|
||||
return DescriptorUtils.getFQName(this).toSafe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class LazyPackageMemberScope extends AbstractLazyMemberScope<NamespaceDescriptor, DeclarationProvider> {
|
||||
|
||||
private final Map<Name, NamespaceDescriptor> packageDescriptors = Maps.newHashMap();
|
||||
|
||||
public LazyPackageMemberScope(@NotNull ResolveSession resolveSession,
|
||||
@NotNull DeclarationProvider declarationProvider,
|
||||
@NotNull NamespaceDescriptor thisPackage) {
|
||||
super(resolveSession, declarationProvider, thisPackage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceDescriptor getNamespace(@NotNull Name name) {
|
||||
NamespaceDescriptor known = packageDescriptors.get(name);
|
||||
if (known != null) return known;
|
||||
if (allDescriptorsComputed) return null;
|
||||
|
||||
if (!declarationProvider.isPackageDeclared(name)) return null;
|
||||
|
||||
DeclarationProvider packageMemberDeclarationProvider = resolveSession.getDeclarationProviderFactory().getPackageMemberDeclarationProvider(
|
||||
DescriptorUtils.getFQName(thisDescriptor).child(name).toSafe());
|
||||
assert packageMemberDeclarationProvider != null : "Package is declared, but declaration provider is not found: " + name;
|
||||
NamespaceDescriptor namespaceDescriptor = new LazyPackageDescriptor(thisDescriptor, name, resolveSession, packageMemberDeclarationProvider);
|
||||
|
||||
packageDescriptors.put(name, namespaceDescriptor);
|
||||
|
||||
return namespaceDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration) {
|
||||
return resolveSession.getScopeProvider().getFileScopeForDeclarationResolution((JetFile) declaration.getContainingFile());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
return ReceiverDescriptor.NO_RECEIVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getNonDeclaredFunctions(@NotNull Name name, @NotNull Set<FunctionDescriptor> result) {
|
||||
// No extra functions
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
|
||||
// No extra properties
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package org.jetbrains.jet.lang.resolve.lazy;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class LazyResolveINjectorGenerator {
|
||||
}
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.jetbrains.jet.util.lazy.LazyValue;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class LazyTypeParameterDescriptor implements TypeParameterDescriptor {
|
||||
private final ResolveSession resolveSession;
|
||||
|
||||
private final SmartPsiElementPointer<JetTypeParameter> jetTypeParameterSmartPsiElementPointer;
|
||||
private final Variance variance;
|
||||
private final int index;
|
||||
private final LazyClassDescriptor containingDeclaration;
|
||||
private final Name name;
|
||||
|
||||
private TypeConstructor typeConstructor;
|
||||
private JetType defaultType;
|
||||
|
||||
private Set<JetType> upperBounds;
|
||||
private JetType upperBoundsAsType;
|
||||
|
||||
private Set<JetType> classObjectBounds;
|
||||
private JetType classObjectBoundsAsType;
|
||||
|
||||
public LazyTypeParameterDescriptor(
|
||||
@NotNull ResolveSession resolveSession,
|
||||
@NotNull LazyClassDescriptor containingDeclaration,
|
||||
@NotNull JetTypeParameter jetTypeParameter,
|
||||
int index) {
|
||||
this.resolveSession = resolveSession;
|
||||
// TODO: different smart pointer implementations in IDE and compiler
|
||||
this.jetTypeParameterSmartPsiElementPointer = new IdentitySmartPointer<JetTypeParameter>(jetTypeParameter);
|
||||
this.variance = jetTypeParameter.getVariance();
|
||||
this.containingDeclaration = containingDeclaration;
|
||||
this.index = index;
|
||||
this.name = jetTypeParameter.getNameAsName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReified() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Variance getVariance() {
|
||||
return variance;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<JetType> getUpperBounds() {
|
||||
if (upperBounds == null) {
|
||||
upperBounds = Sets.newLinkedHashSet();
|
||||
|
||||
JetTypeParameter jetTypeParameter = getElement();
|
||||
|
||||
resolveUpperBoundsFromWhereClause(upperBounds, false);
|
||||
|
||||
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
|
||||
if (extendsBound != null) {
|
||||
upperBounds.add(resolveBoundType(extendsBound));
|
||||
}
|
||||
|
||||
if (upperBounds.isEmpty()) {
|
||||
upperBounds.add(JetStandardClasses.getDefaultBound());
|
||||
}
|
||||
}
|
||||
return upperBounds;
|
||||
}
|
||||
|
||||
private JetTypeParameter resolveUpperBoundsFromWhereClause(Set<JetType> upperBounds, boolean forClassObject) {
|
||||
JetTypeParameter jetTypeParameter = getElement();
|
||||
|
||||
JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(jetTypeParameter, JetClassOrObject.class);
|
||||
if (classOrObject instanceof JetClass) {
|
||||
JetClass jetClass = (JetClass) classOrObject;
|
||||
for (JetTypeConstraint jetTypeConstraint : jetClass.getTypeConstaints()) {
|
||||
if (jetTypeConstraint.isClassObjectContraint() == forClassObject) continue;
|
||||
|
||||
JetSimpleNameExpression constrainedParameterName = jetTypeConstraint.getSubjectTypeParameterName();
|
||||
if (constrainedParameterName != null) {
|
||||
if (name.equals(constrainedParameterName.getReferencedNameAsName())) {
|
||||
|
||||
JetTypeReference boundTypeReference = jetTypeConstraint.getBoundTypeReference();
|
||||
if (boundTypeReference != null) {
|
||||
upperBounds.add(resolveBoundType(boundTypeReference));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return jetTypeParameter;
|
||||
}
|
||||
|
||||
private JetTypeParameter getElement() {
|
||||
JetTypeParameter jetTypeParameter = jetTypeParameterSmartPsiElementPointer.getElement();
|
||||
if (jetTypeParameter == null) {
|
||||
throw new IllegalStateException("Psi element not found for type parameter: " + this);
|
||||
}
|
||||
return jetTypeParameter;
|
||||
}
|
||||
|
||||
private JetType resolveBoundType(@NotNull JetTypeReference boundTypeReference) {
|
||||
return resolveSession.getTypeResolver()
|
||||
.resolveType(containingDeclaration.getScopeForClassHeaderResolution(), boundTypeReference,
|
||||
resolveSession.getTrace(), false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getUpperBoundsAsType() {
|
||||
if (upperBoundsAsType == null) {
|
||||
Set<JetType> upperBounds = getUpperBounds();
|
||||
assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
|
||||
upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
|
||||
if (upperBoundsAsType == null) {
|
||||
upperBoundsAsType = JetStandardClasses.getNothingType();
|
||||
}
|
||||
}
|
||||
return upperBoundsAsType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<JetType> getLowerBounds() {
|
||||
return Collections.singleton(getLowerBoundsAsType());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getLowerBoundsAsType() {
|
||||
return JetStandardClasses.getNothingType();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeConstructor getTypeConstructor() {
|
||||
if (typeConstructor == null) {
|
||||
typeConstructor = new TypeConstructor() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<? extends JetType> getSupertypes() {
|
||||
return LazyTypeParameterDescriptor.this.getUpperBounds();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TypeParameterDescriptor> getParameters() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSealed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassifierDescriptor getDeclarationDescriptor() {
|
||||
return LazyTypeParameterDescriptor.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AnnotationDescriptor> getAnnotations() {
|
||||
return LazyTypeParameterDescriptor.this.getAnnotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName().toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
return typeConstructor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getDefaultType() {
|
||||
if (defaultType == null) {
|
||||
defaultType = new JetTypeImpl(getTypeConstructor(), new LazyScopeAdapter(new LazyValue<JetScope>() {
|
||||
@Override
|
||||
protected JetScope compute() {
|
||||
return getUpperBoundsAsType().getMemberScope();
|
||||
}
|
||||
}));
|
||||
}
|
||||
return defaultType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetType getClassObjectType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClassObjectAValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DeclarationDescriptor getOriginal() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor getContainingDeclaration() {
|
||||
return containingDeclaration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@Deprecated
|
||||
public TypeParameterDescriptor substitute(TypeSubstitutor substitutor) {
|
||||
throw new UnsupportedOperationException("Don't call substitute() on type parameters");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitTypeParameterDescriptor(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
|
||||
visitor.visitTypeParameterDescriptor(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AnnotationDescriptor> getAnnotations() {
|
||||
return Collections.emptyList(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Name getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName().toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.di.InjectorForLazyResolve;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ResolveSession {
|
||||
private final ModuleDescriptor module;
|
||||
private final LazyPackageDescriptor rootPackage;
|
||||
private final ScopeProvider scopeProvider;
|
||||
|
||||
private final BindingTrace trace = new BindingTraceContext();
|
||||
private final DeclarationProviderFactory declarationProviderFactory;
|
||||
|
||||
private final Map<Name, NamespaceDescriptor> packageDescriptors = Maps.newHashMap();
|
||||
private final InjectorForLazyResolve injector;
|
||||
|
||||
public ResolveSession(
|
||||
@NotNull Project project,
|
||||
@NotNull ModuleDescriptor rootDescriptor,
|
||||
@NotNull DeclarationProviderFactory declarationProviderFactory
|
||||
) {
|
||||
this.injector = new InjectorForLazyResolve(project);
|
||||
this.module = rootDescriptor;
|
||||
DeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(FqName.ROOT);
|
||||
assert provider != null : "No declaration provider for root package in " + rootDescriptor;
|
||||
this.rootPackage = new LazyPackageDescriptor(rootDescriptor, JetPsiUtil.ROOT_NAMESPACE_NAME, this, provider);
|
||||
rootDescriptor.setRootNs(rootPackage);
|
||||
|
||||
this.scopeProvider = new ScopeProvider(this);
|
||||
this.declarationProviderFactory = declarationProviderFactory;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DescriptorResolver getDescriptorResolver() {
|
||||
return injector.getDescriptorResolver();
|
||||
}
|
||||
|
||||
public TypeResolver getTypeResolver() {
|
||||
return injector.getTypeResolver();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public NamespaceDescriptor getPackageDescriptor(@NotNull Name shortName) {
|
||||
return rootPackage.getMemberScope().getNamespace(shortName);
|
||||
//NamespaceDescriptor namespaceDescriptor = packageDescriptors.get(shortName);
|
||||
//if (namespaceDescriptor == null) {
|
||||
// DeclarationProvider declarationProvider = declarationProviderFactory.getPackageMemberDeclarationProvider(
|
||||
// FqName.topLevel(shortName));
|
||||
// if (declarationProvider == null) return null;
|
||||
//
|
||||
// namespaceDescriptor = new LazyPackageDescriptor(module.getRootNs(), shortName, this, declarationProvider);
|
||||
//
|
||||
// packageDescriptors.put(shortName, namespaceDescriptor);
|
||||
//}
|
||||
//return namespaceDescriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public NamespaceDescriptor getPackageDescriptorByFqName(FqName fqName) {
|
||||
List<Name> names = fqName.pathSegments();
|
||||
NamespaceDescriptor current = getPackageDescriptor(names.get(0));
|
||||
if (current == null) return null;
|
||||
for (Name name : names.subList(1, names.size())) {
|
||||
current = current.getMemberScope().getNamespace(name);
|
||||
if (current == null) return null;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getClassDescriptor(JetClassOrObject classOrObject) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ScopeProvider getScopeProvider() {
|
||||
return scopeProvider;
|
||||
}
|
||||
|
||||
public Collection<DeclarationDescriptor> getDescriptorsForDeclarations(Collection<PsiElement> declarationsOrFiles) {
|
||||
final List<DeclarationDescriptor> descriptors = Lists.newArrayList();
|
||||
for (PsiElement declarationOrFile : declarationsOrFiles) {
|
||||
declarationOrFile.accept(new JetVisitorVoid() {
|
||||
@Override
|
||||
public void visitJetFile(JetFile file) {
|
||||
JetNamespaceHeader header = file.getNamespaceHeader();
|
||||
if (header == null) {
|
||||
throw new UnsupportedOperationException("Lazy resolve is not supported for scripts");
|
||||
}
|
||||
NamespaceDescriptor packageDescriptor = getPackageDescriptorByFqName(new FqName(header.getQualifiedName()));
|
||||
if (packageDescriptor == null) {
|
||||
throw new IllegalStateException("Package descriptor not found for: " + header.getQualifiedName());
|
||||
}
|
||||
JetScope packageMemberScope = packageDescriptor.getMemberScope();
|
||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||
collectDescriptors(packageMemberScope, declaration);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDeclaration(JetDeclaration dcl) {
|
||||
JetScope scope = scopeProvider.getResolutionScopeForDeclaration(dcl);
|
||||
collectDescriptors(scope, dcl);
|
||||
}
|
||||
|
||||
private void collectDescriptors(JetScope outerScope, JetDeclaration declaration) {
|
||||
if (declaration instanceof JetClass) {
|
||||
JetClass jetClass = (JetClass) declaration;
|
||||
descriptors.add(outerScope.getClassifier(jetClass.getNameAsSafeName()));
|
||||
}
|
||||
else if (declaration instanceof JetFunction) {
|
||||
JetFunction jetFunction = (JetFunction) declaration;
|
||||
Set<FunctionDescriptor> functionDescriptors = outerScope.getFunctions(jetFunction.getNameAsSafeName());
|
||||
descriptors.addAll(functionDescriptors);
|
||||
}
|
||||
else if (declaration instanceof JetProperty) {
|
||||
JetProperty jetProperty = (JetProperty) declaration;
|
||||
Set<VariableDescriptor> functionDescriptors = outerScope.getProperties(jetProperty.getNameAsSafeName());
|
||||
descriptors.addAll(functionDescriptors);
|
||||
}
|
||||
else if (declaration instanceof JetObjectDeclaration) {
|
||||
JetObjectDeclaration jetObjectDeclaration = (JetObjectDeclaration) declaration;
|
||||
descriptors.addAll(outerScope.getProperties(jetObjectDeclaration.getNameAsSafeName()));
|
||||
descriptors.add(outerScope.getObjectDescriptor(jetObjectDeclaration.getNameAsSafeName()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public BindingContext getBindingContext() {
|
||||
return trace.getBindingContext();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
/*package*/ BindingTrace getTrace() {
|
||||
return trace;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DeclarationProviderFactory getDeclarationProviderFactory() {
|
||||
return declarationProviderFactory;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetScope getResolutionScope(PsiElement element) {
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof JetFile) {
|
||||
JetFile file = (JetFile) parent;
|
||||
return getScopeProvider().getFileScopeForDeclarationResolution(file);
|
||||
}
|
||||
|
||||
if (parent instanceof JetClassBody) {
|
||||
JetClassBody classBody = (JetClassBody) parent;
|
||||
JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(classBody, JetClassOrObject.class);
|
||||
ClassDescriptor classDescriptor = getClassDescriptor(classOrObject);
|
||||
assert classDescriptor instanceof LazyClassDescriptor : "Trying to resolve a member of a non-lazily loaded class: " + element;
|
||||
return ((LazyClassDescriptor) classDescriptor).getScopeForMemberDeclarationResolution();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unsupported PSI element: " + element);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetNamespaceHeader;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ScopeProvider {
|
||||
|
||||
private final ResolveSession resolveSession;
|
||||
|
||||
public ScopeProvider(@NotNull ResolveSession resolveSession) {
|
||||
this.resolveSession = resolveSession;
|
||||
}
|
||||
|
||||
// This scope does not contain imported functions
|
||||
@NotNull
|
||||
public JetScope getFileScopeForDeclarationResolution(JetFile file) {
|
||||
// package
|
||||
// + imported classes
|
||||
JetNamespaceHeader header = file.getNamespaceHeader();
|
||||
if (header == null) {
|
||||
throw new IllegalArgumentException("Scripts are not supported: " + file.getName());
|
||||
}
|
||||
|
||||
FqName fqName = new FqName(header.getQualifiedName());
|
||||
NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName(fqName);
|
||||
|
||||
if (packageDescriptor == null) {
|
||||
throw new IllegalStateException("Package not found: " + fqName + " maybe the file is not in scope of this resolve session: " + file.getName());
|
||||
}
|
||||
|
||||
WritableScope writableScope = new WritableScopeImpl(JetScope.EMPTY, packageDescriptor, RedeclarationHandler.DO_NOTHING);
|
||||
writableScope.importScope(packageDescriptor.getMemberScope());
|
||||
|
||||
writableScope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||
// TODO: Cache
|
||||
return writableScope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetScope getScopeForClassMemberResolution(@NotNull JetClassOrObject classOrObject) {
|
||||
// TODO: cache
|
||||
ClassDescriptor classDescriptor = resolveSession.getClassDescriptor(classOrObject);
|
||||
JetScope memberScope = classDescriptor.getDefaultType().getMemberScope();
|
||||
JetScope outerScope = getResolutionScopeForDeclaration((JetDeclaration) classOrObject);
|
||||
|
||||
WritableScope typeParametersScope = new WritableScopeImpl(JetScope.EMPTY, classDescriptor, RedeclarationHandler.DO_NOTHING);
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : classDescriptor.getTypeConstructor().getParameters()) {
|
||||
typeParametersScope.addClassifierDescriptor(typeParameterDescriptor);
|
||||
}
|
||||
|
||||
return new ChainedScope(classDescriptor, memberScope, typeParametersScope, outerScope);
|
||||
}
|
||||
|
||||
public JetScope getScopeForClassSupertypeResolution(JetClassOrObject declaration) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetScope getResolutionScopeForDeclaration(@NotNull JetDeclaration jetDeclaration) {
|
||||
PsiElement immediateParent = jetDeclaration.getParent();
|
||||
if (immediateParent instanceof JetFile) {
|
||||
return getFileScopeForDeclarationResolution((JetFile) immediateParent);
|
||||
}
|
||||
|
||||
JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(jetDeclaration, JetDeclaration.class);
|
||||
if (parentDeclaration instanceof JetClassOrObject) {
|
||||
JetClassOrObject classOrObject = (JetClassOrObject) parentDeclaration;
|
||||
return getScopeForClassMemberResolution(classOrObject);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Don't call this method for local declarations: " + jetDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassDescriptor buildLazyClassDescriptor(DeclarationDescriptor declaration, Name name, JetScope outerScope) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
public NamespaceDescriptor buildLazyPackageDescriptor(DeclarationDescriptor declaration,
|
||||
Name name) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
package org.jetbrains.jet.lang.resolve.lazy;/*
|
||||
* Copyright 2010-2012 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.
|
||||
*/
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class BasicLazyResolveTest {
|
||||
|
||||
private static final Name FOO = Name.identifier("foo");
|
||||
|
||||
private final Disposable rootDisposable = new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
};
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
Disposer.dispose(rootDisposable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
JetCoreEnvironment jetCoreEnvironment =
|
||||
new JetCoreEnvironment(rootDisposable, CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true));
|
||||
|
||||
ModuleDescriptor root = new ModuleDescriptor(Name.special("<root>"));
|
||||
|
||||
Project project = jetCoreEnvironment.getProject();
|
||||
final JetClass jetClass = JetPsiFactory.createClass(project, "package p; class C {fun f() {}}");
|
||||
final JetClass genericJetClass = JetPsiFactory.createClass(project, "package p; open class G<T> {fun f(): T {}}");
|
||||
final JetClass genericJetClass2 = JetPsiFactory.createClass(project, "package p; class G2<E> : G<E> {}");
|
||||
final JetNamedFunction fooFunction1 = JetPsiFactory.createFunction(project, "package p; fun foo() {}");
|
||||
final JetNamedFunction fooFunction2 = JetPsiFactory.createFunction(project, "package p; fun foo(a: C) {}");
|
||||
|
||||
ResolveSession session = new ResolveSession(project, root, new DeclarationProviderFactory() {
|
||||
@Override
|
||||
public DeclarationProvider getPackageMemberDeclarationProvider(@NotNull FqName packageFqName) {
|
||||
if (packageFqName.equals(FqName.ROOT)) {
|
||||
return new DeclarationProvider() {
|
||||
@Override
|
||||
public List<JetDeclaration> getAllDeclarations() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetNamedFunction> getFunctionDeclarations(@NotNull Name name) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetProperty> getPropertyDeclarations(@NotNull Name name) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetClassOrObject getClassOrObjectDeclaration(@NotNull Name name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackageDeclared(@NotNull Name name) {
|
||||
return name.equals(Name.identifier("p"));
|
||||
}
|
||||
};
|
||||
}
|
||||
if (!packageFqName.equals(FqName.topLevel(Name.identifier("p")))) return null;
|
||||
return new DeclarationProvider() {
|
||||
@Override
|
||||
public List<JetDeclaration> getAllDeclarations() {
|
||||
return Arrays.<JetDeclaration>asList(jetClass, genericJetClass, genericJetClass2, fooFunction1, fooFunction2);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetNamedFunction> getFunctionDeclarations(@NotNull Name name) {
|
||||
if (!FOO.equals(name)) return Collections.emptyList();
|
||||
return Arrays.asList(fooFunction1, fooFunction2);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetProperty> getPropertyDeclarations(@NotNull Name name) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetClassOrObject getClassOrObjectDeclaration(@NotNull Name name) {
|
||||
if (name.equals(Name.identifier("C"))) return jetClass;
|
||||
if (name.equals(Name.identifier("G"))) return genericJetClass;
|
||||
if (name.equals(Name.identifier("G2"))) return genericJetClass2;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackageDeclared(@NotNull Name name) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ClassMemberDeclarationProvider getClassMemberDeclarationProvider(@NotNull JetClassOrObject jetClassOrObject) {
|
||||
final JetClass jetClass = (JetClass) jetClassOrObject;
|
||||
return new ClassMemberDeclarationProvider() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JetClassOrObject getOwnerClassOrObject() {
|
||||
return jetClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JetDeclaration> getAllDeclarations() {
|
||||
return jetClass.getDeclarations();
|
||||
}
|
||||
|
||||
private <D, T> List<T> filter(List<D> list, Class<T> t) {
|
||||
//noinspection unchecked
|
||||
return (List) Lists.newArrayList(Collections2.filter(list, Predicates.instanceOf(t)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetNamedFunction> getFunctionDeclarations(@NotNull Name name) {
|
||||
return filter(jetClass.getDeclarations(), JetNamedFunction.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetProperty> getPropertyDeclarations(@NotNull Name name) {
|
||||
return filter(jetClass.getDeclarations(), JetProperty.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetClassOrObject getClassOrObjectDeclaration(@NotNull Name name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackageDeclared(@NotNull Name name) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
NamespaceDescriptor packageDescriptor = session.getPackageDescriptor(Name.identifier("p"));
|
||||
assertNotNull(packageDescriptor);
|
||||
assertEquals(Name.identifier("p"), packageDescriptor.getName());
|
||||
assertNull(packageDescriptor.getMemberScope().getNamespace(FOO));
|
||||
|
||||
ClassifierDescriptor classifier = packageDescriptor.getMemberScope().getClassifier(Name.identifier("C"));
|
||||
assertTrue(ClassDescriptor.class.isInstance(classifier));
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) classifier;
|
||||
assertNotNull(classifier);
|
||||
assertEquals(classifier.getContainingDeclaration(), packageDescriptor);
|
||||
assertEquals(Name.identifier("C"), classifier.getName());
|
||||
assertEquals(Visibilities.INTERNAL, classDescriptor.getVisibility());
|
||||
TypeConstructor typeConstructor = classifier.getTypeConstructor();
|
||||
assertTrue(typeConstructor.isSealed());
|
||||
assertTrue(typeConstructor.getParameters().isEmpty());
|
||||
assertEquals("[Any]", typeConstructor.getSupertypes().toString());
|
||||
|
||||
List<FunctionDescriptor> fooFunctions = Lists.newArrayList(packageDescriptor.getMemberScope().getFunctions(FOO));
|
||||
assertEquals(2, fooFunctions.size());
|
||||
FunctionDescriptor foo1 = fooFunctions.get(0);
|
||||
assertEquals(FOO, foo1.getName());
|
||||
assertEquals(0, foo1.getValueParameters().size());
|
||||
assertEquals(packageDescriptor, foo1.getContainingDeclaration());
|
||||
|
||||
FunctionDescriptor foo2 = fooFunctions.get(1);
|
||||
assertEquals(FOO, foo2.getName());
|
||||
assertEquals(1, foo2.getValueParameters().size());
|
||||
assertEquals(classDescriptor, foo2.getValueParameters().get(0).getType().getConstructor().getDeclarationDescriptor());
|
||||
assertEquals(packageDescriptor, foo2.getContainingDeclaration());
|
||||
|
||||
ClassifierDescriptor genericClassifier2 = packageDescriptor.getMemberScope().getClassifier(Name.identifier("G2"));
|
||||
assertNotNull(genericClassifier2);
|
||||
assertEquals(1, genericClassifier2.getTypeConstructor().getSupertypes().size());
|
||||
assertEquals("G<E>", genericClassifier2.getTypeConstructor().getSupertypes().iterator().next().toString());
|
||||
|
||||
ClassifierDescriptor genericClassifier = packageDescriptor.getMemberScope().getClassifier(Name.identifier("G"));
|
||||
assertNotNull(genericClassifier);
|
||||
assertEquals(1, genericClassifier.getTypeConstructor().getParameters().size());
|
||||
TypeParameterDescriptor typeParameterDescriptor_T = genericClassifier.getTypeConstructor().getParameters().get(0);
|
||||
assertEquals(JetStandardClasses.getNullableAnyType(),
|
||||
typeParameterDescriptor_T.getUpperBoundsAsType());
|
||||
assertEquals("G<T>", genericClassifier.getDefaultType().toString());
|
||||
assertEquals(typeParameterDescriptor_T.getDefaultType(), genericClassifier.getDefaultType().getMemberScope().getFunctions(Name.identifier("f")).iterator().next().getReturnType());
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,7 @@
|
||||
package org.jetbrains.jet.di;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderFactory;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderMode;
|
||||
import org.jetbrains.jet.codegen.ClassCodegen;
|
||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||
import org.jetbrains.jet.codegen.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.ScriptCodegen;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.jet.lang.ModuleConfiguration;
|
||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
||||
@@ -31,7 +25,6 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.*;
|
||||
import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver;
|
||||
import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolverDummyImpl;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
@@ -54,6 +47,16 @@ public class AllInjectorsGenerator {
|
||||
generateInjectorForJavaSemanticServices();
|
||||
generateInjectorForJvmCodegen();
|
||||
generateInjectorForJetTypeMapper();
|
||||
generateInjectorForLazyResolve();
|
||||
}
|
||||
|
||||
private static void generateInjectorForLazyResolve() throws IOException {
|
||||
DependencyInjectorGenerator generator = new DependencyInjectorGenerator(false);
|
||||
generator.addParameter(Project.class);
|
||||
generator.addPublicField(DescriptorResolver.class);
|
||||
generator.addPublicField(ExpressionTypingServices.class);
|
||||
generator.addPublicField(TypeResolver.class);
|
||||
generator.generate("compiler/frontend/src", "org.jetbrains.jet.di", "InjectorForLazyResolve");
|
||||
}
|
||||
|
||||
private static void generateInjectorForTopDownAnalyzerBasic() throws IOException {
|
||||
|
||||
Reference in New Issue
Block a user