001 /*
002 * Copyright 2010-2016 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.asJava.classes;
018
019 import com.intellij.lang.Language;
020 import com.intellij.psi.PsiClass;
021 import com.intellij.psi.PsiElement;
022 import com.intellij.psi.PsiFile;
023 import com.intellij.psi.impl.light.AbstractLightClass;
024 import org.jetbrains.annotations.NotNull;
025 import org.jetbrains.annotations.Nullable;
026 import org.jetbrains.kotlin.asJava.finder.JavaElementFinder;
027 import org.jetbrains.kotlin.idea.KotlinLanguage;
028 import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind;
029 import org.jetbrains.kotlin.psi.KtClassOrObject;
030 import org.jetbrains.kotlin.psi.KtFile;
031
032 /**
033 * This class serves as a workaround for usages of {@link JavaElementFinder#findClasses} which eventually only need names of files
034 * containing the class. When queried for a package class (e.g. test/TestPackage), {@code findClasses} along with a
035 * {@link KtLightClassForFacade} would also return multiple instances of this class for each file present in the package. The client
036 * code can make use of every file in the package then, since {@code getContainingFile} of these instances will represent the whole package.
037 * <p/>
038 * See {@link LineBreakpoint#findClassCandidatesInSourceContent} for the primary usage this was introduced
039 */
040 public class FakeLightClassForFileOfPackage extends AbstractLightClass implements KtLightClass {
041 private final KtLightClassForFacade delegate;
042 private final KtFile file;
043
044 public FakeLightClassForFileOfPackage(@NotNull KtLightClassForFacade delegate, @NotNull KtFile file) {
045 super(delegate.getManager());
046 this.delegate = delegate;
047 this.file = file;
048 }
049
050 @NotNull
051 @Override
052 public PsiClass getClsDelegate() {
053 return delegate;
054 }
055
056 @Nullable
057 @Override
058 public KtClassOrObject getKotlinOrigin() {
059 return null;
060 }
061
062 @Override
063 public PsiFile getContainingFile() {
064 return file;
065 }
066
067 @Override
068 public boolean isValid() {
069 // This is intentionally false to prevent using this as a real class
070 return false;
071 }
072
073 @NotNull
074 @Override
075 public PsiClass getDelegate() {
076 return delegate;
077 }
078
079 @NotNull
080 @Override
081 public PsiElement copy() {
082 return new FakeLightClassForFileOfPackage(delegate, file);
083 }
084
085 @Override
086 public String getText() {
087 return null;
088 }
089
090 @NotNull
091 @Override
092 public Language getLanguage() {
093 return KotlinLanguage.INSTANCE;
094 }
095
096 @Override
097 public boolean equals(Object obj) {
098 if (!(obj instanceof FakeLightClassForFileOfPackage)) return false;
099
100 FakeLightClassForFileOfPackage other = (FakeLightClassForFileOfPackage) obj;
101 return file == other.file && delegate.equals(other.delegate);
102 }
103
104 @Override
105 public int hashCode() {
106 return file.hashCode() * 31 + delegate.hashCode();
107 }
108
109 @NotNull
110 @Override
111 public LightClassOriginKind getOriginKind() {
112 return LightClassOriginKind.SOURCE;
113 }
114 }