001 /* 002 * Copyright 2010-2013 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.jet.lang.resolve.java; 018 019 import com.intellij.openapi.project.Project; 020 import com.intellij.openapi.util.Comparing; 021 import com.intellij.openapi.vfs.VirtualFile; 022 import com.intellij.psi.PsiClass; 023 import com.intellij.psi.PsiPackage; 024 import com.intellij.psi.search.DelegatingGlobalSearchScope; 025 import com.intellij.psi.search.GlobalSearchScope; 026 import org.jetbrains.annotations.NotNull; 027 import org.jetbrains.annotations.Nullable; 028 import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker; 029 import org.jetbrains.jet.lang.resolve.name.FqName; 030 import org.jetbrains.jet.plugin.JetFileType; 031 032 import javax.annotation.PostConstruct; 033 import javax.inject.Inject; 034 035 public class PsiClassFinderImpl implements PsiClassFinder { 036 @NotNull 037 private Project project; 038 039 private GlobalSearchScope javaSearchScope; 040 private JavaPsiFacadeKotlinHacks javaFacade; 041 042 @Inject 043 public void setProject(@NotNull Project project) { 044 this.project = project; 045 } 046 047 @PostConstruct 048 public void initialize() { 049 javaSearchScope = new DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) { 050 @Override 051 public boolean contains(VirtualFile file) { 052 return myBaseScope.contains(file) && file.getFileType() != JetFileType.INSTANCE; 053 } 054 055 @Override 056 public int compare(VirtualFile file1, VirtualFile file2) { 057 // TODO: this is a hackish workaround for the following problem: 058 // since we are working with the allScope(), if the same class FqName 059 // to be on the class path twice, because it is included into different libraries 060 // (e.g. junit-4.0.jar is used as a separate library and as a part of idea_full) 061 // the two libraries are attached to different modules, the parent compare() 062 // can't tell which one comes first, so they can come in random order 063 // To fix this, we sort additionally by the full path, to make the ordering deterministic 064 // TODO: Delete this hack when proper scopes are used 065 int compare = super.compare(file1, file2); 066 if (compare == 0) { 067 return Comparing.compare(file1.getPath(), file2.getPath()); 068 } 069 return compare; 070 } 071 }; 072 javaFacade = new JavaPsiFacadeKotlinHacks(project); 073 } 074 075 @Override 076 @Nullable 077 public PsiClass findPsiClass(@NotNull FqName qualifiedName) { 078 PsiClass original = javaFacade.findClass(qualifiedName.asString(), javaSearchScope); 079 080 if (original != null) { 081 String classQualifiedName = original.getQualifiedName(); 082 FqName actualQualifiedName = classQualifiedName != null ? new FqName(classQualifiedName) : null; 083 if (!qualifiedName.equals(actualQualifiedName)) { 084 throw new IllegalStateException("requested " + qualifiedName + ", got " + actualQualifiedName); 085 } 086 } 087 088 if (original instanceof JetJavaMirrorMarker) { 089 throw new IllegalStateException("JetJavaMirrorMaker is not possible in resolve.java, resolving: " + qualifiedName); 090 } 091 092 return original; 093 } 094 095 @Override 096 @Nullable 097 public PsiPackage findPsiPackage(@NotNull FqName qualifiedName) { 098 return javaFacade.findPackage(qualifiedName.asString()); 099 } 100 }