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.asJava;
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.PsiManager;
024    import com.intellij.psi.impl.light.AbstractLightClass;
025    import org.jetbrains.annotations.NotNull;
026    import org.jetbrains.annotations.Nullable;
027    import org.jetbrains.kotlin.idea.JetLanguage;
028    import org.jetbrains.kotlin.name.FqName;
029    import org.jetbrains.kotlin.psi.JetClassOrObject;
030    import org.jetbrains.kotlin.psi.JetFile;
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 KotlinLightClassForFacade} 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 KotlinLightClass, JetJavaMirrorMarker {
041        private final KotlinLightClassForFacade delegate;
042        private final JetFile file;
043    
044        public FakeLightClassForFileOfPackage(
045                @NotNull PsiManager manager, @NotNull KotlinLightClassForFacade delegate, @NotNull JetFile file
046        ) {
047            super(manager);
048            this.delegate = delegate;
049            this.file = file;
050        }
051    
052        @Nullable
053        @Override
054        public JetClassOrObject getOrigin() {
055            return null;
056        }
057    
058        @Override
059        public PsiFile getContainingFile() {
060            return file;
061        }
062    
063        @Override
064        public boolean isValid() {
065            // This is intentionally false to prevent using this as a real class
066            return false;
067        }
068    
069    
070        @NotNull
071        @Override
072        public FqName getFqName() {
073            return delegate.getFqName();
074        }
075    
076        @NotNull
077        @Override
078        public PsiClass getDelegate() {
079            return delegate;
080        }
081    
082        @NotNull
083        @Override
084        public PsiElement copy() {
085            return new FakeLightClassForFileOfPackage(getManager(), delegate, file);
086        }
087    
088        @Override
089        public String getText() {
090            return null;
091        }
092    
093        @NotNull
094        @Override
095        public Language getLanguage() {
096            return JetLanguage.INSTANCE;
097        }
098    
099        @Override
100        public boolean equals(Object obj) {
101            if (!(obj instanceof FakeLightClassForFileOfPackage)) return false;
102    
103            FakeLightClassForFileOfPackage other = (FakeLightClassForFileOfPackage) obj;
104            return file == other.file && delegate.equals(other.delegate);
105        }
106    
107        @Override
108        public int hashCode() {
109            return file.hashCode() * 31 + delegate.hashCode();
110        }
111    }