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.lang.ASTNode;
020    import com.intellij.navigation.ItemPresentation;
021    import com.intellij.navigation.ItemPresentationProviders;
022    import com.intellij.psi.PsiElement;
023    import com.intellij.util.IncorrectOperationException;
024    import org.jetbrains.annotations.NonNls;
025    import org.jetbrains.annotations.NotNull;
026    import org.jetbrains.annotations.Nullable;
027    import org.jetbrains.kotlin.JetNodeTypes;
028    import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
029    import org.jetbrains.kotlin.lexer.JetTokens;
030    import org.jetbrains.kotlin.psi.stubs.KotlinObjectStub;
031    import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes;
032    
033    import java.util.Collections;
034    import java.util.List;
035    
036    public class JetObjectDeclaration extends JetNamedDeclarationStub<KotlinObjectStub> implements JetClassOrObject  {
037        public JetObjectDeclaration(@NotNull ASTNode node) {
038            super(node);
039        }
040    
041        public JetObjectDeclaration(@NotNull KotlinObjectStub stub) {
042            super(stub, JetStubElementTypes.OBJECT_DECLARATION);
043        }
044    
045        @Override
046        public String getName() {
047            KotlinObjectStub stub = getStub();
048            if (stub != null) {
049                return stub.getName();
050            }
051    
052            JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
053            return nameAsDeclaration == null ? null : nameAsDeclaration.getName();
054        }
055    
056        @Override
057        public boolean isTopLevel() {
058            KotlinObjectStub stub = getStub();
059            if (stub != null) {
060                return stub.isTopLevel();
061            }
062    
063            return getParent() instanceof JetFile;
064        }
065    
066        @Override
067        public PsiElement getNameIdentifier() {
068            JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
069            return nameAsDeclaration == null ? null : nameAsDeclaration.getNameIdentifier();
070        }
071    
072        @Override
073        public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
074            JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
075            return nameAsDeclaration == null ? null : nameAsDeclaration.setName(name);
076        }
077    
078        @Override
079        @Nullable
080        public JetObjectDeclarationName getNameAsDeclaration() {
081            return (JetObjectDeclarationName) findChildByType(JetNodeTypes.OBJECT_DECLARATION_NAME);
082        }
083    
084        @Override
085        @Nullable
086        public JetModifierList getModifierList() {
087            if (isClassObject()) {
088                PsiElement parent = getParentByStub();
089                assert parent instanceof JetDeclaration;
090                return ((JetDeclaration)parent).getModifierList();
091            }
092            return super.getModifierList();
093        }
094    
095        public boolean isClassObject() {
096            KotlinObjectStub stub = getStub();
097            if (stub != null) {
098                return stub.isClassObject();
099            }
100            PsiElement parent = getParent();
101            return parent != null && parent.getNode().getElementType().equals(JetNodeTypes.CLASS_OBJECT);
102        }
103    
104        @Nullable
105        public JetClassObject getClassObjectElement() {
106            if (!isClassObject()) {
107                return null;
108            }
109            return (JetClassObject) getParentByStub();
110        }
111    
112        @Override
113        public boolean hasModifier(@NotNull JetModifierKeywordToken modifier) {
114            JetModifierList modifierList = getModifierList();
115            return modifierList != null && modifierList.hasModifier(modifier);
116        }
117    
118        @Override
119        @Nullable
120        public JetDelegationSpecifierList getDelegationSpecifierList() {
121            return getStubOrPsiChild(JetStubElementTypes.DELEGATION_SPECIFIER_LIST);
122        }
123    
124        @Override
125        @NotNull
126        public List<JetDelegationSpecifier> getDelegationSpecifiers() {
127            JetDelegationSpecifierList list = getDelegationSpecifierList();
128            return list != null ? list.getDelegationSpecifiers() : Collections.<JetDelegationSpecifier>emptyList();
129        }
130    
131        @Override
132        @NotNull
133        public List<JetClassInitializer> getAnonymousInitializers() {
134            JetClassBody body = getBody();
135            if (body == null) return Collections.emptyList();
136    
137            return body.getAnonymousInitializers();
138        }
139    
140        @Override
141        public boolean hasPrimaryConstructor() {
142            return true;
143        }
144    
145        @Override
146        public JetClassBody getBody() {
147            return getStubOrPsiChild(JetStubElementTypes.CLASS_BODY);
148        }
149    
150        @Override
151        public boolean isLocal() {
152            KotlinObjectStub stub = getStub();
153            if (stub != null) {
154                return stub.isLocal();
155            }
156            return JetPsiUtil.isLocal(this);
157        }
158    
159        @Override
160        @NotNull
161        public List<JetDeclaration> getDeclarations() {
162            JetClassBody body = getBody();
163            if (body == null) return Collections.emptyList();
164    
165            return body.getDeclarations();
166        }
167    
168        @Override
169        public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
170            return visitor.visitObjectDeclaration(this, data);
171        }
172    
173        public boolean isObjectLiteral() {
174            KotlinObjectStub stub = getStub();
175            if (stub != null) {
176                return stub.isObjectLiteral();
177            }
178            return getParent() instanceof JetObjectLiteralExpression;
179        }
180    
181        @NotNull
182        public PsiElement getObjectKeyword() {
183            return findChildByType(JetTokens.OBJECT_KEYWORD);
184        }
185    
186        @Override
187        public void delete() throws IncorrectOperationException {
188            JetPsiUtil.deleteClass(this);
189        }
190    
191        @Override
192        public ItemPresentation getPresentation() {
193            return ItemPresentationProviders.getItemPresentation(this);
194        }
195    }