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    
017    package org.jetbrains.jet.lang.psi.stubs.elements;
018    
019    import com.intellij.lang.ASTNode;
020    import com.intellij.psi.PsiElement;
021    import com.intellij.psi.stubs.IndexSink;
022    import com.intellij.psi.stubs.StubElement;
023    import com.intellij.psi.stubs.StubInputStream;
024    import com.intellij.psi.stubs.StubOutputStream;
025    import com.intellij.util.io.StringRef;
026    import org.jetbrains.annotations.NonNls;
027    import org.jetbrains.annotations.NotNull;
028    import org.jetbrains.jet.lang.psi.JetClassObject;
029    import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
030    import org.jetbrains.jet.lang.psi.stubs.PsiJetObjectStub;
031    import org.jetbrains.jet.lang.psi.stubs.impl.PsiJetObjectStubImpl;
032    import org.jetbrains.jet.lang.resolve.name.FqName;
033    
034    import java.io.IOException;
035    
036    public 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    }