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