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.navigation.ItemPresentation; 021 import com.intellij.navigation.ItemPresentationProviders; 022 import com.intellij.psi.*; 023 import com.intellij.psi.impl.PsiClassImplUtil; 024 import com.intellij.psi.impl.light.AbstractLightClass; 025 import com.intellij.psi.impl.source.ClassInnerStuffCache; 026 import com.intellij.psi.impl.source.PsiExtensibleClass; 027 import com.intellij.psi.scope.PsiScopeProcessor; 028 import com.intellij.psi.util.PsiTreeUtil; 029 import com.intellij.util.Function; 030 import com.intellij.util.containers.ContainerUtil; 031 import kotlin.collections.ArraysKt; 032 import kotlin.jvm.functions.Function1; 033 import org.jetbrains.annotations.NotNull; 034 import org.jetbrains.annotations.Nullable; 035 import org.jetbrains.kotlin.idea.KotlinLanguage; 036 import org.jetbrains.kotlin.psi.KtClassOrObject; 037 import org.jetbrains.kotlin.psi.KtDeclaration; 038 import org.jetbrains.kotlin.psi.KtProperty; 039 import org.jetbrains.kotlin.psi.KtPropertyAccessor; 040 041 import java.util.List; 042 043 public abstract class KtWrappingLightClass extends AbstractLightClass implements KtLightClass, PsiExtensibleClass { 044 private final ClassInnerStuffCache myInnersCache = new ClassInnerStuffCache(this); 045 046 protected KtWrappingLightClass(PsiManager manager) { 047 super(manager, KotlinLanguage.INSTANCE); 048 } 049 050 @Nullable 051 @Override 052 public abstract KtClassOrObject getOrigin(); 053 054 @NotNull 055 @Override 056 public abstract PsiClass getDelegate(); 057 058 @Override 059 @NotNull 060 public PsiField[] getFields() { 061 return myInnersCache.getFields(); 062 } 063 064 @Override 065 @NotNull 066 public PsiMethod[] getMethods() { 067 return myInnersCache.getMethods(); 068 } 069 070 @Override 071 @NotNull 072 public PsiMethod[] getConstructors() { 073 return myInnersCache.getConstructors(); 074 } 075 076 @Override 077 @NotNull 078 public PsiClass[] getInnerClasses() { 079 return myInnersCache.getInnerClasses(); 080 } 081 082 @Override 083 @NotNull 084 public PsiField[] getAllFields() { 085 return PsiClassImplUtil.getAllFields(this); 086 } 087 088 @Override 089 @NotNull 090 public PsiMethod[] getAllMethods() { 091 return PsiClassImplUtil.getAllMethods(this); 092 } 093 094 @Override 095 @NotNull 096 public PsiClass[] getAllInnerClasses() { 097 return PsiClassImplUtil.getAllInnerClasses(this); 098 } 099 100 @Override 101 public PsiField findFieldByName(String name, boolean checkBases) { 102 return myInnersCache.findFieldByName(name, checkBases); 103 } 104 105 @Override 106 @NotNull 107 public PsiMethod[] findMethodsByName(String name, boolean checkBases) { 108 return myInnersCache.findMethodsByName(name, checkBases); 109 } 110 111 @Override 112 public PsiClass findInnerClassByName(String name, boolean checkBases) { 113 return myInnersCache.findInnerClassByName(name, checkBases); 114 } 115 116 /** 117 * @see org.jetbrains.kotlin.codegen.binding.CodegenBinding#ENUM_ENTRY_CLASS_NEED_SUBCLASS 118 */ 119 @NotNull 120 @Override 121 public List<PsiField> getOwnFields() { 122 return ContainerUtil.map(getDelegate().getFields(), new Function<PsiField, PsiField>() { 123 @Override 124 public PsiField fun(PsiField field) { 125 LightMemberOrigin origin = ClsWrapperStubPsiFactory.getMemberOrigin(field); 126 return KtLightFieldImpl.Factory.create(origin != null ? origin.getOriginalElement() : null, field, KtWrappingLightClass.this); 127 } 128 }); 129 } 130 131 @NotNull 132 @Override 133 public List<PsiMethod> getOwnMethods() { 134 return ArraysKt.map(getDelegate().getMethods(), new Function1<PsiMethod, PsiMethod>() { 135 @Override 136 public PsiMethod invoke(PsiMethod method) { 137 LightMemberOrigin origin = ClsWrapperStubPsiFactory.getMemberOrigin(method); 138 KtDeclaration originalElement = origin != null ? origin.getOriginalElement() : null; 139 if (originalElement instanceof KtPropertyAccessor) { 140 //noinspection ConstantConditions 141 origin = origin.copy(PsiTreeUtil.getParentOfType(originalElement, KtProperty.class), origin.getOriginKind()); 142 } 143 144 return KtLightMethodImpl.Factory.create(method, origin, KtWrappingLightClass.this); 145 } 146 }); 147 } 148 149 @Override 150 public boolean processDeclarations( 151 @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place 152 ) { 153 if (isEnum()) { 154 if (!PsiClassImplUtil.processDeclarationsInEnum(processor, state, myInnersCache)) return false; 155 } 156 157 return super.processDeclarations(processor, state, lastParent, place); 158 } 159 160 @Override 161 public String getText() { 162 KtClassOrObject origin = getOrigin(); 163 return origin == null ? "" : origin.getText(); 164 } 165 166 @NotNull 167 @Override 168 public Language getLanguage() { 169 return KotlinLanguage.INSTANCE; 170 } 171 172 @Override 173 public ItemPresentation getPresentation() { 174 return ItemPresentationProviders.getItemPresentation(this); 175 } 176 177 @Override 178 public abstract boolean equals(Object obj); 179 180 @Override 181 public abstract int hashCode(); 182 183 @Override 184 public PsiElement getContext() { 185 return getParent(); 186 } 187 }