Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
irengrig
2010-10-29 17:54:38 +04:00
73 changed files with 796 additions and 417 deletions
@@ -504,7 +504,7 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
if (myModel.getSize() == 0) {
setBorder(null);
} else {
if (getBorder() == null) setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0),
if (getBorder() == null) setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(5, 0, 5, 0, UIUtil.getPanelBackground()),
BorderFactory.createLineBorder(UIUtil.getPanelBackgound().darker())));
}
@@ -99,7 +99,8 @@ public class JdkListConfigurable extends BaseStructureConfigurable {
@Nullable
@NonNls
public String getHelpTopic() {
return "reference.settingsdialog.project.structure.jdk";
final NamedConfigurable selectedConfigurable = getSelectedConfugurable();
return selectedConfigurable != null ? selectedConfigurable.getHelpTopic() : "reference.settingsdialog.project.structure.jdk";
}
@NonNls
@@ -30,6 +30,7 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.quickfix.*;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.controlFlow.*;
@@ -395,6 +396,9 @@ public class HighlightControlFlowUtil {
catch (AnalysisCanceledException e) {
codeBlockProblems = Collections.emptyList();
}
catch (IndexNotReadyException e) {
codeBlockProblems = Collections.emptyList();
}
uninitializedVarProblems.put(topBlock, codeBlockProblems);
}
if (codeBlockProblems.contains(expression)) {
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -65,8 +66,27 @@ public class GenerateMembersUtil {
assert spaceNode != null;
if (spaceNode.getStartOffset() <= offset && spaceNode.getStartOffset() + spaceNode.getTextLength() >= offset) {
final ASTNode singleNewLineWhitespace = JavaPsiFacade.getInstance(file.getProject()).getElementFactory().createWhiteSpaceFromText(spaceNode.getText().substring(0, offset - spaceNode.getStartOffset())).getNode();
spaceNode.getTreeParent().replaceChild(spaceNode, singleNewLineWhitespace); // See http://jetbrains.net/jira/browse/IDEADEV-12837
String whiteSpace = spaceNode.getText().substring(0, offset - spaceNode.getStartOffset());
if (!StringUtil.containsLineBreak(whiteSpace)) {
// There is a possible case that the caret is located at the end of the line that already contains expression, say, we
// want to override particular method while caret is located after the field.
// Example - consider that we want to override toString() method at the class below:
// class Test {
// int i;<caret>
// }
// We want to add line feed then in order to avoid situation like below:
// class Test {
// int i;@Override String toString() {
// super.toString();
// }
// }
whiteSpace += "\n";
}
PsiElementFactory factory = JavaPsiFacade.getInstance(file.getProject()).getElementFactory();
final ASTNode singleNewLineWhitespace = factory.createWhiteSpaceFromText(whiteSpace).getNode();
if (singleNewLineWhitespace != null) {
spaceNode.getTreeParent().replaceChild(spaceNode, singleNewLineWhitespace); // See http://jetbrains.net/jira/browse/IDEADEV-12837
}
}
}
@@ -961,7 +961,12 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
ASTNode nextModifier = FormattingAstUtil.getNextNonWhiteSpaceNode(annotation.getNode());
if (nextModifier == null) {
PsiElement element = modifierList.getNextSibling();
if (element != null) dependencyStart = element.getTextRange().getStartOffset();
if (element != null) {
ASTNode node = element.getNode();
if (node != null && node.getTextLength() > 0) {
dependencyStart = element.getTextRange().getStartOffset();
}
}
} else {
dependencyStart = nextModifier.getStartOffset();
}
@@ -23,7 +23,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
public class JavaHelperFactory implements HelperFactory.Factory {
public Helper create(final FileType fileType, final Project project) {
return new JavaHelper(fileType, project);
public IndentHelper create(final FileType fileType, final Project project) {
return new JavaIndentHelper(fileType, project);
}
}
@@ -26,13 +26,13 @@ import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.impl.source.tree.TreeUtil;
public class JavaHelper extends Helper {
public JavaHelper(final FileType fileType, final Project project) {
public class JavaIndentHelper extends IndentHelper {
public JavaIndentHelper(final FileType fileType, final Project project) {
super(fileType, project);
}
protected int getIndentInner(final ASTNode element, final boolean includeNonSpace, final int recursionLevel) {
if (recursionLevel > TOO_BIG_WALK_THRESHOULD) return 0;
if (recursionLevel > TOO_BIG_WALK_THRESHOLD) return 0;
if (element.getTreePrev() != null) {
ASTNode prev = element.getTreePrev();
@@ -43,12 +43,12 @@ public class ShiftIndentInsideHelper {
private final CodeStyleSettings mySettings;
private final FileType myFileType;
private final Helper myIndentHelper;
private final IndentHelper myIndentIndentHelper;
public ShiftIndentInsideHelper(FileType fileType, Project project) {
mySettings = CodeStyleSettingsManager.getSettings(project);
myFileType = fileType;
myIndentHelper = HelperFactory.createHelper(fileType, project);
myIndentIndentHelper = HelperFactory.createHelper(fileType, project);
}
private static int getStartOffset(ASTNode root, ASTNode child) {
@@ -75,10 +75,10 @@ public class ShiftIndentInsideHelper {
}
if (c == '\n' || c == '\r') continue;
String space = text.substring(offset + 1, offset1);
int indent = myIndentHelper.getIndent(space, true);
int indent = myIndentIndentHelper.getIndent(space, true);
int newIndent = indent + indentShift;
newIndent = Math.max(newIndent, 0);
String newSpace = myIndentHelper.fillIndent(newIndent);
String newSpace = myIndentIndentHelper.fillIndent(newIndent);
ASTNode leaf = element.findLeafElementAt(offset);
if (!mayShiftIndentInside(leaf)) {
@@ -96,7 +96,7 @@ public class ShiftIndentInsideHelper {
) &&
next != element) {
if (mySettings.KEEP_FIRST_COLUMN_COMMENT) {
int commentIndent = myIndentHelper.getIndent(next, true);
int commentIndent = myIndentIndentHelper.getIndent(next, true);
if (commentIndent == 0) continue;
}
}
@@ -56,7 +56,11 @@ public class PsiAnnotationImpl extends JavaStubPsiElement<PsiAnnotationStub> imp
return (PsiJavaCodeReferenceElement)stub.getTreeElement().findChildByRoleAsPsiElement(ChildRole.CLASS_REFERENCE);
}
return PsiTreeUtil.getChildOfType(this, PsiJavaCodeReferenceElement.class);
final Object result = PsiTreeUtil.getChildOfType(this, PsiJavaCodeReferenceElement.class);
if (result != null && !(result instanceof PsiJavaCodeReferenceElement)) {
throw new AssertionError("getChildOfType returned rubbish: " + result);
}
return (PsiJavaCodeReferenceElement)result;
}
public PsiAnnotationMemberValue findAttributeValue(String attributeName) {
@@ -306,7 +306,8 @@ public class JavaChangeSignatureDetector implements LanguageChangeSignatureDetec
@Override
public boolean isChangeSignatureAvailable(PsiElement element, ChangeInfo currentInfo) {
if (currentInfo instanceof JavaChangeInfo) {
return element instanceof PsiIdentifier && Comparing.equal(currentInfo.getMethod(), element.getParent());
final PsiMethod method = (PsiMethod)currentInfo.getMethod();
return getSignatureRange(method).contains(element.getTextRange());
}
return false;
}
@@ -316,12 +317,16 @@ public class JavaChangeSignatureDetector implements LanguageChangeSignatureDetec
public TextRange getQuickFixRange(PsiElement element) {
element = element.getParent();
if (element instanceof PsiMethod) {
final PsiCodeBlock body = ((PsiMethod)element).getBody();
return new TextRange(((PsiMethod)element).getModifierList().getTextRange().getStartOffset(), body == null ? element.getTextRange().getEndOffset() : body.getTextRange().getStartOffset() - 1);
return getSignatureRange((PsiMethod)element);
}
return null;
}
private TextRange getSignatureRange(PsiMethod method) {
final PsiCodeBlock body = method.getBody();
return new TextRange(method.getModifierList().getTextRange().getStartOffset(), body == null ? method.getTextRange().getEndOffset() : body.getTextRange().getStartOffset() - 1);
}
@Override
public boolean isToHighlight(PsiElement element, ChangeInfo changeInfo) {
element = element.getParent();
@@ -347,51 +347,20 @@ public class MoveInnerProcessor extends BaseRefactoringProcessor {
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
final HashMap<PsiElement,HashSet<PsiElement>> reported = new HashMap<PsiElement, HashSet<PsiElement>>();
class Visitor extends JavaRecursiveElementWalkingVisitor {
private final HashMap<PsiElement,HashSet<PsiElement>> reported = new HashMap<PsiElement, HashSet<PsiElement>>();
@Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
PsiElement resolved = reference.resolve();
if (resolved instanceof PsiMember &&
PsiTreeUtil.isAncestor(myInnerClass, resolved, true) &&
becomesInaccessible((PsiMember)resolved)) {
final PsiElement container = ConflictsUtil.getContainer(reference);
HashSet<PsiElement> containerSet = reported.get(resolved);
if (containerSet == null) {
containerSet = new HashSet<PsiElement>();
reported.put(resolved, containerSet);
}
if (!containerSet.contains(container)) {
containerSet.add(container);
String message = RefactoringBundle.message("0.will.become.inaccessible.from.1",
RefactoringUIUtil.getDescription(resolved, true),
RefactoringUIUtil.getDescription(container, true));
conflicts.putValue(resolved, message);
}
registerConflict(reference, resolved, reported, conflicts);
}
}
private boolean becomesInaccessible(PsiMember element) {
final String visibilityModifier = VisibilityUtil.getVisibilityModifier(element.getModifierList());
if (PsiModifier.PRIVATE.equals(visibilityModifier)) return true;
if (PsiModifier.PUBLIC.equals(visibilityModifier)) return false;
final PsiFile containingFile = myOuterClass.getContainingFile();
if (myTargetContainer instanceof PsiDirectory) {
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)myTargetContainer);
return !isInPackage(containingFile, aPackage);
}
// target container is a class
PsiFile targetFile = myTargetContainer.getContainingFile();
if (targetFile != null) {
final PsiDirectory containingDirectory = targetFile.getContainingDirectory();
if (containingDirectory != null) {
final PsiPackage targetPackage = JavaDirectoryService.getInstance().getPackage(containingDirectory);
return isInPackage(containingFile, targetPackage);
}
}
return false;
}
@Override public void visitClass(PsiClass aClass) {
@@ -402,10 +371,63 @@ public class MoveInnerProcessor extends BaseRefactoringProcessor {
// if (myInnerClass.hasModifierProperty(PsiModifier.)) {
myOuterClass.accept(new Visitor());
myInnerClass.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
super.visitReferenceElement(reference);
final PsiElement resolve = reference.resolve();
if (resolve instanceof PsiMember) {
if (PsiTreeUtil.isAncestor(myOuterClass, resolve, true) && !PsiTreeUtil.isAncestor(myInnerClass, resolve, true)) {
if (becomesInaccessible((PsiMember)resolve)) {
registerConflict(reference, resolve, reported, conflicts);
}
}
}
}
});
return showConflicts(conflicts, refUsages.get());
}
private static void registerConflict(PsiJavaCodeReferenceElement reference,
PsiElement resolved,
HashMap<PsiElement, HashSet<PsiElement>> reported, MultiMap<PsiElement, String> conflicts) {
final PsiElement container = ConflictsUtil.getContainer(reference);
HashSet<PsiElement> containerSet = reported.get(resolved);
if (containerSet == null) {
containerSet = new HashSet<PsiElement>();
reported.put(resolved, containerSet);
}
if (!containerSet.contains(container)) {
containerSet.add(container);
String message = RefactoringBundle.message("0.will.become.inaccessible.from.1",
RefactoringUIUtil.getDescription(resolved, true),
RefactoringUIUtil.getDescription(container, true));
conflicts.putValue(resolved, message);
}
}
private boolean becomesInaccessible(PsiMember element) {
final String visibilityModifier = VisibilityUtil.getVisibilityModifier(element.getModifierList());
if (PsiModifier.PRIVATE.equals(visibilityModifier)) return true;
if (PsiModifier.PUBLIC.equals(visibilityModifier)) return false;
final PsiFile containingFile = myOuterClass.getContainingFile();
if (myTargetContainer instanceof PsiDirectory) {
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)myTargetContainer);
return !isInPackage(containingFile, aPackage);
}
// target container is a class
PsiFile targetFile = myTargetContainer.getContainingFile();
if (targetFile != null) {
final PsiDirectory containingDirectory = targetFile.getContainingDirectory();
if (containingDirectory != null) {
final PsiPackage targetPackage = JavaDirectoryService.getInstance().getPackage(containingDirectory);
return isInPackage(containingFile, targetPackage);
}
}
return false;
}
private static boolean isInPackage(final PsiFile containingFile, PsiPackage aPackage) {
if (containingFile != null) {
final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
@@ -0,0 +1,19 @@
import java.util.*;
import Node.Details;
public class Node<E> {
public class Details {
public E data;
}
public Details addNode(Node<E> child) {
return new Details();
}
}
class Test {
public static void main(String[] args) {
Map<String, Details> m = null;
Map<String, Node.Details> sorted1;
sorted1 = m;
}
}
@@ -0,0 +1,8 @@
package p;
class A {
private static class C {
}
}
@@ -0,0 +1,5 @@
package p;
class B extends A.C {
}
@@ -0,0 +1,11 @@
package p;
class A {
private static class C {
}
private static class B extends C{
}
}
@@ -101,6 +101,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testWildcardCastConversion() throws Exception { doTest(false); }
public void testTypeWithinItsWildcardBound() throws Exception { doTest(false); }
public void testMethodSignatureEquality() throws Exception { doTest(false); }
public void testInnerClassRef() throws Exception { doTest(false); }
public void testJavaUtilCollections() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
@@ -226,4 +226,29 @@ public class JavaFormatterAlignmentTest extends AbstractJavaFormatterTest {
"}"
);
}
public void testAnnotatedAndNonAnnotatedFieldsInColumnsAlignment() {
// Inspired by IDEA-60237
getSettings().ALIGN_GROUP_FIELD_DECLARATIONS = true;
doTextTest(
"public class Test {\n" +
" @Id\n" +
" private final String name;\n" +
" @Column(length = 2 * 1024 * 1024 /* 2 MB */)\n" +
" private String value;\n" +
" private boolean required;\n" +
" private String unsetValue;\n" +
"}",
"public class Test {\n" +
" @Id\n" +
" private final String name;\n" +
" @Column(length = 2 * 1024 * 1024 /* 2 MB */)\n" +
" private String value;\n" +
" private boolean required;\n" +
" private String unsetValue;\n" +
"}"
);
}
}
@@ -98,10 +98,18 @@ public class JavaFormatterBracesTest extends AbstractJavaFormatterTest {
doClassTest(
"@Override\n" +
"public int hashCode() {\n" +
"}\n" +
"@Deprecated\n" +
"void foo() {\n" +
"}",
"@Override\n" +
"public int hashCode() \n" +
"{\n" +
"}\n" +
"\n" +
"@Deprecated\n" +
"void foo() \n" +
"{\n" +
"}"
);
}
@@ -46,6 +46,16 @@ public class MoveInnerTest extends MultiFileTestCase {
doTest(createAction("xxx.Outer.Inner", "Inner", true, "outer", false, false, null));
}
public void testInnerClassInheritance() throws Exception {
try {
doTest(createAction("p.A.B", "B", false, null, false, false, null));
fail("Conflict was not detected");
}
catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
assertEquals("class <b><code>p.A.C</code></b> will become inaccessible from class <b><code>p.A.B</code></b>.", e.getMessage());
}
}
public void testScr30106() throws Exception {
doTest(createAction("p.A.B", "B", true, "outer", false, false, null));
}
@@ -73,7 +73,9 @@ public abstract class PsiClassType extends PsiType {
String className = getClassName();
String otherClassName = otherClassType.getClassName();
if (!Comparing.equal(className, otherClassName)) return false;
final PsiType[] parameters = getParameters();
final PsiType[] otherParameters = otherClassType.getParameters();
if (parameters.length != otherParameters.length) return false;
final ClassResolveResult result = resolveGenerics();
final ClassResolveResult otherResult = otherClassType.resolveGenerics();
if (result == otherResult) return true;
@@ -84,7 +86,7 @@ public abstract class PsiClassType extends PsiType {
return aClass == otherClass;
}
return aClass.getManager().areElementsEquivalent(aClass, otherClass) &&
PsiUtil.equalOnEquivalentClasses(result.getSubstitutor(), aClass, otherResult.getSubstitutor(), otherClass);
(parameters.length == 0 || PsiUtil.equalOnEquivalentClasses(result.getSubstitutor(), aClass, otherResult.getSubstitutor(), otherClass));
}
/**
@@ -24,7 +24,7 @@ import com.intellij.util.ui.UIUtil
/**
* @author peter
*/
class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCase {
abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCase {
@Override protected void setUp() {
UIUtil.invokeAndWaitIfNeeded(new Runnable(){
@Override
@@ -203,6 +203,30 @@ public abstract class PsiElementPattern<T extends PsiElement,Self extends PsiEle
});
}
public Self withTextLength(@NotNull final ElementPattern lengthPattern) {
return with(new PatternConditionPlus<T, Integer>("withTextLength", lengthPattern) {
@Override
public boolean processValues(T t,
ProcessingContext context,
PairProcessor<Integer, ProcessingContext> integerProcessingContextPairProcessor) {
return integerProcessingContextPairProcessor.process(t.getTextLength(), context);
}
});
}
public Self notEmpty() {
return withTextLengthLongerThan(0);
}
public Self withTextLengthLongerThan(final int minLength) {
return with(new PatternCondition<T>("withTextLengthLongerThan") {
@Override
public boolean accepts(@NotNull T t, ProcessingContext context) {
return t.getTextLength() > minLength;
}
});
}
public Self withText(@NotNull final ElementPattern text) {
return with(_withText(text));
}
@@ -31,6 +31,7 @@ import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiDocumentManager;
@@ -134,7 +135,11 @@ public class AutoPopupController implements Disposable {
if (!editor.isDisposed()) {
documentManager.commitAllDocuments();
int lbraceOffset = editor.getCaretModel().getOffset() - 1;
new ShowParameterInfoHandler().invoke(myProject, editor, file1, lbraceOffset, highlightedMethod);
try {
new ShowParameterInfoHandler().invoke(myProject, editor, file1, lbraceOffset, highlightedMethod);
}
catch (IndexNotReadyException ignored) { //anything can happen on alarm
}
}
}
};
@@ -31,6 +31,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.util.ProgressWindow;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.Messages;
@@ -370,6 +371,9 @@ public abstract class AbstractLayoutCodeProcessor {
catch(ProcessCanceledException e) {
return;
}
catch(IndexNotReadyException e) {
return;
}
/*
finally {
DaemonCodeAnalyzer.getInstance(myProject).setUpdateByTimerEnabled(true);
@@ -381,10 +385,14 @@ public abstract class AbstractLayoutCodeProcessor {
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
public void run() {
if (globalAction) CommandProcessor.getInstance().markCurrentCommandAsGlobal(myProject);
ApplicationManager.getApplication().runWriteAction(writeAction);
try {
ApplicationManager.getApplication().runWriteAction(writeAction);
if (myPostRunnable != null) {
ApplicationManager.getApplication().invokeLater(myPostRunnable);
if (myPostRunnable != null) {
ApplicationManager.getApplication().invokeLater(myPostRunnable);
}
}
catch (IndexNotReadyException ignored) {
}
}
}, myCommandName, null);
@@ -277,6 +277,11 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
startSemaphore.up(); //todo move inside read action
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
if (!parameters.getPosition().isValid() || !parameters.getOriginalFile().isValid()) {
data.set(LookupElement.EMPTY_ARRAY);
return;
}
ProgressManager.checkCanceled();
data.set(CompletionService.getCompletionService().performCompletion(parameters, new Consumer<LookupElement>() {
public void consume(final LookupElement lookupElement) {
@@ -23,7 +23,6 @@ import com.intellij.codeInsight.hint.ParameterInfoController;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.DataManager;
import com.intellij.ide.IdeEventQueue;
@@ -60,7 +59,6 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.content.*;
import com.intellij.ui.popup.AbstractPopup;
import com.intellij.ui.popup.NotLookupOrSearchCondition;
@@ -411,6 +409,8 @@ public class DocumentationManager {
if (myAutoUpdateRequest == null) {
myAutoUpdateRequest = new Runnable() {
public void run() {
if (myProject.isDisposed()) return;
final DataContext dataContext = DataManager.getInstance().getDataContext();
final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
if (editor != null) {
@@ -16,24 +16,25 @@
package com.intellij.codeInsight.folding.impl;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.ex.RangeMarkerEx;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.SmartPsiElementPointer;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class EditorFoldingInfo {
private static final Key<EditorFoldingInfo> KEY = Key.create("EditorFoldingInfo.KEY");
private final Map<FoldRegion, PsiElement> myFoldRegionToSmartPointerMap = new THashMap<FoldRegion, PsiElement>();
private final Map<FoldRegion, SmartPsiElementPointer<?>> myFoldRegionToSmartPointerMap
= new THashMap<FoldRegion, SmartPsiElementPointer<?>>();
public static EditorFoldingInfo get(@NotNull Editor editor) {
EditorFoldingInfo info = editor.getUserData(KEY);
@@ -44,10 +45,17 @@ public class EditorFoldingInfo {
return info;
}
@Nullable
public PsiElement getPsiElement(@NotNull FoldRegion region) {
final PsiElement element = myFoldRegionToSmartPointerMap.get(region);
return element != null && element.isValid() ? element:null;
final SmartPsiElementPointer<?> pointer = myFoldRegionToSmartPointerMap.get(region);
if (pointer == null) {
return null;
}
PsiElement element = pointer.getElement();
return element != null && element.isValid() ? element : null;
}
@Nullable
public TextRange getPsiElementRange(@NotNull FoldRegion region) {
PsiElement element = getPsiElement(region);
if (element == null) return null;
@@ -65,8 +73,8 @@ public class EditorFoldingInfo {
return myFoldRegionToSmartPointerMap.get(region) == null;
}
public void addRegion(@NotNull FoldRegion region, @NotNull FoldingDescriptor element){
myFoldRegionToSmartPointerMap.put(region, element.getElement().getPsi());
public void addRegion(@NotNull FoldRegion region, @NotNull SmartPsiElementPointer<?> pointer){
myFoldRegionToSmartPointerMap.put(region, pointer);
}
public void removeRegion(@NotNull FoldRegion region){
@@ -81,7 +89,7 @@ public class EditorFoldingInfo {
EditorFoldingInfo info = editor.getUserData(KEY);
if (info != null) {
for(FoldRegion region:info.myFoldRegionToSmartPointerMap.keySet()) {
((RangeMarkerEx)region).dispose();
region.dispose();
}
}
editor.putUserData(KEY, null);
@@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.SmartPointerManager;
import com.intellij.util.containers.HashMap;
import java.util.List;
@@ -36,8 +37,8 @@ import static com.intellij.util.containers.CollectionFactory.arrayList;
import static com.intellij.util.containers.CollectionFactory.newTroveMap;
/**
* @author cdr
*/
* @author cdr
*/
class UpdateFoldRegionsOperation implements Runnable {
private final Project myProject;
private final Editor myEditor;
@@ -85,6 +86,7 @@ class UpdateFoldRegionsOperation implements Runnable {
Map<FoldRegion, Boolean> shouldExpand,
Map<FoldingGroup, Boolean> groupExpand) {
List<FoldRegion> newRegions = arrayList();
SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
for (final Map.Entry<PsiElement, FoldingDescriptor> entry : myElementsToFoldMap.entrySet()) {
ProgressManager.checkCanceled();
@@ -96,7 +98,7 @@ class UpdateFoldRegionsOperation implements Runnable {
FoldRegion region = foldingModel.createFoldRegion(range.getStartOffset(), range.getEndOffset(), placeholder == null ? "..." : placeholder, group);
if (region == null || !foldingModel.addFoldRegion(region)) continue;
info.addRegion(region, descriptor);
info.addRegion(region, smartPointerManager.createSmartPsiElementPointer(descriptor.getElement().getPsi()));
newRegions.add(region);
boolean expandStatus = shouldExpandNewRegion(element, range, rangeToExpandStatusMap);
@@ -15,6 +15,7 @@
*/
package com.intellij.execution.runners;
import com.google.common.collect.Lists;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.execution.ExecutionException;
@@ -32,13 +33,10 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
@@ -48,27 +46,27 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.List;
/**
* @author oleg
* This class provides basic functionality for running consoles.
* It launches extrnal process and handles line input with history
* This class provides basic functionality for running consoles.
* It launches extrnal process and handles line input with history
*/
public abstract class AbstractConsoleRunnerWithHistory {
protected final Project myProject;
protected final String myConsoleTitle;
private final Project myProject;
private final String myConsoleTitle;
protected OSProcessHandler myProcessHandler;
protected final CommandLineArgumentsProvider myProvider;
protected final String myWorkingDir;
private ProcessHandler myProcessHandler;
private final CommandLineArgumentsProvider myProvider;
private final String myWorkingDir;
private LanguageConsoleViewImpl myConsoleView;
protected LanguageConsoleViewImpl myConsoleView;
private final ConsoleHistoryModel myHistory = new ConsoleHistoryModel();
private AnAction myRunAction;
private ConsoleExecuteActionHandler myConsoleExecuteActionHandler;
public AbstractConsoleRunnerWithHistory(@NotNull final Project project,
@NotNull final String consoleTitle,
@NotNull final CommandLineArgumentsProvider provider,
@@ -81,16 +79,19 @@ public abstract class AbstractConsoleRunnerWithHistory {
/**
* Launch process, setup history, actions etc.
*
* @throws ExecutionException
*/
public void initAndRun() throws ExecutionException {
// Create Server process
final Process process = createProcess();
final Process process = createProcess(myProvider);
// Init console view
myConsoleView = createConsoleView();
myProcessHandler = createProcessHandler(process);
myProcessHandler = createProcessHandler(process, myProvider.getCommandLineString());
myConsoleExecuteActionHandler = createConsoleExecuteActionHandler();
ProcessTerminatedListener.attach(myProcessHandler);
@@ -147,11 +148,11 @@ public abstract class AbstractConsoleRunnerWithHistory {
protected abstract LanguageConsoleViewImpl createConsoleView();
@Nullable
protected abstract Process createProcess() throws ExecutionException;
protected abstract Process createProcess(CommandLineArgumentsProvider provider) throws ExecutionException;
protected abstract OSProcessHandler createProcessHandler(final Process process);
protected abstract OSProcessHandler createProcessHandler(final Process process, final String commandLine);
private void registerActionShortcuts(final AnAction[] actions, final JComponent component) {
public static void registerActionShortcuts(final AnAction[] actions, final JComponent component) {
for (AnAction action : actions) {
if (action.getShortcutSet() != null) {
action.registerCustomShortcutSet(action.getShortcutSet(), component);
@@ -162,52 +163,32 @@ public abstract class AbstractConsoleRunnerWithHistory {
protected AnAction[] fillToolBarActions(final DefaultActionGroup toolbarActions,
final Executor defaultExecutor,
final RunContentDescriptor myDescriptor) {
List<AnAction> actionList = Lists.newArrayList();
//stop
final AnAction stopAction = createStopAction();
toolbarActions.add(stopAction);
actionList.add(stopAction);
//close
final AnAction closeAction = createCloseAction(defaultExecutor, myDescriptor);
toolbarActions.add(closeAction);
actionList.add(closeAction);
// run action
myRunAction = new DumbAwareAction(null, null, IconLoader.getIcon("/actions/execute.png")) {
public void actionPerformed(final AnActionEvent e) {
runExecuteActionInner();
}
// run and history actions
public void update(final AnActionEvent e) {
final EditorEx editor = getLanguageConsole().getConsoleEditor();
final Lookup lookup = LookupManager.getActiveLookup(editor);
e.getPresentation().setEnabled(!myProcessHandler.isProcessTerminated() &&
(lookup == null || !lookup.isCompletion()));
}
};
EmptyAction.setupAction(myRunAction, "Console.Execute", null);
toolbarActions.add(myRunAction);
ConsoleExecutionActions executionActions =
createConsoleExecActions(getLanguageConsole(), myProcessHandler, myConsoleExecuteActionHandler);
myRunAction = executionActions.getRunAction();
actionList.addAll(executionActions.getActionsAsList());
// Help
toolbarActions.add(CommonActionsManager.getInstance().createHelpAction("interactive_console"));
actionList.add(CommonActionsManager.getInstance().createHelpAction("interactive_console"));
// history actions
final PairProcessor<AnActionEvent, String> historyProcessor = new PairProcessor<AnActionEvent, String>() {
public boolean process(final AnActionEvent e, final String s) {
new WriteCommandAction(myProject, getLanguageConsole().getFile()) {
protected void run(final Result result) throws Throwable {
getLanguageConsole().getEditorDocument().setText(s == null? "" : s);
}
}.execute();
return true;
}
};
final AnAction historyNextAction = ConsoleHistoryModel.createHistoryAction(myHistory, true, historyProcessor);
final AnAction historyPrevAction = ConsoleHistoryModel.createHistoryAction(myHistory, false, historyProcessor);
historyNextAction.getTemplatePresentation().setVisible(false);
historyPrevAction.getTemplatePresentation().setVisible(false);
toolbarActions.add(historyNextAction);
toolbarActions.add(historyPrevAction);
AnAction[] actions = actionList.toArray(new AnAction[actionList.size()]);
return new AnAction[]{stopAction, closeAction, myRunAction, historyNextAction, historyPrevAction};
toolbarActions.addAll(actions);
return actions;
}
protected AnAction createCloseAction(final Executor defaultExecutor, final RunContentDescriptor myDescriptor) {
@@ -218,50 +199,123 @@ public abstract class AbstractConsoleRunnerWithHistory {
return ActionManager.getInstance().getAction(IdeActions.ACTION_STOP_PROGRAM);
}
public void processLine(final String line) {
final Charset charset = myProcessHandler.getCharset();
final OutputStream outputStream = myProcessHandler.getProcessInput();
try {
byte[] bytes = (line + "\n").getBytes(charset.name());
outputStream.write(bytes);
outputStream.flush();
}
catch (IOException e) {
// ignore
}
}
public LanguageConsoleImpl getLanguageConsole() {
return myConsoleView.getConsole();
}
protected void runExecuteActionInner() {
// Process input and add to history
final Document document = getLanguageConsole().getCurrentEditor().getDocument();
final String text = document.getText();
final TextRange range = new TextRange(0, document.getTextLength());
getLanguageConsole().getCurrentEditor().getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
getLanguageConsole().addCurrentToHistory(range, false);
getLanguageConsole().setInputText("");
if (!StringUtil.isEmptyOrSpaces(text)){
myHistory.addToHistory(text);
}
// Send to interpreter / server
processLine(text);
public static ConsoleExecutionActions createConsoleExecActions(final LanguageConsoleImpl languageConsole,
final ProcessHandler processHandler,
final ConsoleExecuteActionHandler consoleExecuteActionHandler) {
final ConsoleHistoryModel myHistory = new ConsoleHistoryModel();
final AnAction runAction = new ConsoleExecuteAction(languageConsole,
myHistory, processHandler, consoleExecuteActionHandler);
final PairProcessor<AnActionEvent, String> historyProcessor = new PairProcessor<AnActionEvent, String>() {
public boolean process(final AnActionEvent e, final String s) {
new WriteCommandAction(languageConsole.getProject(), languageConsole.getFile()) {
protected void run(final Result result) throws Throwable {
languageConsole.getEditorDocument().setText(s == null ? "" : s);
}
}.execute();
return true;
}
};
final AnAction historyNextAction = ConsoleHistoryModel.createHistoryAction(myHistory, true, historyProcessor);
final AnAction historyPrevAction = ConsoleHistoryModel.createHistoryAction(myHistory, false, historyProcessor);
historyNextAction.getTemplatePresentation().setVisible(false);
historyPrevAction.getTemplatePresentation().setVisible(false);
return new ConsoleExecutionActions(runAction, historyNextAction, historyPrevAction);
}
protected static String getProviderCommandLine(final CommandLineArgumentsProvider provider) {
final StringBuilder builder = new StringBuilder();
for (String s : provider.getArguments()) {
if (builder.length() > 0){
builder.append(' ');
}
builder.append(s);
@NotNull
protected abstract ConsoleExecuteActionHandler createConsoleExecuteActionHandler();
public static class ConsoleExecutionActions {
private final AnAction myRunAction;
private final AnAction myNextAction;
private final AnAction myPrevAction;
public ConsoleExecutionActions(AnAction runAction, AnAction nextAction, AnAction prevAction) {
myRunAction = runAction;
myNextAction = nextAction;
myPrevAction = prevAction;
}
return builder.toString();
public AnAction[] getActions() {
return getActionsAsList().toArray(new AnAction[getActionsAsList().size()]);
}
public List<AnAction> getActionsAsList() {
return Lists.newArrayList(myRunAction, myNextAction, myPrevAction);
}
public AnAction getRunAction() {
return myRunAction;
}
}
public static class ConsoleExecuteAction extends DumbAwareAction {
public static final String ACTIONS_EXECUTE_ICON = "/actions/execute.png";
public static final String CONSOLE_EXECUTE = "Console.Execute";
private final LanguageConsoleImpl myLanguageConsole;
private final ConsoleHistoryModel myHistory;
private final ProcessHandler myProcessHandler;
private final ConsoleExecuteActionHandler myConsoleExecuteActionHandler;
public ConsoleExecuteAction(LanguageConsoleImpl languageConsole,
ConsoleHistoryModel history,
ProcessHandler processHandler,
ConsoleExecuteActionHandler consoleExecuteActionHandler) {
super(null, null, IconLoader.getIcon(ACTIONS_EXECUTE_ICON));
myLanguageConsole = languageConsole;
myHistory = history;
myProcessHandler = processHandler;
myConsoleExecuteActionHandler = consoleExecuteActionHandler;
EmptyAction.setupAction(this, CONSOLE_EXECUTE, null);
}
public void actionPerformed(final AnActionEvent e) {
myConsoleExecuteActionHandler.runExecuteAction(myLanguageConsole, myHistory);
}
public void update(final AnActionEvent e) {
final EditorEx editor = myLanguageConsole.getConsoleEditor();
final Lookup lookup = LookupManager.getActiveLookup(editor);
e.getPresentation().setEnabled(!myProcessHandler.isProcessTerminated() &&
(lookup == null || !lookup.isCompletion()));
}
}
public LanguageConsoleViewImpl getConsoleView() {
return myConsoleView;
}
public Project getProject() {
return myProject;
}
public String getConsoleTitle() {
return myConsoleTitle;
}
public String getWorkingDir() {
return myWorkingDir;
}
public ProcessHandler getProcessHandler() {
return myProcessHandler;
}
public ConsoleExecuteActionHandler getConsoleExecuteActionHandler() {
return myConsoleExecuteActionHandler;
}
}
@@ -0,0 +1,70 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.execution.runners;
import com.intellij.execution.console.LanguageConsoleImpl;
import com.intellij.execution.process.ConsoleHistoryModel;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import java.io.IOException;
import java.io.OutputStream;
/**
* @author traff
*/
public class ConsoleExecuteActionHandler {
private final ProcessHandler myProcessHandler;
public ConsoleExecuteActionHandler(ProcessHandler processHandler) {
myProcessHandler = processHandler;
}
public void runExecuteAction(LanguageConsoleImpl languageConsole,
ConsoleHistoryModel consoleHistoryModel) {
// Process input and add to history
final Document document = languageConsole.getCurrentEditor().getDocument();
final String text = document.getText();
final TextRange range = new TextRange(0, document.getTextLength());
languageConsole.getCurrentEditor().getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
languageConsole.addCurrentToHistory(range, false);
languageConsole.setInputText("");
if (!StringUtil.isEmptyOrSpaces(text)) {
consoleHistoryModel.addToHistory(text);
}
// Send to interpreter / server
processLine(text);
}
public void processLine(String line) {
//final Charset charset = myProcessHandler.getCharset();
final OutputStream outputStream = myProcessHandler.getProcessInput();
try {
//byte[] bytes = (line + "\n").getBytes(charset.name());
byte[] bytes = (line + "\n").getBytes();
outputStream.write(bytes);
outputStream.flush();
}
catch (IOException e) {
// ignore
}
}
}
@@ -37,7 +37,7 @@ import java.util.List;
*/
public class MultipleFacetEditorHelperImpl implements MultipleFacetEditorHelper {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.ui.MultipleFacetSettingsEditor");
private final List<AbstactBinding> myBindings = new ArrayList<AbstactBinding>();
private final List<AbstractBinding> myBindings = new ArrayList<AbstractBinding>();
public void bind(@NotNull ThreeStateCheckBox common, @NotNull FacetEditor[] editors, @NotNull NotNullFunction<FacetEditor, JCheckBox> fun) {
List<JCheckBox> checkBoxesList = new ArrayList<JCheckBox>();
@@ -70,17 +70,17 @@ public class MultipleFacetEditorHelperImpl implements MultipleFacetEditorHelper
}
public void unbind() {
for (AbstactBinding binding : myBindings) {
for (AbstractBinding binding : myBindings) {
binding.unbind();
}
myBindings.clear();
}
private static abstract class AbstactBinding {
private static abstract class AbstractBinding {
public abstract void unbind();
}
private static class CheckBoxBinding extends AbstactBinding implements ActionListener {
private static class CheckBoxBinding extends AbstractBinding implements ActionListener {
private final ThreeStateCheckBox myCommon;
private final List<JCheckBox> myCheckBoxesList;
private final List<Boolean> myInitialValues;
@@ -132,7 +132,7 @@ public class MultipleFacetEditorHelperImpl implements MultipleFacetEditorHelper
}
}
private static class TextFieldBinding extends AbstactBinding {
private static class TextFieldBinding extends AbstractBinding {
private final JTextField myCommon;
private final List<JTextField> myTextFields;
private final List<String> myInitialValues;
@@ -173,7 +173,7 @@ public class MultipleFacetEditorHelperImpl implements MultipleFacetEditorHelper
}
}
private static class CombobBoxBinding extends AbstactBinding implements ItemListener {
private static class CombobBoxBinding extends AbstractBinding implements ItemListener {
private final JComboBox myCommon;
private final List<JComboBox> myComponentsList;
private final List<Object> myInitialValues;
@@ -93,7 +93,7 @@ public class AlignmentInColumnsHelper {
break;
}
if (prevSubNode.getElementType() != currSubNode.getElementType()
|| StringUtil.countNewLines(prevSubNode.getChars()) != StringUtil.countNewLines(currSubNode.getChars())) {
/*|| StringUtil.countNewLines(prevSubNode.getChars()) != StringUtil.countNewLines(currSubNode.getChars())*/) {
return true;
}
prevSubNode = getSubNodeThatStartsNewLine(prevSubNode.getTreeNext(), config);
@@ -207,7 +207,8 @@ public class AlignmentInColumnsHelper {
}
/**
* Shorthand for calling {@link #findPreviousNode()} with the type of the given node as a target type.
* Shorthand for calling {@link #findPreviousNode(AlignmentInColumnsConfig, ASTNode, NodeProcessor)} with the type of
* the given node as a target type.
*
* @param config configuration to use
* @param from start node to use
@@ -24,6 +24,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl;
import com.intellij.util.messages.MessageBus;
@@ -278,41 +279,58 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
return myChangeScope;
}
public void replace(int start, int length, String str) {
public void replace(int initialStart, int length, String replace) {
// calculating fragment
// minimize replace
final int oldStart = start;
int start = 0;
int end = start + length;
final int newStringLength = str.length();
final String chars = getText(start, end);
if (chars.equals(str)) return;
final int replaceLength = replace.length();
final String chars = getText(start + initialStart, end + initialStart);
if (chars.equals(replace)) return;
int newStartInString = 0;
int newEndInString = newStringLength;
while (newStartInString < newStringLength && start < end && str.charAt(newStartInString) == chars.charAt(start - oldStart)) {
int newStartInReplace = 0;
int newEndInReplace = replaceLength;
while (newStartInReplace < replaceLength && start < end && replace.charAt(newStartInReplace) == chars.charAt(start)) {
start++;
newStartInString++;
newStartInReplace++;
}
while (end > start && newEndInString > newStartInString && str.charAt(newEndInString - 1) == chars.charAt(end - oldStart - 1)) {
newEndInString--;
while (start < end && newStartInReplace < newEndInReplace && replace.charAt(newEndInReplace - 1) == chars.charAt(end - 1)) {
newEndInReplace--;
end--;
}
// optimization: when delete fragment from the middle of the text, prefer split at the line boundaries
if (newStartInReplace == newEndInReplace && start > 0 && start < end && StringUtil.indexOf(chars, '\n', start, end) != -1) {
// try to align to the line boundaries
while (start > 0 &&
newStartInReplace > 0 &&
chars.charAt(start - 1) == chars.charAt(end - 1) &&
chars.charAt(end - 1) != '\n'
) {
start--;
end--;
newStartInReplace--;
newEndInReplace--;
}
}
//[mike] dirty hack for xml:
//make sure that deletion of <t> in: <tag><t/><tag> doesn't remove t/><
//which is perfectly valid but invalidates range markers
start += initialStart;
end += initialStart;
final CharSequence charsSequence = myDocument.getCharsSequence();
while (start < charsSequence.length() && end < charsSequence.length() && start > 0 &&
charsSequence.subSequence(start, end).toString().endsWith("><") && charsSequence.charAt(start - 1) == '<') {
start--;
newStartInString--;
newStartInReplace--;
end--;
newEndInString--;
newEndInReplace--;
}
str = str.substring(newStartInString, newEndInString);
replace = replace.substring(newStartInReplace, newEndInReplace);
length = end - start;
final Pair<MutableTextRange, StringBuffer> fragment = getFragmentByRange(start, length);
@@ -320,7 +338,7 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
final int startInFragment = start - fragment.getFirst().getStartOffset();
// text range adjustment
final int lengthDiff = str.length() - length;
final int lengthDiff = replace.length() - length;
final Iterator<Pair<MutableTextRange, StringBuffer>> iterator = myAffectedFragments.iterator();
boolean adjust = false;
while (iterator.hasNext()) {
@@ -329,7 +347,7 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
if (pair == fragment) adjust = true;
}
fragmentReplaceText.replace(startInFragment, startInFragment + length, str);
fragmentReplaceText.replace(startInFragment, startInFragment + length, replace);
}
private String getText(final int start, final int end) {
@@ -44,7 +44,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.PsiTreeDebugBuilder;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade;
import com.intellij.psi.impl.source.codeStyle.Helper;
import com.intellij.psi.impl.source.codeStyle.IndentHelper;
import com.intellij.psi.impl.source.codeStyle.HelperFactory;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
@@ -537,25 +537,25 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable
final Document document,
final TextRange[] indents,
final int indentAdjustment) {
final Helper formatHelper = HelperFactory.createHelper(file.getFileType(), file.getProject());
final IndentHelper formatIndentHelper = HelperFactory.createHelper(file.getFileType(), file.getProject());
final CharSequence charsSequence = document.getCharsSequence();
for (final TextRange indent : indents) {
final String oldIndentStr = charsSequence.subSequence(indent.getStartOffset() + 1, indent.getEndOffset()).toString();
final int oldIndent = formatHelper.getIndent(oldIndentStr, true);
final String newIndentStr = formatHelper.fillIndent(Math.max(oldIndent + indentAdjustment, 0));
final int oldIndent = formatIndentHelper.getIndent(oldIndentStr, true);
final String newIndentStr = formatIndentHelper.fillIndent(Math.max(oldIndent + indentAdjustment, 0));
document.replaceString(indent.getStartOffset() + 1, indent.getEndOffset(), newIndentStr);
}
}
private static int getNewIndent(final PsiFile psiFile, final int firstWhitespace) {
final Helper formatHelper = HelperFactory.createHelper(psiFile.getFileType(), psiFile.getProject());
final IndentHelper formatIndentHelper = HelperFactory.createHelper(psiFile.getFileType(), psiFile.getProject());
final Document document = psiFile.getViewProvider().getDocument();
final int startOffset = document.getLineStartOffset(document.getLineNumber(firstWhitespace));
int endOffset = startOffset;
final CharSequence charsSequence = document.getCharsSequence();
while (Character.isWhitespace(charsSequence.charAt(endOffset++))) ;
final String newIndentStr = charsSequence.subSequence(startOffset, endOffset - 1).toString();
return formatHelper.getIndent(newIndentStr, true);
return formatIndentHelper.getIndent(newIndentStr, true);
}
public boolean isDisabled() {
@@ -37,7 +37,6 @@ import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.impl.source.tree.TreeUtil;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -135,8 +134,8 @@ public class CodeEditUtil {
return;
}
final PsiFile containingFile = psiElement.getContainingFile();
final Helper helper = HelperFactory.createHelper(containingFile.getFileType(), containingFile.getProject());
setOldIndentation((TreeElement)first, helper.getIndent(first));
final IndentHelper indentHelper = HelperFactory.createHelper(containingFile.getFileType(), containingFile.getProject());
setOldIndentation((TreeElement)first, indentHelper.getIndent(first));
}
public static int getOldIndentation(ASTNode node){
@@ -307,7 +307,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
if (!SourceTreeToPsiMap.hasTreeElement(file)) {
return false;
}
Helper helper = HelperFactory.createHelper(file.getFileType(), myProject);
IndentHelper indentHelper = HelperFactory.createHelper(file.getFileType(), myProject);
CharSequence chars = file.getViewProvider().getContents();
int start = CharArrayUtil.shiftBackward(chars, offset - 1, " \t");
if (start > 0 && chars.charAt(start) != '\n' && chars.charAt(start) != '\r') {
@@ -334,7 +334,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
}
*/
if (getSettings().KEEP_FIRST_COLUMN_COMMENT && isCommentToken(element)) {
if (helper.getIndent(element, true) == 0) {
if (indentHelper.getIndent(element, true) == 0) {
return false;
}
}
@@ -382,8 +382,8 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
public Indent getIndent(String text, FileType fileType) {
int indent = HelperFactory.createHelper(fileType, myProject).getIndent(text, true);
int indenLevel = indent / Helper.INDENT_FACTOR;
int spaceCount = indent - indenLevel * Helper.INDENT_FACTOR;
int indenLevel = indent / IndentHelper.INDENT_FACTOR;
int spaceCount = indent - indenLevel * IndentHelper.INDENT_FACTOR;
return new IndentImpl(getSettings(), indenLevel, spaceCount, fileType);
}
@@ -408,7 +408,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
}
}
}
return HelperFactory.createHelper(fileType, myProject).fillIndent(indentLevel * Helper.INDENT_FACTOR + spaceCount);
return HelperFactory.createHelper(fileType, myProject).fillIndent(indentLevel * IndentHelper.INDENT_FACTOR + spaceCount);
}
public Indent zeroIndent() {
@@ -24,20 +24,20 @@ import com.intellij.openapi.project.Project;
public class HelperFactory {
private static Factory INSTANCE = new Factory() {
public Helper create(final FileType fileType, final Project project) {
return new Helper(fileType, project);
public IndentHelper create(final FileType fileType, final Project project) {
return new IndentHelper(fileType, project);
}
};
private HelperFactory() {
}
public static Helper createHelper(FileType fileType, Project project) {
public static IndentHelper createHelper(FileType fileType, Project project) {
return INSTANCE.create(fileType, project);
}
interface Factory {
Helper create(FileType fileType, Project project);
IndentHelper create(FileType fileType, Project project);
}
public static void setFactory(Factory factory) {
@@ -24,11 +24,11 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.TreeUtil;
public class Helper {
public class IndentHelper {
private final CodeStyleSettings mySettings;
private final FileType myFileType;
protected Helper(FileType fileType, Project project) {
protected IndentHelper(FileType fileType, Project project) {
mySettings = CodeStyleSettingsManager.getSettings(project);
myFileType = fileType;
}
@@ -45,10 +45,10 @@ public class Helper {
return getIndentInner(element, includeNonSpace, 0);
}
public static final int TOO_BIG_WALK_THRESHOULD = 450;
public static final int TOO_BIG_WALK_THRESHOLD = 450;
protected int getIndentInner(final ASTNode element, boolean includeNonSpace, int recursionLevel) {
if (recursionLevel > TOO_BIG_WALK_THRESHOULD) return 0;
if (recursionLevel > TOO_BIG_WALK_THRESHOLD) return 0;
if (element.getTreePrev() != null) {
ASTNode prev = element.getTreePrev();
@@ -358,6 +358,8 @@ public class CompositeElement extends TreeElement {
cachedLength = myCachedLength;
if (cachedLength >= 0) return cachedLength;
ApplicationManager.getApplication().assertReadAccessAllowed(); //otherwise a write action can modify the tree while we're walking it
walkCachingLength();
return myCachedLength;
}
@@ -16,10 +16,12 @@
package com.intellij.refactoring.changeSignature;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Iconable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Icons;
import com.intellij.util.IncorrectOperationException;
@@ -32,14 +34,14 @@ import javax.swing.*;
* User: anna
* Date: Sep 6, 2010
*/
public class ChangeSignatureDetectorAction implements IntentionAction, Iconable {
public class ChangeSignatureDetectorAction extends PsiElementBaseIntentionAction implements Iconable {
private static final Logger LOG = Logger.getInstance("#" + ChangeSignatureDetectorAction.class.getName());
@NonNls public static final String CHANGE_SIGNATURE = "Change signature ...";
@NotNull
@Override
public String getText() {
return "Change signature ...";
return CHANGE_SIGNATURE;
}
@NotNull
@@ -49,8 +51,8 @@ public class ChangeSignatureDetectorAction implements IntentionAction, Iconable
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return ChangeSignatureGestureDetector.getInstance(project).containsChangeSignatureChange(file);
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
return ChangeSignatureGestureDetector.getInstance(project).isChangeSignatureAvailable(element);
}
@Override
@@ -1,129 +0,0 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.refactoring.changeSignature;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.HighlightVisitor;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Icons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
/**
* User: anna
* Date: Sep 8, 2010
*/
public class ChangeSignatureGestureVisitor implements HighlightVisitor {
private static final Logger LOG = Logger.getInstance("#" + ChangeSignatureGestureDetector.class.getName());
@NonNls private static final String SIGNATURE_SHOULD_BE_POSSIBLY_CHANGED = "Signature should be possibly changed";
@Override
public boolean suitableForFile(PsiFile file) {
return file != null && LanguageChangeSignatureDetectors.isSuitableForLanguage(file.getLanguage());
}
@Override
public void visit(final PsiElement element, HighlightInfoHolder holder) {
final ChangeSignatureGestureDetector detector = ChangeSignatureGestureDetector.getInstance(element.getProject());
if (detector.isChangeSignatureAvailable(element)) {
final TextRange range = LanguageChangeSignatureDetectors.getHighlightingRange(element);
LOG.assertTrue(range != null);
final ChangeInfo changeInfo = detector.getChangeInfo(element.getContainingFile());
LOG.assertTrue(changeInfo != null);
final boolean toHighlight = LanguageChangeSignatureDetectors.INSTANCE.forLanguage(element.getLanguage()).isToHighlight(element, changeInfo);
final HighlightInfo info = new HighlightInfo(new TextAttributes(null, null, null, toHighlight ? EffectType.BOXED : null, Font.PLAIN),
HighlightInfoType.INFORMATION, range.getStartOffset(), range.getEndOffset(),
SIGNATURE_SHOULD_BE_POSSIBLY_CHANGED, SIGNATURE_SHOULD_BE_POSSIBLY_CHANGED,
HighlightSeverity.INFORMATION, false, true, false);
final ChangeSignatureDetectorAction action = new ChangeSignatureDetectorAction();
info.setGutterIconRenderer(new MyGutterIconRenderer(action, element));
holder.add(info);
}
}
@Override
public boolean analyze(Runnable action, boolean updateWholeFile, PsiFile file) {
action.run();
return true;
}
@Override
public HighlightVisitor clone() {
return new ChangeSignatureGestureVisitor();
}
@Override
public int order() {
return 10;
}
private static class MyGutterIconRenderer extends GutterIconRenderer {
private final ChangeSignatureDetectorAction myAction;
private final PsiElement myElement;
public MyGutterIconRenderer(ChangeSignatureDetectorAction action, PsiElement element) {
myAction = action;
myElement = element;
}
@NotNull
@Override
public Icon getIcon() {
return Icons.ADVICE_ICON;
}
@Override
public AnAction getClickAction() {
return new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
myAction.invoke(myElement.getProject(), null, myElement.getContainingFile());
}
};
}
@Override
public String getTooltipText() {
return ChangeSignatureDetectorAction.CHANGE_SIGNATURE;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof MyGutterIconRenderer)) return false;
return true;
}
@Override
public int hashCode() {
return 0;
}
}
}
@@ -15,6 +15,8 @@
*/
package com.intellij.execution.process;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
@@ -22,14 +24,27 @@ import java.util.Map;
/**
* @author Roman.Chernyatchik, oleg
*/
public interface CommandLineArgumentsProvider {
public abstract class CommandLineArgumentsProvider {
/**
* @return Commands to execute (one command corresponds to one add argument)
*/
String[] getArguments();
public abstract String[] getArguments();
boolean passParentEnvs();
public abstract boolean passParentEnvs();
@Nullable
Map<String, String> getAdditionalEnvs();
public abstract Map<String, String> getAdditionalEnvs();
public String getCommandLineString() {
return toCommandLine(getArguments());
}
public static String toCommandLine(String... commands) {
if (commands.length > 0) {
commands[0] = FileUtil.toSystemDependentName(commands[0]);
return StringUtil.join(commands, " ");
}
return "";
}
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -237,8 +238,7 @@ public class BrowserUtil {
if (jarVirtualFile == null) return null;
String targetFilePath = file.getPath();
String targetFileRelativePath = targetFilePath.substring(
targetFilePath.indexOf(JarFileSystem.JAR_SEPARATOR) + JarFileSystem.JAR_SEPARATOR.length());
String targetFileRelativePath = StringUtil.substringAfter(targetFilePath, JarFileSystem.JAR_SEPARATOR);
String jarVirtualFileLocationHash = jarVirtualFile.getName() + Integer.toHexString(jarVirtualFile.getUrl().hashCode());
final File outputDir = new File(getExtractedFilesDir(), jarVirtualFileLocationHash);
@@ -43,7 +43,7 @@ public class JBScrollPane extends JScrollPane {
init();
}
private void init() {
protected void init() {
setBorder(IdeBorderFactory.createBorder());
setCorner(UPPER_RIGHT_CORNER, new Corner(UPPER_RIGHT_CORNER));
setCorner(UPPER_LEFT_CORNER, new Corner(UPPER_LEFT_CORNER));
@@ -244,7 +244,13 @@ public class ProjectUtil {
final FileType fileType) {
final boolean iprBased = fileType instanceof WorkspaceFileType || fileType instanceof ProjectFileType || fileType instanceof ModuleFileType;
if (iprBased) return true;
final VirtualFile parent = file.getParent();
return parent != null && parent.getName().equals(DIRECTORY_BASED_PROJECT_DIR);
VirtualFile parent = file.getParent();
if (parent != null) {
if (parent.getName().equals(DIRECTORY_BASED_PROJECT_DIR)) return true;
parent = parent.getParent();
if (parent != null && parent.getName().equals(DIRECTORY_BASED_PROJECT_DIR)) return true;
}
return false;
}
}
@@ -68,6 +68,7 @@ import com.intellij.util.IJSwingUtilities;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.ui.ButtonlessScrollBarUI;
import com.intellij.util.ui.EmptyClipboardOwner;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.UiNotifyConnector;
@@ -5198,6 +5199,34 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
public JScrollBar createVerticalScrollBar() {
return new MyScrollBar(Adjustable.VERTICAL);
}
@Override
protected void init() {
super.init();
setCorner(LOWER_LEFT_CORNER, new JPanel() {
@Override
public void paint(Graphics g) {
final Rectangle bounds = getBounds();
int width = bounds.width;
int height = bounds.height;
g.setColor(ButtonlessScrollBarUI.TRACK_BACKGROUND);
g.fillRect(0, 0, width, height);
int shortner = 0;
if (myGutterComponent.isFoldingOutlineShown()) {
shortner = myGutterComponent.getFoldingAreaWidth() / 2;
}
g.setColor(myGutterComponent.getBackground());
g.fillRect(0, 0, width - shortner, height);
g.setColor(ButtonlessScrollBarUI.TRACK_BORDER);
g.drawLine(width - 1 - shortner, 0, width - 1 - shortner, height);
g.drawLine(0, 0, width - 1, 0);
}
});
}
}
private class MyHeaderPanel extends JPanel {
@@ -351,14 +351,14 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
@Override
protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
g.translate(5, 0);
g.translate(6, 0);
super.paintThumb(g, c, thumbBounds);
g.translate(-5, 0);
g.translate(-6, 0);
}
@Override
protected int adjustThumbWidth(int width) {
return width - 5;
return width - 1;
}
@Override
@@ -576,6 +576,11 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw
}
}
@Override
public String toString() {
return myCache.toString();
}
private class CacheState {
public boolean valid = true;
@@ -249,7 +249,9 @@ public class FrameWrapper implements Disposable {
}
myPreferedFocus = null;
myFocusTrackback.restoreFocus();
if (myFocusTrackback != null) {
myFocusTrackback.restoreFocus();
}
if (myComponent != null && myFocusWatcher != null) {
myFocusWatcher.deinstall(myComponent);
}
@@ -341,21 +341,26 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
}
public void doWhenFocusSettlesDown(@NotNull final Runnable runnable) {
if (myRunContext != null) {
runnable.run();
return;
}
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
if (myRunContext != null) {
runnable.run();
return;
}
final boolean needsRestart = isIdleQueueEmpty();
myIdleRequests.add(runnable);
final boolean needsRestart = isIdleQueueEmpty();
myIdleRequests.add(runnable);
if (isFocusTransferReady()) {
flushIdleRequests();
} else {
if (needsRestart) {
restartIdleAlarm();
if (isFocusTransferReady()) {
flushIdleRequests();
} else {
if (needsRestart) {
restartIdleAlarm();
}
}
}
}
});
}
private void restartIdleAlarm() {
@@ -410,7 +415,9 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
final Runnable[] all = myIdleRequests.toArray(new Runnable[myIdleRequests.size()]);
myIdleRequests.clear();
for (Runnable each : all) {
each.run();
if (each != null) {
each.run();
}
}
}
}
@@ -466,6 +466,9 @@
<intentionAction>
<className>com.intellij.codeInsight.intention.impl.EditFoldingOptionsAction</className>
</intentionAction>
<intentionAction>
<className>com.intellij.refactoring.changeSignature.ChangeSignatureDetectorAction</className>
</intentionAction>
<!-- CodeInsightSettings -->
<editorActionHandler action="EditorEnter" implementationClass="com.intellij.codeInsight.editorActions.EnterHandler" id="editorEnter"/>
@@ -595,7 +598,7 @@
<indexPatternProvider implementation="com.intellij.ide.todo.TodoIndexPatternProvider"/>
<hectorComponentProvider implementation="com.intellij.codeInsight.daemon.PowerSaveHectorProvider"/>
<highlightVisitor implementation="com.intellij.refactoring.changeSignature.ChangeSignatureGestureVisitor"/>
<editorActionHandler action="EditorEscape" implementationClass="com.intellij.refactoring.changeSignature.EditorEscapeHandler" id="hide-cs-gesture" order="before hide-hints"/>
<copyPastePostProcessor implementation="com.intellij.codeInsight.editorActions.CopyPasteIndentProcessor"/>
@@ -1337,6 +1337,18 @@ public class StringUtil {
return -1;
}
public static int indexOfSubstringEnd(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
if (i == -1) return -1;
return i + subString.length();
}
public static String substringAfter(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
if (i == -1) return null;
return text.substring(i + subString.length());
}
/**
* Allows to retrieve index of last occurrence of the given symbols at <code>[start; end)</code> sub-sequence of the given text.
*
@@ -20,7 +20,7 @@
* Date: Jul 26, 2007
* Time: 3:52:05 PM
*/
package com.intellij.util;
package com.intellij.util.concurrency;
import org.jetbrains.annotations.NotNull;
import sun.misc.Unsafe;
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.annotate;
import com.intellij.util.Consumer;
/**
* @author Konstantin Bulenkov
*/
public interface LineNumberListener extends Consumer<Integer> {
}
@@ -34,7 +34,6 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.actions.VcsContextFactory;
import com.intellij.openapi.vcs.annotate.LineAnnotationAspect;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
@@ -583,9 +582,14 @@ public class VcsUtil {
}
private static String ANNO_ASPECT = "show.vcs.annotation.aspect.";
public static boolean isAspectAvailableByDefault(LineAnnotationAspect aspect) {
if (aspect.getId() == null) return aspect.isShowByDefault();
return PropertiesComponent.getInstance().getBoolean(ANNO_ASPECT + aspect.getId(), aspect.isShowByDefault());
//public static boolean isAspectAvailableByDefault(LineAnnotationAspect aspect) {
// if (aspect.getId() == null) return aspect.isShowByDefault();
// return PropertiesComponent.getInstance().getBoolean(ANNO_ASPECT + aspect.getId(), aspect.isShowByDefault());
//}
public static boolean isAspectAvailableByDefault(String id) {
if (id == null) return false;
return PropertiesComponent.getInstance().getBoolean(ANNO_ASPECT + id, true);
}
public static void setAspectAvailability(String aspectID, boolean showByDefault) {
@@ -15,7 +15,9 @@
*/
package com.intellij.openapi.vcs.actions;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
@@ -215,12 +217,17 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
final List<AnnotationFieldGutter> gutters = new ArrayList<AnnotationFieldGutter>();
final AnnotationSourceSwitcher switcher = fileAnnotation.getAnnotationSourceSwitcher();
final AnnotationPresentation presentation;
final List<AnAction> additionalActions = new ArrayList<AnAction>();
if (vcs.getCommittedChangesProvider() != null) {
final ShowDiffFromAnnotation showDiff = new ShowDiffFromAnnotation(getUpToDateLineNumber, fileAnnotation, vcs, file);
presentation = new AnnotationPresentation(highlighting, switcher, editorGutter, gutters, showDiff);
presentation.addLineNumberListener(showDiff);
} else {
presentation = new AnnotationPresentation(highlighting, switcher, editorGutter, gutters);
additionalActions.add(new ShowDiffFromAnnotation(getUpToDateLineNumber, fileAnnotation, vcs, file));
}
additionalActions.add(new CopyRevisionNumberAction(fileAnnotation));
presentation = new AnnotationPresentation(highlighting, switcher, editorGutter, gutters, additionalActions.toArray(new AnAction[additionalActions.size()]));
for (AnAction action : additionalActions) {
if (action instanceof LineNumberListener) {
presentation.addLineNumberListener((LineNumberListener)action);
}
}
final Map<String, Color> bgColorMap = Registry.is("vcs.show.colored.annotations") ? computeBgColors(fileAnnotation) : null;
@@ -250,13 +257,14 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
gutter.setAspectValueToBgColorMap(bgColorMap);
gutters.add(gutter);
}
gutters.add(new HighlightedAdditionalColumn(fileAnnotation, editor, null, presentation, highlighting, bgColorMap));
presentation.addAction(new AnnotateActionGroup(gutters, editorGutter), 1); //do not include history gutter
if (historyIds != null) {
gutters.add(new HistoryIdColumn(fileAnnotation, editor, presentation, bgColorMap, historyIds));
}
gutters.add(new HighlightedAdditionalColumn(fileAnnotation, editor, null, presentation, highlighting, bgColorMap));
presentation.addAction(new AnnotateActionGroup(gutters, editorGutter), 1);
for (AnnotationFieldGutter gutter : gutters) {
final AnnotationGutterLineConvertorProxy proxy = new AnnotationGutterLineConvertorProxy(getUpToDateLineNumber, gutter);
@@ -31,7 +31,6 @@ import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -123,13 +122,7 @@ class AnnotationFieldGutter implements ActiveAnnotationGutter {
}
public List<AnAction> getPopupActions(int line, final Editor editor) {
final ArrayList<AnAction> actions = new ArrayList<AnAction>(myPresentation.getActions(line));
//TODO do something with files where user has made changes. Calculate actual 'line"
final VcsRevisionNumber revisionNumber = myAnnotation.getLineRevisionNumber(line);
if (revisionNumber != null) {
actions.add(0, new CopyRevisionNumberAction(revisionNumber.asString()));
}
return actions;
return myPresentation.getActions(line);
}
public void gutterClosed() {
@@ -176,7 +169,7 @@ class AnnotationFieldGutter implements ActiveAnnotationGutter {
}
public boolean isAvailable() {
return myShowAdditionalInfo || myAspect == null || VcsUtil.isAspectAvailableByDefault(myAspect);
return myShowAdditionalInfo || VcsUtil.isAspectAvailableByDefault(getID());
}
@Nullable
@@ -39,7 +39,7 @@ class AnnotationPresentation implements TextAnnotationPresentation {
private final AnnotationSourceSwitcher mySwitcher;
private final ArrayList<AnAction> myActions;
private SwitchAnnotationSourceAction mySwitchAction;
private final List<Consumer<Integer>> myPopupLineNumberListeners;
private final List<LineNumberListener> myPopupLineNumberListeners;
AnnotationPresentation(@NotNull final HighlightAnnotationsActions highlighting, @Nullable final AnnotationSourceSwitcher switcher,
final EditorGutterComponentEx gutter,
@@ -47,7 +47,7 @@ class AnnotationPresentation implements TextAnnotationPresentation {
final AnAction... actions) {
myHighlighting = highlighting;
mySwitcher = switcher;
myPopupLineNumberListeners = new LinkedList<Consumer<Integer>>();
myPopupLineNumberListeners = new LinkedList<LineNumberListener>();
myActions = new ArrayList<AnAction>();
myActions.add(Separator.getInstance());
@@ -68,7 +68,7 @@ class AnnotationPresentation implements TextAnnotationPresentation {
myActions.add(new ShowShortenNames(gutter));
}
public void addLineNumberListener(final Consumer<Integer> listener) {
public void addLineNumberListener(final LineNumberListener listener) {
myPopupLineNumberListeners.add(listener);
}
@@ -82,7 +82,7 @@ class AnnotationPresentation implements TextAnnotationPresentation {
}
public List<AnAction> getActions(int line) {
for (Consumer<Integer> listener : myPopupLineNumberListeners) {
for (LineNumberListener listener : myPopupLineNumberListeners) {
listener.consume(line);
}
return myActions;
@@ -18,21 +18,41 @@ package com.intellij.openapi.vcs.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.annotate.LineNumberListener;
import com.intellij.openapi.vcs.history.TextTransferrable;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
/**
* @author Konstantin Bulenkov
*/
public class CopyRevisionNumberAction extends AnAction {
private final String myRevision;
public class CopyRevisionNumberAction extends AnAction implements LineNumberListener {
private final FileAnnotation myAnnotation;
private int myLineNumber = -1;
public CopyRevisionNumberAction(String revision) {
public CopyRevisionNumberAction(FileAnnotation annotation) {
super("Copy revision number");
myRevision = revision;
myAnnotation = annotation;
}
@Override
public void actionPerformed(AnActionEvent e) {
CopyPasteManager.getInstance().setContents(new TextTransferrable(myRevision, myRevision));
final VcsRevisionNumber revisionNumber = myAnnotation.getLineRevisionNumber(myLineNumber);
if (revisionNumber != null) {
final String revision = revisionNumber.asString();
CopyPasteManager.getInstance().setContents(new TextTransferrable(revision, revision));
}
}
@Override
public void update(AnActionEvent e) {
final boolean enabled = myLineNumber != -1 && myAnnotation.getLineRevisionNumber(myLineNumber) != null;
e.getPresentation().setEnabled(enabled);
e.getPresentation().setVisible(enabled);
}
@Override
public void consume(Integer integer) {
myLineNumber = integer;
}
}
@@ -41,6 +41,7 @@ class HistoryIdColumn extends AnnotationFieldGutter {
@Override
public String getLineText(int line, Editor editor) {
if (!isAvailable()) return "";
final VcsRevisionNumber revisionNumber = myAnnotation.getLineRevisionNumber(line);
if (revisionNumber != null) {
final Integer num = myHistoryIds.get(revisionNumber.asString());
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.annotate.LineNumberListener;
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.actions.ShowDiffAction;
@@ -37,7 +38,6 @@ import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.containers.CacheOneStepIterator;
import org.jetbrains.annotations.NotNull;
@@ -50,7 +50,7 @@ import java.util.List;
/**
* @author Konstantin Bulenkov
*/
class ShowDiffFromAnnotation extends AnAction implements Consumer<Integer> {
class ShowDiffFromAnnotation extends AnAction implements LineNumberListener {
private final UpToDateLineNumberProvider myLineNumberProvider;
private final FileAnnotation myFileAnnotation;
private final AbstractVcs myVcs;
@@ -48,10 +48,10 @@ public class AbstractMethodWithMissingImplementationsInspection
}
public BaseInspectionVisitor buildVisitor() {
return new AbstactMethodWithMissingImplementationsVisitor();
return new AbstractMethodWithMissingImplementationsVisitor();
}
private static class AbstactMethodWithMissingImplementationsVisitor
private static class AbstractMethodWithMissingImplementationsVisitor
extends BaseInspectionVisitor {
@Override public void visitMethod(PsiMethod method) {
@@ -191,9 +191,14 @@ public class GroovyToJavaGenerator {
private void generateClassStub(@NotNull PsiClass typeDefinition, GrPackageDefinition packageDefinition, Map<String, String> output) {
StringBuffer text = new StringBuffer();
writeTypeDefinition(text, typeDefinition, packageDefinition, true);
try {
writeTypeDefinition(text, typeDefinition, packageDefinition, true);
output.put(getPackageDirectory(packageDefinition) + typeDefinition.getName() + "." + "java", text.toString());
output.put(getPackageDirectory(packageDefinition) + typeDefinition.getName() + "." + "java", text.toString());
}
catch (Throwable e) {
LOG.error(e);
}
}
private static GrTopStatement[] getTopStatementsInReadAction(final GroovyFileBase myPsiFile) {
@@ -26,6 +26,8 @@ import com.intellij.debugger.engine.jdi.VirtualMachineProxy;
import com.intellij.debugger.requests.ClassPrepareRequestor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
@@ -34,10 +36,7 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.*;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
@@ -240,9 +239,17 @@ public class GroovyPositionManager implements PositionManager {
}
final GlobalSearchScope searchScope = myDebugProcess.getSearchScope();
final PsiClass[] classes = GroovyPsiManager.getInstance(project).getNamesCache().getClassesByFQName(qName, searchScope);
PsiClass clazz = classes.length == 1 ? classes[0] : null;
if (clazz != null) return clazz.getContainingFile();
try {
final PsiClass[] classes = GroovyPsiManager.getInstance(project).getNamesCache().getClassesByFQName(qName, searchScope);
PsiClass clazz = classes.length == 1 ? classes[0] : null;
if (clazz != null) return clazz.getContainingFile();
}
catch (ProcessCanceledException e) {
return null;
}
catch (IndexNotReadyException e) {
return null;
}
DirectoryIndex directoryIndex = DirectoryIndex.getInstance(project);
int dotIndex = qName.lastIndexOf(".");
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.gant;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.FilenameIndex;
@@ -51,6 +52,8 @@ public class GantPositionManagerHelper extends ScriptPositionManagerHelper {
}
catch (ProcessCanceledException ignored) {
}
catch (IndexNotReadyException ignored) {
}
return null;
}
}
@@ -126,6 +126,7 @@ public class VariableDefinitions implements GroovyElementTypes {
}
defaultValueMarker.done(DEFAULT_ANNOTATION_VALUE);
ThrowClause.parse(builder); //every method must have a throws clause, so says the Java API
return ANNOTATION_METHOD;
}
if (ParserUtils.lookAhead(builder, mNLS, kTHROWS) || ParserUtils.lookAhead(builder, mNLS, mLCURLY)) {
@@ -281,7 +281,7 @@ public abstract class GrMethodBaseImpl<T extends NamedStub> extends GroovyBaseEl
@NotNull
public PsiReferenceList getThrowsList() {
GrThrowsClause clause = findChildByClass(GrThrowsClause.class);
assert clause != null;
assert clause != null : this;
return clause;
}
@@ -17,6 +17,7 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.types;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.InheritanceImplUtil;
@@ -53,6 +54,7 @@ import java.util.List;
* @author ilyas
*/
public class GrTypeParameterImpl extends GroovyPsiElementImpl implements GrTypeParameter {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.lang.psi.impl.types.GrTypeParameterImpl");
public GrTypeDefinitionBody getBody() {
return null;
}
@@ -302,6 +304,9 @@ public class GrTypeParameterImpl extends GroovyPsiElementImpl implements GrTypeP
final PsiElement parent = getParent();
if (parent == null) throw new PsiInvalidElementAccessException(this);
final PsiElement parentParent = parent.getParent();
if (parentParent != null && !(parentParent instanceof PsiTypeParameterListOwner)) {
throw new AssertionError("CCE: " + parentParent);
}
return (PsiTypeParameterListOwner)parentParent;
}
@@ -39,6 +39,8 @@ Groovy script
Literal
PsiElement(Integer)('8')
PsiElement(])(']')
Throw clause
<empty list>
PsiElement(;)(';')
PsiElement(new line)('\n')
PsiElement(})('}')
@@ -44,5 +44,7 @@ Groovy script
PsiWhiteSpace(' ')
Annotation arguments
<empty list>
Throw clause
<empty list>
PsiElement(new line)('\n')
PsiElement(})('}')
@@ -39,5 +39,7 @@ Groovy script
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('5')
Throw clause
<empty list>
PsiElement(new line)('\n')
PsiElement(})('}')
@@ -557,7 +557,14 @@ public abstract class DomInvocationHandler<T extends AbstractDomChildDescription
}
final List<XmlTag> tags = DomImplUtil.findSubTags(subTags, evaluatedXmlName, getFile());
if (tags.size() > index) {
return myManager.getSemService().getSemElement(DomManagerImpl.DOM_INDEXED_HANDLER_KEY, tags.get(index));
final XmlTag child = tags.get(index);
final IndexedElementInvocationHandler semElement = myManager.getSemService().getSemElement(DomManagerImpl.DOM_INDEXED_HANDLER_KEY, child);
if (semElement == null) {
final IndexedElementInvocationHandler take2 = myManager.getSemService().getSemElement(DomManagerImpl.DOM_INDEXED_HANDLER_KEY, child);
throw new AssertionError("No DOM at XML. Parent=" + tag + "; child=" + child + "; index=" + index+ "; second attempt=" + take2);
}
return semElement;
}
}
return new IndexedElementInvocationHandler(evaluatedXmlName, description, index, new VirtualDomParentStrategy(this), myManager, "");
@@ -22,7 +22,7 @@ package com.intellij.lang.html;
import com.intellij.codeInsight.completion.CompletionUtil;
import com.intellij.codeInsight.daemon.XmlErrorMessages;
import com.intellij.lang.PsiBuilder;
import com.intellij.psi.impl.source.codeStyle.Helper;
import com.intellij.psi.impl.source.codeStyle.IndentHelper;
import com.intellij.psi.tree.CustomParsingType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ILazyParseableElementType;
@@ -615,5 +615,5 @@ public class HtmlParsing {
myBuilder.error(message);
}
private static final int MAGIC_FRAME_COUNT = Helper.TOO_BIG_WALK_THRESHOULD + (int)(Math.pow(Math.E, Math.PI) * Math.sin(Math.random()));
private static final int MAGIC_FRAME_COUNT = IndentHelper.TOO_BIG_WALK_THRESHOLD + (int)(Math.pow(Math.E, Math.PI) * Math.sin(Math.random()));
}