001 /* 002 * Copyright 2010-2015 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.jetbrains.kotlin.load.java; 018 019 import com.intellij.openapi.project.Project; 020 import com.intellij.openapi.vfs.VirtualFile; 021 import com.intellij.psi.PsiClass; 022 import com.intellij.psi.PsiPackage; 023 import com.intellij.psi.search.DelegatingGlobalSearchScope; 024 import com.intellij.psi.search.GlobalSearchScope; 025 import org.jetbrains.annotations.NotNull; 026 import org.jetbrains.annotations.Nullable; 027 import org.jetbrains.kotlin.asJava.KtJavaMirrorMarker; 028 import org.jetbrains.kotlin.idea.KotlinFileType; 029 import org.jetbrains.kotlin.load.java.structure.JavaClass; 030 import org.jetbrains.kotlin.load.java.structure.JavaPackage; 031 import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl; 032 import org.jetbrains.kotlin.load.java.structure.impl.JavaPackageImpl; 033 import org.jetbrains.kotlin.name.ClassId; 034 import org.jetbrains.kotlin.name.FqName; 035 import org.jetbrains.kotlin.resolve.jvm.JavaClassFinderPostConstruct; 036 import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade; 037 038 import javax.annotation.PostConstruct; 039 import javax.inject.Inject; 040 import java.util.Set; 041 042 public class JavaClassFinderImpl implements JavaClassFinder { 043 private Project project; 044 private GlobalSearchScope baseScope; 045 046 private GlobalSearchScope javaSearchScope; 047 private KotlinJavaPsiFacade javaFacade; 048 049 @Inject 050 public void setProject(@NotNull Project project) { 051 this.project = project; 052 } 053 054 @Inject 055 public void setScope(@NotNull GlobalSearchScope scope) { 056 this.baseScope = scope; 057 } 058 059 @Inject 060 public void setComponentPostConstruct(@NotNull JavaClassFinderPostConstruct finderPostConstruct) { 061 // Only activate post create 062 } 063 064 @PostConstruct 065 public void initialize() { 066 javaSearchScope = new DelegatingGlobalSearchScope(baseScope) { 067 @Override 068 public boolean contains(@NotNull VirtualFile file) { 069 return myBaseScope.contains(file) && (file.isDirectory() || file.getFileType() != KotlinFileType.INSTANCE); 070 } 071 072 //NOTE: expected by class finder to be not null 073 @NotNull 074 @Override 075 public Project getProject() { 076 return project; 077 } 078 079 @Override 080 public String toString() { 081 return "JCFI: " + baseScope; 082 } 083 }; 084 085 javaFacade = KotlinJavaPsiFacade.getInstance(project); 086 } 087 088 @Nullable 089 @Override 090 public JavaClass findClass(@NotNull ClassId classId) { 091 PsiClass psiClass = javaFacade.findClass(classId, javaSearchScope); 092 if (psiClass == null) return null; 093 094 JavaClassImpl javaClass = new JavaClassImpl(psiClass); 095 FqName fqName = classId.asSingleFqName(); 096 if (!fqName.equals(javaClass.getFqName())) { 097 throw new IllegalStateException("Requested " + fqName + ", got " + javaClass.getFqName()); 098 } 099 100 if (psiClass instanceof KtJavaMirrorMarker) { 101 throw new IllegalStateException("Kotlin light classes should not be found by JavaPsiFacade, resolving: " + fqName); 102 } 103 104 return javaClass; 105 } 106 107 @Nullable 108 @Override 109 public JavaPackage findPackage(@NotNull FqName fqName) { 110 PsiPackage psiPackage = javaFacade.findPackage(fqName.asString(), javaSearchScope); 111 return psiPackage == null ? null : new JavaPackageImpl(psiPackage, javaSearchScope); 112 } 113 114 @Nullable 115 @Override 116 public Set<String> knownClassNamesInPackage(@NotNull FqName packageFqName) { 117 return javaFacade.knownClassNamesInPackage(packageFqName); 118 } 119 }