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.psi.stubs.elements;
018    
019    import com.intellij.lang.ASTNode;
020    import com.intellij.psi.stubs.IndexSink;
021    import com.intellij.psi.stubs.StubElement;
022    import com.intellij.psi.stubs.StubInputStream;
023    import com.intellij.psi.stubs.StubOutputStream;
024    import com.intellij.util.io.StringRef;
025    import org.jetbrains.annotations.NonNls;
026    import org.jetbrains.annotations.NotNull;
027    import org.jetbrains.kotlin.name.FqName;
028    import org.jetbrains.kotlin.psi.KtClass;
029    import org.jetbrains.kotlin.psi.KtEnumEntry;
030    import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
031    import org.jetbrains.kotlin.psi.stubs.KotlinClassStub;
032    import org.jetbrains.kotlin.psi.stubs.impl.KotlinClassStubImpl;
033    import org.jetbrains.kotlin.psi.stubs.impl.Utils;
034    import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils;
035    
036    import java.io.IOException;
037    import java.util.List;
038    
039    public class KtClassElementType extends KtStubElementType<KotlinClassStub, KtClass> {
040        public KtClassElementType(@NotNull @NonNls String debugName) {
041            super(debugName, KtClass.class, KotlinClassStub.class);
042        }
043    
044        @NotNull
045        @Override
046        public KtClass createPsi(@NotNull KotlinClassStub stub) {
047            return !stub.isEnumEntry() ? new KtClass(stub) : new KtEnumEntry(stub);
048        }
049    
050        @NotNull
051        @Override
052        public KtClass createPsiFromAst(@NotNull ASTNode node) {
053            return node.getElementType() != KtStubElementTypes.ENUM_ENTRY ? new KtClass(node) : new KtEnumEntry(node);
054        }
055    
056        @Override
057        public KotlinClassStub createStub(@NotNull KtClass psi, StubElement parentStub) {
058            FqName fqName = ResolveSessionUtils.safeFqNameForLazyResolve(psi);
059            boolean isEnumEntry = psi instanceof KtEnumEntry;
060            List<String> superNames = KtPsiUtilKt.getSuperNames(psi);
061            return new KotlinClassStubImpl(
062                    getStubType(isEnumEntry), parentStub, StringRef.fromString(fqName != null ? fqName.asString() : null),
063                    StringRef.fromString(psi.getName()), Utils.INSTANCE.wrapStrings(superNames), psi.isInterface(), isEnumEntry,
064                    psi.isLocal(), psi.isTopLevel());
065        }
066    
067        @Override
068        public void serialize(@NotNull KotlinClassStub stub, @NotNull StubOutputStream dataStream) throws IOException {
069            dataStream.writeName(stub.getName());
070            FqName fqName = stub.getFqName();
071            dataStream.writeName(fqName == null ? null : fqName.asString());
072            dataStream.writeBoolean(stub.isInterface());
073            dataStream.writeBoolean(stub.isEnumEntry());
074            dataStream.writeBoolean(stub.isLocal());
075            dataStream.writeBoolean(stub.isTopLevel());
076    
077            List<String> superNames = stub.getSuperNames();
078            dataStream.writeVarInt(superNames.size());
079            for (String name : superNames) {
080                dataStream.writeName(name);
081            }
082        }
083    
084        @NotNull
085        @Override
086        public KotlinClassStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
087            StringRef name = dataStream.readName();
088            StringRef qualifiedName = dataStream.readName();
089            boolean isTrait = dataStream.readBoolean();
090            boolean isEnumEntry = dataStream.readBoolean();
091            boolean isLocal = dataStream.readBoolean();
092            boolean isTopLevel = dataStream.readBoolean();
093    
094            int superCount = dataStream.readVarInt();
095            StringRef[] superNames = StringRef.createArray(superCount);
096            for (int i = 0; i < superCount; i++) {
097                superNames[i] = dataStream.readName();
098            }
099    
100            return new KotlinClassStubImpl(getStubType(isEnumEntry), parentStub, qualifiedName, name, superNames,
101                                           isTrait, isEnumEntry, isLocal, isTopLevel);
102        }
103    
104        @Override
105        public void indexStub(@NotNull KotlinClassStub stub, @NotNull IndexSink sink) {
106            StubIndexService.getInstance().indexClass(stub, sink);
107        }
108    
109        public static KtClassElementType getStubType(boolean isEnumEntry) {
110            return isEnumEntry ? KtStubElementTypes.ENUM_ENTRY : KtStubElementTypes.CLASS;
111        }
112    }