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