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