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.JetFile;
029import org.jetbrains.jet.lang.psi.JetNamedFunction;
030import org.jetbrains.jet.lang.psi.stubs.PsiJetFunctionStub;
031import org.jetbrains.jet.lang.psi.stubs.impl.PsiJetFunctionStubImpl;
032import org.jetbrains.jet.lang.resolve.name.FqName;
033
034import java.io.IOException;
035
036public class JetFunctionElementType extends JetStubElementType<PsiJetFunctionStub, JetNamedFunction> {
037
038    public JetFunctionElementType(@NotNull @NonNls String debugName) {
039        super(debugName);
040    }
041
042    @Override
043    public JetNamedFunction createPsiFromAst(@NotNull ASTNode node) {
044        return new JetNamedFunction(node);
045    }
046
047    @Override
048    public JetNamedFunction createPsi(@NotNull PsiJetFunctionStub stub) {
049        return new JetNamedFunction(stub);
050    }
051
052    @Override
053    public boolean shouldCreateStub(ASTNode node) {
054        if (super.shouldCreateStub(node)) {
055            PsiElement psi = node.getPsi();
056            if (psi instanceof JetNamedFunction) {
057                JetNamedFunction function = (JetNamedFunction) psi;
058                return function.getName() != null;
059            }
060        }
061
062        return false;
063    }
064
065    @Override
066    public PsiJetFunctionStub createStub(@NotNull JetNamedFunction psi, @NotNull StubElement parentStub) {
067        boolean isTopLevel = psi.getParent() instanceof JetFile;
068        boolean isExtension = psi.getReceiverTypeRef() != null;
069
070        FqName qualifiedName = psi.getFqName();
071
072        return new PsiJetFunctionStubImpl(JetStubElementTypes.FUNCTION, parentStub, psi.getName(), isTopLevel, qualifiedName, isExtension);
073    }
074
075    @Override
076    public void serialize(PsiJetFunctionStub stub, StubOutputStream dataStream) throws IOException {
077        dataStream.writeName(stub.getName());
078        dataStream.writeBoolean(stub.isTopLevel());
079
080        FqName topFQName = stub.getTopFQName();
081        dataStream.writeName(topFQName != null ? topFQName.toString() : null);
082
083        dataStream.writeBoolean(stub.isExtension());
084    }
085
086    @Override
087    public PsiJetFunctionStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
088        StringRef name = dataStream.readName();
089        boolean isTopLevel = dataStream.readBoolean();
090
091        StringRef topFQNameStr = dataStream.readName();
092        FqName fqName = topFQNameStr != null ? new FqName(topFQNameStr.toString()) : null;
093
094        boolean isExtension = dataStream.readBoolean();
095
096        return new PsiJetFunctionStubImpl(JetStubElementTypes.FUNCTION, parentStub, name, isTopLevel, fqName, isExtension);
097    }
098
099    @Override
100    public void indexStub(PsiJetFunctionStub stub, IndexSink sink) {
101        StubIndexServiceFactory.getInstance().indexFunction(stub, sink);
102    }
103}