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