KT-689 Allow to put Java and Kotlin files in the same packages

This commit is contained in:
Andrey Breslav
2011-12-06 14:43:10 +04:00
parent 47050a11d1
commit deb8d5ea20
27 changed files with 219 additions and 171 deletions
@@ -1,7 +1,9 @@
package org.jetbrains.jet.lang.resolve.java;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.CachedValue;
@@ -20,8 +22,10 @@ import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author abreslav
@@ -34,22 +38,11 @@ public class AnalyzerFacade {
return Collections.<JetDeclaration>singleton(file.getRootNamespace());
}
};
private static final AnalyzingUtils ANALYZING_UTILS = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS);
private final static Key<CachedValue<BindingContext>> BINDING_CONTEXT = Key.create("BINDING_CONTEXT");
private static final Object lock = new Object();
public static BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
return ANALYZING_UTILS.analyzeNamespace(namespace, flowDataTraceFactory);
}
public static BindingContext analyzeFileWithCache(@NotNull final JetFile file, @NotNull final Function<JetFile, Collection<JetDeclaration>> declarationProvider) {
return analyzeFileWithCache(ANALYZING_UTILS, file, declarationProvider);
}
public static BindingContext analyzeFileWithCache(@NotNull final AnalyzingUtils analyzingUtils,
@NotNull final JetFile file,
@NotNull final Function<JetFile, Collection<JetDeclaration>> declarationProvider) {
// TODO : Synchronization?
CachedValue<BindingContext> bindingContextCachedValue = file.getUserData(BINDING_CONTEXT);
if (bindingContextCachedValue == null) {
@@ -58,11 +51,7 @@ public class AnalyzerFacade {
public Result<BindingContext> compute() {
synchronized (lock) {
try {
BindingContext bindingContext = analyzingUtils.analyzeNamespaces(
file.getProject(),
declarationProvider.fun(file),
Predicates.<PsiFile>equalTo(file),
JetControlFlowDataTraceFactory.EMPTY);
BindingContext bindingContext = analyzeNamespacesWithJavaIntegration(file.getProject(), declarationProvider.fun(file), Predicates.<PsiFile>equalTo(file), JetControlFlowDataTraceFactory.EMPTY);
return new Result<BindingContext>(bindingContext, PsiModificationTracker.MODIFICATION_COUNT);
}
catch (ProcessCanceledException e) {
@@ -84,4 +73,39 @@ public class AnalyzerFacade {
}
return bindingContextCachedValue.getValue();
}
public static BindingContext analyzeOneNamespaceWithJavaIntegration(JetNamespace namespace, JetControlFlowDataTraceFactory flowDataTraceFactory) {
return analyzeNamespacesWithJavaIntegration(namespace.getProject(), Collections.singleton(namespace), Predicates.<PsiFile>alwaysTrue(), flowDataTraceFactory);
}
public static BindingContext analyzeNamespacesWithJavaIntegration(Project project, Collection<? extends JetDeclaration> declarations, Predicate<PsiFile> filesToAnalyzeCompletely, JetControlFlowDataTraceFactory flowDataTraceFactory) {
BindingTraceContext bindingTraceContext = new BindingTraceContext();
return AnalyzingUtils.getInstance().analyzeNamespacesWithGivenTrace(
project,
JavaBridgeConfiguration.createJavaBridgeConfiguration(project, bindingTraceContext),
declarations,
filesToAnalyzeCompletely,
flowDataTraceFactory, bindingTraceContext);
}
public static BindingContext shallowAnalyzeFiles(Collection<PsiFile> files) {
assert files.size() > 0;
Project project = files.iterator().next().getProject();
Collection<JetNamespace> namespaces = collectRootNamespaces(files);
return analyzeNamespacesWithJavaIntegration(project, namespaces, Predicates.<PsiFile>alwaysFalse(), JetControlFlowDataTraceFactory.EMPTY);
}
public static List<JetNamespace> collectRootNamespaces(Collection<PsiFile> files) {
List<JetNamespace> namespaces = new ArrayList<JetNamespace>();
for (PsiFile file : files) {
if (file instanceof JetFile) {
namespaces.add(((JetFile) file).getRootNamespace());
}
}
return namespaces;
}
}
@@ -0,0 +1,37 @@
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.Configuration;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
/**
* @author abreslav
*/
public class JavaBridgeConfiguration implements Configuration {
public static Configuration createJavaBridgeConfiguration(@NotNull Project project, @NotNull BindingTrace trace) {
return new JavaBridgeConfiguration(project, trace);
}
private final JavaSemanticServices javaSemanticServices;
private JavaBridgeConfiguration(Project project, BindingTrace trace) {
this.javaSemanticServices = new JavaSemanticServices(project, JetSemanticServices.createSemanticServices(project), trace);
}
@Override
public void addDefaultImports(BindingTrace trace, WritableScope rootScope) {
rootScope.importScope(new JavaPackageScope("", null, javaSemanticServices));
rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
}
@Override
public void extendNamespaceScope(BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) {
namespaceMemberScope.importScope(new JavaPackageScope(DescriptorUtils.getFQName(namespaceDescriptor), namespaceDescriptor, javaSemanticServices));
}
}
@@ -1,24 +0,0 @@
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.ImportingStrategy;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
/**
* @author abreslav
*/
public class JavaDefaultImports {
public static final ImportingStrategy JAVA_DEFAULT_IMPORTS = new ImportingStrategy() {
@Override
public void addImports(Project project, JetSemanticServices semanticServices, BindingTrace trace, WritableScope rootScope) {
JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, semanticServices, trace);
rootScope.importScope(new JavaPackageScope("", null, javaSemanticServices));
rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
}
};
private JavaDefaultImports() {
}
}
@@ -13,7 +13,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.plugin.JetFileType;
@@ -53,7 +52,7 @@ public class JavaDescriptorResolver {
}
};
protected final Map<String, ClassDescriptor> classDescriptorCache = new HashMap<String, ClassDescriptor>();
protected final Map<String, ClassDescriptor> classDescriptorCache = Maps.newHashMap();
protected final Map<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap();
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
@@ -122,7 +121,7 @@ public class JavaDescriptorResolver {
psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
!psiClass.hasModifierProperty(PsiModifier.FINAL))
);
classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), psiClass));
classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass));
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
@@ -163,7 +162,7 @@ public class JavaDescriptorResolver {
Collections.<AnnotationDescriptor>emptyList(), // TODO
false);
constructorDescriptor.initialize(typeParameters, resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()), Modality.FINAL,
resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), constructor));
resolveVisibilityFromPsiModifiers(constructor));
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
classDescriptor.addConstructor(constructorDescriptor);
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, constructor, constructorDescriptor);
@@ -368,7 +367,7 @@ public class JavaDescriptorResolver {
containingDeclaration,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), field),
resolveVisibilityFromPsiModifiers(field),
!isFinal,
null,
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
@@ -454,7 +453,7 @@ public class JavaDescriptorResolver {
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters),
semanticServices.getTypeTransformer().transformToType(returnType),
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)),
resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), method)
resolveVisibilityFromPsiModifiers(method)
);
semanticServices.getTrace().record(BindingContext.FUNCTION, method, functionDescriptorImpl);
FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl;
@@ -464,7 +463,7 @@ public class JavaDescriptorResolver {
return substitutedFunctionDescriptor;
}
private static Visibility resolveVisibilityFromPsiModifiers(BindingTrace trace, PsiModifierListOwner modifierListOwner) {
private static Visibility resolveVisibilityFromPsiModifiers(PsiModifierListOwner modifierListOwner) {
//TODO report error
return modifierListOwner.hasModifierProperty(PsiModifier.PUBLIC) ? Visibility.PUBLIC :
(modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE) ? Visibility.PRIVATE :