001/*
002 * Copyright 2010-2013 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
017package org.jetbrains.jet.lang.psi.stubs.elements;
018
019import com.intellij.lang.ASTNode;
020import com.intellij.psi.PsiElement;
021import com.intellij.psi.stubs.IndexSink;
022import com.intellij.psi.stubs.StubElement;
023import com.intellij.psi.stubs.StubInputStream;
024import com.intellij.psi.stubs.StubOutputStream;
025import com.intellij.util.io.StringRef;
026import org.jetbrains.annotations.NonNls;
027import org.jetbrains.annotations.NotNull;
028import org.jetbrains.jet.lang.psi.JetClassObject;
029import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
030import org.jetbrains.jet.lang.psi.stubs.PsiJetObjectStub;
031import org.jetbrains.jet.lang.psi.stubs.impl.PsiJetObjectStubImpl;
032import org.jetbrains.jet.lang.resolve.name.FqName;
033
034import java.io.IOException;
035
036public class JetObjectElementType extends JetStubElementType<PsiJetObjectStub, JetObjectDeclaration> {
037    public JetObjectElementType(@NotNull @NonNls String debugName) {
038        super(debugName);
039    }
040
041    @Override
042    public JetObjectDeclaration createPsiFromAst(@NotNull ASTNode node) {
043        return new JetObjectDeclaration(node);
044    }
045
046    @Override
047    public JetObjectDeclaration createPsi(@NotNull PsiJetObjectStub stub) {
048        return new JetObjectDeclaration(stub);
049    }
050
051    @Override
052    public boolean shouldCreateStub(ASTNode node) {
053        if (super.shouldCreateStub(node)) {
054            PsiElement psiElement = node.getPsi();
055            if (psiElement instanceof JetObjectDeclaration) {
056                JetObjectDeclaration objectDeclaration = (JetObjectDeclaration) psiElement;
057                return objectDeclaration.getName() != null || isClassObject(objectDeclaration);
058            }
059        }
060
061        return false;
062    }
063
064    @Override
065    public PsiJetObjectStub createStub(@NotNull JetObjectDeclaration psi, @NotNull StubElement parentStub) {
066        String name = psi.getName();
067        FqName fqName = psi.getFqName();
068        return new PsiJetObjectStubImpl(JetStubElementTypes.OBJECT_DECLARATION, parentStub, name, fqName, psi.isTopLevel(), isClassObject(psi));
069    }
070
071    @Override
072    public void serialize(PsiJetObjectStub stub, StubOutputStream dataStream) throws IOException {
073        dataStream.writeName(stub.getName());
074        FqName fqName = stub.getFqName();
075        dataStream.writeName(fqName != null ? fqName.toString() : null);
076        dataStream.writeBoolean(stub.isTopLevel());
077        dataStream.writeBoolean(stub.isClassObject());
078    }
079
080    @Override
081    public PsiJetObjectStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
082        StringRef name = dataStream.readName();
083        StringRef fqNameStr = dataStream.readName();
084        FqName fqName = fqNameStr != null ? new FqName(fqNameStr.toString()) : null;
085        boolean isTopLevel = dataStream.readBoolean();
086        boolean isClassObject = dataStream.readBoolean();
087
088        return new PsiJetObjectStubImpl(JetStubElementTypes.OBJECT_DECLARATION, parentStub, name, fqName, isTopLevel, isClassObject);
089    }
090
091    @Override
092    public void indexStub(PsiJetObjectStub stub, IndexSink sink) {
093        StubIndexServiceFactory.getInstance().indexObject(stub, sink);
094    }
095
096    private static boolean isClassObject(@NotNull JetObjectDeclaration objectDeclaration) {
097        return objectDeclaration.getParent() instanceof JetClassObject;
098    }
099}