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;
018    
019    import com.intellij.extapi.psi.StubBasedPsiElementBase;
020    import com.intellij.lang.ASTNode;
021    import com.intellij.lang.Language;
022    import com.intellij.psi.*;
023    import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
024    import com.intellij.psi.stubs.IStubElementType;
025    import com.intellij.psi.stubs.StubElement;
026    import com.intellij.util.IncorrectOperationException;
027    import org.jetbrains.annotations.NotNull;
028    import org.jetbrains.kotlin.idea.KotlinLanguage;
029    import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementType;
030    
031    import java.util.Arrays;
032    import java.util.List;
033    
034    public class KtElementImplStub<T extends StubElement<?>> extends StubBasedPsiElementBase<T>
035            implements KtElement, StubBasedPsiElement<T> {
036        public KtElementImplStub(@NotNull T stub, @NotNull IStubElementType nodeType) {
037            super(stub, nodeType);
038        }
039    
040        public KtElementImplStub(@NotNull ASTNode node) {
041            super(node);
042        }
043    
044        @NotNull
045        @Override
046        public Language getLanguage() {
047            return KotlinLanguage.INSTANCE;
048        }
049    
050        @Override
051        public String toString() {
052            return getElementType().toString();
053        }
054    
055        @Override
056        public final void accept(@NotNull PsiElementVisitor visitor) {
057            if (visitor instanceof KtVisitor) {
058                accept((KtVisitor) visitor, null);
059            }
060            else {
061                visitor.visitElement(this);
062            }
063        }
064    
065        @NotNull
066        @Override
067        public KtFile getContainingKtFile() {
068            PsiFile file = getContainingFile();
069            assert file instanceof KtFile : "KtElement not inside KtFile: " + file + " " + (file.isValid() ? file.getText() : "<invalid>");
070            return (KtFile) file;
071        }
072    
073        @Override
074        public <D> void acceptChildren(@NotNull KtVisitor<Void, D> visitor, D data) {
075            PsiElement child = getFirstChild();
076            while (child != null) {
077                if (child instanceof KtElement) {
078                    ((KtElement) child).accept(visitor, data);
079                }
080                child = child.getNextSibling();
081            }
082        }
083    
084        @Override
085        public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
086            return visitor.visitKtElement(this, data);
087        }
088    
089        @Override
090        public void delete() throws IncorrectOperationException {
091            KtElementUtilsKt.deleteSemicolon(this);
092            super.delete();
093        }
094    
095        @Override
096        public PsiReference getReference() {
097            PsiReference[] references = getReferences();
098            if (references.length == 1) return references[0];
099            else return null;
100        }
101    
102        @NotNull
103        @Override
104        public PsiReference[] getReferences() {
105            return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
106        }
107    
108        @NotNull
109        protected <PsiT extends KtElementImplStub<?>, StubT extends StubElement> List<PsiT> getStubOrPsiChildrenAsList(
110                @NotNull KtStubElementType<StubT, PsiT> elementType
111        ) {
112            return Arrays.asList(getStubOrPsiChildren(elementType, elementType.getArrayFactory()));
113        }
114    
115        @NotNull
116        @Override
117        public KtElement getPsiOrParent() {
118            return this;
119        }
120    }