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.idea.JetFileType; 028 import org.jetbrains.kotlin.load.java.structure.JavaClass; 029 import org.jetbrains.kotlin.load.java.structure.JavaPackage; 030 import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl; 031 import org.jetbrains.kotlin.load.java.structure.impl.JavaPackageImpl; 032 import org.jetbrains.kotlin.name.ClassId; 033 import org.jetbrains.kotlin.name.FqName; 034 import org.jetbrains.kotlin.name.FqNameUnsafe; 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 041 public class JavaClassFinderImpl implements JavaClassFinder { 042 private Project project; 043 private GlobalSearchScope baseScope; 044 045 private GlobalSearchScope javaSearchScope; 046 private KotlinJavaPsiFacade javaFacade; 047 048 @Inject 049 public void setProject(@NotNull Project project) { 050 this.project = project; 051 } 052 053 @Inject 054 public void setScope(@NotNull GlobalSearchScope scope) { 055 this.baseScope = scope; 056 } 057 058 @Inject 059 public void setComponentPostConstruct(@NotNull JavaClassFinderPostConstruct finderPostConstruct) { 060 // Only activate post create 061 } 062 063 @PostConstruct 064 public void initialize() { 065 javaSearchScope = new DelegatingGlobalSearchScope(baseScope) { 066 @Override 067 public boolean contains(@NotNull VirtualFile file) { 068 return myBaseScope.contains(file) && (file.isDirectory() || file.getFileType() != JetFileType.INSTANCE); 069 } 070 071 //NOTE: expected by class finder to be not null 072 @NotNull 073 @Override 074 public Project getProject() { 075 return project; 076 } 077 078 @Override 079 public String toString() { 080 return "JCFI: " + baseScope; 081 } 082 }; 083 084 javaFacade = KotlinJavaPsiFacade.getInstance(project); 085 } 086 087 @Nullable 088 @Override 089 public JavaClass findClass(@NotNull ClassId classId) { 090 FqNameUnsafe fqName = classId.asSingleFqName(); 091 092 PsiClass psiClass = javaFacade.findClass(fqName.asString(), javaSearchScope); 093 if (psiClass == null) return null; 094 095 JavaClassImpl javaClass = new JavaClassImpl(psiClass); 096 097 if (!fqName.equalsTo(javaClass.getFqName())) { 098 throw new IllegalStateException("Requested " + fqName + ", got " + javaClass.getFqName()); 099 } 100 101 if (javaClass.getOriginKind() == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) { 102 throw new IllegalStateException("Kotlin light classes should not be found by JavaPsiFacade, resolving: " + fqName); 103 } 104 105 return javaClass; 106 } 107 108 @Nullable 109 @Override 110 public JavaPackage findPackage(@NotNull FqName fqName) { 111 PsiPackage psiPackage = javaFacade.findPackage(fqName.asString(), javaSearchScope); 112 return psiPackage == null ? null : new JavaPackageImpl(psiPackage, javaSearchScope); 113 } 114 }