提交 55040150 编写于 作者: A Andrey Breslav

Preliminary version of lazy resolve

The implementation is incomplete and thus not used anywhere other than the test
上级 7c0b8876
/*
* 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;
}
}
/*
* 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);
}
}
}
/*
* 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();
}
/*
* 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);
}
/*
* 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);
}
/*
* 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();
}
}
/*
* 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();
}
}
}
/*
* 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
}
}
/*
* 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;
}
}
/*
* 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
}
}
/*
* 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
}
}
package org.jetbrains.jet.lang.resolve.lazy;
/**
* @author abreslav
*/
public class LazyResolveINjectorGenerator {
}
/*
* 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();
}
}
/*
* 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);
}
}
/*
* 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
}
}
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());
}
}
\ No newline at end of file
......@@ -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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册