diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationErrorsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationErrorsComponent.java index bbf11c63dfe4..ceec9ac6ff15 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationErrorsComponent.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationErrorsComponent.java @@ -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()))); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/JdkListConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/JdkListConfigurable.java index ab2fc0aaca2d..213a54ad599e 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/JdkListConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/JdkListConfigurable.java @@ -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 diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java index d1dd5faf14d7..76a73bc8d01b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java @@ -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)) { diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index 6bf2f39f859a..6189fdfa094f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -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; + // } + // 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 + } } } diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index b6e09cc8b234..53fbf0f4e68c 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -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(); } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaHelperFactory.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaHelperFactory.java index 0a372306d6c1..f54d43485d93 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaHelperFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaHelperFactory.java @@ -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); } } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaHelper.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaIndentHelper.java similarity index 94% rename from java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaHelper.java rename to java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaIndentHelper.java index 01e8b0389519..5fd7811feb60 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaHelper.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaIndentHelper.java @@ -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(); diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ShiftIndentInsideHelper.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ShiftIndentInsideHelper.java index d828085352a9..6b9ff5fd85eb 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ShiftIndentInsideHelper.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ShiftIndentInsideHelper.java @@ -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; } } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java index d698a1be14bb..dfb49cfd007d 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java @@ -56,7 +56,11 @@ public class PsiAnnotationImpl extends JavaStubPsiElement 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) { diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java index 469973b164c8..839e0e129605 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java @@ -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(); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java index 21662cf5cb64..b4ee2f244238 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java @@ -347,51 +347,20 @@ public class MoveInnerProcessor extends BaseRefactoringProcessor { protected boolean preprocessUsages(Ref refUsages) { final MultiMap conflicts = new MultiMap(); - + final HashMap> reported = new HashMap>(); class Visitor extends JavaRecursiveElementWalkingVisitor { - private final HashMap> reported = new HashMap>(); + @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 containerSet = reported.get(resolved); - if (containerSet == null) { - containerSet = new HashSet(); - 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> reported, MultiMap conflicts) { + final PsiElement container = ConflictsUtil.getContainer(reference); + HashSet containerSet = reported.get(resolved); + if (containerSet == null) { + containerSet = new HashSet(); + 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(); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/InnerClassRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/InnerClassRef.java new file mode 100644 index 000000000000..27efb83f3ba5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/InnerClassRef.java @@ -0,0 +1,19 @@ +import java.util.*; +import Node.Details; + +public class Node { + public class Details { + public E data; + } + public Details addNode(Node child) { + return new Details(); + } +} + +class Test { + public static void main(String[] args) { + Map m = null; + Map sorted1; + sorted1 = m; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveInner/innerClassInheritance/after/p/A.java b/java/java-tests/testData/refactoring/moveInner/innerClassInheritance/after/p/A.java new file mode 100644 index 000000000000..b3d833439653 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInner/innerClassInheritance/after/p/A.java @@ -0,0 +1,8 @@ +package p; + +class A { + private static class C { + + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveInner/innerClassInheritance/after/p/B.java b/java/java-tests/testData/refactoring/moveInner/innerClassInheritance/after/p/B.java new file mode 100644 index 000000000000..7d34f7987856 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInner/innerClassInheritance/after/p/B.java @@ -0,0 +1,5 @@ +package p; + +class B extends A.C { + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveInner/innerClassInheritance/before/p/A.java b/java/java-tests/testData/refactoring/moveInner/innerClassInheritance/before/p/A.java new file mode 100644 index 000000000000..e22caf06f854 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInner/innerClassInheritance/before/p/A.java @@ -0,0 +1,11 @@ +package p; + +class A { + private static class C { + + } + + private static class B extends C{ + + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index a6e88a128ae4..0a352a05bab3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -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())); diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterAlignmentTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterAlignmentTest.java index a8365efd152e..df01c1730213 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterAlignmentTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterAlignmentTest.java @@ -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" + + "}" + ); + } } diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java index bd01e7476843..823218a86e1c 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBracesTest.java @@ -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" + "}" ); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MoveInnerTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MoveInnerTest.java index cab9b256ae04..f05f64f5b8f5 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/MoveInnerTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/MoveInnerTest.java @@ -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 p.A.C will become inaccessible from class p.A.B.", e.getMessage()); + } + } + public void testScr30106() throws Exception { doTest(createAction("p.A.B", "B", true, "outer", false, false, null)); } diff --git a/java/openapi/src/com/intellij/psi/PsiClassType.java b/java/openapi/src/com/intellij/psi/PsiClassType.java index e65b7729923e..f2a1a11ffc5c 100644 --- a/java/openapi/src/com/intellij/psi/PsiClassType.java +++ b/java/openapi/src/com/intellij/psi/PsiClassType.java @@ -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)); } /** diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy index f09ec9971795..2a34d1039468 100644 --- a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy +++ b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy @@ -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 diff --git a/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java b/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java index 6f4c943c1653..cd72d658f331 100644 --- a/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java +++ b/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java @@ -203,6 +203,30 @@ public abstract class PsiElementPattern("withTextLength", lengthPattern) { + @Override + public boolean processValues(T t, + ProcessingContext context, + PairProcessor integerProcessingContextPairProcessor) { + return integerProcessingContextPairProcessor.process(t.getTextLength(), context); + } + }); + } + + public Self notEmpty() { + return withTextLengthLongerThan(0); + } + + public Self withTextLengthLongerThan(final int minLength) { + return with(new PatternCondition("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)); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java index caf36d6f81b8..d5e094431c6d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java @@ -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 + } } } }; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java index 4c3ff799df5a..115bf2933107 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java @@ -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); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index c5401a1bcf57..c50fdbdb8c96 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -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() { public void consume(final LookupElement lookupElement) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index 25c77c062594..66a13383a5fd 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -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) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java index 1cbdc3ec7f31..f5e9f16a1052 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/EditorFoldingInfo.java @@ -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 KEY = Key.create("EditorFoldingInfo.KEY"); - private final Map myFoldRegionToSmartPointerMap = new THashMap(); + private final Map> myFoldRegionToSmartPointerMap + = new THashMap>(); 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); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java index 97e81c3cf9f5..3298d508b542 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java @@ -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 shouldExpand, Map groupExpand) { List newRegions = arrayList(); + SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject); for (final Map.Entry 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); diff --git a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java index 53c8e402ef93..ae4dc897502a 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java @@ -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 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 historyProcessor = new PairProcessor() { - 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 historyProcessor = new PairProcessor() { + 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 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; + } } diff --git a/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java new file mode 100644 index 000000000000..55bf52f98001 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java @@ -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 + } + } +} diff --git a/platform/lang-impl/src/com/intellij/facet/impl/ui/MultipleFacetEditorHelperImpl.java b/platform/lang-impl/src/com/intellij/facet/impl/ui/MultipleFacetEditorHelperImpl.java index e7cd7fc6f74d..9690c8fd38d6 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/ui/MultipleFacetEditorHelperImpl.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/ui/MultipleFacetEditorHelperImpl.java @@ -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 myBindings = new ArrayList(); + private final List myBindings = new ArrayList(); public void bind(@NotNull ThreeStateCheckBox common, @NotNull FacetEditor[] editors, @NotNull NotNullFunction fun) { List checkBoxesList = new ArrayList(); @@ -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 myCheckBoxesList; private final List 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 myTextFields; private final List 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 myComponentsList; private final List myInitialValues; diff --git a/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentInColumnsHelper.java b/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentInColumnsHelper.java index 808906ba89c3..e91bcafc82d3 100644 --- a/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentInColumnsHelper.java +++ b/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentInColumnsHelper.java @@ -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 diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java index e13498d8e54f..819fb5c75547 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java @@ -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 in: 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 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> 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) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java index 05c15dd437ca..433e464474f9 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java @@ -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() { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java index 6933ac1f6a6b..0f3143b812e8 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java @@ -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){ diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java index 360233341f9a..a26fe4b5c0f4 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java @@ -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() { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/HelperFactory.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/HelperFactory.java index f75ed0a169cf..e8302ccf2e32 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/HelperFactory.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/HelperFactory.java @@ -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) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/Helper.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/IndentHelper.java similarity index 96% rename from platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/Helper.java rename to platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/IndentHelper.java index c52e532f19f4..1c36dd590578 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/Helper.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/IndentHelper.java @@ -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(); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java index 698dfb2c5e0d..f4c5e86e9d4c 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java @@ -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; } diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDetectorAction.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDetectorAction.java index 99faade340d9..01166f62b0b0 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDetectorAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDetectorAction.java @@ -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 diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureVisitor.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureVisitor.java deleted file mode 100644 index 40bfd2fae9d0..000000000000 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureGestureVisitor.java +++ /dev/null @@ -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; - } - } -} diff --git a/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java b/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java index 68d99ba6bb54..4bd59d27ff5d 100644 --- a/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java +++ b/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java @@ -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 getAdditionalEnvs(); + public abstract Map 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 ""; + } } diff --git a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java index 0c3c9fd315c7..cbd70aa2db7c 100644 --- a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java +++ b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java @@ -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); diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java index 237ea837fa17..4b3daa94a8df 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java @@ -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)); diff --git a/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java b/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java index 7862a170ffa7..313b92f74a2d 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java @@ -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; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index eb9c81221af8..6e60a04338af 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -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 { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java index 4c679ded4657..6a9e1a654267 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java @@ -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 diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java index c13abcb29224..db4a4efd72c3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java @@ -576,6 +576,11 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw } } + @Override + public String toString() { + return myCache.toString(); + } + private class CacheState { public boolean valid = true; diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java index deb6fd93a510..29bb22bf8dcf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java @@ -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); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index 864f6dc754b0..edee5c2db77c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -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(); + } } } } diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 77c2a33adafe..81fd24ef52b8 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -466,6 +466,9 @@ com.intellij.codeInsight.intention.impl.EditFoldingOptionsAction + + com.intellij.refactoring.changeSignature.ChangeSignatureDetectorAction + @@ -595,7 +598,7 @@ - + diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index 16e7cb310777..5750eb21ad51 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -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 [start; end) sub-sequence of the given text. * diff --git a/platform/util/src/com/intellij/util/AtomicFieldUpdater.java b/platform/util/src/com/intellij/util/concurrency/AtomicFieldUpdater.java similarity index 98% rename from platform/util/src/com/intellij/util/AtomicFieldUpdater.java rename to platform/util/src/com/intellij/util/concurrency/AtomicFieldUpdater.java index 8e2899e1b574..41d97776f302 100644 --- a/platform/util/src/com/intellij/util/AtomicFieldUpdater.java +++ b/platform/util/src/com/intellij/util/concurrency/AtomicFieldUpdater.java @@ -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; diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/LineNumberListener.java b/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/LineNumberListener.java new file mode 100644 index 000000000000..c570315abd73 --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/LineNumberListener.java @@ -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 { +} diff --git a/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java b/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java index 657d44d2d7b2..1815393c6167 100644 --- a/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java +++ b/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java @@ -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) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java index adbec1fb44b7..52bb3cb5df37 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java @@ -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 gutters = new ArrayList(); final AnnotationSourceSwitcher switcher = fileAnnotation.getAnnotationSourceSwitcher(); final AnnotationPresentation presentation; + final List additionalActions = new ArrayList(); 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 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); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationFieldGutter.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationFieldGutter.java index 028fb394dd23..89cbe0ad49b5 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationFieldGutter.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationFieldGutter.java @@ -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 getPopupActions(int line, final Editor editor) { - final ArrayList actions = new ArrayList(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 diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationPresentation.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationPresentation.java index e97ca51da743..1f865d4d839d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationPresentation.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationPresentation.java @@ -39,7 +39,7 @@ class AnnotationPresentation implements TextAnnotationPresentation { private final AnnotationSourceSwitcher mySwitcher; private final ArrayList myActions; private SwitchAnnotationSourceAction mySwitchAction; - private final List> myPopupLineNumberListeners; + private final List 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>(); + myPopupLineNumberListeners = new LinkedList(); myActions = new ArrayList(); myActions.add(Separator.getInstance()); @@ -68,7 +68,7 @@ class AnnotationPresentation implements TextAnnotationPresentation { myActions.add(new ShowShortenNames(gutter)); } - public void addLineNumberListener(final Consumer listener) { + public void addLineNumberListener(final LineNumberListener listener) { myPopupLineNumberListeners.add(listener); } @@ -82,7 +82,7 @@ class AnnotationPresentation implements TextAnnotationPresentation { } public List getActions(int line) { - for (Consumer listener : myPopupLineNumberListeners) { + for (LineNumberListener listener : myPopupLineNumberListeners) { listener.consume(line); } return myActions; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CopyRevisionNumberAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CopyRevisionNumberAction.java index 9fa8f1220e06..a2788e86e42c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CopyRevisionNumberAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CopyRevisionNumberAction.java @@ -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; } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/HistoryIdColumn.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/HistoryIdColumn.java index dc36d15233dc..6d134753e44f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/HistoryIdColumn.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/HistoryIdColumn.java @@ -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()); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/ShowDiffFromAnnotation.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/ShowDiffFromAnnotation.java index ca2f814d1ca2..3f54008625d0 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/ShowDiffFromAnnotation.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/ShowDiffFromAnnotation.java @@ -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 { +class ShowDiffFromAnnotation extends AnAction implements LineNumberListener { private final UpToDateLineNumberProvider myLineNumberProvider; private final FileAnnotation myFileAnnotation; private final AbstractVcs myVcs; diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/inheritance/AbstractMethodWithMissingImplementationsInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/inheritance/AbstractMethodWithMissingImplementationsInspection.java index ca5d6b25af41..d53322c67448 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/inheritance/AbstractMethodWithMissingImplementationsInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/inheritance/AbstractMethodWithMissingImplementationsInspection.java @@ -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) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java index b51abdc337ac..4e54bcb542c3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java @@ -191,9 +191,14 @@ public class GroovyToJavaGenerator { private void generateClassStub(@NotNull PsiClass typeDefinition, GrPackageDefinition packageDefinition, Map 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) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java index 39ad3c5aac26..da9f998f0a2e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java @@ -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("."); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantPositionManagerHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantPositionManagerHelper.java index 642f93e627e1..f204e8ee6cf6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantPositionManagerHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantPositionManagerHelper.java @@ -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; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/VariableDefinitions.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/VariableDefinitions.java index c04f77ea2724..18db239213f2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/VariableDefinitions.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/VariableDefinitions.java @@ -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)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java index 5bc64ebe2ba6..85cb372c321e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java @@ -281,7 +281,7 @@ public abstract class GrMethodBaseImpl extends GroovyBaseEl @NotNull public PsiReferenceList getThrowsList() { GrThrowsClause clause = findChildByClass(GrThrowsClause.class); - assert clause != null; + assert clause != null : this; return clause; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrTypeParameterImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrTypeParameterImpl.java index 64e87babacba..68f2dc09b3ad 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrTypeParameterImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrTypeParameterImpl.java @@ -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; } diff --git a/plugins/groovy/testdata/parsing/groovy/types/ann_def3.test b/plugins/groovy/testdata/parsing/groovy/types/ann_def3.test index 7b22016c10d1..026b3d40209c 100644 --- a/plugins/groovy/testdata/parsing/groovy/types/ann_def3.test +++ b/plugins/groovy/testdata/parsing/groovy/types/ann_def3.test @@ -39,6 +39,8 @@ Groovy script Literal PsiElement(Integer)('8') PsiElement(])(']') + Throw clause + PsiElement(;)(';') PsiElement(new line)('\n') PsiElement(})('}') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/types/default1.test b/plugins/groovy/testdata/parsing/groovy/types/default1.test index 3dd10bc60610..275ba92ab990 100644 --- a/plugins/groovy/testdata/parsing/groovy/types/default1.test +++ b/plugins/groovy/testdata/parsing/groovy/types/default1.test @@ -44,5 +44,7 @@ Groovy script PsiWhiteSpace(' ') Annotation arguments + Throw clause + PsiElement(new line)('\n') PsiElement(})('}') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/types/default2.test b/plugins/groovy/testdata/parsing/groovy/types/default2.test index 3023d7c0be64..abfc413b52e7 100644 --- a/plugins/groovy/testdata/parsing/groovy/types/default2.test +++ b/plugins/groovy/testdata/parsing/groovy/types/default2.test @@ -39,5 +39,7 @@ Groovy script PsiWhiteSpace(' ') Literal PsiElement(Integer)('5') + Throw clause + PsiElement(new line)('\n') PsiElement(})('}') \ No newline at end of file diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java index 9962c02ae701..357f73623b0e 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java @@ -557,7 +557,14 @@ public abstract class DomInvocationHandler 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, ""); diff --git a/xml/impl/src/com/intellij/lang/html/HtmlParsing.java b/xml/impl/src/com/intellij/lang/html/HtmlParsing.java index 533d124299d6..54dd2104de3c 100644 --- a/xml/impl/src/com/intellij/lang/html/HtmlParsing.java +++ b/xml/impl/src/com/intellij/lang/html/HtmlParsing.java @@ -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())); }