fix IllegalArgumentException
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInsight / CodeInsightUtilBase.java
blobd50115e426bf761733cd12eb42d01cc048ecc1b4
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.
17 package com.intellij.codeInsight;
19 import com.intellij.codeInsight.hint.HintManager;
20 import com.intellij.lang.Language;
21 import com.intellij.openapi.application.ApplicationManager;
22 import com.intellij.openapi.editor.Document;
23 import com.intellij.openapi.editor.Editor;
24 import com.intellij.openapi.editor.RangeMarker;
25 import com.intellij.openapi.fileEditor.FileEditorManager;
26 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
27 import com.intellij.openapi.project.Project;
28 import com.intellij.openapi.vfs.ReadonlyStatusHandler;
29 import com.intellij.openapi.vfs.VfsUtil;
30 import com.intellij.openapi.vfs.VirtualFile;
31 import com.intellij.psi.PsiDocumentManager;
32 import com.intellij.psi.PsiElement;
33 import com.intellij.psi.PsiFile;
34 import com.intellij.psi.PsiWhiteSpace;
35 import com.intellij.psi.util.PsiTreeUtil;
36 import com.intellij.psi.util.PsiUtilBase;
37 import com.intellij.util.ReflectionCache;
38 import gnu.trove.THashSet;
40 import java.util.Arrays;
41 import java.util.Collection;
42 import java.util.Set;
44 public class CodeInsightUtilBase {
45 private CodeInsightUtilBase() {
48 static <T extends PsiElement> T findElementInRange(final PsiFile file,
49 int startOffset,
50 int endOffset,
51 final Class<T> klass,
52 final Language language) {
53 PsiElement element1 = file.getViewProvider().findElementAt(startOffset, language);
54 PsiElement element2 = file.getViewProvider().findElementAt(endOffset - 1, language);
55 if (element1 instanceof PsiWhiteSpace) {
56 startOffset = element1.getTextRange().getEndOffset();
57 element1 = file.getViewProvider().findElementAt(startOffset, language);
59 if (element2 instanceof PsiWhiteSpace) {
60 endOffset = element2.getTextRange().getStartOffset();
61 element2 = file.getViewProvider().findElementAt(endOffset - 1, language);
63 if (element2 == null || element1 == null) return null;
64 final PsiElement commonParent = PsiTreeUtil.findCommonParent(element1, element2);
65 final T element =
66 ReflectionCache.isAssignable(klass, commonParent.getClass())
67 ? (T)commonParent : PsiTreeUtil.getParentOfType(commonParent, klass);
68 if (element == null || element.getTextRange().getStartOffset() != startOffset || element.getTextRange().getEndOffset() != endOffset) {
69 return null;
71 return element;
74 public static <T extends PsiElement> T forcePsiPostprocessAndRestoreElement(final T element) {
75 final PsiFile psiFile = element.getContainingFile();
76 final Document document = psiFile.getViewProvider().getDocument();
77 if (document == null) return element;
78 final Language language = PsiUtilBase.getDialect(element);
79 final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(psiFile.getProject());
80 final RangeMarker rangeMarker = document.createRangeMarker(element.getTextRange());
81 documentManager.doPostponedOperationsAndUnblockDocument(document);
82 documentManager.commitDocument(document);
84 return findElementInRange(psiFile, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(),
85 (Class<? extends T>)element.getClass(),
86 language);
89 public static boolean prepareFileForWrite(final PsiFile psiFile) {
90 if (psiFile == null) return false;
91 final VirtualFile file = psiFile.getVirtualFile();
92 final Project project = psiFile.getProject();
94 final Editor editor =
95 psiFile.isWritable() ? null : FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file), true);
96 if (!ReadonlyStatusHandler.ensureFilesWritable(project, file)) {
97 ApplicationManager.getApplication().invokeLater(new Runnable() {
98 public void run() {
99 if (editor != null && editor.getComponent().isDisplayable()) {
100 HintManager.getInstance()
101 .showErrorHint(editor, CodeInsightBundle.message("error.hint.file.is.readonly", file.getPresentableUrl()));
106 return false;
109 return true;
112 public static boolean preparePsiElementForWrite(PsiElement element) {
113 PsiFile file = element == null ? null : element.getContainingFile();
114 return prepareFileForWrite(file);
117 public static boolean preparePsiElementsForWrite(PsiElement... elements) {
118 return preparePsiElementsForWrite(Arrays.asList(elements));
120 public static boolean preparePsiElementsForWrite(Collection<? extends PsiElement> elements) {
121 if (elements.isEmpty()) return true;
122 Set<VirtualFile> files = new THashSet<VirtualFile>();
123 Project project = null;
124 for (PsiElement element : elements) {
125 project = element.getProject();
126 PsiFile file = element.getContainingFile();
127 if (file == null) continue;
128 VirtualFile virtualFile = file.getVirtualFile();
129 if (virtualFile == null) continue;
130 files.add(virtualFile);
132 if (!files.isEmpty()) {
133 VirtualFile[] virtualFiles = VfsUtil.toVirtualFileArray(files);
134 ReadonlyStatusHandler.OperationStatus status = ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(virtualFiles);
135 return !status.hasReadonlyFiles();
137 return true;