update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / psi / impl / compiled / ClsElementImpl.java
blobe8c591ec5fa07bafba685ba55377e9becc371edb
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.psi.impl.compiled;
18 import com.intellij.lang.ASTNode;
19 import com.intellij.lang.Language;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.fileTypes.StdFileTypes;
22 import com.intellij.openapi.util.Key;
23 import com.intellij.openapi.util.TextRange;
24 import com.intellij.psi.*;
25 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
26 import com.intellij.psi.impl.PsiElementBase;
27 import com.intellij.psi.impl.source.SourceTreeToPsiMap;
28 import com.intellij.psi.impl.source.tree.TreeElement;
29 import com.intellij.psi.tree.IElementType;
30 import com.intellij.psi.util.PsiTreeUtil;
31 import com.intellij.util.IncorrectOperationException;
32 import org.jetbrains.annotations.NotNull;
34 public abstract class ClsElementImpl extends PsiElementBase implements PsiCompiledElement {
35 private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsElementImpl");
36 private static final boolean CHECK_MIRROR_ENABLED = false;
37 protected static final Object LAZY_BUILT_LOCK = new String("lazy cls tree initialization lock");
38 public static final Key<PsiCompiledElement> COMPILED_ELEMENT = Key.create("COMPILED_ELEMENT");
40 private TreeElement myMirror = null;
42 @NotNull
43 public Language getLanguage() {
44 return StdFileTypes.JAVA.getLanguage();
47 public PsiManager getManager() {
48 return getParent().getManager();
51 public PsiFile getContainingFile() {
52 PsiElement parent = getParent();
53 if (parent == null) {
54 if (!isValid()) throw new PsiInvalidElementAccessException(this);
55 return null;
57 return parent.getContainingFile();
60 public final boolean isWritable() {
61 return false;
64 public boolean isPhysical() {
65 return true;
68 public boolean isValid() {
69 PsiElement parent = getParent();
70 return parent != null && parent.isValid();
73 public PsiElement copy() {
74 return this;
77 public void checkAdd(@NotNull PsiElement element) throws IncorrectOperationException {
78 throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE);
81 public PsiElement add(@NotNull PsiElement element) throws IncorrectOperationException {
82 throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE);
85 public PsiElement addBefore(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException {
86 throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE);
89 public PsiElement addAfter(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException {
90 throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE);
93 public void delete() throws IncorrectOperationException {
94 throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE);
97 public void checkDelete() throws IncorrectOperationException {
98 throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE);
101 public PsiElement replace(@NotNull PsiElement newElement) throws IncorrectOperationException {
102 throw new IncorrectOperationException(CAN_NOT_MODIFY_MESSAGE);
105 protected static final String CAN_NOT_MODIFY_MESSAGE = PsiBundle.message("psi.error.attempt.to.edit.class.file");
107 public abstract void appendMirrorText(final int indentLevel, final StringBuffer buffer);
109 protected static void goNextLine(int indentLevel, StringBuffer buffer) {
110 buffer.append('\n');
111 for (int i = 0; i < indentLevel; i++) buffer.append(' ');
114 protected int getIndentSize() {
115 return CodeStyleSettingsManager.getSettings(getProject()).getIndentSize(StdFileTypes.JAVA);
118 public abstract void setMirror(@NotNull TreeElement element);
120 public PsiElement getMirror() {
121 synchronized (ClsFileImpl.MIRROR_LOCK) {
122 if (myMirror == null) {
123 final ClsFileImpl file = (ClsFileImpl)getContainingFile();
124 file.getMirror();
126 return SourceTreeToPsiMap.treeElementToPsi(myMirror);
130 public final TextRange getTextRange() {
131 PsiElement mirror = getMirror();
132 return mirror != null ? mirror.getTextRange() : new TextRange(0, 0);
135 public final int getStartOffsetInParent() {
136 PsiElement mirror = getMirror();
137 return mirror != null ? mirror.getStartOffsetInParent() : -1;
140 public int getTextLength() {
141 String text = getText();
142 if (text == null){
143 LOG.error("getText() == null, element = " + this + ", parent = " + getParent());
144 return 0;
146 return text.length();
149 public PsiElement findElementAt(int offset) {
150 PsiElement mirrorAt = getMirror().findElementAt(offset);
151 while(true){
152 if (mirrorAt == null) return null;
153 PsiElement elementAt = mirrorToElement(mirrorAt);
154 if (elementAt != null) return elementAt;
155 mirrorAt = mirrorAt.getParent();
159 PsiElement[] children = getChildren();
160 if (children.length == 0) return this;
161 for(int i = 0; i < children.length; i++){
162 int start = children[i].getStartOffsetInParent();
163 if (offset < start) return null;
164 int end = start + children[i].getTextLength();
165 if (offset < end){
166 return children[i].findElementAt(offset - start);
169 return null;
173 public PsiReference findReferenceAt(int offset) {
174 PsiReference mirrorRef = getMirror().findReferenceAt(offset);
175 if (mirrorRef == null) return null;
176 PsiElement mirrorElement = mirrorRef.getElement();
177 PsiElement element = mirrorToElement(mirrorElement);
178 if (element == null) return null;
179 return element.getReference();
182 private PsiElement mirrorToElement(PsiElement mirror) {
183 final PsiElement m = getMirror();
184 if (m == mirror) return this;
186 PsiElement[] children = getChildren();
187 if (children.length == 0) return null;
189 for (PsiElement child : children) {
190 ClsElementImpl clsChild = (ClsElementImpl)child;
191 if (PsiTreeUtil.isAncestor(clsChild.getMirror(), mirror, false)) {
192 PsiElement element = clsChild.mirrorToElement(mirror);
193 if (element != null) return element;
197 return null;
200 public final int getTextOffset() {
201 PsiElement mirror = getMirror();
202 return mirror != null ? mirror.getTextOffset() : -1;
205 public String getText() {
206 PsiElement mirror = getMirror();
207 return mirror != null ? mirror.getText() : null;
210 @NotNull
211 public char[] textToCharArray() {
212 return getMirror().textToCharArray();
215 public boolean textMatches(@NotNull CharSequence text) {
216 return getText().equals(text.toString());
219 public boolean textMatches(@NotNull PsiElement element) {
220 return getText().equals(element.getText());
223 @NotNull
224 public PsiElement getNavigationElement() {
225 return this;
228 public PsiElement getOriginalElement() {
229 return this;
232 public ASTNode getNode() {
233 return null;
236 protected void setMirrorCheckingType(@NotNull TreeElement element, IElementType type) {
237 if (CHECK_MIRROR_ENABLED) {
238 LOG.assertTrue(myMirror == null);
241 if (type != null) {
242 LOG.assertTrue(element.getElementType() == type);
245 element.putUserData(COMPILED_ELEMENT, this);
246 myMirror = element;