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 }