From ccfb7976735ff02255e2b71bd721a6faf924e16e Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Thu, 22 Jul 2010 18:08:33 +0400 Subject: [PATCH 001/102] typo: accesible -> accessible --- .../changeSignature/JavaChangeSignatureUsageProcessor.java | 2 +- .../ConvertToInstanceMethodProcessor.java | 2 +- .../introduceParameter/IntroduceParameterProcessor.java | 2 +- .../refactoring/move/moveMembers/MoveMembersProcessor.java | 3 +-- .../com/intellij/refactoring/IntroduceParameterTest.java | 2 +- .../src/messages/RefactoringBundle.properties | 4 ++-- .../changeSignature/GrChangeSignatureConflictSearcher.java | 2 +- .../introduceParameter/IntroduceParameterTest.java | 2 +- 8 files changed, 9 insertions(+), 10 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index cd8ff0b67273..4bc0184be9a7 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -819,7 +819,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr if (!JavaPsiFacade.getInstance(element.getProject()).getResolveHelper() .isAccessible(method, modifierList, element, accessObjectClass, null)) { String message = - RefactoringBundle.message("0.with.1.visibility.is.not.accesible.from.2", + RefactoringBundle.message("0.with.1.visibility.is.not.accessible.from.2", RefactoringUIUtil.getDescription(method, true), myChangeInfo.getNewVisibility(), RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true)); diff --git a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java index d0e9c6c0db7e..0b28044344e0 100644 --- a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java @@ -200,7 +200,7 @@ public class ConvertToInstanceMethodProcessor extends BaseRefactoringProcessor { } if (!JavaResolveUtil.isAccessible(myMethod, myTargetClass, copy, call, accessObjectClass, null)) { final String newVisibility = myNewVisibility == null ? VisibilityUtil.getVisibilityStringToDisplay(myMethod) : myNewVisibility; - String message = RefactoringBundle.message("0.with.1.visibility.is.not.accesible.from.2", + String message = RefactoringBundle.message("0.with.1.visibility.is.not.accessible.from.2", RefactoringUIUtil.getDescription(myMethod, true), newVisibility, RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(call), true)); conflicts.putValue(myMethod, message); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java index c21a50c78698..a0f83301939d 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java @@ -268,7 +268,7 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem !JavaPsiFacade.getInstance(myProject).getResolveHelper().isAccessible((PsiMember)element, place, null)) { String message = RefactoringBundle.message( - "0.is.not.accesible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect", + "0.is.not.accessible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect", RefactoringUIUtil.getDescription(element, true), RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(place), true)); conflicts.putValue(element, message); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java index bc6d43828c3b..3fd190737da0 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java @@ -21,7 +21,6 @@ package com.intellij.refactoring.move.moveMembers; import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector; -import com.intellij.lang.LanguageExtension; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; @@ -282,7 +281,7 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor { if (!JavaResolveUtil.isAccessible(member, myTargetClass, modifierListCopies.get(member), element, accessObjectClass, null)) { newVisibility = newVisibility == null ? VisibilityUtil.getVisibilityStringToDisplay(member) : newVisibility; String message = - CommonRefactoringUtil.capitalize(RefactoringBundle.message("0.with.1.visibility.is.not.accesible.from.2", RefactoringUIUtil.getDescription(member, false), + CommonRefactoringUtil.capitalize(RefactoringBundle.message("0.with.1.visibility.is.not.accessible.from.2", RefactoringUIUtil.getDescription(member, false), newVisibility, RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true))); conflicts.putValue(member, message); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java index 983646c48293..697f07edcf98 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java @@ -78,7 +78,7 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase { } public void testThisSubstitutionInQualifier() throws Exception { - doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false, false, "field Test.i is not accesible from method XTest.n(). Value for introduced parameter in that method call will be incorrect."); + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false, false, "field Test.i is not accessible from method XTest.n(). Value for introduced parameter in that method call will be incorrect."); } public void testFieldAccess() throws Exception { diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties index 031d2b333c23..a3cd67c0784f 100644 --- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties +++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties @@ -247,7 +247,7 @@ method.does.not.have.a.body=Method {0} does not have a body. method.has.an.empty.body=Method {0} has an empty body. idea.has.not.found.any.code.that.can.be.replaced.with.method.call={0} has not found any code that can be replaced with method call method.duplicates.found.message={0, choice, 1#1 code fragment|2#{0,number} code fragments} found -0.with.1.visibility.is.not.accesible.from.2={0} with {1} visibility won''t be accesible from {2} +0.with.1.visibility.is.not.accessible.from.2={0} with {1} visibility won''t be accessible from {2} 0.contains.call.with.null.argument.for.parameter.1={0} contains call with null argument for parameter {1} no.members.selected=No members selected 0.already.exists.in.the.target.class={0} already exists in the target class. @@ -283,7 +283,7 @@ refactoring.cannot.be.performed=Refactoring cannot be performed there.is.already.a.0.it.will.conflict.with.an.introduced.parameter=There is already a {0}. It will conflict with an introduced parameter introduce.parameter.command=Introducing parameter to {0} parameter.initializer.contains.0.but.not.all.calls.to.method.are.in.its.class=Parameter initializer contains {0}, but not all calls to method are in its class. -0.is.not.accesible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect={0} is not accesible from {1}. Value for introduced parameter in that method call will be incorrect. +0.is.not.accessible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect={0} is not accessible from {1}. Value for introduced parameter in that method call will be incorrect. use.interface.superclass.in.instanceof=Use interface/superclass in instanceof introduce.parameter.to.method=Introduce parameter to method: introduced.variable.will.conflict.with.0=Introduced variable will conflict with {0} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureConflictSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureConflictSearcher.java index 27acb2f08c76..6a9e1fb90e7d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureConflictSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureConflictSearcher.java @@ -98,7 +98,7 @@ class GrChangeSignatureConflictSearcher { if (!JavaPsiFacade.getInstance(element.getProject()).getResolveHelper() .isAccessible(method, modifierList, element, accessObjectClass, null)) { String message = - RefactoringBundle.message("0.with.1.visibility.is.not.accesible.from.2", + RefactoringBundle.message("0.with.1.visibility.is.not.accessible.from.2", RefactoringUIUtil.getDescription(method, true), myChangeInfo.getNewVisibility(), RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true)); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.java index d2e11e031e63..109853732d1b 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/IntroduceParameterTest.java @@ -155,7 +155,7 @@ public class IntroduceParameterTest extends LightCodeInsightFixtureTestCase { } public void testThisSubstitutionInQualifier() throws Throwable { - doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false, "field Test.i is not accesible from method XTest.n(). Value for introduced parameter in that method call will be incorrect."); + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, false, "field Test.i is not accessible from method XTest.n(). Value for introduced parameter in that method call will be incorrect."); } public void testFieldAccess() throws Throwable { From 454a77b083c8fd3378b835f13a64b1c90c9a7066 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 20 Jul 2010 20:22:00 +0400 Subject: [PATCH 002/102] Inline Included File: decoding file references --- .../refactoring/move/FileReferenceContextUtil.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/FileReferenceContextUtil.java b/platform/lang-impl/src/com/intellij/refactoring/move/FileReferenceContextUtil.java index dcef9296759c..cc4286bdf47d 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/FileReferenceContextUtil.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/FileReferenceContextUtil.java @@ -78,12 +78,11 @@ public class FileReferenceContextUtil { if (!range.intersects(element.getTextRange())) return; String text = element.getText(); PsiFileSystemItem item = map.get(text); - element = bindElement(element, item); - if (element != null) { - element.acceptChildren(this); - } + element.putCopyableUserData(REF_FILE_SYSTEM_ITEM_KEY, item); + element.acceptChildren(this); } }); + decodeFileReferences(element); } private static PsiElement bindElement(PsiElement element, PsiFileSystemItem item) { From 70683e16ce98f620a8f7bcb0f9ddc4995aae0629 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 20 Jul 2010 20:57:11 +0400 Subject: [PATCH 003/102] extracting includes with non-default extensions --- .../intellij/refactoring/lang/ExtractIncludeDialog.java | 7 ++++--- .../src/messages/RefactoringBundle.properties | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/lang/ExtractIncludeDialog.java b/platform/lang-impl/src/com/intellij/refactoring/lang/ExtractIncludeDialog.java index 8eb29eb36e6e..b7f52a6293e9 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/lang/ExtractIncludeDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/lang/ExtractIncludeDialog.java @@ -50,7 +50,7 @@ public class ExtractIncludeDialog extends DialogWrapper { private JTextField myNameField; private final PsiDirectory myCurrentDirectory; private static final String REFACTORING_NAME = RefactoringBundle.message("extractIncludeFile.name"); - private final String myExtension; + protected final String myExtension; protected JLabel myTargetDirLabel; public PsiDirectory getTargetDirectory() { @@ -60,7 +60,8 @@ public class ExtractIncludeDialog extends DialogWrapper { private PsiDirectory myTargetDirectory; public String getTargetFileName () { - return myNameField.getText().trim() + "." + myExtension; + String name = myNameField.getText().trim(); + return name.contains(".") ? name: name + "." + myExtension; } public ExtractIncludeDialog(final PsiDirectory currentDirectory, final String extension) { @@ -116,7 +117,7 @@ public class ExtractIncludeDialog extends DialogWrapper { } protected String getNameLabel() { - return RefactoringBundle.message("name.for.extracted.include.file"); + return RefactoringBundle.message("name.for.extracted.include.file", myExtension); } private void validateOKButton() { diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties index a3cd67c0784f..59da84ef90b8 100644 --- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties +++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties @@ -87,7 +87,7 @@ javadoc.for.abstracts=JavaDoc for abstracts extractIncludeFile.name=Extract Include File file.already.exist=File {0} already exists file.already.exist.title=Extract Include File -name.for.extracted.include.file=&Name for extracted include file (without extension): +name.for.extracted.include.file=&Name for extracted include file (default extension: {0}) extract.to.directory=Extract to &directory: select.target.directory=Select target directory select.target.directory.description=The file will be created in this directory From f8dfd6beb4f1d57151e7460d4fe757c1b68ac889 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Thu, 22 Jul 2010 18:39:11 +0400 Subject: [PATCH 004/102] IDEA-19372: Refactoring: Extract .tag file for static piece of JSP --- .../src/com/intellij/psi/jsp/BaseJspFile.java | 4 ++-- .../src/com/intellij/openapi/vfs/VfsUtil.java | 4 ++-- .../fixtures/CodeInsightFixtureTestCase.java | 5 +++++ .../fixtures/impl/CodeInsightTestFixtureImpl.java | 2 +- xml/impl/src/com/intellij/xml/util/XmlUtil.java | 11 ++++++++--- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/java/jsp-base-openapi/src/com/intellij/psi/jsp/BaseJspFile.java b/java/jsp-base-openapi/src/com/intellij/psi/jsp/BaseJspFile.java index 2327d9b7ad54..08e182bfc842 100644 --- a/java/jsp-base-openapi/src/com/intellij/psi/jsp/BaseJspFile.java +++ b/java/jsp-base-openapi/src/com/intellij/psi/jsp/BaseJspFile.java @@ -32,7 +32,7 @@ public interface BaseJspFile extends XmlFile { boolean isTagPage(); XmlTag[] getDirectiveTags(JspDirectiveKind directiveKind, final boolean searchInIncludes); - XmlTag createDirective(XmlTag context, JspDirectiveKind page); + XmlTag createDirective(XmlTag context, JspDirectiveKind directiveKind); PsiFile getBaseLanguageRoot(); /** @@ -43,4 +43,4 @@ public interface BaseJspFile extends XmlFile { @NotNull JspxFileViewProvider getViewProvider(); -} \ No newline at end of file +} diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java index 8ed063a63bbf..a76d0a3738a5 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java @@ -658,8 +658,8 @@ public class VfsUtil { } @Nullable - public static VirtualFile createDirectoryIfMissing(@NotNull String dir) throws IOException { - return doCreateDirectoriesIfMissing(FileUtil.toSystemIndependentName(dir)); + public static VirtualFile createDirectoryIfMissing(@NotNull String directoryPath) throws IOException { + return doCreateDirectoriesIfMissing(FileUtil.toSystemIndependentName(directoryPath)); } private static VirtualFile doCreateDirectoriesIfMissing(String dir) throws IOException { diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightFixtureTestCase.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightFixtureTestCase.java index d08ecca169ef..4f7371286685 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightFixtureTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightFixtureTestCase.java @@ -19,6 +19,7 @@ import com.intellij.openapi.application.PathManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.builders.EmptyModuleFixtureBuilder; import org.jetbrains.annotations.NonNls; @@ -83,4 +84,8 @@ public abstract class CodeInsightFixtureTestCase extends UsefulTestCase { protected Editor getEditor() { return myFixture.getEditor(); } + + protected PsiFile getFile() { + return myFixture.getFile(); + } } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 07b303e3a8b9..51826773cf31 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -185,7 +185,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig FileUtil.copy(fromFile, destFile); } catch (IOException e) { - throw new RuntimeException(e); + throw new RuntimeException("Cannot copy " + fromFile + " to " + destFile, e); } } } diff --git a/xml/impl/src/com/intellij/xml/util/XmlUtil.java b/xml/impl/src/com/intellij/xml/util/XmlUtil.java index 3e803752e185..5d7e3834e6c3 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlUtil.java +++ b/xml/impl/src/com/intellij/xml/util/XmlUtil.java @@ -190,12 +190,17 @@ public class XmlUtil { return null; } - @Nullable - public static String findNamespacePrefixByURI(XmlFile file, @NonNls String uri) { + @SuppressWarnings({"ConstantConditions"}) + public static XmlTag getRootTag(XmlFile file) { if (file == null) return null; final XmlDocument document = file.getDocument(); if (document == null) return null; - final XmlTag tag = document.getRootTag(); + return document.getRootTag(); + } + + @Nullable + public static String findNamespacePrefixByURI(XmlFile file, @NonNls String uri) { + final XmlTag tag = getRootTag(file); if (tag == null) return null; for (XmlAttribute attribute : tag.getAttributes()) { From 061b258d8bab296ef104bbec356c7af33437b48e Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 22 Jul 2010 19:17:54 +0400 Subject: [PATCH 005/102] IDEA-56656 IDEA does not highlight not well-formed XML: comment before XML declaration --- .../src/messages/XmlErrorMessages.properties | 1 + .../impl/analysis/XmlHighlightVisitor.java | 24 +++++++++++++++++++ .../xml/XmlProcessingInstructionImpl.java | 2 +- .../com/intellij/psi/XmlElementVisitor.java | 4 ++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/platform/platform-resources-en/src/messages/XmlErrorMessages.properties b/platform/platform-resources-en/src/messages/XmlErrorMessages.properties index af35e58f9cee..4ab6cd49b655 100644 --- a/platform/platform-resources-en/src/messages/XmlErrorMessages.properties +++ b/platform/platform-resources-en/src/messages/XmlErrorMessages.properties @@ -74,3 +74,4 @@ xml.parsing.closing.tag.name.missing=Closing tag name missing xml.parsing.closing.tag.is.not.done=Closing tag is not done attribute.should.be.preceded.with.space=There should be a space between attribute and previous attribute cdata.end.should.not.appear.in.content.unless.to.mark.end.of.cdata.section=Character sequence ']]>' must not appear in content unless used to mark the end of a CDATA section +xml.declaration.should.precede.all.document.content=Xml declaration should precede all document content diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java index 97c49723b40e..d7e24d4f9219 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java @@ -167,6 +167,30 @@ public class XmlHighlightVisitor extends XmlElementVisitor implements HighlightV bindMessageToAstNode(childByRole, warning, 0, messageLength, localizedMessage, quickFixActions); } + + @Override + public void visitXmlProcessingInstruction(XmlProcessingInstruction processingInstruction) { + super .visitXmlProcessingInstruction(processingInstruction); + PsiElement parent = processingInstruction.getParent(); + + if (parent instanceof XmlProlog && processingInstruction.getText().startsWith(" Date: Thu, 22 Jul 2010 20:19:33 +0400 Subject: [PATCH 006/102] no costly indexing inside zip files and when we have no RNG_NAMESPACE reference inside document --- .../relaxNG/model/resolve/RelaxSymbolIndex.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java index 0e9aeb55c489..43d4baa8a535 100644 --- a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java +++ b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java @@ -7,6 +7,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -19,6 +20,8 @@ import com.intellij.psi.xml.XmlFile; import com.intellij.util.indexing.*; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; +import com.intellij.util.text.CharArrayUtil; +import com.intellij.util.text.CharSequenceReader; import com.intellij.util.xml.NanoXmlUtil; import org.intellij.plugins.relaxNG.ProjectLoader; import org.intellij.plugins.relaxNG.compact.RncFileType; @@ -30,11 +33,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.io.ByteArrayInputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /* * Created by IntelliJ IDEA. @@ -68,7 +67,9 @@ public class RelaxSymbolIndex extends ScalarIndexExtension { public Map map(FileContent inputData) { final HashMap map = new HashMap(); if (inputData.getFileType() == XmlFileType.INSTANCE) { - NanoXmlUtil.parse(new ByteArrayInputStream(inputData.getContent()), new NanoXmlUtil.IXMLBuilderAdapter() { + CharSequence inputDataContentAsText = inputData.getContentAsText(); + if (CharArrayUtil.indexOf(inputDataContentAsText, ProjectLoader.RNG_NAMESPACE, 0) == -1) return Collections.EMPTY_MAP; + NanoXmlUtil.parse(new CharSequenceReader(inputDataContentAsText), new NanoXmlUtil.IXMLBuilderAdapter() { NanoXmlUtil.IXMLBuilderAdapter attributeHandler; int depth; @@ -131,6 +132,9 @@ public class RelaxSymbolIndex extends ScalarIndexExtension { public FileBasedIndex.InputFilter getInputFilter() { return new FileBasedIndex.InputFilter() { public boolean acceptInput(VirtualFile file) { + if (file.getFileSystem() instanceof JarFileSystem) { + return false; // there is lots and lots of custom XML inside zip files + } return file.getFileType() == StdFileTypes.XML || file.getFileType() == RncFileType.getInstance(); } }; From de233866a8dfcf3fbd9b1a92087674499d419431 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 22 Jul 2010 20:50:37 +0400 Subject: [PATCH 007/102] do not highlight error about preceding content from subsequence processing instructions --- .../codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java index d7e24d4f9219..7aaeffa377a9 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java @@ -181,6 +181,7 @@ public class XmlHighlightVisitor extends XmlElementVisitor implements HighlightV } PsiElement eParent = e.getParent(); if (eParent instanceof PsiComment) e = eParent; + if (eParent instanceof XmlProcessingInstruction) break; addToResults(HighlightInfo.createHighlightInfo( HighlightInfoType.ERROR, From 1a26ee025304e775b34918e9e9e52e29cbd059f0 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Thu, 22 Jul 2010 21:14:37 +0400 Subject: [PATCH 008/102] AS extract superclass: more conflicts checks when extracting implementation --- .../refactoring/util/RefactoringDescriptionLocation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/util/RefactoringDescriptionLocation.java b/platform/lang-impl/src/com/intellij/refactoring/util/RefactoringDescriptionLocation.java index e7058714c681..f5e195366706 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/util/RefactoringDescriptionLocation.java +++ b/platform/lang-impl/src/com/intellij/refactoring/util/RefactoringDescriptionLocation.java @@ -25,7 +25,7 @@ import com.intellij.psi.ElementDescriptionProvider; public class RefactoringDescriptionLocation extends ElementDescriptionLocation { private final boolean myWithParent; - private RefactoringDescriptionLocation(boolean withParent) { + protected RefactoringDescriptionLocation(boolean withParent) { myWithParent = withParent; } From 5a1c840fc330129c8eed2eabc7b258f836b00b03 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 23 Jul 2010 00:27:36 +0400 Subject: [PATCH 009/102] IDEA-49791 (Grails: variable defined in g:each tag is not resolved in the element's body) --- .../plugins/groovy/lang/psi/impl/GrClassReferenceType.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClassReferenceType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClassReferenceType.java index 6e988f3b13f2..8a5af195f087 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClassReferenceType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrClassReferenceType.java @@ -19,12 +19,16 @@ package org.jetbrains.plugins.groovy.lang.psi.impl; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; +import java.util.ArrayList; +import java.util.List; + /** * @author ven */ @@ -62,8 +66,7 @@ public class GrClassReferenceType extends PsiClassType { @NotNull public PsiType[] getParameters() { - //todo - return PsiType.EMPTY_ARRAY; + return myReferenceElement.getTypeArguments(); } @NotNull From 372ccc46617abf81b6d79a3c5eb616d9c8c7d8df Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 23 Jul 2010 00:13:58 +0200 Subject: [PATCH 010/102] IDEA-55337 (False Positive on InstanceVariableUninitializedUse) --- .../psiutils/UninitializedReadCollector.java | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/UninitializedReadCollector.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/UninitializedReadCollector.java index 8b4ff4a3a08b..272eb6da9469 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/UninitializedReadCollector.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/UninitializedReadCollector.java @@ -171,9 +171,8 @@ public class UninitializedReadCollector { } else if(statement instanceof PsiSwitchLabelStatement){ return false; } else{ - throw new RuntimeException("unknown statement: " + statement); - // unknown statement type - //return false; + assert false : "unknown statement: " + statement; + return false; } } @@ -441,7 +440,15 @@ public class UninitializedReadCollector { (PsiAssignmentExpression) expression; return assignmentExpressonAssignsVariable(assignment, variable, stamp, checkedMethods); + } else if(expression instanceof PsiParenthesizedExpression) { + final PsiParenthesizedExpression parenthesizedExpression = + (PsiParenthesizedExpression) expression; + final PsiExpression innerExpression = + parenthesizedExpression.getExpression(); + return expressionAssignsVariable(innerExpression, variable, stamp, + checkedMethods); } else{ + assert false : "unknown expression: " + expression; return false; } } @@ -473,6 +480,10 @@ public class UninitializedReadCollector { int stamp, @NotNull Set checkedMethods) { final PsiExpression qualifierExpression = referenceExpression.getQualifierExpression(); + if (expressionAssignsVariable(qualifierExpression, variable, + stamp, checkedMethods)) { + return true; + } if(variable.equals(referenceExpression.resolve())){ final PsiElement parent = referenceExpression.getParent(); if(parent instanceof PsiAssignmentExpression){ @@ -489,9 +500,7 @@ public class UninitializedReadCollector { qualifierExpression); } } - return referenceExpression.isQualified() && - expressionAssignsVariable(qualifierExpression, variable, - stamp, checkedMethods); + return false; } private void checkReferenceExpression( @@ -550,6 +559,12 @@ public class UninitializedReadCollector { @NotNull PsiMethodCallExpression callExpression, @NotNull PsiVariable variable, int stamp, @NotNull Set checkedMethods){ + final PsiReferenceExpression methodExpression = + callExpression.getMethodExpression(); + if(expressionAssignsVariable(methodExpression, variable, + stamp, checkedMethods)) { + return true; + } final PsiExpressionList argumentList = callExpression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); for(final PsiExpression argument : arguments){ @@ -558,12 +573,6 @@ public class UninitializedReadCollector { return true; } } - final PsiReferenceExpression methodExpression = - callExpression.getMethodExpression(); - if(expressionAssignsVariable(methodExpression, variable, - stamp, checkedMethods)) { - return true; - } final PsiMethod method = callExpression.resolveMethod(); if(method == null){ return false; From 78fc355e825fd129a55ae8b8b8c6c7689a898dd8 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Thu, 22 Jul 2010 20:03:24 +0400 Subject: [PATCH 011/102] NPE --- .../find/findUsages/PsiElement2UsageTargetAdapter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java index 0b945f1708d4..06575edbfbff 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java @@ -230,7 +230,8 @@ public class PsiElement2UsageTargetAdapter implements PsiElementUsageTarget, Typ } public Icon getIcon(boolean open) { - return open ? myIconOpen.getIcon() : myIconClosed.getIcon(); + final ComputableIcon computableIcon = open ? myIconOpen : myIconClosed; + return computableIcon == null? null : computableIcon.getIcon(); } } } From 2f7fc74c0b673f71f843fcbfa23287d55eb359a9 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Fri, 23 Jul 2010 11:54:20 +0400 Subject: [PATCH 012/102] RUBY-6392 RubyMine doesn't properly handle HAML 3 syntax --- .../intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java index 8349d2e3792d..46906487120e 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java @@ -120,7 +120,7 @@ public class CodeFormatterFacade { PsiDocumentManager.getInstance(project).getDocument(file), project, mySettings, fileType, file); - //printToConsole(rootBlock, model); + printToConsole(rootBlock, model); FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptions(fileType), ranges); } From 4685e3734589ae44a449f22a016ae0b272280f9b Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 20 Jul 2010 15:25:05 +0400 Subject: [PATCH 013/102] CCE --- .../codeInspection/localCanBeFinal/LocalCanBeFinal.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java b/java/java-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java index 9f614c0b288a..ae341918a927 100644 --- a/java/java-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java +++ b/java/java-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java @@ -254,7 +254,7 @@ public class LocalCanBeFinal extends BaseLocalInspectionTool { if (!CodeInsightUtilBase.preparePsiElementForWrite(problem.getPsiElement())) return; PsiElement nameIdentifier = problem.getPsiElement(); if (nameIdentifier == null) return; - PsiVariable psiVariable = (PsiVariable)nameIdentifier.getParent(); + PsiVariable psiVariable = PsiTreeUtil.getParentOfType(nameIdentifier, PsiVariable.class, false); if (psiVariable == null) return; try { psiVariable.normalizeDeclaration(); From 856b5c883cf233be7cf867bbfe342789e2f4a6ea Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 20 Jul 2010 18:48:35 +0400 Subject: [PATCH 014/102] rename: balloon notification about filtered unresolvable collisions (IDEA-56611) --- .../refactoring/rename/RenameProcessor.java | 49 ++++++++++++++++--- .../refactoring/rename/RenameUtil.java | 6 ++- .../rename/naming/AutomaticRenamer.java | 18 +++++-- 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java index 54a045c4b108..2599740ff7a5 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java @@ -17,12 +17,18 @@ package com.intellij.refactoring.rename; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.StatusBarEx; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.impl.light.LightElement; @@ -39,6 +45,7 @@ import com.intellij.refactoring.util.RelatedUsageInfo; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashSet; import com.intellij.util.containers.MultiMap; @@ -46,6 +53,8 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; import java.util.*; public class RenameProcessor extends BaseRefactoringProcessor { @@ -65,6 +74,7 @@ public class RenameProcessor extends BaseRefactoringProcessor { private NonCodeUsageInfo[] myNonCodeUsages = new NonCodeUsageInfo[0]; private final List myRenamerFactories = new ArrayList(); private final List myRenamers = new ArrayList(); + private final List mySkippedUsages = new ArrayList(); public RenameProcessor(Project project, PsiElement element, @@ -139,8 +149,6 @@ public class RenameProcessor extends BaseRefactoringProcessor { return false; } } - Set usagesSet = new HashSet(Arrays.asList(usagesIn)); - RenameUtil.removeConflictUsages(usagesSet); final List variableUsages = new ArrayList(); if (!myRenamers.isEmpty()) { @@ -174,10 +182,13 @@ public class RenameProcessor extends BaseRefactoringProcessor { } } - if (!variableUsages.isEmpty()) { - usagesSet.addAll(variableUsages); - refUsages.set(usagesSet.toArray(new UsageInfo[usagesSet.size()])); + final Set usagesSet = new HashSet(Arrays.asList(usagesIn)); + usagesSet.addAll(variableUsages); + final List conflictUsages = RenameUtil.removeConflictUsages(usagesSet); + if (conflictUsages != null) { + mySkippedUsages.addAll(conflictUsages); } + refUsages.set(usagesSet.toArray(new UsageInfo[usagesSet.size()])); prepareSuccessful(); return true; @@ -192,7 +203,7 @@ public class RenameProcessor extends BaseRefactoringProcessor { final Runnable runnable = new Runnable() { public void run() { for (final AutomaticRenamer renamer : myRenamers) { - renamer.findUsages(variableUsages, mySearchInComments, mySearchTextOccurrences); + renamer.findUsages(variableUsages, mySearchInComments, mySearchTextOccurrences, mySkippedUsages); } } }; @@ -326,6 +337,32 @@ public class RenameProcessor extends BaseRefactoringProcessor { } } myNonCodeUsages = nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]); + if (!mySkippedUsages.isEmpty()) { + if (!ApplicationManager.getApplication().isUnitTestMode() && !ApplicationManager.getApplication().isHeadlessEnvironment()) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final IdeFrame ideFrame = WindowManager.getInstance().getIdeFrame(myProject); + if (ideFrame != null) { + + StatusBarEx statusBar = (StatusBarEx)ideFrame.getStatusBar(); + HyperlinkListener listener = new HyperlinkListener() { + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) return; + Messages.showMessageDialog("" + + StringUtil.join(mySkippedUsages, new Function() { + public String fun(UnresolvableCollisionUsageInfo unresolvableCollisionUsageInfo) { + return unresolvableCollisionUsageInfo.getDescription(); + } + }, "
") + + "", "Don't panic! They are safe to skip", null); + } + }; + statusBar.notifyProgressByBalloon(MessageType.WARNING, "Unable to rename certain usages. Browse", null, listener); + } + } + }, ModalityState.NON_MODAL); + } + } } protected void performPsiSpoilingRefactoring() { diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java index a5fe42aa49c6..25a5b074a2d5 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java @@ -239,13 +239,17 @@ public class RenameUtil { ref.handleElementRename(newName); } - public static void removeConflictUsages(Set usages) { + @Nullable + public static List removeConflictUsages(Set usages) { + final List result = new ArrayList(); for (Iterator iterator = usages.iterator(); iterator.hasNext();) { UsageInfo usageInfo = iterator.next(); if (usageInfo instanceof UnresolvableCollisionUsageInfo) { + result.add((UnresolvableCollisionUsageInfo)usageInfo); iterator.remove(); } } + return result.isEmpty() ? null : result; } public static void addConflictDescriptions(UsageInfo[] usages, MultiMap conflicts) { diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/naming/AutomaticRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/naming/AutomaticRenamer.java index f1c73f546ebd..4ddd95046b5c 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/naming/AutomaticRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/naming/AutomaticRenamer.java @@ -47,9 +47,16 @@ public abstract class AutomaticRenamer { } public void findUsages(List result, final boolean searchInStringsAndComments, final boolean searchInNonJavaFiles) { + findUsages(result, searchInStringsAndComments, searchInNonJavaFiles, null); + } + + public void findUsages(List result, + final boolean searchInStringsAndComments, + final boolean searchInNonJavaFiles, + List unresolvedUsages) { for (Iterator iterator = myElements.iterator(); iterator.hasNext();) { final PsiNamedElement variable = iterator.next(); - final boolean success = findUsagesForElement(variable, result, searchInStringsAndComments, searchInNonJavaFiles); + final boolean success = findUsagesForElement(variable, result, searchInStringsAndComments, searchInNonJavaFiles, unresolvedUsages); if (!success) { iterator.remove(); } @@ -59,12 +66,17 @@ public abstract class AutomaticRenamer { private boolean findUsagesForElement(PsiNamedElement element, List result, final boolean searchInStringsAndComments, - final boolean searchInNonJavaFiles) { + final boolean searchInNonJavaFiles, List unresolvedUsages) { final String newName = getNewName(element); if (newName != null) { final UsageInfo[] usages = RenameUtil.findUsages(element, newName, searchInStringsAndComments, searchInNonJavaFiles, myRenames); for (final UsageInfo usage : usages) { - if (usage instanceof UnresolvableCollisionUsageInfo) return false; + if (usage instanceof UnresolvableCollisionUsageInfo) { + if (unresolvedUsages != null) { + unresolvedUsages.add((UnresolvableCollisionUsageInfo)usage); + } + return false; + } } ContainerUtil.addAll(result, usages); } From 5db6c87168a152d612f5cc24278c49f24ba6e722 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 20 Jul 2010 19:50:54 +0400 Subject: [PATCH 015/102] testframework refactoring: split printer&printable --- .../execution/testframework/DeferingPrinter.java | 16 +++++++++------- .../execution/testframework/Printer.java | 4 +--- .../ui/TestsOutputConsolePrinter.java | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java b/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java index fb4f68b73187..94b7c5ed3e0d 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java @@ -19,32 +19,34 @@ package com.intellij.execution.testframework; import com.intellij.execution.filters.HyperlinkInfo; import com.intellij.execution.ui.ConsoleViewContentType; -public class DeferingPrinter extends CompositePrintable implements Printer.Intermediate { +public class DeferingPrinter implements Printer { private final boolean myCollectOutput; + private CompositePrintable myCompositePrintable; public DeferingPrinter(final boolean collectOutput) { myCollectOutput = collectOutput; + myCompositePrintable = new CompositePrintable(); } public void print(final String text, final ConsoleViewContentType contentType) { - addLast(new ExternalOutput(text, contentType)); + myCompositePrintable.addLast(new ExternalOutput(text, contentType)); } public void onNewAvailable(final Printable printable) { - addLast(printable); + myCompositePrintable.addLast(printable); } public void printHyperlink(final String text, final HyperlinkInfo info) { - addLast(new HyperLink(text, info)); + myCompositePrintable.addLast(new HyperLink(text, info)); } public void mark() { - addLast(new PrinterMark()); + myCompositePrintable.addLast(new PrinterMark()); } public void printOn(final Printer printer) { - super.printOn(printer); + myCompositePrintable.printOn(printer); if (!myCollectOutput) - clear(); + myCompositePrintable.clear(); } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/Printer.java b/platform/testRunner/src/com/intellij/execution/testframework/Printer.java index 82c5c507eb6a..7f16ef825f51 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/Printer.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/Printer.java @@ -24,13 +24,11 @@ public interface Printer { void printHyperlink(String text, HyperlinkInfo info); void mark(); - interface Intermediate extends Printer, Printable {} - Intermediate DEAF = new Intermediate() { + Printer DEAF = new Printer() { public void print(final String text, final ConsoleViewContentType contentType) {} public void onNewAvailable(final Printable printable) {} public void printHyperlink(final String text, final HyperlinkInfo info) {} public void mark() {} - public void printOn(final Printer printer) {} }; } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java index 0ce237470883..34b0990a6b65 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java @@ -41,8 +41,8 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { // If output collection was enabled for this console printer - all output will be collected in // myOutputStorage component. Otherwise no output will be stored. // 'myCurrentOutputStorage' printer is used for displaying whole output for test's root - private final Intermediate myOutputStorage = new DeferingPrinter(true); - private Intermediate myCurrentOutputStorage = myOutputStorage; + private final DeferingPrinter myOutputStorage = new DeferingPrinter(true); + private Printer myCurrentOutputStorage = myOutputStorage; private int myMarkOffset = 0; From 5c0fb7bc03f1a4e5d4d737ffd1165bfe16bd5039 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 20 Jul 2010 20:31:02 +0400 Subject: [PATCH 016/102] testframework refactoring: inline ExternalOutput; cleanup --- .../testframework/DeferingPrinter.java | 6 +- .../testframework/ExternalOutput.java | 54 --------------- .../ui/BaseTestsOutputConsoleView.java | 11 +-- .../intellij/execution/junit/TestObject.java | 6 +- .../intellij/execution/junit2/TestProxy.java | 11 +-- .../execution/junit2/TestRootImpl.java | 68 ------------------- 6 files changed, 23 insertions(+), 133 deletions(-) delete mode 100644 platform/testRunner/src/com/intellij/execution/testframework/ExternalOutput.java delete mode 100644 plugins/junit/src/com/intellij/execution/junit2/TestRootImpl.java diff --git a/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java b/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java index 94b7c5ed3e0d..eaee83bad9d0 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java @@ -29,7 +29,11 @@ public class DeferingPrinter implements Printer { } public void print(final String text, final ConsoleViewContentType contentType) { - myCompositePrintable.addLast(new ExternalOutput(text, contentType)); + myCompositePrintable.addLast(new Printable() { + public void printOn(final Printer printer) { + printer.print(text, contentType); + } + }); } public void onNewAvailable(final Printable printable) { diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ExternalOutput.java b/platform/testRunner/src/com/intellij/execution/testframework/ExternalOutput.java deleted file mode 100644 index 49558e6df03e..000000000000 --- a/platform/testRunner/src/com/intellij/execution/testframework/ExternalOutput.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2000-2009 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.testframework; - - - -import com.intellij.execution.ui.ConsoleViewContentType; - - - - - -public class ExternalOutput implements Printable { - - private final ConsoleViewContentType myType; - - private final String myContents; - - - - public ExternalOutput(final String contents, final ConsoleViewContentType type) { - - myType = type; - - myContents = contents; - - } - - - - public void printOn(final Printer printer) { - - printer.print(myContents, myType); - - } - -} - diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestsOutputConsoleView.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestsOutputConsoleView.java index 6e1880baecc8..3175216d3194 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestsOutputConsoleView.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestsOutputConsoleView.java @@ -18,10 +18,7 @@ package com.intellij.execution.testframework.ui; import com.intellij.execution.filters.Filter; import com.intellij.execution.filters.HyperlinkInfo; import com.intellij.execution.filters.TextConsoleBuilderFactory; -import com.intellij.execution.testframework.ExternalOutput; -import com.intellij.execution.testframework.HyperLink; -import com.intellij.execution.testframework.Printable; -import com.intellij.execution.testframework.TestConsoleProperties; +import com.intellij.execution.testframework.*; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.ObservableConsoleView; @@ -57,7 +54,11 @@ public abstract class BaseTestsOutputConsoleView implements ConsoleView, Observa protected abstract TestResultsPanel createTestResultsPanel(); public void print(final String s, final ConsoleViewContentType contentType) { - printNew(new ExternalOutput(s, contentType)); + printNew(new Printable() { + public void printOn(final Printer printer) { + printer.print(s, contentType); + } + }); } public void clear() { diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index 72e4ab484949..35de8646519a 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -312,7 +312,11 @@ public abstract class TestObject implements JavaCommandLine { currentTest.onOutput(text, consoleViewType); } else { - consoleView.getPrinter().onNewAvailable(new ExternalOutput(text, consoleViewType)); + consoleView.getPrinter().onNewAvailable(new Printable() { + public void printOn(final Printer printer) { + printer.print(text, consoleViewType); + } + }); } } }); diff --git a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java index 17a9cc5e0c11..48236aa93170 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java +++ b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java @@ -19,11 +19,11 @@ package com.intellij.execution.junit2; import com.intellij.execution.Location; import com.intellij.execution.junit2.events.*; import com.intellij.execution.junit2.info.TestInfo; -import com.intellij.execution.junit2.segments.InputConsumer; import com.intellij.execution.junit2.states.Statistics; import com.intellij.execution.junit2.states.TestState; import com.intellij.execution.testframework.*; import com.intellij.execution.testframework.ui.PrintableTestProxy; +import com.intellij.execution.testframework.ui.TestsOutputConsolePrinter; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -36,7 +36,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -public class TestProxy extends CompositePrintable implements PrintableTestProxy, InputConsumer, ChangingPrintable { +public class TestProxy extends CompositePrintable implements PrintableTestProxy, ChangingPrintable { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.TestProxy"); private final TestInfo myInfo; @@ -67,8 +67,11 @@ public class TestProxy extends CompositePrintable implements PrintableTestProxy, myPrinter.mark(); myMarked = true; } - final ExternalOutput printable = new ExternalOutput(text, contentType); - addLast(printable); + addLast(new Printable() { + public void printOn(final Printer printer) { + printer.print(text, contentType); + } + }); } public void addLast(final Printable printable) { diff --git a/plugins/junit/src/com/intellij/execution/junit2/TestRootImpl.java b/plugins/junit/src/com/intellij/execution/junit2/TestRootImpl.java deleted file mode 100644 index 64e6a7fb5d85..000000000000 --- a/plugins/junit/src/com/intellij/execution/junit2/TestRootImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2000-2009 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.junit2; - -import com.intellij.execution.junit2.info.ClassBasedInfo; -import com.intellij.execution.junit2.info.DisplayTestInfoExtractor; -import com.intellij.execution.junit2.segments.ObjectReader; -import com.intellij.util.containers.HashMap; - -import java.util.List; - -public class TestRootImpl implements TestRoot { - private final TestProxy myRootTest; - private final HashMap myKnownDynamicParents = new HashMap(); - - public TestRootImpl(final TestProxy rootTest) { - myRootTest = rootTest; - } - - public void addChild(final TestProxy child) { - if (child == myRootTest) - return; - getDynamicParentFor(child).addChild(child); - } - - private TestProxy getDynamicParentFor(final TestProxy child) { - final String parentClass = child.getInfo().getComment(); - TestProxy dynamicParent = myKnownDynamicParents.get(parentClass); - if (dynamicParent == null) { - dynamicParent = new TestProxy(new DynamicParentInfo(parentClass)); - myKnownDynamicParents.put(parentClass, dynamicParent); - myRootTest.addChild(dynamicParent); - } - return dynamicParent; - } - - public TestProxy getRootTest() { - return myRootTest; - } - - public List getAllTests() { - return getRootTest().getAllTests(); - } - - private static class DynamicParentInfo extends ClassBasedInfo { - public DynamicParentInfo(final String className) { - super(DisplayTestInfoExtractor.FOR_CLASS); - setClassName(className); - } - - public void readFrom(final ObjectReader reader) { - } - } -} From f31ab71f32acd8bdbe25eff78eee860303361b3d Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 21 Jul 2010 13:45:27 +0400 Subject: [PATCH 017/102] CCE --- .../execution/junit2/configuration/JUnitConfigurable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java index a27a2cc70cdf..6128e3a710e2 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java +++ b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java @@ -356,7 +356,7 @@ public class JUnitConfigurable extends SettingsEditor { } private String getClassName() { - return ((LabeledComponent)getTestLocation(JUnitConfigurationModel.CLASS).getComponent()).getText(); + return ((LabeledComponent)getTestLocation(JUnitConfigurationModel.CLASS)).getComponent().getText(); } private void setPackage(final PsiPackage aPackage) { From 6ec509cc1c25f5cde4709fbae2e63dbc80b61826 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 21 Jul 2010 14:14:49 +0400 Subject: [PATCH 018/102] testframework refactoring: compact tests hierarchy --- .../testframework/sm/runner/SMTestProxy.java | 35 +---------- .../sm/runner/states/SuiteFinishedState.java | 5 +- .../sm/runner/states/TestFailedState.java | 9 +-- .../sm/runner/states/TestIgnoredState.java | 11 ++-- .../sm/runner/ui/SMTRunnerConsoleView.java | 3 +- .../runner/ui/SMTRunnerUIActionsHandler.java | 4 +- .../sm/runner/ui/SMTestRunnerResultsForm.java | 3 +- .../ui/TestProxyTreeSelectionListener.java | 4 +- .../sm/runner/SMTRunnerConsoleTest.java | 22 +++---- .../testframework/AbstractTestProxy.java | 63 ++++++++++++++----- .../testframework/ChangingPrintable.java | 54 ---------------- .../testframework/CompositePrintable.java | 27 +------- .../testframework/ui/PrintableTestProxy.java | 28 --------- .../ui/TestsOutputConsolePrinter.java | 15 ++--- .../intellij/execution/junit2/TestProxy.java | 30 +-------- .../execution/junit2/states/FaultyState.java | 7 ++- .../execution/junit2/states/IgnoredState.java | 9 +-- .../execution/junit2/states/SkippedState.java | 5 +- .../testng/model/TestProxy.java | 44 ++++++------- .../testng/model/TreeRootNode.java | 7 ++- 20 files changed, 124 insertions(+), 261 deletions(-) delete mode 100644 platform/testRunner/src/com/intellij/execution/testframework/ChangingPrintable.java delete mode 100644 platform/testRunner/src/com/intellij/execution/testframework/ui/PrintableTestProxy.java diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java index 16182f240d2b..7eb0bfab4810 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java @@ -20,7 +20,6 @@ import com.intellij.execution.testframework.*; import com.intellij.execution.testframework.sm.TestsLocationProviderUtil; import com.intellij.execution.testframework.sm.runner.states.*; import com.intellij.execution.testframework.sm.runner.ui.TestsPresentationUtil; -import com.intellij.execution.testframework.ui.PrintableTestProxy; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.ide.util.EditSourceUtil; import com.intellij.openapi.diagnostic.Logger; @@ -39,7 +38,7 @@ import java.util.List; /** * @author: Roman Chernyatchik */ -public class SMTestProxy extends CompositePrintable implements PrintableTestProxy { +public class SMTestProxy extends AbstractTestProxy { private static final Logger LOG = Logger.getInstance(SMTestProxy.class.getName()); private List myChildren; @@ -53,8 +52,6 @@ public class SMTestProxy extends CompositePrintable implements PrintableTestProx private boolean myHasErrors = false; private boolean myHasErrorsCached = false; - private Printer myPrinter = Printer.DEAF; - private final boolean myIsSuite; public SMTestProxy(final String testName, final boolean isSuite, @@ -152,9 +149,7 @@ public class SMTestProxy extends CompositePrintable implements PrintableTestProx child.setParent(this); // if parent is being printed then all childs output // should be also send to the same printer - if (myPrinter != Printer.DEAF) { - child.setPrintLinstener(myPrinter); - } + setChildPrinter(child); } public String getName() { @@ -333,17 +328,6 @@ public class SMTestProxy extends CompositePrintable implements PrintableTestProx return getParent() == null; } - public void setPrintLinstener(final Printer printer) { - myPrinter = printer; - - if (myChildren == null) { - return; - } - - for (ChangingPrintable child : myChildren) { - child.setPrintLinstener(printer); - } - } /** * Prints this proxy and all its children on given printer @@ -356,17 +340,6 @@ public class SMTestProxy extends CompositePrintable implements PrintableTestProx myState.printOn(printer); } - /** - * Stores printable information in internal buffer and notifies - * proxy's printer about new text available - * @param printable Printable info - */ - @Override - public void addLast(final Printable printable) { - super.addLast(printable); - fireOnNewPrintable(printable); - } - public void addStdOutput(final String output, final Key outputType) { addLast(new Printable() { public void printOn(final Printer printer) { @@ -404,10 +377,6 @@ public class SMTestProxy extends CompositePrintable implements PrintableTestProx }); } - private void fireOnNewPrintable(final Printable printable) { - myPrinter.onNewAvailable(printable); - } - @NotNull public String getPresentableName() { return TestsPresentationUtil.getPresentableName(this); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/SuiteFinishedState.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/SuiteFinishedState.java index 8575594a4b48..aa989c08fbad 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/SuiteFinishedState.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/SuiteFinishedState.java @@ -15,9 +15,10 @@ */ package com.intellij.execution.testframework.sm.runner.states; +import com.intellij.execution.testframework.CompositePrintable; import com.intellij.execution.testframework.Printer; import com.intellij.execution.testframework.sm.SMTestsRunnerBundle; -import com.intellij.execution.testframework.ui.PrintableTestProxy; +import com.intellij.execution.testframework.sm.runner.SMTestProxy; import com.intellij.execution.ui.ConsoleViewContentType; import org.jetbrains.annotations.NonNls; @@ -105,7 +106,7 @@ public abstract class SuiteFinishedState extends AbstractState { public void printOn(final Printer printer) { super.printOn(printer); - final String msg = EMPTY_SUITE_TEXT + PrintableTestProxy.NEW_LINE; + final String msg = EMPTY_SUITE_TEXT + CompositePrintable.NEW_LINE; printer.print(msg, ConsoleViewContentType.SYSTEM_OUTPUT); } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java index 4c6a5602c4f7..879f75b6b77a 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java @@ -15,8 +15,9 @@ */ package com.intellij.execution.testframework.sm.runner.states; +import com.intellij.execution.testframework.CompositePrintable; import com.intellij.execution.testframework.Printer; -import com.intellij.execution.testframework.ui.PrintableTestProxy; +import com.intellij.execution.testframework.sm.runner.SMTestProxy; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; @@ -38,16 +39,16 @@ public class TestFailedState extends AbstractState { @Nullable final String stackTrace) { final String text = (StringUtil.isEmptyOrSpaces(localizedMessage) ? "" - : localizedMessage + PrintableTestProxy.NEW_LINE) + + : localizedMessage + CompositePrintable.NEW_LINE) + (StringUtil.isEmptyOrSpaces(stackTrace) ? "" - : stackTrace + PrintableTestProxy.NEW_LINE); + : stackTrace + CompositePrintable.NEW_LINE); return StringUtil.isEmptyOrSpaces(text) ? null : text; } public static void printError(@NotNull final Printer printer, @NotNull final String errorPresentationText) { - printer.print(PrintableTestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); printer.mark(); printer.print(errorPresentationText, ConsoleViewContentType.ERROR_OUTPUT); } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestIgnoredState.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestIgnoredState.java index 22beed25458d..73fb154f8cfb 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestIgnoredState.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestIgnoredState.java @@ -15,9 +15,10 @@ */ package com.intellij.execution.testframework.sm.runner.states; +import com.intellij.execution.testframework.CompositePrintable; import com.intellij.execution.testframework.Printer; import com.intellij.execution.testframework.sm.SMTestsRunnerBundle; -import com.intellij.execution.testframework.ui.PrintableTestProxy; +import com.intellij.execution.testframework.sm.runner.SMTestProxy; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NonNls; @@ -33,8 +34,8 @@ public class TestIgnoredState extends AbstractState { public TestIgnoredState(final String ignoredComment, @Nullable final String stackTrace) { final String ignored_msg = StringUtil.isEmpty(ignoredComment) ? IGNORED_TEST_TEXT : ignoredComment; - myText = PrintableTestProxy.NEW_LINE + ignored_msg; - myStacktrace = stackTrace == null ? null : stackTrace + PrintableTestProxy.NEW_LINE; + myText = CompositePrintable.NEW_LINE + ignored_msg; + myStacktrace = stackTrace == null ? null : stackTrace + CompositePrintable.NEW_LINE; } public boolean isInProgress() { @@ -67,10 +68,10 @@ public class TestIgnoredState extends AbstractState { printer.print(myText, ConsoleViewContentType.SYSTEM_OUTPUT); if (StringUtil.isEmptyOrSpaces(myStacktrace)) { - printer.print(PrintableTestProxy.NEW_LINE, ConsoleViewContentType.SYSTEM_OUTPUT); + printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.SYSTEM_OUTPUT); } else { - printer.print(PrintableTestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); printer.mark(); printer.print(myStacktrace, ConsoleViewContentType.ERROR_OUTPUT); } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java index 21f0ddf8eca9..e46afbed361d 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java @@ -23,7 +23,6 @@ import com.intellij.execution.testframework.TestFrameworkRunningModel; import com.intellij.execution.testframework.sm.SMRunnerUtil; import com.intellij.execution.testframework.sm.runner.SMTestProxy; import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView; -import com.intellij.execution.testframework.ui.PrintableTestProxy; import com.intellij.execution.testframework.ui.TestResultsPanel; import com.intellij.openapi.application.ModalityState; import org.jetbrains.annotations.NotNull; @@ -88,7 +87,7 @@ public class SMTRunnerConsoleView extends BaseTestsOutputConsoleView { // Do nothing } - public void onSelected(@Nullable final PrintableTestProxy selectedTestProxy, + public void onSelected(@Nullable final SMTestProxy selectedTestProxy, @NotNull final TestResultsViewer viewer, @NotNull final TestFrameworkRunningModel model) { if (selectedTestProxy == null) { diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java index dc1c8428ff64..52b00aed4532 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerUIActionsHandler.java @@ -16,11 +16,9 @@ package com.intellij.execution.testframework.sm.runner.ui; import com.intellij.execution.testframework.AbstractTestProxy; -import com.intellij.execution.testframework.Filter; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.execution.testframework.TestFrameworkRunningModel; import com.intellij.execution.testframework.sm.runner.ProxyFilters; -import com.intellij.execution.testframework.ui.PrintableTestProxy; import com.intellij.execution.testframework.actions.ScrollToTestSourceAction; import com.intellij.execution.testframework.sm.runner.SMTestProxy; import com.intellij.execution.testframework.sm.SMRunnerUtil; @@ -79,7 +77,7 @@ public class SMTRunnerUIActionsHandler implements TestResultsViewer.EventsListen } } - public void onSelected(@Nullable final PrintableTestProxy selectedTestProxy, + public void onSelected(@Nullable final SMTestProxy selectedTestProxy, @NotNull final TestResultsViewer viewer, @NotNull final TestFrameworkRunningModel model) { //TODO: tests o "onSelected" diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java index 16149d7a4319..82734b46d644 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java @@ -26,7 +26,6 @@ import com.intellij.execution.testframework.sm.runner.SMTRunnerTreeStructure; import com.intellij.execution.testframework.sm.runner.SMTestProxy; import com.intellij.execution.testframework.sm.runner.ui.statistics.StatisticsPanel; import com.intellij.execution.testframework.ui.AbstractTestTreeBuilder; -import com.intellij.execution.testframework.ui.PrintableTestProxy; import com.intellij.execution.testframework.ui.TestResultsPanel; import com.intellij.execution.testframework.ui.TestsProgressAnimator; import com.intellij.openapi.Disposable; @@ -344,7 +343,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra //e.g. it is focused. Otherwise it is side effect of selecting proxy in //try by other component //if (myTreeView.isFocusOwner()) { - @Nullable final PrintableTestProxy selectedProxy = (PrintableTestProxy)getTreeView().getSelectedTest(); + @Nullable final SMTestProxy selectedProxy = (SMTestProxy)getTreeView().getSelectedTest(); listener.onSelected(selectedProxy, SMTestRunnerResultsForm.this, SMTestRunnerResultsForm.this); //} } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestProxyTreeSelectionListener.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestProxyTreeSelectionListener.java index 0d0fdffc1915..4b7a8770b98b 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestProxyTreeSelectionListener.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestProxyTreeSelectionListener.java @@ -15,7 +15,7 @@ */ package com.intellij.execution.testframework.sm.runner.ui; -import com.intellij.execution.testframework.ui.PrintableTestProxy; +import com.intellij.execution.testframework.sm.runner.SMTestProxy; import com.intellij.execution.testframework.TestFrameworkRunningModel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,7 +30,7 @@ public interface TestProxyTreeSelectionListener { * @param viewer * @param model */ - void onSelected(@Nullable PrintableTestProxy selectedTestProxy, + void onSelected(@Nullable SMTestProxy selectedTestProxy, @NotNull TestResultsViewer viewer, @NotNull TestFrameworkRunningModel model); } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java index 4a5a46eceb63..3fe425c26070 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java @@ -86,7 +86,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testPrintTestProxy() { - mySimpleTest.setPrintLinstener(myMockResetablePrinter); + mySimpleTest.setPrintListener(myMockResetablePrinter); mySimpleTest.addLast(new Printable() { public void printOn(final Printer printer) { printer.print("std out", ConsoleViewContentType.NORMAL_OUTPUT); @@ -98,7 +98,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testAddStdOut() { - mySimpleTest.setPrintLinstener(myMockResetablePrinter); + mySimpleTest.setPrintListener(myMockResetablePrinter); mySimpleTest.addStdOutput("one", ProcessOutputTypes.STDOUT); assertStdOutput(myMockResetablePrinter, "one"); @@ -114,14 +114,14 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testAddStdSys() { - mySimpleTest.setPrintLinstener(myMockResetablePrinter); + mySimpleTest.setPrintListener(myMockResetablePrinter); mySimpleTest.addSystemOutput("sys"); assertAllOutputs(myMockResetablePrinter, "", "", "sys"); } public void testPrintTestProxy_Order() { - mySimpleTest.setPrintLinstener(myMockResetablePrinter); + mySimpleTest.setPrintListener(myMockResetablePrinter); sendToTestProxyStdOut(mySimpleTest, "first "); sendToTestProxyStdOut(mySimpleTest, "second"); @@ -132,7 +132,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { public void testSetPrintListener_ForExistingChildren() { mySuite.addChild(mySimpleTest); - mySuite.setPrintLinstener(myMockResetablePrinter); + mySuite.setPrintListener(myMockResetablePrinter); sendToTestProxyStdOut(mySimpleTest, "child "); sendToTestProxyStdOut(mySuite, "root"); @@ -141,7 +141,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testSetPrintListener_OnNewChild() { - mySuite.setPrintLinstener(myMockResetablePrinter); + mySuite.setPrintListener(myMockResetablePrinter); sendToTestProxyStdOut(mySuite, "root "); @@ -299,7 +299,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { myEventsProcessor.onSuiteStarted("suite", null); final SMTestProxy suite = myEventsProcessor.getCurrentSuite(); - suite.setPrintLinstener(myMockResetablePrinter); + suite.setPrintListener(myMockResetablePrinter); myEventsProcessor.onError("error msg:suite", "method1:1\nmethod2:2"); assertAllOutputs(myMockResetablePrinter, "", "\n" + @@ -387,13 +387,13 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testOnUncapturedOutput_BeforeProcessStarted() { - myRootSuite.setPrintLinstener(myMockResetablePrinter); + myRootSuite.setPrintListener(myMockResetablePrinter); assertOnUncapturedOutput(); } public void testOnUncapturedOutput_BeforeFirstSuiteStarted() { - myRootSuite.setPrintLinstener(myMockResetablePrinter); + myRootSuite.setPrintListener(myMockResetablePrinter); myEventsProcessor.onStartTesting(); assertOnUncapturedOutput(); @@ -405,7 +405,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { myEventsProcessor.onSuiteStarted("my suite", null); final SMTestProxy mySuite = myEventsProcessor.getCurrentSuite(); assertTrue(mySuite != myRootSuite); - mySuite.setPrintLinstener(myMockResetablePrinter); + mySuite.setPrintListener(myMockResetablePrinter); assertOnUncapturedOutput(); } @@ -476,7 +476,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { myEventsProcessor.onTestStarted(testName, null); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(myEventsProcessor.getFullTestName(testName)); - proxy.setPrintLinstener(myMockResetablePrinter); + proxy.setPrintListener(myMockResetablePrinter); return proxy; } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java index c21b28d0f4e4..fb8dbf1fe377 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java @@ -26,36 +26,67 @@ import com.intellij.openapi.project.Project; import com.intellij.pom.Navigatable; import org.jetbrains.annotations.NonNls; +import java.util.Iterator; import java.util.List; -public interface AbstractTestProxy { - DataKey DATA_KEY = DataKey.create("testProxy"); - @Deprecated @NonNls String DATA_CONSTANT = DATA_KEY.getName(); +public abstract class AbstractTestProxy extends CompositePrintable { + public static final DataKey DATA_KEY = DataKey.create("testProxy"); + protected Printer myPrinter = Printer.DEAF; - boolean isInProgress(); + public abstract boolean isInProgress(); - boolean isDefect(); + public abstract boolean isDefect(); //todo? - boolean shouldRun(); + public abstract boolean shouldRun(); - int getMagnitude(); + public abstract int getMagnitude(); - boolean isLeaf(); + public abstract boolean isLeaf(); - boolean isInterrupted(); + public abstract boolean isInterrupted(); - boolean isPassed(); + public abstract boolean isPassed(); - String getName(); + public abstract String getName(); - Location getLocation(final Project project); + public abstract Location getLocation(final Project project); - Navigatable getDescriptor(final Location location); + public abstract Navigatable getDescriptor(final Location location); - AbstractTestProxy getParent(); + public abstract AbstractTestProxy getParent(); - List getChildren(); + public abstract List getChildren(); - List getAllTests(); + public abstract List getAllTests(); + + public abstract boolean isRoot(); + + public void setChildPrinter(AbstractTestProxy child) { + if (myPrinter != Printer.DEAF) { + child.setPrintListener(myPrinter); + } + } + + public void fireOnNewPrintable(final Printable printable) { + myPrinter.onNewAvailable(printable); + } + + public void setPrintListener(final Printer printer) { + myPrinter = printer; + for (AbstractTestProxy testProxy : getChildren()) { + testProxy.setPrintListener(printer); + } + } + + /** + * Stores printable information in internal buffer and notifies + * proxy's printer about new text available + * @param printable Printable info + */ + @Override + public void addLast(final Printable printable) { + super.addLast(printable); + fireOnNewPrintable(printable); + } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ChangingPrintable.java b/platform/testRunner/src/com/intellij/execution/testframework/ChangingPrintable.java deleted file mode 100644 index 9d2af2549bbd..000000000000 --- a/platform/testRunner/src/com/intellij/execution/testframework/ChangingPrintable.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2000-2009 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.testframework; - - - -public interface ChangingPrintable extends Printable { - - void setPrintLinstener(Printer printer); - - ChangingPrintable DEAF = new ChangingPrintable() { - - public void setPrintLinstener(final Printer printer) { - - } - - - - public void printOn(final Printer printer) { - - } - - - - @Override - - public String toString() { - - //noinspection HardCodedStringLiteral - - return "DEAF printer"; - - } - - }; - -} - diff --git a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java index 40679ce9c509..e8e27118cb44 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java @@ -13,58 +13,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - - package com.intellij.execution.testframework; - - import java.util.ArrayList; import java.util.List; - - public class CompositePrintable implements Printable { + public static final String NEW_LINE = "\n"; private final ArrayList myNestedPrintables = new ArrayList(); - - public void printOn(final Printer printer) { - printAllOn(myNestedPrintables, printer); - } - - public void addLast(final Printable printable) { - myNestedPrintables.add(printable); - } - - protected void clear() { - myNestedPrintables.clear(); - } - - public static void printAllOn(final List printables, final Printer console) { - for (final T printable : printables) { - printable.printOn(console); - } - } - } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/PrintableTestProxy.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/PrintableTestProxy.java deleted file mode 100644 index 7a854143927d..000000000000 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/PrintableTestProxy.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2000-2009 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.testframework.ui; - -import com.intellij.execution.testframework.AbstractTestProxy; -import com.intellij.execution.testframework.ChangingPrintable; - -/** - * @author Roman Chernyatchik - */ -public interface PrintableTestProxy extends AbstractTestProxy, ChangingPrintable { - String NEW_LINE = "\n"; - - boolean isRoot(); -} diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java index 34b0990a6b65..b95c5eba35f9 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java @@ -25,7 +25,7 @@ import com.intellij.openapi.Disposable; public class TestsOutputConsolePrinter implements Printer, Disposable { private final ConsoleView myConsole; private final TestConsoleProperties myProperties; - private ChangingPrintable myCurrentPrintable = ChangingPrintable.DEAF; + private AbstractTestProxy myCurrentPrintable; private Printer myOutput; // After pause action has been invoked - all output will be redirected to special @@ -91,19 +91,18 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { * This method must be invoked in Event Dispatch Thread * @param test Selected test */ - public void updateOnTestSelected(final PrintableTestProxy test) { + public void updateOnTestSelected(final AbstractTestProxy test) { if (myCurrentPrintable == test) { return; } - myCurrentPrintable.setPrintLinstener(DEAF); myConsole.clear(); myMarkOffset = 0; if (test == null) { - myCurrentPrintable = ChangingPrintable.DEAF; + myCurrentPrintable = null; return; } myCurrentPrintable = test; - myCurrentPrintable.setPrintLinstener(this); + myCurrentPrintable.setPrintListener(this); if (test.isRoot()) { myOutputStorage.printOn(this); } @@ -132,11 +131,7 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { } public boolean canPause() { - if (myCurrentPrintable instanceof AbstractTestProxy) { - final AbstractTestProxy test = (AbstractTestProxy)myCurrentPrintable; - return test.isInProgress(); - } - return false; + return myCurrentPrintable != null ? myCurrentPrintable.isInProgress() : false; } protected void scrollToBeginning() { diff --git a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java index 48236aa93170..f2b13c3aab54 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java +++ b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java @@ -22,8 +22,6 @@ import com.intellij.execution.junit2.info.TestInfo; import com.intellij.execution.junit2.states.Statistics; import com.intellij.execution.junit2.states.TestState; import com.intellij.execution.testframework.*; -import com.intellij.execution.testframework.ui.PrintableTestProxy; -import com.intellij.execution.testframework.ui.TestsOutputConsolePrinter; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -36,12 +34,11 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -public class TestProxy extends CompositePrintable implements PrintableTestProxy, ChangingPrintable { +public class TestProxy extends AbstractTestProxy { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.TestProxy"); private final TestInfo myInfo; private TestState myState = TestState.DEFAULT; - private Printer myPrinter = Printer.DEAF; private final TestProxyListenersNotifier myNotifier = new TestProxyListenersNotifier(); private Statistics myStatistics = new Statistics(); private TestEventsConsumer myEventsConsumer; @@ -74,15 +71,6 @@ public class TestProxy extends CompositePrintable implements PrintableTestProxy, }); } - public void addLast(final Printable printable) { - super.addLast(printable); - fireOnNewPrintable(printable); - } - - private void fireOnNewPrintable(final Printable printable) { - myPrinter.onNewAvailable(printable); - } - public void printOn(final Printer printer) { super.printOn(printer); CompositePrintable.printAllOn(myChildren.getList(), printer); @@ -117,10 +105,6 @@ public class TestProxy extends CompositePrintable implements PrintableTestProxy, return myStateTimestamp; } - public TestProxy getChildAt(final int childIndex) { - return myChildren.getList().get(childIndex); - } - public int getChildCount() { return myChildren.getList().size(); } @@ -181,22 +165,12 @@ public class TestProxy extends CompositePrintable implements PrintableTestProxy, return;//todo throw new RuntimeException("Test: "+child + " already has parent: " + child.getParent()); myChildren.add(child); child.myParent = this; - if (myPrinter != Printer.DEAF) { - child.setPrintLinstener(myPrinter); - child.fireOnNewPrintable(child); - } + setChildPrinter(child); pullEvent(new NewChildEvent(this, child)); getState().changeStateAfterAddingChildTo(this, child); myNotifier.onChildAdded(this, child); } - public void setPrintLinstener(final Printer printer) { - myPrinter = printer; - for (Iterator iterator = myChildren.iterator(); iterator.hasNext();) { - final TestProxy testProxy = (TestProxy) iterator.next(); - testProxy.setPrintLinstener(printer); - } - } public TestInfo getInfo() { return myInfo; diff --git a/plugins/junit/src/com/intellij/execution/junit2/states/FaultyState.java b/plugins/junit/src/com/intellij/execution/junit2/states/FaultyState.java index 519e03569f5f..b29137523911 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/states/FaultyState.java +++ b/plugins/junit/src/com/intellij/execution/junit2/states/FaultyState.java @@ -20,8 +20,9 @@ import com.intellij.execution.Location; import com.intellij.execution.PsiLocation; import com.intellij.execution.junit2.segments.ObjectReader; import com.intellij.execution.stacktrace.StackTraceLine; +import com.intellij.execution.testframework.AbstractTestProxy; +import com.intellij.execution.testframework.CompositePrintable; import com.intellij.execution.testframework.Printer; -import com.intellij.execution.testframework.ui.PrintableTestProxy; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.diff.LineTokenizer; import com.intellij.pom.Navigatable; @@ -44,11 +45,11 @@ public class FaultyState extends ReadableState { } public void printOn(final Printer printer) { - printer.print(PrintableTestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); printer.mark(); for (int i = 0; i < myMessages.size(); i++) { printExceptionHeader(printer, myMessages.get(i)); - printer.print(myStackTraces.get(i) + PrintableTestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + printer.print(myStackTraces.get(i) + CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); } } diff --git a/plugins/junit/src/com/intellij/execution/junit2/states/IgnoredState.java b/plugins/junit/src/com/intellij/execution/junit2/states/IgnoredState.java index fba1b82b200c..54ce283592d0 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/states/IgnoredState.java +++ b/plugins/junit/src/com/intellij/execution/junit2/states/IgnoredState.java @@ -19,8 +19,9 @@ package com.intellij.execution.junit2.states; import com.intellij.execution.ExecutionBundle; import com.intellij.execution.junit2.TestProxy; import com.intellij.execution.junit2.segments.ObjectReader; +import com.intellij.execution.testframework.AbstractTestProxy; +import com.intellij.execution.testframework.CompositePrintable; import com.intellij.execution.testframework.Printer; -import com.intellij.execution.testframework.ui.PrintableTestProxy; import com.intellij.execution.ui.ConsoleViewContentType; public class IgnoredState extends ReadableState { @@ -39,12 +40,12 @@ public class IgnoredState extends ReadableState { public void printOn(final Printer printer) { String parentName = myPeformedTest.getParent() == null ? myPeformedTest.getInfo().getComment() : myPeformedTest.getParent().toString(); String message = ExecutionBundle.message("junit.runing.info.ignored.console.message", parentName, myPeformedTest.getInfo().getName()); - printer.print(message + (myIgnoredMessage.length() > 0 ? " (" + myIgnoredMessage + ")": "") + PrintableTestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + printer.print(message + (myIgnoredMessage.length() > 0 ? " (" + myIgnoredMessage + ")": "") + CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); if (myMessage.length() > 0) { - printer.print(myMessage + PrintableTestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + printer.print(myMessage + CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); } if (myStackTrace.length() > 0) { - printer.print(myStackTrace + PrintableTestProxy.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); + printer.print(myStackTrace + CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT); } } } diff --git a/plugins/junit/src/com/intellij/execution/junit2/states/SkippedState.java b/plugins/junit/src/com/intellij/execution/junit2/states/SkippedState.java index 6634c1f74cc3..dfb25753cfaf 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/states/SkippedState.java +++ b/plugins/junit/src/com/intellij/execution/junit2/states/SkippedState.java @@ -19,8 +19,9 @@ package com.intellij.execution.junit2.states; import com.intellij.execution.junit2.TestProxy; import com.intellij.execution.junit2.segments.ObjectReader; import com.intellij.execution.junit2.ui.Formatters; +import com.intellij.execution.testframework.AbstractTestProxy; +import com.intellij.execution.testframework.CompositePrintable; import com.intellij.execution.testframework.Printer; -import com.intellij.execution.testframework.ui.PrintableTestProxy; import com.intellij.execution.ui.ConsoleViewContentType; public class SkippedState extends ReadableState { @@ -31,7 +32,7 @@ public class SkippedState extends ReadableState { } public void printOn(final Printer printer) { - printer.print(Formatters.printTest(myPeformedTest) + ":" + PrintableTestProxy.NEW_LINE, + printer.print(Formatters.printTest(myPeformedTest) + ":" + CompositePrintable.NEW_LINE, ConsoleViewContentType.SYSTEM_OUTPUT); myPeformedTest.printOn(printer); } diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java index c7426e894bfd..e298bd340871 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java @@ -21,6 +21,7 @@ import com.intellij.execution.stacktrace.StackTraceLine; import com.intellij.execution.testframework.AbstractTestProxy; import com.intellij.execution.testframework.Filter; import com.intellij.execution.testframework.Printable; +import com.intellij.execution.testframework.Printer; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.ide.util.EditSourceUtil; import com.intellij.openapi.application.ApplicationManager; @@ -42,7 +43,7 @@ import java.util.List; /** * @author Hani Suleiman Date: Jul 28, 2005 Time: 10:52:51 PM */ -public class TestProxy implements AbstractTestProxy { +public class TestProxy extends AbstractTestProxy { private final List results = new ArrayList(); private TestResultMessage resultMessage; private String name; @@ -63,10 +64,6 @@ public class TestProxy implements AbstractTestProxy { return name; } - public void setName(String name) { - this.name = name; - } - @Nullable public PsiElement getPsiElement() { return psiElement != null ? psiElement.getElement() : null; @@ -202,17 +199,6 @@ public class TestProxy implements AbstractTestProxy { return EditSourceUtil.getDescriptor(location.getPsiElement()); } - public TestProxy[] getPathFromRoot() { - ArrayList arraylist = new ArrayList(); - TestProxy testproxy = this; - do { - arraylist.add(testproxy); - } - while ((testproxy = testproxy.getParent()) != null); - Collections.reverse(arraylist); - return arraylist.toArray(new TestProxy[arraylist.size()]); - } - @Override public String toString() { return name + ' ' + results; @@ -258,6 +244,11 @@ public class TestProxy implements AbstractTestProxy { return total; } + @Override + public boolean isRoot() { + return false; + } + public int getChildCount() { return results.size(); } @@ -275,15 +266,6 @@ public class TestProxy implements AbstractTestProxy { return null; } - public boolean childExists(String child) { - for (int count = 0; count < getChildCount(); count++) { - if (child.equals(getChildAt(count).getName())) { - return true; - } - } - return false; - } - public int getExceptionMark() { if (myExceptionMark == 0 && getChildCount() > 0) { return (output != null ? output.size() : 0) + getChildAt(0).getExceptionMark(); @@ -309,4 +291,16 @@ public class TestProxy implements AbstractTestProxy { public void setTearDownFailure(boolean tearDownFailure) { myTearDownFailure = tearDownFailure; } + + @Override + public void printOn(Printer printer) {//todo + } + + @Override + public void setPrintListener(Printer printer) {// todo + } + + @Override + public void fireOnNewPrintable(Printable printable) {// todo + } } diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TreeRootNode.java b/plugins/testng/src/com/theoryinpractice/testng/model/TreeRootNode.java index c99f9f9120f0..d27ee711dce0 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TreeRootNode.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TreeRootNode.java @@ -33,7 +33,12 @@ public class TreeRootNode extends TestProxy return inProgress; } - public void setInProgress(boolean inProgress) { + @Override + public boolean isRoot() { + return true; + } + + public void setInProgress(boolean inProgress) { this.inProgress = inProgress; } From cee7bb5f3fbf7ec0305579b1d321ecc352f42797 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 21 Jul 2010 14:41:00 +0400 Subject: [PATCH 019/102] testframework refactoring: test proxy schould forget about printer's marks --- .../ui/TestsOutputConsolePrinter.java | 4 ++++ .../intellij/execution/junit/TestObject.java | 19 +++++++++++++------ .../intellij/execution/junit2/TestProxy.java | 15 +-------------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java index b95c5eba35f9..9532523d7c07 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java @@ -141,4 +141,8 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { } }); } + + public boolean isMarked() { + return myMarkOffset > 0; + } } \ No newline at end of file diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index 35de8646519a..9023b2351041 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -33,6 +33,7 @@ import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.testframework.*; +import com.intellij.execution.testframework.ui.TestsOutputConsolePrinter; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.util.JavaParametersUtil; import com.intellij.openapi.Disposable; @@ -308,15 +309,21 @@ public abstract class TestObject implements JavaCommandLine { final String text = event.getText(); final ConsoleViewContentType consoleViewType = ConsoleViewContentType.getConsoleViewType(outputType); final TestProxy currentTest = packetsReceiver.getCurrentTest(); + final TestsOutputConsolePrinter consolePrinter = consoleView.getPrinter(); + final Printable printable = new Printable() { + public void printOn(final Printer printer) { + printer.print(text, consoleViewType); + } + }; + if (currentTest != null) { - currentTest.onOutput(text, consoleViewType); + if (consoleViewType == ConsoleViewContentType.ERROR_OUTPUT && !consolePrinter.isMarked()) { + consolePrinter.mark(); + } + currentTest.addLast(printable); } else { - consoleView.getPrinter().onNewAvailable(new Printable() { - public void printOn(final Printer printer) { - printer.print(text, consoleViewType); - } - }); + consolePrinter.onNewAvailable(printable); } } }); diff --git a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java index f2b13c3aab54..bc1b280ed94a 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java +++ b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java @@ -44,9 +44,8 @@ public class TestProxy extends AbstractTestProxy { private TestEventsConsumer myEventsConsumer; private int myPreviousMagnitude = -1; private int myStateTimestamp = 0; - private boolean myMarked = false; -// private ArrayList myChildren = new ArrayList(); + // private ArrayList myChildren = new ArrayList(); private final FilterCache myChildren = new FilterCache(); private TestProxy myParent = null; public static final Filter NOT_LEAF = Filter.LEAF.not(); @@ -59,18 +58,6 @@ public class TestProxy extends AbstractTestProxy { return getInfo().getComment() + "." + getInfo().getName(); } - public void onOutput(final String text, final ConsoleViewContentType contentType) { - if (!myMarked && contentType == ConsoleViewContentType.ERROR_OUTPUT) { - myPrinter.mark(); - myMarked = true; - } - addLast(new Printable() { - public void printOn(final Printer printer) { - printer.print(text, contentType); - } - }); - } - public void printOn(final Printer printer) { super.printOn(printer); CompositePrintable.printAllOn(myChildren.getList(), printer); From bc5ab28d29ac839ffad72cf38f9140801682fbec Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 21 Jul 2010 18:27:00 +0400 Subject: [PATCH 020/102] testframework refactoring: paused printer & unbound output refactored --- .../testframework/sm/runner/SMTestProxy.java | 6 +- .../sm/runner/ui/SMTRunnerConsoleView.java | 3 +- .../sm/runner/SMTRunnerConsoleTest.java | 24 +++--- .../sm/runner/SMTestProxyTest.java | 4 +- .../testframework/AbstractTestProxy.java | 21 ++---- .../testframework/DeferingPrinter.java | 9 +-- .../execution/testframework/Printer.java | 8 -- .../ui/BaseTestsOutputConsoleView.java | 4 +- .../ui/TestsOutputConsolePrinter.java | 74 ++++++++----------- .../intellij/execution/junit/TestObject.java | 12 ++- .../intellij/execution/junit2/TestProxy.java | 9 +-- .../junit2/ui/JUnitTreeConsoleView.java | 9 ++- .../junit2/ui/model/RootTestInfo.java | 54 ++++++++++++++ .../junit2/ui/model/SpecialNode.java | 41 +--------- .../testng/model/TestProxy.java | 18 ----- .../testng/model/TreeRootNode.java | 4 - .../testng/ui/TestNGConsoleView.java | 2 +- 17 files changed, 131 insertions(+), 171 deletions(-) create mode 100644 plugins/junit/src/com/intellij/execution/junit2/ui/model/RootTestInfo.java diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java index 7eb0bfab4810..b75a28fdc6ca 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java @@ -149,7 +149,7 @@ public class SMTestProxy extends AbstractTestProxy { child.setParent(this); // if parent is being printed then all childs output // should be also send to the same printer - setChildPrinter(child); + child.setPrinter(myPrinter); } public String getName() { @@ -324,10 +324,6 @@ public class SMTestProxy extends AbstractTestProxy { return myState.wasLaunched(); } - public boolean isRoot() { - return getParent() == null; - } - /** * Prints this proxy and all its children on given printer diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java index e46afbed361d..37a79cbdd18a 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTRunnerConsoleView.java @@ -52,7 +52,7 @@ public class SMTRunnerConsoleView extends BaseTestsOutputConsoleView { public SMTRunnerConsoleView(final TestConsoleProperties consoleProperties, final RunnerSettings runnerSettings, final ConfigurationPerRunnerSettings configurationPerRunnerSettings, @Nullable final String splitterProperty) { - super(consoleProperties); + super(consoleProperties, null); myRunnerSettings = runnerSettings; myConfigurationPerRunnerSettings = configurationPerRunnerSettings; mySplitterProperty = splitterProperty; @@ -109,6 +109,5 @@ public class SMTRunnerConsoleView extends BaseTestsOutputConsoleView { } public void attachToProcess(final ProcessHandler processHandler) { - getPrinter().setCollectOutput(false); } } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java index 3fe425c26070..a3d76f356472 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java @@ -46,7 +46,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { final ConfigurationPerRunnerSettings configurationPerRunnerSettings) { super(consoleProperties, runnerSettings, configurationPerRunnerSettings); - myTestsOutputConsolePrinter = new TestsOutputConsolePrinter(MyConsoleView.this, consoleProperties) { + myTestsOutputConsolePrinter = new TestsOutputConsolePrinter(MyConsoleView.this, consoleProperties, null) { @Override public void print(final String text, final ConsoleViewContentType contentType) { myMockResetablePrinter.print(text, contentType); @@ -86,7 +86,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testPrintTestProxy() { - mySimpleTest.setPrintListener(myMockResetablePrinter); + mySimpleTest.setPrinter(myMockResetablePrinter); mySimpleTest.addLast(new Printable() { public void printOn(final Printer printer) { printer.print("std out", ConsoleViewContentType.NORMAL_OUTPUT); @@ -98,7 +98,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testAddStdOut() { - mySimpleTest.setPrintListener(myMockResetablePrinter); + mySimpleTest.setPrinter(myMockResetablePrinter); mySimpleTest.addStdOutput("one", ProcessOutputTypes.STDOUT); assertStdOutput(myMockResetablePrinter, "one"); @@ -114,14 +114,14 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testAddStdSys() { - mySimpleTest.setPrintListener(myMockResetablePrinter); + mySimpleTest.setPrinter(myMockResetablePrinter); mySimpleTest.addSystemOutput("sys"); assertAllOutputs(myMockResetablePrinter, "", "", "sys"); } public void testPrintTestProxy_Order() { - mySimpleTest.setPrintListener(myMockResetablePrinter); + mySimpleTest.setPrinter(myMockResetablePrinter); sendToTestProxyStdOut(mySimpleTest, "first "); sendToTestProxyStdOut(mySimpleTest, "second"); @@ -132,7 +132,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { public void testSetPrintListener_ForExistingChildren() { mySuite.addChild(mySimpleTest); - mySuite.setPrintListener(myMockResetablePrinter); + mySuite.setPrinter(myMockResetablePrinter); sendToTestProxyStdOut(mySimpleTest, "child "); sendToTestProxyStdOut(mySuite, "root"); @@ -141,7 +141,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testSetPrintListener_OnNewChild() { - mySuite.setPrintListener(myMockResetablePrinter); + mySuite.setPrinter(myMockResetablePrinter); sendToTestProxyStdOut(mySuite, "root "); @@ -299,7 +299,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { myEventsProcessor.onSuiteStarted("suite", null); final SMTestProxy suite = myEventsProcessor.getCurrentSuite(); - suite.setPrintListener(myMockResetablePrinter); + suite.setPrinter(myMockResetablePrinter); myEventsProcessor.onError("error msg:suite", "method1:1\nmethod2:2"); assertAllOutputs(myMockResetablePrinter, "", "\n" + @@ -387,13 +387,13 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { } public void testOnUncapturedOutput_BeforeProcessStarted() { - myRootSuite.setPrintListener(myMockResetablePrinter); + myRootSuite.setPrinter(myMockResetablePrinter); assertOnUncapturedOutput(); } public void testOnUncapturedOutput_BeforeFirstSuiteStarted() { - myRootSuite.setPrintListener(myMockResetablePrinter); + myRootSuite.setPrinter(myMockResetablePrinter); myEventsProcessor.onStartTesting(); assertOnUncapturedOutput(); @@ -405,7 +405,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { myEventsProcessor.onSuiteStarted("my suite", null); final SMTestProxy mySuite = myEventsProcessor.getCurrentSuite(); assertTrue(mySuite != myRootSuite); - mySuite.setPrintListener(myMockResetablePrinter); + mySuite.setPrinter(myMockResetablePrinter); assertOnUncapturedOutput(); } @@ -476,7 +476,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase { myEventsProcessor.onTestStarted(testName, null); final SMTestProxy proxy = myEventsProcessor.getProxyByFullTestName(myEventsProcessor.getFullTestName(testName)); - proxy.setPrintListener(myMockResetablePrinter); + proxy.setPrinter(myMockResetablePrinter); return proxy; } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTestProxyTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTestProxyTest.java index ce491c3b5047..7bb988ed6505 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTestProxyTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTestProxyTest.java @@ -78,11 +78,11 @@ public class SMTestProxyTest extends BaseSMTRunnerTestCase { public void testIsRoot() { final SMTestProxy rootTest = createTestProxy("root"); - assertTrue(rootTest.isRoot()); + assertTrue(rootTest.getParent() == null); rootTest.addChild(mySimpleTest); - assertFalse(mySimpleTest.isRoot()); + assertFalse(mySimpleTest.getParent() == null); } public void testTestStarted() { diff --git a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java index fb8dbf1fe377..4f78a229d8a8 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java @@ -21,17 +21,16 @@ package com.intellij.execution.testframework; import com.intellij.execution.Location; +import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.project.Project; import com.intellij.pom.Navigatable; -import org.jetbrains.annotations.NonNls; -import java.util.Iterator; import java.util.List; public abstract class AbstractTestProxy extends CompositePrintable { public static final DataKey DATA_KEY = DataKey.create("testProxy"); - protected Printer myPrinter = Printer.DEAF; + protected Printer myPrinter = null; public abstract boolean isInProgress(); @@ -60,22 +59,16 @@ public abstract class AbstractTestProxy extends CompositePrintable { public abstract List getAllTests(); - public abstract boolean isRoot(); - - public void setChildPrinter(AbstractTestProxy child) { - if (myPrinter != Printer.DEAF) { - child.setPrintListener(myPrinter); + public void fireOnNewPrintable(final Printable printable) { + if (myPrinter != null) { + myPrinter.onNewAvailable(printable); } } - public void fireOnNewPrintable(final Printable printable) { - myPrinter.onNewAvailable(printable); - } - - public void setPrintListener(final Printer printer) { + public void setPrinter(final Printer printer) { myPrinter = printer; for (AbstractTestProxy testProxy : getChildren()) { - testProxy.setPrintListener(printer); + testProxy.setPrinter(printer); } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java b/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java index eaee83bad9d0..678783d4fc80 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/DeferingPrinter.java @@ -20,11 +20,9 @@ import com.intellij.execution.filters.HyperlinkInfo; import com.intellij.execution.ui.ConsoleViewContentType; public class DeferingPrinter implements Printer { - private final boolean myCollectOutput; private CompositePrintable myCompositePrintable; - public DeferingPrinter(final boolean collectOutput) { - myCollectOutput = collectOutput; + public DeferingPrinter() { myCompositePrintable = new CompositePrintable(); } @@ -48,9 +46,8 @@ public class DeferingPrinter implements Printer { myCompositePrintable.addLast(new PrinterMark()); } - public void printOn(final Printer printer) { + public void printAndForget(final Printer printer) { myCompositePrintable.printOn(printer); - if (!myCollectOutput) - myCompositePrintable.clear(); + myCompositePrintable.clear(); } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/Printer.java b/platform/testRunner/src/com/intellij/execution/testframework/Printer.java index 7f16ef825f51..87d480bfb612 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/Printer.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/Printer.java @@ -23,12 +23,4 @@ public interface Printer { void onNewAvailable(Printable printable); void printHyperlink(String text, HyperlinkInfo info); void mark(); - - - Printer DEAF = new Printer() { - public void print(final String text, final ConsoleViewContentType contentType) {} - public void onNewAvailable(final Printable printable) {} - public void printHyperlink(final String text, final HyperlinkInfo info) {} - public void mark() {} - }; } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestsOutputConsoleView.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestsOutputConsoleView.java index 3175216d3194..97f92c7351f1 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestsOutputConsoleView.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestsOutputConsoleView.java @@ -35,10 +35,10 @@ public abstract class BaseTestsOutputConsoleView implements ConsoleView, Observa protected TestConsoleProperties myProperties; protected TestResultsPanel myTestResultsPanel; - public BaseTestsOutputConsoleView(final TestConsoleProperties properties) { + public BaseTestsOutputConsoleView(final TestConsoleProperties properties, final AbstractTestProxy unboundOutputRoot) { myProperties = properties; myConsole = TextConsoleBuilderFactory.getInstance().createBuilder(properties.getProject(), myProperties.getScope()).getConsole(); - myPrinter = new TestsOutputConsolePrinter(myConsole, properties); + myPrinter = new TestsOutputConsolePrinter(myConsole, properties, unboundOutputRoot); myProperties.setConsole(this); Disposer.register(this, myProperties); diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java index 9532523d7c07..21b93561e768 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestsOutputConsolePrinter.java @@ -25,24 +25,13 @@ import com.intellij.openapi.Disposable; public class TestsOutputConsolePrinter implements Printer, Disposable { private final ConsoleView myConsole; private final TestConsoleProperties myProperties; - private AbstractTestProxy myCurrentPrintable; - private Printer myOutput; + private final AbstractTestProxy myUnboundOutputRoot; + private AbstractTestProxy myCurrentTest; // After pause action has been invoked - all output will be redirected to special - // myDeferingPrinter which will dump all buffered data after user will continue process. - private final DeferingPrinter myDeferingPrinter = new DeferingPrinter(false); - - // It seems it is storage for uncaptured output by other printers (e.g. test proxies). - // To prevent duplicated output collectioning output on this printer must be paused - // (i.e. setCollectOutput(false)) after additional printer have been attached. You can - // continue to collect output after additional printers will be deattached(e.g. test runner stops - // sending events to test proxies). - - // If output collection was enabled for this console printer - all output will be collected in - // myOutputStorage component. Otherwise no output will be stored. - // 'myCurrentOutputStorage' printer is used for displaying whole output for test's root - private final DeferingPrinter myOutputStorage = new DeferingPrinter(true); - private Printer myCurrentOutputStorage = myOutputStorage; + // myPausedPrinter which will dump all buffered data after user will continue process. + private final DeferingPrinter myPausedPrinter = new DeferingPrinter(); + private boolean myPaused = false; private int myMarkOffset = 0; @@ -52,11 +41,11 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { } }; - public TestsOutputConsolePrinter(final ConsoleView console, final TestConsoleProperties properties) { + public TestsOutputConsolePrinter(final ConsoleView console, final TestConsoleProperties properties, final AbstractTestProxy unboundOutputRoot) { myConsole = console; myProperties = properties; + myUnboundOutputRoot = unboundOutputRoot; myProperties.addListener(TestConsoleProperties.SCROLL_TO_STACK_TRACE, myPropertyListener); - myOutput = this; } public ConsoleView getConsole() { @@ -64,15 +53,13 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { } public boolean isPaused() { - return myOutput != this; + return myPaused; } public void pause(final boolean doPause) { - if (doPause) - myOutput = myDeferingPrinter; - else { - myOutput = this; - myDeferingPrinter.printOn(myOutput); + myPaused = doPause; + if (!doPause) { + myPausedPrinter.printAndForget(this); } } @@ -81,8 +68,11 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { } public void onNewAvailable(final Printable printable) { - printable.printOn(myCurrentOutputStorage); - printable.printOn(myOutput); + if (myPaused) { + printable.printOn(myPausedPrinter); + } else { + printable.printOn(this); + } } /** @@ -92,27 +82,35 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { * @param test Selected test */ public void updateOnTestSelected(final AbstractTestProxy test) { - if (myCurrentPrintable == test) { + if (myCurrentTest == test) { return; } + if (myCurrentTest != null) { + myCurrentTest.setPrinter(null); + } myConsole.clear(); myMarkOffset = 0; if (test == null) { - myCurrentPrintable = null; + myCurrentTest = null; return; } - myCurrentPrintable = test; - myCurrentPrintable.setPrintListener(this); - if (test.isRoot()) { - myOutputStorage.printOn(this); + myCurrentTest = test; + myCurrentTest.setPrinter(this); + if (isRoot() && myUnboundOutputRoot != null) { + myUnboundOutputRoot.printOn(this); + } else { + myCurrentTest.printOn(this); } - myCurrentPrintable.printOn(this); scrollToBeginning(); if (myConsole instanceof ConsoleViewImpl) { ((ConsoleViewImpl)myConsole).foldImmediately(); } } + private boolean isRoot() { + return myCurrentTest.getParent() == myUnboundOutputRoot; + } + public void printHyperlink(final String text, final HyperlinkInfo info) { myConsole.printHyperlink(text, info); } @@ -125,13 +123,9 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { public void dispose() { myProperties.removeListener(TestConsoleProperties.SCROLL_TO_STACK_TRACE, myPropertyListener); } - - public void setCollectOutput(final boolean doCollect) { - myCurrentOutputStorage = doCollect ? myOutputStorage : DEAF; - } public boolean canPause() { - return myCurrentPrintable != null ? myCurrentPrintable.isInProgress() : false; + return myCurrentTest != null ? myCurrentTest.isInProgress() : false; } protected void scrollToBeginning() { @@ -141,8 +135,4 @@ public class TestsOutputConsolePrinter implements Printer, Disposable { } }); } - - public boolean isMarked() { - return myMarkOffset > 0; - } } \ No newline at end of file diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index 9023b2351041..190e397270b7 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -27,13 +27,13 @@ import com.intellij.execution.junit2.ui.JUnitTreeConsoleView; import com.intellij.execution.junit2.ui.TestsPacketsReceiver; import com.intellij.execution.junit2.ui.actions.RerunFailedTestsAction; import com.intellij.execution.junit2.ui.model.JUnitRunningModel; +import com.intellij.execution.junit2.ui.model.RootTestInfo; import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties; import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.testframework.*; -import com.intellij.execution.testframework.ui.TestsOutputConsolePrinter; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.util.JavaParametersUtil; import com.intellij.openapi.Disposable; @@ -259,8 +259,9 @@ public abstract class TestObject implements JavaCommandLine { for(final RunConfigurationExtension ext: Extensions.getExtensions(RunConfigurationExtension.EP_NAME)) { ext.handleStartProcess(myConfiguration, handler); } + final TestProxy unboundOutputRoot = new TestProxy(new RootTestInfo()); final JUnitConsoleProperties consoleProperties = new JUnitConsoleProperties(myConfiguration); - final JUnitTreeConsoleView consoleView = new JUnitTreeConsoleView(consoleProperties, getRunnerSettings(), getConfigurationSettings()); + final JUnitTreeConsoleView consoleView = new JUnitTreeConsoleView(consoleProperties, getRunnerSettings(), getConfigurationSettings(), unboundOutputRoot); consoleView.initUI(); consoleView.attachToProcess(handler); @@ -268,6 +269,7 @@ public abstract class TestObject implements JavaCommandLine { @Override public void notifyStart(TestProxy root) { super.notifyStart(root); + unboundOutputRoot.addChild(root); final JUnitRunningModel model = getModel(); if (model != null) { handler.getOut().setDispatchListener(model.getNotifier()); @@ -309,7 +311,6 @@ public abstract class TestObject implements JavaCommandLine { final String text = event.getText(); final ConsoleViewContentType consoleViewType = ConsoleViewContentType.getConsoleViewType(outputType); final TestProxy currentTest = packetsReceiver.getCurrentTest(); - final TestsOutputConsolePrinter consolePrinter = consoleView.getPrinter(); final Printable printable = new Printable() { public void printOn(final Printer printer) { printer.print(text, consoleViewType); @@ -317,13 +318,10 @@ public abstract class TestObject implements JavaCommandLine { }; if (currentTest != null) { - if (consoleViewType == ConsoleViewContentType.ERROR_OUTPUT && !consolePrinter.isMarked()) { - consolePrinter.mark(); - } currentTest.addLast(printable); } else { - consolePrinter.onNewAvailable(printable); + unboundOutputRoot.addLast(printable); } } }); diff --git a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java index bc1b280ed94a..a9b57d0d690f 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java +++ b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java @@ -22,7 +22,6 @@ import com.intellij.execution.junit2.info.TestInfo; import com.intellij.execution.junit2.states.Statistics; import com.intellij.execution.junit2.states.TestState; import com.intellij.execution.testframework.*; -import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.pom.Navigatable; @@ -60,7 +59,6 @@ public class TestProxy extends AbstractTestProxy { public void printOn(final Printer printer) { super.printOn(printer); - CompositePrintable.printAllOn(myChildren.getList(), printer); myState.printOn(printer); } @@ -152,7 +150,8 @@ public class TestProxy extends AbstractTestProxy { return;//todo throw new RuntimeException("Test: "+child + " already has parent: " + child.getParent()); myChildren.add(child); child.myParent = this; - setChildPrinter(child); + addLast(child); + child.setPrinter(myPrinter); pullEvent(new NewChildEvent(this, child)); getState().changeStateAfterAddingChildTo(this, child); myNotifier.onChildAdded(this, child); @@ -260,8 +259,4 @@ public class TestProxy extends AbstractTestProxy { return parents.toArray(new TestProxy[parents.size()]); } - public boolean isRoot() { - return getParent() == null; - } - } diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/JUnitTreeConsoleView.java b/plugins/junit/src/com/intellij/execution/junit2/ui/JUnitTreeConsoleView.java index d2311ceb6758..b8179f52552c 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/JUnitTreeConsoleView.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/JUnitTreeConsoleView.java @@ -18,10 +18,12 @@ package com.intellij.execution.junit2.ui; import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.junit2.TestProxy; import com.intellij.execution.junit2.ui.model.JUnitRunningModel; import com.intellij.execution.junit2.ui.model.TreeCollapser; import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties; import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.testframework.AbstractTestProxy; import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView; import com.intellij.execution.testframework.ui.TestResultsPanel; @@ -35,12 +37,12 @@ public class JUnitTreeConsoleView extends BaseTestsOutputConsoleView { public JUnitTreeConsoleView(final JUnitConsoleProperties properties, final RunnerSettings runnerSettings, - final ConfigurationPerRunnerSettings configurationSettings) { - super(properties); + final ConfigurationPerRunnerSettings configurationSettings, + final AbstractTestProxy unboundOutputRoot) { + super(properties, unboundOutputRoot); myProperties = properties; myRunnerSettings = runnerSettings; myConfigurationSettings = configurationSettings; - getPrinter().setCollectOutput(true); } protected TestResultsPanel createTestResultsPanel() { @@ -64,7 +66,6 @@ public class JUnitTreeConsoleView extends BaseTestsOutputConsoleView { } public void attachToModel(JUnitRunningModel model) { - getPrinter().setCollectOutput(false); myConsolePanel.getTreeView().attachToModel(model); model.attachToTree(myConsolePanel.getTreeView()); myConsolePanel.setModel(model); diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/model/RootTestInfo.java b/plugins/junit/src/com/intellij/execution/junit2/ui/model/RootTestInfo.java new file mode 100644 index 000000000000..aebcbfa39109 --- /dev/null +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/model/RootTestInfo.java @@ -0,0 +1,54 @@ +/* + * 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.junit2.ui.model; + +import com.intellij.execution.Location; +import com.intellij.execution.junit2.info.TestInfo; +import com.intellij.execution.junit2.segments.ObjectReader; +import com.intellij.openapi.project.Project; + +/** +* User: anna +* Date: Jul 21, 2010 +*/ +public class RootTestInfo extends TestInfo { + private String myName = SpecialNode.TESTS_IN_PROGRESS; + + public String getComment() { + return ""; + } + + public String getName() { return myName; } + + public void setName(final String name) { myName = name; } + + public boolean shouldRun() { + return false; + } + + public int getTestsCount() { + return 0; + } + + @Override + public void readFrom(ObjectReader reader) { + } + + public Location getLocation(final Project project) { + return null; + } + +} diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/model/SpecialNode.java b/plugins/junit/src/com/intellij/execution/junit2/ui/model/SpecialNode.java index a5e62e2d1cc6..0771d642175b 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/model/SpecialNode.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/model/SpecialNode.java @@ -16,22 +16,18 @@ package com.intellij.execution.junit2.ui.model; -import com.intellij.execution.Location; import com.intellij.execution.ExecutionBundle; -import com.intellij.execution.junit2.segments.ObjectReader; import com.intellij.execution.junit2.ui.TestProgress; import com.intellij.execution.junit2.TestProxy; -import com.intellij.execution.junit2.info.TestInfo; import com.intellij.execution.junit2.states.NotFailedState; import com.intellij.ide.util.treeView.AbstractTreeBuilder; -import com.intellij.openapi.project.Project; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class SpecialNode extends TestProxy { - private static final String ALL_PASSED = ExecutionBundle.message("junit.all.tests.passed.label"); - private static final String TESTS_IN_PROGRESS = ExecutionBundle.message("junit.tests.in.progress.label"); + public static final String ALL_PASSED = ExecutionBundle.message("junit.all.tests.passed.label"); + public static final String TESTS_IN_PROGRESS = ExecutionBundle.message("junit.tests.in.progress.label"); private final JUnitRunningModel myModel; private final AbstractTreeBuilder myBuilder; @@ -40,7 +36,7 @@ public class SpecialNode extends TestProxy { private CompletionEvent myCompletionEvent; public SpecialNode(final TestTreeBuilder treeBuilder, final JUnitRunningModel model) { - super(new MyTestInfo()); + super(new RootTestInfo()); myModel = model; myBuilder = treeBuilder; final MyJUnitAdapter listener = new MyJUnitAdapter(); @@ -59,35 +55,6 @@ public class SpecialNode extends TestProxy { updateName(); } - private static class MyTestInfo extends TestInfo { - private String myName = TESTS_IN_PROGRESS; - - public String getComment() { - return ""; - } - - public String getName() { return myName; } - - public void setName(final String name) { myName = name; } - - public boolean shouldRun() { - return false; - } - - public int getTestsCount() { - return 0; - } - - @Override - public void readFrom(ObjectReader reader) { - } - - public Location getLocation(final Project project) { - return null; - } - - } - private class MyJUnitAdapter extends JUnitAdapter implements ChangeListener { public void stateChanged(final ChangeEvent e) { if (myCompletionEvent != null) updateName(); @@ -107,7 +74,7 @@ public class SpecialNode extends TestProxy { private void updateName() { if (!myIsVisible) return; - final MyTestInfo myTestInfo = (MyTestInfo)getInfo(); + final RootTestInfo myTestInfo = (RootTestInfo)getInfo(); final String newName; final TestProgress progress = myModel.getProgress(); if (myCompletionEvent == null) { diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java index e298bd340871..8241c28c409e 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java @@ -36,7 +36,6 @@ import org.testng.remote.strprotocol.MessageHelper; import org.testng.remote.strprotocol.TestResultMessage; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -244,11 +243,6 @@ public class TestProxy extends AbstractTestProxy { return total; } - @Override - public boolean isRoot() { - return false; - } - public int getChildCount() { return results.size(); } @@ -291,16 +285,4 @@ public class TestProxy extends AbstractTestProxy { public void setTearDownFailure(boolean tearDownFailure) { myTearDownFailure = tearDownFailure; } - - @Override - public void printOn(Printer printer) {//todo - } - - @Override - public void setPrintListener(Printer printer) {// todo - } - - @Override - public void fireOnNewPrintable(Printable printable) {// todo - } } diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TreeRootNode.java b/plugins/testng/src/com/theoryinpractice/testng/model/TreeRootNode.java index d27ee711dce0..c5edc3c12a64 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TreeRootNode.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TreeRootNode.java @@ -33,10 +33,6 @@ public class TreeRootNode extends TestProxy return inProgress; } - @Override - public boolean isRoot() { - return true; - } public void setInProgress(boolean inProgress) { this.inProgress = inProgress; diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java index 310e28496e87..129721c3668d 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java @@ -65,7 +65,7 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView { public TestNGConsoleView(TestNGConfiguration config, final RunnerSettings runnerSettings, final ConfigurationPerRunnerSettings configurationPerRunnerSettings) { - super(new TestNGConsoleProperties(config)); + super(new TestNGConsoleProperties(config), null); myConfiguration = config; myRunnerSettings = runnerSettings; myConfigurationPerRunnerSettings = configurationPerRunnerSettings; From abe0fea650ed706762d80ca9e64465943885df26 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 22 Jul 2010 14:35:57 +0400 Subject: [PATCH 021/102] testframework refactoring: deal with testng output the same way as junit --- .../testframework/CompositePrintable.java | 2 +- .../configuration/TestNGRunnableState.java | 32 +++-- .../testng/model/TestNGRemoteListener.java | 82 ++++++------ .../testng/model/TestProxy.java | 29 +---- .../testng/model/TestTreeBuilder.java | 2 +- .../testng/ui/TestNGConsoleView.java | 123 +++++------------- .../testng/ui/TestNGResults.java | 28 +--- 7 files changed, 106 insertions(+), 192 deletions(-) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java index e8e27118cb44..a8177102ae2e 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java @@ -22,7 +22,7 @@ import java.util.List; public class CompositePrintable implements Printable { public static final String NEW_LINE = "\n"; - private final ArrayList myNestedPrintables = new ArrayList(); + protected final ArrayList myNestedPrintables = new ArrayList(); public void printOn(final Printer printer) { printAllOn(myNestedPrintables, printer); diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java index 93f14f39c44d..9adb1a1e2a33 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java @@ -31,9 +31,7 @@ import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; -import com.intellij.execution.testframework.TestConsoleProperties; -import com.intellij.execution.testframework.TestFrameworkRunningModel; -import com.intellij.execution.testframework.TestSearchScope; +import com.intellij.execution.testframework.*; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.util.JavaParametersUtil; import com.intellij.openapi.application.PathManager; @@ -60,10 +58,7 @@ import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.pom.java.LanguageLevel; import com.intellij.util.PathUtil; import com.intellij.util.net.NetUtils; -import com.theoryinpractice.testng.model.IDEARemoteTestRunnerClient; -import com.theoryinpractice.testng.model.TestData; -import com.theoryinpractice.testng.model.TestNGRemoteListener; -import com.theoryinpractice.testng.model.TestType; +import com.theoryinpractice.testng.model.*; import com.theoryinpractice.testng.ui.TestNGConsoleView; import com.theoryinpractice.testng.ui.TestNGResults; import com.theoryinpractice.testng.ui.actions.RerunFailedTestsAction; @@ -131,7 +126,8 @@ public class TestNGRunnableState extends JavaCommandLineState { } throw e; } - final TestNGConsoleView console = new TestNGConsoleView(config, runnerSettings, myConfigurationPerRunnerSettings); + final TreeRootNode unboundOutputRoot = new TreeRootNode(); + final TestNGConsoleView console = new TestNGConsoleView(config, runnerSettings, myConfigurationPerRunnerSettings, unboundOutputRoot); console.initUI(); for (RunConfigurationExtension ext : Extensions.getExtensions(RunConfigurationExtension.EP_NAME)) { ext.handleStartProcess(config, processHandler); @@ -166,8 +162,9 @@ public class TestNGRunnableState extends JavaCommandLineState { @Override public void startNotified(final ProcessEvent event) { - TestNGRemoteListener listener = new TestNGRemoteListener(console); + TestNGRemoteListener listener = new TestNGRemoteListener(console, unboundOutputRoot); client.startListening(listener, listener, port); + } @Override @@ -180,9 +177,20 @@ public class TestNGRunnableState extends JavaCommandLineState { @Override public void onTextAvailable(final ProcessEvent event, final Key outputType) { - //we override this since we wrap the underlying console, and proxy the attach call, - //so we never get a chance to intercept the text. - console.print(event.getText(), ConsoleViewContentType.getConsoleViewType(outputType)); + final TestProxy currentTest = console.getCurrentTest(); + final String text = event.getText(); + final ConsoleViewContentType consoleViewType = ConsoleViewContentType.getConsoleViewType(outputType); + final Printable printable = new Printable() { + public void printOn(final Printer printer) { + printer.print(text, consoleViewType); + } + }; + if (currentTest != null) { + currentTest.addLast(printable); + } + else { + unboundOutputRoot.addLast(printable); + } } }); console.attachToProcess(processHandler); diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGRemoteListener.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGRemoteListener.java index 5bd7e5f3d89e..eaec7f802dcc 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGRemoteListener.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGRemoteListener.java @@ -27,58 +27,60 @@ import com.theoryinpractice.testng.ui.TestNGResults; import org.testng.remote.strprotocol.*; public class TestNGRemoteListener implements IRemoteSuiteListener, IRemoteTestListener { - private final TestNGConsoleView console; + private final TestNGConsoleView console; + private final TreeRootNode unboundOutputRoot; - public TestNGRemoteListener(TestNGConsoleView console) { - this.console = console; - } + public TestNGRemoteListener(TestNGConsoleView console, TreeRootNode unboundOutputRoot) { + this.console = console; + this.unboundOutputRoot = unboundOutputRoot; + } - public void onInitialization(GenericMessage genericMessage) { - } + public void onInitialization(GenericMessage genericMessage) { + } - public void onStart(SuiteMessage suiteMessage) { - console.flushOutput(); - final TestNGResults view = console.getResultsView(); - if (view != null) { - view.start(); - } + public void onStart(SuiteMessage suiteMessage) { + final TestNGResults view = console.getResultsView(); + if (view != null) { + view.start(); } + } - public void onFinish(SuiteMessage suiteMessage) { - console.flush(); - final TestNGResults view = console.getResultsView(); - if (view != null) { - view.finish(); - } + public void onFinish(SuiteMessage suiteMessage) { + console.finish(); + final TestNGResults view = console.getResultsView(); + if (view != null) { + view.finish(); } + } - public void onStart(TestMessage tm) { - final TestNGResults view = console.getResultsView(); - if (view != null) { - view.setTotal(tm.getTestMethodCount()); - } + public void onStart(TestMessage tm) { + unboundOutputRoot.addChild(console.getResultsView().getRoot()); + final TestNGResults view = console.getResultsView(); + if (view != null) { + view.setTotal(tm.getTestMethodCount()); } + } - public void onTestStart(TestResultMessage trm) { - console.testStarted(trm); - } + public void onTestStart(TestResultMessage trm) { + console.testStarted(trm); + } - public void onFinish(TestMessage tm) { - console.rebuildTree(); - } + public void onFinish(TestMessage tm) { + console.rebuildTree(); + } - public void onTestSuccess(TestResultMessage trm) { - console.addTestResult(trm); - } + public void onTestSuccess(TestResultMessage trm) { + console.addTestResult(trm); + } - public void onTestFailure(TestResultMessage trm) { - console.addTestResult(trm); - } + public void onTestFailure(TestResultMessage trm) { + console.addTestResult(trm); + } - public void onTestSkipped(TestResultMessage trm) { - console.addTestResult(trm); - } + public void onTestSkipped(TestResultMessage trm) { + console.addTestResult(trm); + } - public void onTestFailedButWithinSuccessPercentage(TestResultMessage trm) { - } + public void onTestFailedButWithinSuccessPercentage(TestResultMessage trm) { + } } diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java index 8241c28c409e..b3ab68e164dd 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java @@ -47,7 +47,6 @@ public class TestProxy extends AbstractTestProxy { private TestResultMessage resultMessage; private String name; private TestProxy parent; - private List output; private SmartPsiElementPointer psiElement; private boolean inProgress; private int myExceptionMark; @@ -86,19 +85,6 @@ public class TestProxy extends AbstractTestProxy { return filter.select(results); } - public List getOutput() { - if (output != null) return output; - List total = new ArrayList(); - for (TestProxy child : results) { - final List out = child.getOutput(); - if (total.size() > 0 && out.size() > 0) { - total.add(new TestNGConsoleView.Chunk("\n===============================================\n\n", ConsoleViewContentType.NORMAL_OUTPUT)); - } - total.addAll(out); - } - return total; - } - public List getChildren() { return results; } @@ -170,7 +156,7 @@ public class TestProxy extends AbstractTestProxy { public Navigatable getDescriptor(final Location location) { if (location == null) return null; - if (isNotPassed() && output != null) { + if (isNotPassed()) { final PsiLocation psiLocation = location.toPsiLocation(); final PsiClass containingClass = psiLocation.getParentElement(PsiClass.class); if (containingClass != null) { @@ -181,7 +167,7 @@ public class TestProxy extends AbstractTestProxy { } if (containingMethod != null) { final String qualifiedName = containingClass.getQualifiedName(); - for (Printable aStackTrace : output) { + for (Printable aStackTrace : myNestedPrintables) { if (aStackTrace instanceof TestNGConsoleView.Chunk) { final String[] stackTrace = new LineTokenizer(((TestNGConsoleView.Chunk)aStackTrace).text).execute(); for (String line : stackTrace) { @@ -203,9 +189,10 @@ public class TestProxy extends AbstractTestProxy { return name + ' ' + results; } - public void addResult(TestProxy proxy) { + public void addChild(TestProxy proxy) { results.add(proxy); proxy.setParent(this); + addLast(proxy); } public void setParent(TestProxy parent) { @@ -216,10 +203,6 @@ public class TestProxy extends AbstractTestProxy { return parent; } - public void setOutput(List output) { - this.output = output; - } - public boolean isNotPassed() { if (resultNotPassed()) return true; //we just added the node, so we don't know if it has passes or fails @@ -260,9 +243,9 @@ public class TestProxy extends AbstractTestProxy { return null; } - public int getExceptionMark() { + public int getExceptionMark() {//todo if (myExceptionMark == 0 && getChildCount() > 0) { - return (output != null ? output.size() : 0) + getChildAt(0).getExceptionMark(); + return getChildAt(0).getExceptionMark(); } return myExceptionMark; } diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestTreeBuilder.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestTreeBuilder.java index 531b249228b1..1bf037826de8 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestTreeBuilder.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestTreeBuilder.java @@ -50,7 +50,7 @@ public class TestTreeBuilder extends AbstractTestTreeBuilder } public void addItem(TestProxy parent, TestProxy proxy) { - parent.addResult(proxy); + parent.addChild(proxy); DefaultMutableTreeNode parentNode = getNodeForElement(parent); if (parentNode != null) updateSubtree(parentNode); diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java index 129721c3668d..428cfa97feed 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java @@ -28,6 +28,7 @@ import com.intellij.execution.filters.HyperlinkInfo; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.testframework.Printable; import com.intellij.execution.testframework.Printer; +import com.intellij.execution.testframework.TestTreeView; import com.intellij.execution.testframework.stacktrace.DiffHyperlink; import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView; import com.intellij.execution.testframework.ui.TestResultsPanel; @@ -37,10 +38,13 @@ import com.intellij.openapi.application.ApplicationManager; import com.theoryinpractice.testng.configuration.TestNGConfiguration; import com.theoryinpractice.testng.model.TestNGConsoleProperties; import com.theoryinpractice.testng.model.TestProxy; +import com.theoryinpractice.testng.model.TreeRootNode; import org.jetbrains.annotations.NonNls; import org.testng.remote.strprotocol.TestResultMessage; import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -54,8 +58,7 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView { @NonNls private static final Pattern EXPECTED_NOT_SAME_BUT_WAS_PATTERN = Pattern.compile("(.*)expected not same with:\\<(.*)\\> but was:\\<(.*)\\>.*", Pattern.DOTALL); private TestNGResults testNGResults; - private final List currentTestOutput = new ArrayList(); - private final List nonTestOutput = new ArrayList(); + private TestProxy currentTest; private int myExceptionalMark = -1; private final TestNGConfiguration myConfiguration; @@ -64,8 +67,9 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView { public TestNGConsoleView(TestNGConfiguration config, final RunnerSettings runnerSettings, - final ConfigurationPerRunnerSettings configurationPerRunnerSettings) { - super(new TestNGConsoleProperties(config), null); + final ConfigurationPerRunnerSettings configurationPerRunnerSettings, + final TreeRootNode unboundOutputRoot) { + super(new TestNGConsoleProperties(config), unboundOutputRoot); myConfiguration = config; myRunnerSettings = runnerSettings; myConfigurationPerRunnerSettings = configurationPerRunnerSettings; @@ -76,6 +80,16 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView { return testNGResults; } + @Override + public void initUI() { + super.initUI(); + final TestTreeView testTreeView = testNGResults.getTreeView(); + testTreeView.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + getPrinter().updateOnTestSelected(testTreeView.getSelectedTest()); + } + }); + } @Override public void dispose() { @@ -96,50 +110,30 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView { public void addTestResult(TestResultMessage result) { if (testNGResults != null) { int exceptionMark = myExceptionalMark == -1 ? 0 : myExceptionalMark; + final String stackTrace = result.getStackTrace(); if (stackTrace != null && stackTrace.length() > 10) { //trim useless crud from stacktrace String trimmed = trimStackTrace(stackTrace); List printables = getPrintables(result, trimmed); for (Printable printable : printables) { - printable.printOn(wrapConsoleView(getConsole())); //enable for root element - } - synchronized (currentTestOutput) { - exceptionMark = currentTestOutput.size(); - currentTestOutput.addAll(printables); + currentTest.addLast(printable); } + exceptionMark = printables.size(); } - testNGResults.addTestResult(result, new ArrayList(currentTestOutput), exceptionMark); - + final TestProxy failedToStart = testNGResults.getFailedToStart(); + if (failedToStart != null) { + currentTest.addChild(failedToStart); + exceptionMark += failedToStart.getExceptionMark(); + } + testNGResults.addTestResult(result, exceptionMark); myExceptionalMark = -1; - synchronized (currentTestOutput) { - currentTestOutput.clear(); - } } } public void testStarted(TestResultMessage result) { if (testNGResults != null) { - testNGResults.testStarted(result); - } - } - - public void flushOutput() { - synchronized (currentTestOutput) { - if (!currentTestOutput.isEmpty()) { //non empty for first test only - nonTestOutput.addAll(currentTestOutput); - currentTestOutput.clear(); - } - } - } - - public void flush() { - final TestProxy failedToStart = testNGResults.getFailedToStart(); - if (failedToStart != null) { - final List output = failedToStart.getOutput(); - if (output != null) { - nonTestOutput.addAll(output); - } + currentTest = testNGResults.testStarted(result); } } @@ -204,66 +198,15 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView { return printables; } - public void print(String s, ConsoleViewContentType contentType) { - if (myExceptionalMark == -1 && contentType == ConsoleViewContentType.ERROR_OUTPUT) { - myExceptionalMark = currentTestOutput.size(); - } - Chunk chunk = new Chunk(s, contentType); - synchronized (currentTestOutput) { - currentTestOutput.add(chunk); - } - } - - public void reset() { - final List printables = new ArrayList(); - printables.addAll(nonTestOutput); - printables.addAll(testNGResults.getRoot().getOutput()); - printables.addAll(currentTestOutput); - setView(printables, 0); - } - public void attachToProcess(ProcessHandler processHandler) { - getConsole().attachToProcess(processHandler); - } - - public void setView(final List output, final int i) { - if (!ApplicationManager.getApplication().isDispatchThread()) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - setView(output, i); - } - }); - } - else { - final ConsoleView consoleView = getConsole(); - consoleView.clear(); - int idx = 0; - int offset = 0; - for (Printable chunk : new ArrayList(output)) { - chunk.printOn(wrapConsoleView(consoleView)); - if (idx++ < i) { - offset = consoleView.getContentSize(); - } - } - consoleView.scrollTo(offset); - } } - private static Printer wrapConsoleView(final ConsoleView consoleView) { - return new Printer() { - public void print(String text, ConsoleViewContentType contentType) { - consoleView.print(text, contentType); - } + public TestProxy getCurrentTest() { + return currentTest; + } - public void onNewAvailable(Printable printable) {} - - public void printHyperlink(String text, HyperlinkInfo info) { - consoleView.printHyperlink(text, info); - } - - public void mark() { - } - }; + public void finish() { + currentTest = null; } public static class Chunk implements Printable { diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java index d6c45d8b1649..d137b3739d14 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java @@ -81,7 +81,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn private final TreeRootNode rootNode; private static final String NO_PACKAGE = "No Package"; private TestNGResults.OpenSourceSelectionListener openSourceListener; - private final TestNGConsoleView myConsole; private int myStatus = MessageHelper.PASSED_TEST; private Set startedMethods = new HashSet(); @@ -92,7 +91,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn final ConfigurationPerRunnerSettings configurationSettings) { super(component, console.createConsoleActions(), console.getProperties(), runnerSettings, configurationSettings, TESTNG_SPLITTER_PROPERTY, 0.5f); - myConsole = console; this.project = configuration.getProject(); model = new TestNGResultsTableModel(); @@ -132,7 +130,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn animator = new Animator(this, treeBuilder); - openSourceListener = new OpenSourceSelectionListener(structure, myConsole); + openSourceListener = new OpenSourceSelectionListener(); tree.getSelectionModel().addTreeSelectionListener(openSourceListener); return tree; @@ -218,11 +216,8 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn return proxy; } - public void addTestResult(final TestResultMessage result, List output, int exceptionMark) { - if (failedToStart != null) { - output.addAll(failedToStart.getOutput()); - exceptionMark += failedToStart.getExceptionMark(); - } + public void addTestResult(final TestResultMessage result, int exceptionMark) { + TestProxy testCase; synchronized (started) { @@ -261,7 +256,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn failedToStart = testCase; } - testCase.setOutput(output); testCase.setExceptionMark(exceptionMark); if (result.getResult() == MessageHelper.FAILED_TEST) { @@ -415,8 +409,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn public void dispose() { super.dispose(); - openSourceListener.structure = null; - openSourceListener.console = null; tree.getSelectionModel().removeTreeSelectionListener(openSourceListener); } @@ -425,13 +417,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn } private class OpenSourceSelectionListener implements TreeSelectionListener { - private TestTreeStructure structure; - private TestNGConsoleView console; - - public OpenSourceSelectionListener(TestTreeStructure structure, TestNGConsoleView console) { - this.structure = structure; - this.console = console; - } public void valueChanged(TreeSelectionEvent e) { TreePath path = e.getPath(); @@ -441,13 +426,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn if (ScrollToTestSourceAction.isScrollEnabled(TestNGResults.this)) { OpenSourceUtil.openSourcesFrom(tree, false); } - if (proxy == structure.getRootElement()) { - console.reset(); - } - else { - console - .setView(proxy.getOutput(), TestNGConsoleProperties.SCROLL_TO_STACK_TRACE.value(getProperties()) ? proxy.getExceptionMark() : 0); - } } } } From 44c26ed91f5673d8093ae7585a16c81c844daaf2 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 22 Jul 2010 14:42:09 +0400 Subject: [PATCH 022/102] testframework refactoring: cleanup --- .../testng/ui/TestNGResults.java | 50 ++----------------- 1 file changed, 5 insertions(+), 45 deletions(-) diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java index d137b3739d14..60c312ab097d 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java @@ -33,6 +33,7 @@ import com.intellij.openapi.progress.util.ColorProgressBar; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.util.ClassUtil; import com.intellij.ui.table.TableView; @@ -55,7 +56,6 @@ import java.awt.event.MouseEvent; import java.text.NumberFormat; import java.util.*; import java.util.List; -import java.util.regex.Matcher; import java.util.regex.Pattern; public class TestNGResults extends TestResultsPanel implements TestFrameworkRunningModel { @@ -77,7 +77,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn private TestTreeBuilder treeBuilder; private Animator animator; - private final Pattern packagePattern = Pattern.compile("(.*)\\.(.*)"); private final TreeRootNode rootNode; private static final String NO_PACKAGE = "No Package"; private TestNGResults.OpenSourceSelectionListener openSourceListener; @@ -179,15 +178,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn } public TestProxy testStarted(TestResultMessage result) { - // TODO This should be an action button which rebuilds the tree when toggled. - boolean flattenPackages = true; - TestProxy classNode; - if (flattenPackages) { - classNode = getPackageClassNodeFor(result); - } - else { - classNode = getClassNodeFor(result); - } + TestProxy classNode = getPackageClassNodeFor(result); TestProxy proxy = new TestProxy(); proxy.setParent(classNode); proxy.setResultMessage(result); @@ -217,8 +208,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn } public void addTestResult(final TestResultMessage result, int exceptionMark) { - - TestProxy testCase; synchronized (started) { final List dups = started.get(result); @@ -268,34 +257,15 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn updateStatusLine(); } - private String packageNameFor(String fqnClassName) { - Matcher matcher = packagePattern.matcher(fqnClassName); - if (matcher.matches()) { - return matcher.group(1); - } - else { - return NO_PACKAGE; - } - } - - private String classNameFor(String fqnClassName) { - Matcher matcher = packagePattern.matcher(fqnClassName); - if (matcher.matches()) { - return matcher.group(2); - } - else { - return fqnClassName; - } - } - private TestProxy getPackageClassNodeFor(final TestResultMessage result) { TestProxy owner = treeBuilder.getRoot(); - String packageName = packageNameFor(result.getTestClass()); + final String packageName1 = StringUtil.getPackageName(result.getTestClass()); + String packageName = packageName1.length() == 0 ? NO_PACKAGE : packageName1; owner = getChildNodeNamed(owner, packageName); if (owner.getPsiElement() == null) { owner.setPsiElement(JavaPsiFacade.getInstance(project).findPackage(packageName)); } - owner = getChildNodeNamed(owner, classNameFor(result.getTestClass())); + owner = getChildNodeNamed(owner, StringUtil.getShortName(result.getTestClass())); //look up the psiclass now if (owner.getPsiElement() == null) { final TestProxy finalOwner = owner; @@ -308,16 +278,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn return owner; } - private TestProxy getClassNodeFor(TestResultMessage result) { - - String[] nodes = result.getTestClass().split("\\."); - TestProxy owner = treeBuilder.getRoot(); - for (String node : nodes) { - owner = getChildNodeNamed(owner, node); - } - return owner; - } - private TestProxy getChildNodeNamed(TestProxy currentNode, String node) { for (TestProxy child : currentNode.getChildren()) { if (child.getName().equals(node)) { From 00c3065fd9e4b484c410ac4b790dad1f8ff78857 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 22 Jul 2010 15:09:09 +0400 Subject: [PATCH 023/102] testng: restore scroll to stacktrace --- .../execution/testframework/CompositePrintable.java | 4 ++++ .../src/com/theoryinpractice/testng/model/TestProxy.java | 8 ++++++++ .../com/theoryinpractice/testng/ui/TestNGConsoleView.java | 3 +-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java index a8177102ae2e..e1ccc285041c 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java @@ -36,6 +36,10 @@ public class CompositePrintable implements Printable { myNestedPrintables.clear(); } + public int getCurrentSize() { + return myNestedPrintables.size(); + } + public static void printAllOn(final List printables, final Printer console) { for (final T printable : printables) { printable.printOn(console); diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java index b3ab68e164dd..3a0ea9996921 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java @@ -254,6 +254,14 @@ public class TestProxy extends AbstractTestProxy { myExceptionMark = exceptionMark; } + @Override + public void printOn(Printer printer) { + for (int i = 0; i < myNestedPrintables.size(); i++) { + if (i == myExceptionMark && i > 0) printer.mark(); + myNestedPrintables.get(i).printOn(printer); + } + } + public boolean isInterrupted() { return !isInProgress() && inProgress; } diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java index 428cfa97feed..4d67bccc0add 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGConsoleView.java @@ -113,18 +113,17 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView { final String stackTrace = result.getStackTrace(); if (stackTrace != null && stackTrace.length() > 10) { + exceptionMark = currentTest.getCurrentSize(); //trim useless crud from stacktrace String trimmed = trimStackTrace(stackTrace); List printables = getPrintables(result, trimmed); for (Printable printable : printables) { currentTest.addLast(printable); } - exceptionMark = printables.size(); } final TestProxy failedToStart = testNGResults.getFailedToStart(); if (failedToStart != null) { currentTest.addChild(failedToStart); - exceptionMark += failedToStart.getExceptionMark(); } testNGResults.addTestResult(result, exceptionMark); myExceptionalMark = -1; From c02afc829fe4acc980d94de32cb3c3ac4eb54256 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 22 Jul 2010 16:03:53 +0400 Subject: [PATCH 024/102] testng: append configuration nodes; correct icons --- .../com/theoryinpractice/testng/ui/ResultTreeRenderer.java | 7 +++++++ .../src/com/theoryinpractice/testng/ui/TestNGResults.java | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java b/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java index 9ba78be31a4b..ecfb304133f7 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java @@ -103,6 +103,13 @@ public class ResultTreeRenderer extends ColoredTreeCellRenderer return PoolOfTestIcons.TERMINATED_ICON; } } else { + if (node.getChildCount() == 0) { + final TestProxy nodeParent = node.getParent(); + if (nodeParent.getResultMessage().getResult() == MessageHelper.PASSED_TEST && nodeParent.isTearDownFailure()) { + return PoolOfTestIcons.FAILED_ICON; + } + return PoolOfTestIcons.NOT_RAN; + } boolean hasFail = false; boolean hasSkipped = false; boolean hasTerminated = false; diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java index 60c312ab097d..ddde6b7f8af0 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java @@ -241,7 +241,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn } else { //do not remember testresultmessage: test hierarchy is not set - testCase = new TestProxy(); + testCase = new TestProxy(result.toDisplayString()); failedToStart = testCase; } From 67154f8c2dbac16d876e56b35c93d9ccf20a144c Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 22 Jul 2010 16:14:41 +0400 Subject: [PATCH 025/102] testng: setup printer --- .../testng/src/com/theoryinpractice/testng/model/TestProxy.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java index 3a0ea9996921..7324f5c8f146 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java @@ -192,6 +192,7 @@ public class TestProxy extends AbstractTestProxy { public void addChild(TestProxy proxy) { results.add(proxy); proxy.setParent(this); + proxy.setPrinter(myPrinter); addLast(proxy); } From 1a9183d531d27729c13c929f84acbb07a87cd215 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 22 Jul 2010 16:18:54 +0400 Subject: [PATCH 026/102] testng: navigation simplified --- .../testng/model/TestProxy.java | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java index 7324f5c8f146..ca98bbbcc88b 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java +++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java @@ -154,33 +154,9 @@ public class TestProxy extends AbstractTestProxy { return new PsiLocation(project, element); } + @Nullable public Navigatable getDescriptor(final Location location) { if (location == null) return null; - if (isNotPassed()) { - final PsiLocation psiLocation = location.toPsiLocation(); - final PsiClass containingClass = psiLocation.getParentElement(PsiClass.class); - if (containingClass != null) { - String containingMethod = null; - for (Iterator> iterator = psiLocation.getAncestors(PsiMethod.class, false); iterator.hasNext();) { - final PsiMethod psiMethod = iterator.next().getPsiElement(); - if (containingClass.equals(psiMethod.getContainingClass())) containingMethod = psiMethod.getName(); - } - if (containingMethod != null) { - final String qualifiedName = containingClass.getQualifiedName(); - for (Printable aStackTrace : myNestedPrintables) { - if (aStackTrace instanceof TestNGConsoleView.Chunk) { - final String[] stackTrace = new LineTokenizer(((TestNGConsoleView.Chunk)aStackTrace).text).execute(); - for (String line : stackTrace) { - final StackTraceLine stackLine = new StackTraceLine(containingClass.getProject(), line); - if (containingMethod.equals(stackLine.getMethodName()) && Comparing.strEqual(qualifiedName, stackLine.getClassName())) { - return stackLine.getOpenFileDescriptor(containingClass.getContainingFile().getVirtualFile()); - } - } - } - } - } - } - } return EditSourceUtil.getDescriptor(location.getPsiElement()); } From 8ae3f80c2f5d5c469a667c67316015fdbe0e0aa1 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 22 Jul 2010 18:14:14 +0400 Subject: [PATCH 027/102] ctrl-Q: simplify throws section (IDEA-56681;IDEA-28233) --- .../javadoc/JavaDocInfoGenerator.java | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index b50a34e6d9c6..996023b3bbc9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -46,9 +46,7 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -1290,32 +1288,26 @@ public class JavaDocInfoGenerator { LinkedList>> collectedTags = new LinkedList>>(); - LinkedList holder = new LinkedList(Arrays.asList(method.getThrowsList().getReferencedTypes())); + final List declaredThrows = new ArrayList(Arrays.asList(method.getThrowsList().getReferencedTypes())); for (int i = localTags.length - 1; i > -1; i--) { PsiDocTagValue valueElement = localTags[i].getValueElement(); if (valueElement != null) { - boolean contains = false; - for (PsiClassType classType : holder) { + for (Iterator iterator = declaredThrows.iterator(); iterator.hasNext();) { + PsiClassType classType = iterator.next(); if (Comparing.strEqual(valueElement.getText(), classType.getClassName())) { - contains = true; + iterator.remove(); break; } } - if (contains) continue; - try { - PsiClassType t = (PsiClassType)JavaPsiFacade.getInstance(method.getProject()).getElementFactory() - .createTypeFromText(valueElement.getText(), method); - if (!holder.contains(t)) { - holder.addFirst(t); - } - } catch(IncorrectOperationException e) {} // nonvalid type + collectedTags.addFirst(new Pair>(localTags[i], ourEmptyProvider)); } } - PsiClassType[] trousers = holder.toArray(new PsiClassType[holder.size()]); + + PsiClassType[] trousers = declaredThrows.toArray(new PsiClassType[declaredThrows.size()]); for (PsiClassType trouser : trousers) { if (trouser != null) { From b4a34f8d765fe111797cd1b52341cde832e2afc2 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 23 Jul 2010 13:00:10 +0400 Subject: [PATCH 028/102] Maia replaced with IdeaX --- build/scripts/dist.gant | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant index aabf6e5e8876..07e8849d3af9 100644 --- a/build/scripts/dist.gant +++ b/build/scripts/dist.gant @@ -67,8 +67,8 @@ def wire_build_date(String buildNumber) { target('default': 'The default target') { depends(compile) layoutAll( - buildNumber: "IC-90.SNAPSHOT", - version: "Maia", + buildNumber: "IC-X.SNAPSHOT", + version: "IdeaX", system_selector: "IntelliJIdeaCE10", jdk_req: "1.6*", vmoptions: "-Xms128m -Xmx512m -XX:MaxPermSize=250m -ea", From b59acf07388f9780b1505842b07893651bba773a Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Thu, 22 Jul 2010 19:38:25 +0400 Subject: [PATCH 029/102] IDEA-56691: NPE at com.intellij.psi.util.PsiUtilBase.getElementAtCaret --- .../src/com/intellij/lang/refactoring/InlineActionHandler.java | 3 ++- platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/lang-api/src/com/intellij/lang/refactoring/InlineActionHandler.java b/platform/lang-api/src/com/intellij/lang/refactoring/InlineActionHandler.java index bc9ddaf7a954..5cd8c6a6acbf 100644 --- a/platform/lang-api/src/com/intellij/lang/refactoring/InlineActionHandler.java +++ b/platform/lang-api/src/com/intellij/lang/refactoring/InlineActionHandler.java @@ -21,6 +21,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; /** * @author yole @@ -38,7 +39,7 @@ public abstract class InlineActionHandler { return canInlineElement(element); } - public boolean isEnabledOnElement(PsiElement element, Editor editor) { + public boolean isEnabledOnElement(PsiElement element, @Nullable Editor editor) { return isEnabledOnElement(element); } diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java index 02577d3b0d7b..7f7f02cf0c52 100644 --- a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java +++ b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java @@ -432,7 +432,7 @@ public class PsiUtilBase { } @Nullable - public static PsiElement getElementAtCaret(Editor editor) { + public static PsiElement getElementAtCaret(@NotNull Editor editor) { Project project = editor.getProject(); if (project == null) return null; PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); From bf256e43580fe79a2e96d97f35e0489aa074a334 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Fri, 23 Jul 2010 13:38:56 +0400 Subject: [PATCH 030/102] Do not dump formatter. Sorry --- .../intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java index 46906487120e..8349d2e3792d 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java @@ -120,7 +120,7 @@ public class CodeFormatterFacade { PsiDocumentManager.getInstance(project).getDocument(file), project, mySettings, fileType, file); - printToConsole(rootBlock, model); + //printToConsole(rootBlock, model); FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptions(fileType), ranges); } From 0fea708d580d54509e759a8fc71a97884a8cffbd Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 23 Jul 2010 13:38:05 +0400 Subject: [PATCH 031/102] EA-21249 - more logging added --- .../src/com/intellij/openapi/vfs/impl/jar/JarHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java index 98bf517b35b4..04fa533e8ecf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java @@ -266,9 +266,11 @@ public class JarHandler implements FileSystemInterface { } final ZipFile zip = getZip(); - assert zip != null; + assert zip != null : file; final InputStream stream = zip.getInputStream(entry); + assert stream != null : file; + try { return FileUtil.loadBytes(stream, (int)entry.getSize()); } From 3f399561c211ece4648dc5d58c9dbefcf9f73fa5 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 13:52:56 +0400 Subject: [PATCH 032/102] good code is red: upper bound should move up if next parameter requires (IDEA-56696) --- .../source/resolve/PsiResolveHelperImpl.java | 2 +- .../InferenceWithUpperBoundPromotion.java | 30 +++++++++++++++++++ .../daemon/GenericsHighlightingTest.java | 1 + 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/InferenceWithUpperBoundPromotion.java diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index a674ea013098..173ac1533da0 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -175,7 +175,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } break; case SUBTYPE: - if (PsiType.NULL.equals(upperBound)) { + if (PsiType.NULL.equals(upperBound) || TypeConversionUtil.isAssignable(upperBound, type)) { upperBound = type; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/InferenceWithUpperBoundPromotion.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/InferenceWithUpperBoundPromotion.java new file mode 100644 index 000000000000..82a2a68570ad --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/InferenceWithUpperBoundPromotion.java @@ -0,0 +1,30 @@ + +public class NestedGenericGoodCodeIsRed { + + public void main( String[] args ) { + satisfiesAllOf(isPositive(), isEqualTo(10.9)); + satisfiesAllOf(isPositive(), isEqualTo(10)); + + Number num = null; + satisfiesAllOf(isPositive(), isEqualTo(num)); + + this.satisfiesAllOf(isPositive(), isEqualTo(10)); + } + + + public interface Predicate { + + } + + public void satisfiesAllOf( Predicate first, Predicate second ) { + } + + public Predicate isPositive() { + return null; + } + + public Predicate isEqualTo( EQUALTO target ) { + return null; + } + +} \ 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 a68ee6bf6d3f..286dd2015d09 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -50,6 +50,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testExplicitMethodParameters1() throws Exception { doTest(false); } public void testInferenceWithBounds() throws Exception {doTest(false);} public void testInferenceWithSuperBounds() throws Exception {doTest(false);} + public void testInferenceWithUpperBoundPromotion() throws Exception {doTest(false);} public void testVariance() throws Exception {doTest(false);} public void testForeachTypes() throws Exception {doTest(false);} public void testRawOverridingMethods() throws Exception {doTest(false);} From 84891eec845842915786cbce7356a0e9aaf80733 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Fri, 23 Jul 2010 13:22:48 +0400 Subject: [PATCH 033/102] AS extract super dialog: radiobutton for 'extract super and turn refs' mode --- .../refactoring/extractSuperclass/ExtractSuperBaseDialog.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java b/platform/lang-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java index aca732f738ac..3344a574e4a8 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java @@ -128,6 +128,7 @@ public abstract class ExtractSuperBaseDialog Date: Thu, 22 Jul 2010 18:32:48 +0100 Subject: [PATCH 034/102] map literals with 'super' key may be assigned to the classes with a non-default constructor --- .../jetbrains/plugins/groovy/gpp/GppTypeConverter.java | 5 +++++ .../plugins/groovy/lang/psi/impl/GrMapType.java | 6 ++++++ .../impl/statements/arguments/GrArgumentLabelImpl.java | 2 +- .../plugins/groovy/lang/GppFunctionalTest.groovy | 10 ++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java index 64ba6c939cad..b03125b76fd1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppTypeConverter.java @@ -66,6 +66,11 @@ public class GppTypeConverter extends GrTypeConverter { (!TypesUtil.isAssignable(lKeyType, parameters[0], context) || !TypesUtil.isAssignable(lValueType, parameters[1], context))) { return null; } + + if (((GrMapType)rType).getValueType("super") != null) { + return true; + } + if (hasDefaultConstructor(lType)) { return true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java index 2a45e985ae61..3fbe912f1cc7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java @@ -26,6 +26,7 @@ import com.intellij.psi.PsiType; import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -149,6 +150,11 @@ public class GrMapType extends GrLiteralClassType { return super.equals(obj); } + @Nullable + public PsiType getValueType(@NotNull String key) { + return myStringEntries.get(key); + } + public boolean isAssignableFrom(@NotNull PsiType type) { return type instanceof GrMapType || myFacade.getElementFactory().createTypeFromText(getJavaClassName(), null).isAssignableFrom(type); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java index fbce8d317fcd..7109cb41489b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/arguments/GrArgumentLabelImpl.java @@ -103,7 +103,7 @@ public class GrArgumentLabelImpl extends GroovyPsiElementImpl implements GrArgum } final IElementType elemType = element.getNode().getElementType(); - if (GroovyTokenTypes.mIDENT == elemType) { + if (GroovyTokenTypes.mIDENT == elemType || GroovyTokenTypes.KEYWORDS.contains(elemType)) { return element.getText(); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy index 345efb7e3450..f5d5fb58dfd0 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy @@ -375,6 +375,16 @@ s.doSmth() assertEquals "doSmth", ((PsiMethod) findReference().resolve()).name } + public void testBaseConstructorCallInMapLiteras() throws Exception { + configureScript """ +@Typed File foo() { ['super':['a']] } +@Typed File goo() { [:] } +File bar() { [:] } +""" + myFixture.enableInspections new GroovyAssignabilityCheckInspection() + myFixture.checkHighlighting(true, false, false) + } + } class GppProjectDescriptor extends DefaultLightProjectDescriptor { From cba2326c413fca505831bb334af2e8effcca8b74 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 22 Jul 2010 18:39:45 +0100 Subject: [PATCH 035/102] a (failing) test for dependent classes recompilation --- .../groovy/compiler/GppCompilerTest.groovy | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy index 3de2fac8e4ab..94ccc740d1da 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.compiler; +import com.intellij.openapi.vfs.VfsUtil import com.intellij.testFramework.PsiTestUtil import org.jetbrains.plugins.groovy.util.TestUtils @@ -58,4 +59,60 @@ class Foo implements SomeTrait { assertEmpty(make()); } + public void _testRecompileDependentGroovyClasses() throws Exception { + def a = myFixture.addFileToProject("A.gpp", """ +class A { + void foo() { + print "239" + } +} +""") + myFixture.addFileToProject("b.gpp", """ +new A().foo() +""") + assertEmpty make() + assertOutput "b", "239" + + VfsUtil.saveText a.virtualFile, """ +class A { + def foo() { + print "239" + } +} +""" + + assertEmpty make() + assertOutput "b", "239" + } + + public void _testRecompileDependentJavaClasses() throws Exception { + def a = myFixture.addFileToProject("A.gpp", """ +class A { + void foo() { + print "239" + } +} +""") + myFixture.addFileToProject("B.gpp", """ +public class B { + public static void main() { + new A().foo(); + } +} +""") + assertEmpty make() + assertOutput "b", "239" + + VfsUtil.saveText a.virtualFile, """ +class A { + def foo() { + print "239" + } +} +""" + + assertEmpty make() + assertOutput "b", "239" + } + } From 37aed39ca120fa00cab7f0aa5d694166bd741be1 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 22 Jul 2010 21:59:35 +0100 Subject: [PATCH 036/102] USER_HOME path macro done right save paths outside project & module roots as absolute --- .../impl/ModulePathMacroManager.java | 52 ++++-------------- .../options/PathMacrosCollector.java | 6 +-- .../application/options/PathMacrosImpl.java | 2 +- .../options/ReplacePathToMacroMap.java | 20 +++++-- .../impl/ApplicationPathMacroManager.java | 3 -- .../components/impl/BasePathMacroManager.java | 54 ++++++++++++++----- .../impl/ProjectPathMacroManager.java | 45 ++-------------- 7 files changed, 73 insertions(+), 109 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/ModulePathMacroManager.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/ModulePathMacroManager.java index aac6a5b317eb..a5ed8206ea55 100644 --- a/platform/lang-impl/src/com/intellij/openapi/components/impl/ModulePathMacroManager.java +++ b/platform/lang-impl/src/com/intellij/openapi/components/impl/ModulePathMacroManager.java @@ -20,24 +20,18 @@ import com.intellij.application.options.PathMacrosImpl; import com.intellij.application.options.ReplacePathToMacroMap; import com.intellij.openapi.components.ExpandMacroToPathMap; import com.intellij.openapi.components.PathMacroMap; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import java.io.File; -public class ModulePathMacroManager extends BasePathMacroManager /*ProjectPathMacroManager*/ { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.ModulePathMacroManager"); - +public class ModulePathMacroManager extends BasePathMacroManager { private final Module myModule; - public ModulePathMacroManager(final Module module) { - //super((ProjectEx) module.getProject()); myModule = module; } @@ -49,9 +43,14 @@ public class ModulePathMacroManager extends BasePathMacroManager /*ProjectPathMa } public ReplacePathToMacroMap getReplacePathMap() { - ReplacePathToMacroMap result = new ReplacePathToMacroMap(); - result.putAll(super.getReplacePathMap()); - getModuleHomeReplacements(result, true); + ReplacePathToMacroMap result = super.getReplacePathMap(); + if (!myModule.isDisposed()) { + String projectDir = ProjectPathMacroManager.getProjectDir(myModule.getProject()); + if (projectDir != null) { + projectDir = projectDir.replace('/', File.separatorChar); + } + addFileHierarchyReplacements(result, PathMacrosImpl.MODULE_DIR_MACRO_NAME, getModuleDir(myModule.getModuleFilePath()), projectDir); + } return result; } @@ -76,39 +75,6 @@ public class ModulePathMacroManager extends BasePathMacroManager /*ProjectPathMa result.put(s, path); } - private void getModuleHomeReplacements(@NonNls ReplacePathToMacroMap result, final boolean addRelativePathMacros) { - String moduleDir = myModule.isDisposed() ? null : getModuleDir(myModule.getModuleFilePath()); - if (moduleDir == null) return; - - File f = new File(moduleDir.replace('/', File.separatorChar)); - // [dsl]: Q? - //if(!f.exists()) return; - - String macro = "$" + PathMacrosImpl.MODULE_DIR_MACRO_NAME + "$"; - boolean check = false; - while (f != null && f.getParentFile() != null) { - @NonNls String path = PathMacroMap.quotePath(f.getAbsolutePath()); - String s = macro; - - if (StringUtil.endsWithChar(path, '/')) s += "/"; - - putIfAbsent(result, "file://" + path, "file://" + s, check); - putIfAbsent(result, "file:/" + path, "file:/" + s, check); - putIfAbsent(result, "file:" + path, "file:" + s, check); - putIfAbsent(result, "jar://" + path, "jar://" + s, check); - putIfAbsent(result, "jar:/" + path, "jar:/" + s, check); - putIfAbsent(result, "jar:" + path, "jar:" + s, check); - if (!path.equalsIgnoreCase("e:/") && !path.equalsIgnoreCase("r:/") && !path.equalsIgnoreCase("p:/")) { - putIfAbsent(result, path, s, check); - } - - if (!addRelativePathMacros) break; - macro += "/.."; - check = true; - f = f.getParentFile(); - } - } - @Nullable private String getModuleDir(String moduleFilePath) { File moduleDirFile = new File(moduleFilePath).getParentFile(); diff --git a/platform/platform-impl/src/com/intellij/application/options/PathMacrosCollector.java b/platform/platform-impl/src/com/intellij/application/options/PathMacrosCollector.java index 496980b815e1..1109e141eb27 100644 --- a/platform/platform-impl/src/com/intellij/application/options/PathMacrosCollector.java +++ b/platform/platform-impl/src/com/intellij/application/options/PathMacrosCollector.java @@ -39,7 +39,7 @@ public class PathMacrosCollector extends PathMacroMap { private static final Set ourSystemMacroNames = new HashSet( Arrays.asList(PathMacrosImpl.APPLICATION_HOME_MACRO_NAME, PathMacrosImpl.MODULE_DIR_MACRO_NAME, PathMacrosImpl.PROJECT_DIR_MACRO_NAME - //, PathMacrosImpl.USER_HOME_MACRO_NAME + , PathMacrosImpl.USER_HOME_MACRO_NAME )); private static final String FILE_PROTOCOL = "file:"; private static final String JAR_PROTOCOL = "jar:"; @@ -48,10 +48,6 @@ public class PathMacrosCollector extends PathMacroMap { myMatcher = MACRO_PATTERN.matcher(""); } - public static Set getMacroNames(Element root, @Nullable final NotNullFunction filter) { - return getMacroNames(root, filter, null); - } - public static Set getMacroNames(Element root, @Nullable final NotNullFunction filter, @Nullable final NotNullFunction recursiveFilter, @NotNull final PathMacros pathMacros) { final PathMacrosCollector collector = new PathMacrosCollector(); collector.substitute(root, true, false, filter, recursiveFilter); diff --git a/platform/platform-impl/src/com/intellij/application/options/PathMacrosImpl.java b/platform/platform-impl/src/com/intellij/application/options/PathMacrosImpl.java index eafe6816dcef..ea609218c127 100644 --- a/platform/platform-impl/src/com/intellij/application/options/PathMacrosImpl.java +++ b/platform/platform-impl/src/com/intellij/application/options/PathMacrosImpl.java @@ -70,7 +70,7 @@ public class PathMacrosImpl extends PathMacros implements ApplicationComponent, ourSystemMacroNames.add(APPLICATION_HOME_MACRO_NAME); ourSystemMacroNames.add(PROJECT_DIR_MACRO_NAME); ourSystemMacroNames.add(MODULE_DIR_MACRO_NAME); - //ourSystemMacroNames.add(USER_HOME_MACRO_NAME); + ourSystemMacroNames.add(USER_HOME_MACRO_NAME); } private static final Set ourToolsMacros = new HashSet(); diff --git a/platform/platform-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java b/platform/platform-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java index 9f28cf2f0209..1fcfcbef0aa7 100644 --- a/platform/platform-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java +++ b/platform/platform-impl/src/com/intellij/application/options/ReplacePathToMacroMap.java @@ -37,16 +37,28 @@ public class ReplacePathToMacroMap extends PathMacroMap { if (idx1 != idx2) return idx1 - idx2; - return o2.getKey().length() - o1.getKey().length(); + return stripPrefix(o2.getKey()).length() - stripPrefix(o1.getKey()).length(); } private int getIndex(final Map.Entry s) { - if (s.getValue().indexOf("..") >= 0) return 3; + final String replacement = s.getValue(); + if (replacement.indexOf("..") >= 0) return 3; + if (replacement.indexOf("$" + PathMacrosImpl.USER_HOME_MACRO_NAME + "$") >= 0) return 3; - if (s.getValue().indexOf("$MODULE_DIR$") >= 0) return 1; - if (s.getValue().indexOf("$PROJECT_DIR$") >= 0) return 1; + if (replacement.indexOf("$" + PathMacrosImpl.MODULE_DIR_MACRO_NAME + "$") >= 0) return 1; + if (replacement.indexOf("$" + PathMacrosImpl.PROJECT_DIR_MACRO_NAME + "$") >= 0) return 1; return 2; } + + private String stripPrefix(String key) { + key = StringUtil.trimStart(key, "jar:"); + key = StringUtil.trimStart(key, "file:"); + while (key.startsWith("/")) { + key = key.substring(1); + } + return key; + } + }; @NonNls private static final String[] PROTOCOLS = new String[]{"file", "jar"}; diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/ApplicationPathMacroManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/ApplicationPathMacroManager.java index 5c0a9850e3d8..134708f38230 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/ApplicationPathMacroManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/ApplicationPathMacroManager.java @@ -19,7 +19,4 @@ package com.intellij.openapi.components.impl; * @author mike */ public class ApplicationPathMacroManager extends BasePathMacroManager { - public ApplicationPathMacroManager() { - super(true); - } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java index cf68311297e6..b06b42197040 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java @@ -20,33 +20,63 @@ import com.intellij.application.options.ReplacePathToMacroMap; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.ExpandMacroToPathMap; import com.intellij.openapi.components.PathMacroManager; +import com.intellij.openapi.components.PathMacroMap; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.SystemProperties; import com.intellij.util.containers.FactoryMap; import org.jdom.Element; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; +import java.io.File; import java.util.*; public class BasePathMacroManager extends PathMacroManager { private PathMacrosImpl myPathMacros; - private boolean myUseUserMacroses; + protected static void addFileHierarchyReplacements(ReplacePathToMacroMap result, + String variableName, + @Nullable String _path, @Nullable String stopAt) { + if (_path == null) { + return; + } - public BasePathMacroManager(boolean useUserMacroses) { - myUseUserMacroses = useUserMacroses; - } + String macro = "$" + variableName + "$"; + File dir = new File(_path.replace('/', File.separatorChar)); + boolean check = false; + while (dir != null && dir.getParentFile() != null) { + @NonNls String path = PathMacroMap.quotePath(dir.getAbsolutePath()); + String s = macro; - public BasePathMacroManager() { - this(true); + if (StringUtil.endsWithChar(path, '/')) s += "/"; + + putIfAbsent(result, "file:" + path, "file:" + s, check); + putIfAbsent(result, "file:/" + path, "file:/" + s, check); + putIfAbsent(result, "file://" + path, "file://" + s, check); + putIfAbsent(result, "jar:" + path, "jar:" + s, check); + putIfAbsent(result, "jar:/" + path, "jar:/" + s, check); + putIfAbsent(result, "jar://" + path, "jar://" + s, check); + if (!path.equalsIgnoreCase("e:/") && !path.equalsIgnoreCase("r:/") && !path.equalsIgnoreCase("p:/")) { + putIfAbsent(result, path, s, check); + } + + if (dir.getPath().equals(stopAt)) { + break; + } + + macro += "/.."; + check = true; + dir = dir.getParentFile(); + } } public ExpandMacroToPathMap getExpandMacroMap() { ExpandMacroToPathMap result = new ExpandMacroToPathMap(); result.addMacroExpand(PathMacrosImpl.APPLICATION_HOME_MACRO_NAME, PathManager.getHomePath()); - if (myUseUserMacroses) { - getPathMacros().addMacroExpands(result); - } + result.addMacroExpand(PathMacrosImpl.USER_HOME_MACRO_NAME, SystemProperties.getUserHome()); + getPathMacros().addMacroExpands(result); return result; } @@ -55,10 +85,8 @@ public class BasePathMacroManager extends PathMacroManager { ReplacePathToMacroMap result = new ReplacePathToMacroMap(); result.addMacroReplacement(PathManager.getHomePath(), PathMacrosImpl.APPLICATION_HOME_MACRO_NAME); - if (myUseUserMacroses) { - getPathMacros().addMacroReplacements(result); - } - + result.addMacroReplacement(SystemProperties.getUserHome(), PathMacrosImpl.USER_HOME_MACRO_NAME); + getPathMacros().addMacroReplacements(result); return result; } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/ProjectPathMacroManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/ProjectPathMacroManager.java index 93fbcfa82204..1c9f79824353 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/ProjectPathMacroManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/ProjectPathMacroManager.java @@ -19,10 +19,10 @@ import com.intellij.application.options.PathMacrosImpl; import com.intellij.application.options.ReplacePathToMacroMap; import com.intellij.openapi.components.ExpandMacroToPathMap; import com.intellij.openapi.components.PathMacroMap; +import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectEx; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -30,7 +30,6 @@ import java.io.File; public class ProjectPathMacroManager extends BasePathMacroManager { private final ProjectEx myProject; - public ProjectPathMacroManager(final ProjectEx project) { myProject = project; } @@ -42,47 +41,13 @@ public class ProjectPathMacroManager extends BasePathMacroManager { } public ReplacePathToMacroMap getReplacePathMap() { - ReplacePathToMacroMap result = new ReplacePathToMacroMap(); - result.putAll(super.getReplacePathMap()); - getProjectHomeReplacements(result, true); + ReplacePathToMacroMap result = super.getReplacePathMap(); + addFileHierarchyReplacements(result, PathMacrosImpl.PROJECT_DIR_MACRO_NAME, getProjectDir(myProject), null); return result; } - private void getProjectHomeReplacements(@NonNls ReplacePathToMacroMap result, final boolean savePathsRelative) { - String projectDir = getProjectDir(); - if (projectDir == null) return; - - File f = new File(projectDir.replace('/', File.separatorChar)); - //LOG.assertTrue(f.exists()); - - String macro = "$" + PathMacrosImpl.PROJECT_DIR_MACRO_NAME + "$"; - boolean check = false; - while (f != null && f.getParentFile() != null) { - String path = PathMacroMap.quotePath(f.getAbsolutePath()); - String s = macro; - - if (StringUtil.endsWithChar(path, '/')) s += "/"; - - putIfAbsent(result, "file://" + path, "file://" + s, check); - putIfAbsent(result, "file:/" + path, "file:/" + s, check); - putIfAbsent(result, "file:" + path, "file:" + s, check); - putIfAbsent(result, "jar://" + path, "jar://" + s, check); - putIfAbsent(result, "jar:/" + path, "jar:/" + s, check); - putIfAbsent(result, "jar:" + path, "jar:" + s, check); - //noinspection HardCodedStringLiteral - if (!path.equalsIgnoreCase("e:/") && !path.equalsIgnoreCase("r:/") && !path.equalsIgnoreCase("p:/")) { - putIfAbsent(result, path, s, check); - } - - if (!savePathsRelative) break; - check = true; - macro += "/.."; - f = f.getParentFile(); - } - } - private void getExpandProjectHomeReplacements(ExpandMacroToPathMap result) { - String projectDir = getProjectDir(); + String projectDir = getProjectDir(myProject); if (projectDir == null) return; File f = new File(projectDir.replace('/', File.separatorChar)); @@ -103,7 +68,7 @@ public class ProjectPathMacroManager extends BasePathMacroManager { } @Nullable - private String getProjectDir() { + public static String getProjectDir(Project myProject) { final VirtualFile baseDir = myProject.getBaseDir(); return baseDir != null ? baseDir.getPath() : null; } From 6e66abc1741d9849a65d0f6d0ec7cfe05970ee11 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 23 Jul 2010 09:28:36 +0100 Subject: [PATCH 037/102] mark USER_HOME_GRAILS/GRIFFON as legacy: read but don't write --- .../openapi/application/PathMacros.java | 9 +++++ .../options/PathMacrosCollector.java | 8 +--- .../application/options/PathMacrosImpl.java | 40 +++++++++++++++++-- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/application/PathMacros.java b/platform/platform-api/src/com/intellij/openapi/application/PathMacros.java index 30977acf0523..23bdf55938a6 100644 --- a/platform/platform-api/src/com/intellij/openapi/application/PathMacros.java +++ b/platform/platform-api/src/com/intellij/openapi/application/PathMacros.java @@ -32,6 +32,13 @@ public abstract class PathMacros { public abstract void setMacro(String name, String value); + /** + * Obsolete macros that are to be removed gently from the project files. They can be read, but not written again. Not persisted. + * @param name + * @param value + */ + public abstract void addLegacyMacro(@NotNull String name, @NotNull String value); + public abstract void removeMacro(String name); public abstract Set getUserMacroNames(); @@ -47,4 +54,6 @@ public abstract class PathMacros { public abstract boolean isIgnoredMacroName(@NotNull final String macro); public abstract void removeAllMacros(); + + public abstract Collection getLegacyMacroNames(); } diff --git a/platform/platform-impl/src/com/intellij/application/options/PathMacrosCollector.java b/platform/platform-impl/src/com/intellij/application/options/PathMacrosCollector.java index 1109e141eb27..79f980fb684b 100644 --- a/platform/platform-impl/src/com/intellij/application/options/PathMacrosCollector.java +++ b/platform/platform-impl/src/com/intellij/application/options/PathMacrosCollector.java @@ -22,7 +22,6 @@ import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; @@ -37,10 +36,6 @@ public class PathMacrosCollector extends PathMacroMap { private final Matcher myMatcher; - private static final Set ourSystemMacroNames = new HashSet( - Arrays.asList(PathMacrosImpl.APPLICATION_HOME_MACRO_NAME, PathMacrosImpl.MODULE_DIR_MACRO_NAME, PathMacrosImpl.PROJECT_DIR_MACRO_NAME - , PathMacrosImpl.USER_HOME_MACRO_NAME - )); private static final String FILE_PROTOCOL = "file:"; private static final String JAR_PROTOCOL = "jar:"; @@ -52,7 +47,8 @@ public class PathMacrosCollector extends PathMacroMap { final PathMacrosCollector collector = new PathMacrosCollector(); collector.substitute(root, true, false, filter, recursiveFilter); final HashSet result = new HashSet(collector.myMacroMap.keySet()); - result.removeAll(ourSystemMacroNames); + result.removeAll(pathMacros.getSystemMacroNames()); + result.removeAll(pathMacros.getLegacyMacroNames()); result.removeAll(PathMacrosImpl.getToolMacroNames()); result.removeAll(pathMacros.getIgnoredMacroNames()); return result; diff --git a/platform/platform-impl/src/com/intellij/application/options/PathMacrosImpl.java b/platform/platform-impl/src/com/intellij/application/options/PathMacrosImpl.java index ea609218c127..ce82d3c66632 100644 --- a/platform/platform-impl/src/com/intellij/application/options/PathMacrosImpl.java +++ b/platform/platform-impl/src/com/intellij/application/options/PathMacrosImpl.java @@ -39,6 +39,7 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public class PathMacrosImpl extends PathMacros implements ApplicationComponent, NamedJDOMExternalizable, RoamingTypeDisabled { private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.PathMacrosImpl"); + private final Map myLegacyMacros = new HashMap(); private final Map myMacros = new HashMap(); private final JBReentrantReadWriteLock myLock = LockFactory.createReadWriteLock(); private final List myIgnoredMacros = new CopyOnWriteArrayList(); @@ -213,6 +214,17 @@ public class PathMacrosImpl extends PathMacros implements ApplicationComponent, } } + @Override + public Collection getLegacyMacroNames() { + try { + myLock.readLock().lock(); + return myLegacyMacros.keySet(); + } + finally { + myLock.readLock().unlock(); + } + } + public void setMacro(@NotNull String name, @NotNull String value) { if (value.trim().length() == 0) return; try { @@ -224,6 +236,18 @@ public class PathMacrosImpl extends PathMacros implements ApplicationComponent, } } + @Override + public void addLegacyMacro(@NotNull String name, @NotNull String value) { + try { + myLock.writeLock().lock(); + myLegacyMacros.put(name, value); + myMacros.remove(name); + } + finally { + myLock.writeLock().unlock(); + } + } + public void removeMacro(String name) { try { myLock.writeLock().lock(); @@ -278,8 +302,7 @@ public class PathMacrosImpl extends PathMacros implements ApplicationComponent, } public void addMacroReplacements(ReplacePathToMacroMap result) { - final Set macroNames = getUserMacroNames(); - for (final String name : macroNames) { + for (final String name : getUserMacroNames()) { final String value = getValue(name); if (value != null && value.trim().length() > 0) result.addMacroReplacement(value, name); } @@ -287,11 +310,20 @@ public class PathMacrosImpl extends PathMacros implements ApplicationComponent, public void addMacroExpands(ExpandMacroToPathMap result) { - final Set macroNames = getUserMacroNames(); - for (final String name : macroNames) { + for (final String name : getUserMacroNames()) { final String value = getValue(name); if (value != null && value.trim().length() > 0) result.addMacroExpand(name, value); } + + myLock.readLock().lock(); + try { + for (Map.Entry entry : myLegacyMacros.entrySet()) { + result.addMacroExpand(entry.getKey(), entry.getValue()); + } + } + finally { + myLock.readLock().unlock(); + } } } From 12754ce4bd384d8557af3f57ee7802d81cec7b96 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 23 Jul 2010 13:34:30 +0400 Subject: [PATCH 038/102] fixed clicking on icon --- .../platform-api/src/com/intellij/ui/HyperlinkLabel.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java index 3dec125ac557..32dba0682118 100644 --- a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java +++ b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java @@ -35,6 +35,7 @@ import java.util.List; public class HyperlinkLabel extends HighlightableComponent { private HighlightedText myHighlightedText; private final List myListeners = new ArrayList(); + private boolean myUseIconAsLink; private final Color myTextForegroundColor; private final Color myTextBackgroundColor; private final Color myTextEffectColor; @@ -62,6 +63,7 @@ public class HyperlinkLabel extends HighlightableComponent { } public void setHyperlinkText(String text) { + myUseIconAsLink = true; setHyperlinkText("", text, ""); } @@ -71,6 +73,10 @@ public class HyperlinkLabel extends HighlightableComponent { adjustSize(); } + public void setUseIconAsLink(boolean useIconAsLink) { + myUseIconAsLink = useIconAsLink; + } + private void adjustSize() { final Dimension preferredSize = this.getPreferredSize(); this.setMinimumSize(preferredSize); @@ -96,6 +102,9 @@ public class HyperlinkLabel extends HighlightableComponent { } private boolean isOnLink(int x) { + if (myUseIconAsLink && myIcon != null && x < myIcon.getIconWidth()) { + return true; + } return findRegionByX(x) != null; } From f5b0e245ce3fc1c382b47ba385174f4c3989bbad Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 23 Jul 2010 14:42:05 +0400 Subject: [PATCH 039/102] optimization (inspired by peter) --- .../scopes/LibraryRuntimeClasspathScope.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java index d943f7c4b886..dbbbacc90f1d 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java @@ -20,6 +20,8 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.containers.ContainerUtil; @@ -43,8 +45,21 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope { super(project); myModules = modules; myIndex = ProjectRootManager.getInstance(project).getFileIndex(); + final Set processedSdk = new THashSet(); + final Set processedLibraries = new THashSet(); + final Set processedModules = new THashSet(); + final Condition condition = new Condition() { + @Override + public boolean value(OrderEntry orderEntry) { + if (orderEntry instanceof ModuleOrderEntry) { + final Module module = ((ModuleOrderEntry)orderEntry).getModule(); + return module != null && processedModules.add(module); + } + return true; + } + }; for (Module module : modules) { - buildEntries(module); + buildEntries(module, processedModules, processedLibraries, processedSdk, condition); } } @@ -60,13 +75,20 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope { return that.myModules.equals(myModules); } - private void buildEntries(@NotNull final Module module) { - final Set myJDKProcessed = new THashSet(); + private void buildEntries(@NotNull final Module module, + @NotNull final Set processedModules, + @NotNull final Set processedLibraries, + @NotNull final Set processedSdk, + Condition condition) { + if (!processedModules.add(module)) return; - ModuleRootManager.getInstance(module).orderEntries().recursively().process(new RootPolicy>() { + ModuleRootManager.getInstance(module).orderEntries().recursively().satisfying(condition).process(new RootPolicy>() { public LinkedHashSet visitLibraryOrderEntry(final LibraryOrderEntry libraryOrderEntry, final LinkedHashSet value) { - ContainerUtil.addAll(value, libraryOrderEntry.getRootFiles(OrderRootType.CLASSES)); + final Library library = libraryOrderEntry.getLibrary(); + if (library != null && processedLibraries.add(library)) { + ContainerUtil.addAll(value, libraryOrderEntry.getRootFiles(OrderRootType.CLASSES)); + } return value; } @@ -77,8 +99,10 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope { } public LinkedHashSet visitJdkOrderEntry(final JdkOrderEntry jdkOrderEntry, final LinkedHashSet value) { - if (!myJDKProcessed.add(jdkOrderEntry.getJdk())) return value; - ContainerUtil.addAll(value, jdkOrderEntry.getRootFiles(OrderRootType.CLASSES)); + final Sdk jdk = jdkOrderEntry.getJdk(); + if (jdk != null && processedSdk.add(jdk)) { + ContainerUtil.addAll(value, jdkOrderEntry.getRootFiles(OrderRootType.CLASSES)); + } return value; } }, myEntries); From c78e9d3d8c863653a1ee13cc8893c8ba7c603169 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 14:41:08 +0400 Subject: [PATCH 040/102] test data fixed --- java/java-tests/testData/codeInsight/javadocIG/ideadev2326.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-tests/testData/codeInsight/javadocIG/ideadev2326.html b/java/java-tests/testData/codeInsight/javadocIG/ideadev2326.html index 4ada6b3a0ac8..82e25213efa2 100644 --- a/java/java-tests/testData/codeInsight/javadocIG/ideadev2326.html +++ b/java/java-tests/testData/codeInsight/javadocIG/ideadev2326.html @@ -1,2 +1,2 @@ Idea4780
public Object read()
-           throws IOException
Throws:
EOFException - if this source is already closed when the read() is called, or is closed during the read().
InterruptedIOException - if the reading thread is interrupted.
IOException - if an I/O error occurs while reading.
\ No newline at end of file + throws IOException
Throws:
IOException - if an I/O error occurs while reading.
EOFException - if this source is already closed when the read() is called, or is closed during the read().
InterruptedIOException - if the reading thread is interrupted.
\ No newline at end of file From c737bb0c7c45625651833ef9057660ec3f3b300d Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 14:48:29 +0400 Subject: [PATCH 041/102] NPE --- .../memberPullUp/JavaPullUpHandler.java | 4 +++- .../memberPullUp/PullUpConflictsUtil.java | 20 +++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java index bd2e176dd899..4854d4d58bde 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java @@ -150,8 +150,10 @@ public class JavaPullUpHandler implements RefactoringActionHandler, PullUpDialog final MultiMap conflicts = new MultiMap(); if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { public void run() { + final PsiDirectory targetDirectory = superClass.getContainingFile().getContainingDirectory(); + final PsiPackage targetPackage = targetDirectory != null ? JavaDirectoryService.getInstance().getPackage(targetDirectory) : null; conflicts - .putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, null, null, dialog.getContainmentVerifier())); + .putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, targetPackage, targetDirectory, dialog.getContainmentVerifier())); } }, "Detecting possible conflicts...", true, myProject)) return false; if (!conflicts.isEmpty()) { diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java index fd26092d74cb..dc86c0c8a88a 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java @@ -28,10 +28,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.searches.ClassInheritorsSearch; -import com.intellij.psi.util.MethodSignature; -import com.intellij.psi.util.MethodSignatureUtil; -import com.intellij.psi.util.PsiUtil; -import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.psi.util.*; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.RefactoringConflictsUtil; @@ -143,9 +140,20 @@ public class PullUpConflictsUtil { } RefactoringConflictsUtil.analyzeModuleConflicts(subclass.getProject(), checkModuleConflictsList, new UsageInfo[0], targetRepresentativeElement, conflicts); + final String fqName = subclass.getQualifiedName(); + final String packageName; + if (fqName != null) { + packageName = StringUtil.getPackageName(fqName); + } else { + final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiFile.class); + if (psiFile instanceof PsiClassOwner) { + packageName = ((PsiClassOwner)psiFile).getPackageName(); + } else { + packageName = null; + } + } + final boolean toDifferentPackage = !Comparing.strEqual(targetPackage.getQualifiedName(), packageName); for (final PsiMethod abstractMethod : abstractMethods) { - final boolean toDifferentPackage = - !Comparing.strEqual(targetPackage.getQualifiedName(), StringUtil.getPackageName(subclass.getQualifiedName())); abstractMethod.accept(new ClassMemberReferencesVisitor(subclass) { @Override protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { From c67029e6e151189c1d7512ff48d8034c5d0bf739 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 23 Jul 2010 13:03:22 +0200 Subject: [PATCH 042/102] fix typo in method name --- .../src/com/siyeh/ig/psiutils/UninitializedReadCollector.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/UninitializedReadCollector.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/UninitializedReadCollector.java index 272eb6da9469..08afa15e435a 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/UninitializedReadCollector.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/UninitializedReadCollector.java @@ -438,7 +438,7 @@ public class UninitializedReadCollector { } else if(expression instanceof PsiAssignmentExpression){ final PsiAssignmentExpression assignment = (PsiAssignmentExpression) expression; - return assignmentExpressonAssignsVariable(assignment, variable, + return assignmentExpressionAssignsVariable(assignment, variable, stamp, checkedMethods); } else if(expression instanceof PsiParenthesizedExpression) { final PsiParenthesizedExpression parenthesizedExpression = @@ -453,7 +453,7 @@ public class UninitializedReadCollector { } } - private boolean assignmentExpressonAssignsVariable( + private boolean assignmentExpressionAssignsVariable( @NotNull PsiAssignmentExpression assignment, @NotNull PsiVariable variable, int stamp, @NotNull Set checkedMethods) { From b8e0a03e8d39afbe7edee5654401c349369a5c55 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 15:09:12 +0400 Subject: [PATCH 043/102] test framework: output graber should recieve default printer from the very beginning --- plugins/junit/src/com/intellij/execution/junit/TestObject.java | 1 + .../testng/configuration/TestNGRunnableState.java | 1 + 2 files changed, 2 insertions(+) diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index 190e397270b7..dceaf3e1518d 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -264,6 +264,7 @@ public abstract class TestObject implements JavaCommandLine { final JUnitTreeConsoleView consoleView = new JUnitTreeConsoleView(consoleProperties, getRunnerSettings(), getConfigurationSettings(), unboundOutputRoot); consoleView.initUI(); consoleView.attachToProcess(handler); + unboundOutputRoot.setPrinter(consoleView.getPrinter()); final TestsPacketsReceiver packetsReceiver = new TestsPacketsReceiver(consoleView) { @Override diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java index 9adb1a1e2a33..d9669df9ee23 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGRunnableState.java @@ -129,6 +129,7 @@ public class TestNGRunnableState extends JavaCommandLineState { final TreeRootNode unboundOutputRoot = new TreeRootNode(); final TestNGConsoleView console = new TestNGConsoleView(config, runnerSettings, myConfigurationPerRunnerSettings, unboundOutputRoot); console.initUI(); + unboundOutputRoot.setPrinter(console.getPrinter()); for (RunConfigurationExtension ext : Extensions.getExtensions(RunConfigurationExtension.EP_NAME)) { ext.handleStartProcess(config, processHandler); } From cce7d6dc0ac687508c80d87df7d35281fb3fb9b1 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 15:10:42 +0400 Subject: [PATCH 044/102] junit: suppress runners NPE --- .../junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java b/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java index 7bd1c2672ff0..8b87d1aa369c 100644 --- a/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java +++ b/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java @@ -39,6 +39,7 @@ public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner { myListeners = listeners; try { Test suite = TestRunnerUtil.getTestSuite(this, args); + if (suite == null) return -1; TestResult result = doRun(suite); if (!result.wasSuccessful()) { return -1; From e005a2df9a9965b867b9f46e186265dc9ddf28a5 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Fri, 23 Jul 2010 15:44:20 +0400 Subject: [PATCH 045/102] CIDR: code fragments CIDR-debugger: value type resolving --- .../intellij/psi/tree/IFileElementType.java | 4 ---- .../com/intellij/psi/util/PsiTreeUtil.java | 20 ++++++++++++++++++ .../com/intellij/extapi/psi/PsiFileBase.java | 21 ------------------- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/platform/lang-api/src/com/intellij/psi/tree/IFileElementType.java b/platform/lang-api/src/com/intellij/psi/tree/IFileElementType.java index d21b5255b26f..221fa01d1570 100644 --- a/platform/lang-api/src/com/intellij/psi/tree/IFileElementType.java +++ b/platform/lang-api/src/com/intellij/psi/tree/IFileElementType.java @@ -42,8 +42,4 @@ public class IFileElementType extends ILazyParseableElementType { final PsiParser parser = LanguageParserDefinitions.INSTANCE.forLanguage(getLanguage()).createParser(project); return parser.parse(this, builder).getFirstChildNode(); } - - //public boolean isParsable(CharSequence buffer, final Project project) { - // return true; - //} } diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java b/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java index 471c3b15720e..f20559eef3fd 100644 --- a/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java +++ b/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java @@ -175,6 +175,26 @@ public class PsiTreeUtil { return parents; } + @Nullable public static T findChildOfType(@NotNull final PsiElement element, @NotNull final Class aClass) { + return findChildOfType(element, aClass, true); + } + + @Nullable public static T findChildOfType(@NotNull final PsiElement element, @NotNull final Class aClass, final boolean strict) { + PsiElementProcessor.FindElement processor = new PsiElementProcessor.FindElement() { + @Override + public boolean execute(PsiElement each) { + if (strict && each == element) return true; + if (instanceOf(aClass, each)) { + return setFound(each); + } + return true; + } + }; + + PsiTreeUtil.processElements(element, processor); + return (T)processor.getFoundElement(); + } + @Nullable public static T getChildOfType(@NotNull PsiElement element, @NotNull Class aClass) { for(PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()){ if (instanceOf(aClass, child)) return (T)child; diff --git a/platform/lang-impl/src/com/intellij/extapi/psi/PsiFileBase.java b/platform/lang-impl/src/com/intellij/extapi/psi/PsiFileBase.java index 6a69377c94ae..04f32480e7a9 100644 --- a/platform/lang-impl/src/com/intellij/extapi/psi/PsiFileBase.java +++ b/platform/lang-impl/src/com/intellij/extapi/psi/PsiFileBase.java @@ -66,27 +66,6 @@ public abstract class PsiFileBase extends PsiFileImpl { return myLanguage; } - protected final FileElement createFileElement(final CharSequence docText) { - //final ParserDefinition parserDefinition = myLanguage.getParserDefinition(); - //if (parserDefinition != null && parserDefinition.createParser(getProject()) != PsiUtil.NULL_PARSER) { - // return _createFileElement(docText, myLanguage, getProject(), parserDefinition); - //} - return super.createFileElement(docText); - } - - //private static FileElement _createFileElement(final CharSequence docText, - // final Language language, - // Project project, - // final ParserDefinition parserDefinition) { - // final PsiParser parser = parserDefinition.createParser(project); - // final IElementType root = parserDefinition.getFileNodeType(); - // final PsiBuilderImpl builder = new PsiBuilderImpl(language, project, null, docText); - // final FileElement fileRoot = (FileElement)parser.parse(root, builder); - // LOG.assertTrue(fileRoot.getElementType() == root, - // "Parsing file text returns rootElement with type different from declared in parser definition"); - // return fileRoot; - //} - public void accept(@NotNull PsiElementVisitor visitor) { visitor.visitFile(this); } From d87341eab3243b21d6b20821f1f098656a39dcd3 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Fri, 23 Jul 2010 15:46:25 +0400 Subject: [PATCH 046/102] IDEA-56727 ctrl-hover provides preview hint for element different from actual navigation target --- .../intellij/codeInsight/navigation/CtrlMouseHandler.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java index 41c1532c96d1..d79634d1e78d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java @@ -401,9 +401,10 @@ public class CtrlMouseHandler extends AbstractProjectComponent { @Nullable private static PsiElement resolve(final PsiReference ref) { - PsiElement resolvedElement = null; + // IDEA-56727 try resolve first as in GotoDeclarationAction + PsiElement resolvedElement = ref.resolve(); - if (ref instanceof PsiPolyVariantReference) { + if (resolvedElement == null && ref instanceof PsiPolyVariantReference) { final ResolveResult[] psiElements = ((PsiPolyVariantReference)ref).multiResolve(false); if (psiElements.length > 0) { final ResolveResult resolveResult = psiElements[0]; @@ -412,9 +413,6 @@ public class CtrlMouseHandler extends AbstractProjectComponent { } } } - else { - resolvedElement = ref.resolve(); - } return resolvedElement; } From ebaf9bd41a3ece68684e7be4c13fbd9694815b99 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 23 Jul 2010 13:34:02 +0400 Subject: [PATCH 047/102] moved base64 converter to util --- .../com/intellij/util/Base64Converter.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 platform/util/src/com/intellij/util/Base64Converter.java diff --git a/platform/util/src/com/intellij/util/Base64Converter.java b/platform/util/src/com/intellij/util/Base64Converter.java new file mode 100644 index 000000000000..f25f6a59e6be --- /dev/null +++ b/platform/util/src/com/intellij/util/Base64Converter.java @@ -0,0 +1,88 @@ +package com.intellij.util; + +/** + * Created by IntelliJ IDEA. + * User: maxim + * Date: 18.07.2006 + * Time: 21:16:57 + * To change this template use File | Settings | File Templates. + */ +public class Base64Converter { + public static final char [ ] alphabet = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 to 7 + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 8 to 15 + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 16 to 23 + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 24 to 31 + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 32 to 39 + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 40 to 47 + 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 48 to 55 + '4', '5', '6', '7', '8', '9', '+', '/'}; // 56 to 63 + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + public static String encode(String s) + ////////////////////////////////////////////////////////////////////// + { + return encode(s.getBytes()); + } + + public static String encode(byte [ ] octetString) + ////////////////////////////////////////////////////////////////////// + { + int bits24; + int bits6; + + char [ ] out + = new char [ ((octetString.length - 1) / 3 + 1) * 4 ]; + + int outIndex = 0; + int i = 0; + + while ((i + 3) <= octetString.length) { + // store the octets + bits24 = (octetString[i++] & 0xFF) << 16; + bits24 |= (octetString[i++] & 0xFF) << 8; + bits24 |= (octetString[i++] & 0xFF) << 0; + + bits6 = (bits24 & 0x00FC0000) >> 18; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x0003F000) >> 12; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x00000FC0) >> 6; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x0000003F); + out[outIndex++] = alphabet[bits6]; + } + + if (octetString.length - i == 2) { + // store the octets + bits24 = (octetString[i] & 0xFF) << 16; + bits24 |= (octetString[i + 1] & 0xFF) << 8; + + bits6 = (bits24 & 0x00FC0000) >> 18; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x0003F000) >> 12; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x00000FC0) >> 6; + out[outIndex++] = alphabet[bits6]; + + // padding + out[outIndex++] = '='; + } else if (octetString.length - i == 1) { + // store the octets + bits24 = (octetString[i] & 0xFF) << 16; + + bits6 = (bits24 & 0x00FC0000) >> 18; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x0003F000) >> 12; + out[outIndex++] = alphabet[bits6]; + + // padding + out[outIndex++] = '='; + out[outIndex++] = '='; + } + + return new String(out); + } +} From babbba22bb2b6b0ff1bd3db86bff62934f696bc1 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 15:57:39 +0400 Subject: [PATCH 048/102] scope view panel should ignore changes in injected files --- .../src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java index 9323ec533c83..75c0ffc18755 100644 --- a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java @@ -33,6 +33,7 @@ import com.intellij.ide.scopeView.nodes.BasePsiNode; import com.intellij.ide.util.DeleteHandler; import com.intellij.ide.util.DirectoryChooserUtil; import com.intellij.ide.util.EditorHelper; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; @@ -505,7 +506,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di final NamedScope scope = getCurrentScope(); final PsiElement element = event.getNewChild(); final PsiFile psiFile = event.getFile(); - if (psiFile != null) { + if (psiFile != null && !InjectedLanguageManager.getInstance(myProject).isInjectedFragment(psiFile)) { if (psiFile.getLanguage() == psiFile.getViewProvider().getBaseLanguage()) { queueUpdate(new Runnable() { public void run() { From aaa4b19f54526f418c213c9b1120656812aa8c19 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 23 Jul 2010 16:01:12 +0400 Subject: [PATCH 049/102] Typos --- platform/util/src/com/intellij/Patches.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/platform/util/src/com/intellij/Patches.java b/platform/util/src/com/intellij/Patches.java index 6c05955bc86b..c20edf165fed 100644 --- a/platform/util/src/com/intellij/Patches.java +++ b/platform/util/src/com/intellij/Patches.java @@ -17,26 +17,26 @@ package com.intellij; import com.intellij.openapi.util.SystemInfo; -@SuppressWarnings({"HardCodedStringLiteral"}) +@SuppressWarnings({"HardCodedStringLiteral", "UtilityClassWithoutPrivateConstructor"}) public class Patches { public static final boolean ALL_FOLDERS_ARE_WRITABLE = SystemInfo.isWindows; /** - * See sun bug parage. + * See sun bug parade. * When JTable loses focus it cancel cell editing. It should stop cell editing instead. * Actually SUN-boys told they have fixed the bug, but they cancel editing instead of stopping it. */ public static final boolean SUN_BUG_ID_4503845 = SystemInfo.JAVA_VERSION.indexOf("1.4.") != -1; /** - * See sun bug parage [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620537]. + * See sun bug parade [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620537]. * MouseListener on JTabbedPane with SCROLL_TAB_LAYOUT policy doesn't get events. In the related bug * #4499556 Sun advices to reimplement or hack JTabbedPane as workaround :) */ public static final boolean SUN_BUG_ID_4620537 = SystemInfo.JAVA_VERSION.indexOf("1.4.") != -1; /** - * See sun bug parage. + * See sun bug parade. * Debugger hangs on any attempt to attach/listen Connector when attach hanged once. */ public static final boolean SUN_BUG_338675 = SystemInfo.JAVA_VERSION.indexOf("1.4.") != -1; @@ -68,7 +68,7 @@ public class Patches { public static final boolean SUN_BUG_ID_4738042 = SystemInfo.JAVA_VERSION.indexOf("1.4.") != -1 && SystemInfo.JAVA_VERSION.indexOf("1.4.2") == -1; - /** BasicTreeUI.FocusHandler doesn't preperly repaint JTree on focus changes */ + /** BasicTreeUI.FocusHandler doesn't properly repaint JTree on focus changes */ public static final boolean SUN_BUG_ID_4893787 = true; public static final boolean FILE_CHANNEL_TRANSFER_BROKEN = SystemInfo.isLinux && SystemInfo.OS_VERSION.startsWith("2.6"); @@ -111,12 +111,14 @@ public class Patches { public static final boolean MAC_AQUA_TABS_HACK = SystemInfo.isMac; /** - * it happened on Mac that some thread did not suspended during VM suspend - * resiming VM in this case caused com.sun.jdi.InternalException #13 + * It happened on Mac that some thread did not suspended during VM suspend + * resuming VM in this case caused com.sun.jdi.InternalException #13 */ public static final boolean MAC_RESUME_VM_HACK = SystemInfo.isMac; - // IBM java machine 1.4.2 craches if debugger uses ObjectReference.disableCollection() and ObjectReference.enableCollection() + /** + * IBM java machine 1.4.2 crashes if debugger uses ObjectReference.disableCollection() and ObjectReference.enableCollection() + */ public static final boolean IBM_JDK_DISABLE_COLLECTION_BUG = "false".equalsIgnoreCase(System.getProperty("idea.debugger.keep.temp.objects")); public static final boolean MAC_HIDE_QUIT_HACK = false; From 78e0b4e584419b53d826b65a94b93c63655e7231 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 16:28:11 +0400 Subject: [PATCH 050/102] scope view: skip "injected" modifications --- .../intellij/ide/scopeView/ScopeTreeViewPanel.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java index 75c0ffc18755..fa901642487f 100644 --- a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeTreeViewPanel.java @@ -420,7 +420,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di } private void processNodeCreation(final PsiElement psiElement) { - if (psiElement instanceof PsiFile) { + if (psiElement instanceof PsiFile && !isInjected((PsiFile)psiElement)) { reload(myBuilder.addFileNode((PsiFile)psiElement)); } else if (psiElement instanceof PsiDirectory) { @@ -434,7 +434,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di public void beforeChildRemoval(final PsiTreeChangeEvent event) { final PsiElement child = event.getChild(); final PsiElement parent = event.getParent(); - if (parent instanceof PsiDirectory && (child instanceof PsiFile || child instanceof PsiDirectory)) { + if (parent instanceof PsiDirectory && (child instanceof PsiFile && !isInjected((PsiFile)child) || child instanceof PsiDirectory)) { queueUpdate(new Runnable() { public void run() { collapseExpand(myBuilder.removeNode(child, (PsiDirectory)parent)); @@ -448,7 +448,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di final PsiElement newParent = event.getNewParent(); final PsiElement child = event.getChild(); if (oldParent instanceof PsiDirectory && newParent instanceof PsiDirectory) { - if (child instanceof PsiFile) { + if (child instanceof PsiFile && !isInjected((PsiFile)child)) { final PsiFile file = (PsiFile)child; queueUpdate(new Runnable() { public void run() { @@ -471,7 +471,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di final PsiElement parent = event.getParent(); final PsiFile file = parent.getContainingFile(); if (file != null && file.getFileType() == StdFileTypes.JAVA) { - if (!file.getViewProvider().isPhysical()) return; + if (!file.getViewProvider().isPhysical() && !isInjected(file)) return; queueUpdate(new Runnable() { public void run() { if (file.isValid()) { @@ -506,7 +506,7 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di final NamedScope scope = getCurrentScope(); final PsiElement element = event.getNewChild(); final PsiFile psiFile = event.getFile(); - if (psiFile != null && !InjectedLanguageManager.getInstance(myProject).isInjectedFragment(psiFile)) { + if (psiFile != null && !isInjected(psiFile)) { if (psiFile.getLanguage() == psiFile.getViewProvider().getBaseLanguage()) { queueUpdate(new Runnable() { public void run() { @@ -520,6 +520,10 @@ public class ScopeTreeViewPanel extends JPanel implements JDOMExternalizable, Di } } + private boolean isInjected(PsiFile psiFile) { + return InjectedLanguageManager.getInstance(myProject).isInjectedFragment(psiFile); + } + private void queueRefreshScope(final NamedScope scope) { myUpdateQueue.cancelAllUpdates(); queueUpdate(new Runnable() { From 5e2d900b2bea74204ddaec3d64184a92add4bb18 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 17:09:16 +0400 Subject: [PATCH 051/102] @Nullable/@NotNull --- .../refactoring/memberPullUp/PullUpConflictsUtil.java | 11 ++++++----- .../com/intellij/refactoring/PullUpMultifileTest.java | 9 ++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java index dc86c0c8a88a..79f624db5293 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpConflictsUtil.java @@ -40,6 +40,7 @@ import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.usageView.UsageInfo; import com.intellij.util.VisibilityUtil; import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -53,17 +54,17 @@ public class PullUpConflictsUtil { public static MultiMap checkConflicts(final MemberInfo[] infos, PsiClass subclass, @Nullable PsiClass superClass, - PsiPackage targetPackage, - PsiDirectory targetDirectory, + @NotNull PsiPackage targetPackage, + @NotNull PsiDirectory targetDirectory, final InterfaceContainmentVerifier interfaceContainmentVerifier) { return checkConflicts(infos, subclass, superClass, targetPackage, targetDirectory, interfaceContainmentVerifier, true); } public static MultiMap checkConflicts(final MemberInfo[] infos, - final PsiClass subclass, + @NotNull final PsiClass subclass, @Nullable PsiClass superClass, - final PsiPackage targetPackage, - PsiDirectory targetDirectory, + @NotNull final PsiPackage targetPackage, + @NotNull PsiDirectory targetDirectory, final InterfaceContainmentVerifier interfaceContainmentVerifier, boolean movedMembers2Super) { final Set movedMembers = new HashSet(); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java index fcfbec4fa1bd..adc2a9256c9b 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java @@ -24,10 +24,7 @@ import com.intellij.JavaTestUtil; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil; import com.intellij.refactoring.memberPullUp.PullUpHelper; @@ -75,8 +72,10 @@ public class PullUpMultifileTest extends MultiFileTestCase { memberInfo.setChecked(true); membersToMove[0] = memberInfo; + final PsiDirectory targetDirectory = targetClass.getContainingFile().getContainingDirectory(); + final PsiPackage targetPackage = targetDirectory != null ? JavaDirectoryService.getInstance().getPackage(targetDirectory) : null; conflictsMap.putAllValues( - PullUpConflictsUtil.checkConflicts(membersToMove, srcClass, targetClass, null, null, new InterfaceContainmentVerifier() { + PullUpConflictsUtil.checkConflicts(membersToMove, srcClass, targetClass, targetPackage, targetDirectory, new InterfaceContainmentVerifier() { public boolean checkedInterfacesContain(PsiMethod psiMethod) { return PullUpHelper.checkedInterfacesContain(Arrays.asList(membersToMove), psiMethod); } From 3e412f94d0b650c9c5f7aad48ec80370529bfe24 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 23 Jul 2010 17:27:37 +0400 Subject: [PATCH 052/102] IDEA-55772 system selection update like in JTextComponent --- .../src/com/intellij/openapi/editor/impl/SelectionModelImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java index ebc8e2463e05..56ac422beb0e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java @@ -277,7 +277,6 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi mySelectionMarker.release(); mySelectionMarker = null; fireSelectionChanged(startOffset, endOffset, myLastSelectionStart, myLastSelectionStart); - updateSystemSelection(); } } From af96b3fb7111c715b6efab3b8b5b5625458cd3c0 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Fri, 23 Jul 2010 20:00:02 +0400 Subject: [PATCH 053/102] AS extract interface action works in MXML files --- .../refactoring/actions/BaseExtractModuleAction.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/BaseExtractModuleAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/BaseExtractModuleAction.java index e9b0b8bebe3c..d20e83f49be3 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/actions/BaseExtractModuleAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/BaseExtractModuleAction.java @@ -34,23 +34,26 @@ public abstract class BaseExtractModuleAction extends BaseRefactoringAction { public boolean isEnabledOnElements(PsiElement[] elements) { if (elements.length > 0) { final Language language = elements[0].getLanguage(); - final RefactoringActionHandler handler = LanguageRefactoringSupport.INSTANCE.forLanguage(language).getExtractModuleHandler(); + final RefactoringActionHandler handler = getRefactoringSupport(language).getExtractModuleHandler(); return isEnabledOnLanguage(language) && handler instanceof ElementsHandler && ((ElementsHandler)handler).isEnabledOnElements(elements); } return false; } + protected RefactoringSupportProvider getRefactoringSupport(Language language) { + return LanguageRefactoringSupport.INSTANCE.forLanguage(language); + } + public RefactoringActionHandler getHandler(DataContext dataContext) { PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext); if (file == null) return null; - final RefactoringSupportProvider supportProvider = LanguageRefactoringSupport.INSTANCE.forLanguage(file.getViewProvider().getBaseLanguage()); + final RefactoringSupportProvider supportProvider = getRefactoringSupport(file.getViewProvider().getBaseLanguage()); return supportProvider != null ? supportProvider.getExtractModuleHandler() : null; } protected boolean isAvailableForLanguage(final Language language) { - return isEnabledOnLanguage(language) && - LanguageRefactoringSupport.INSTANCE.forLanguage(language).getExtractModuleHandler() != null; + return isEnabledOnLanguage(language) && getRefactoringSupport(language).getExtractModuleHandler() != null; } protected abstract boolean isEnabledOnLanguage(final Language language); From 5a15a09b6e8b4a77b5b602e51f0934e6f8b4ce37 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Fri, 23 Jul 2010 20:20:08 +0400 Subject: [PATCH 054/102] huge number of text usages per file support (multiple RA & singlepass lexing) --- .../intellij/find/impl/FindInProjectUtil.java | 67 +++++---- .../com/intellij/usages/ChunkExtractor.java | 138 ++++++++++++------ .../src/com/intellij/usages/TextChunk.java | 3 + .../usages/UsageInfo2UsageAdapter.java | 2 +- 4 files changed, 139 insertions(+), 71 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java index ad6002473a98..976802fd04cd 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java @@ -85,6 +85,7 @@ import java.util.regex.Pattern; public class FindInProjectUtil { private static final int USAGES_LIMIT = 1000; + private static final int USAGES_PER_READ_ACTION = 100; private static final int FILES_SIZE_LIMIT = 70 * 1024 * 1024; // megabytes. private static final int SINGLE_FILE_SIZE_LIMIT = 5 * 1024 * 1024; // megabytes. @@ -218,7 +219,7 @@ public class FindInProjectUtil { int i = 0; long totalFilesSize = 0; int count = 0; - boolean warningShown = false; + final boolean[] warningShown = new boolean[] {false}; final UsageViewManager usageViewManager = UsageViewManager.getInstance(project); for (final PsiFile psiFile : psiFiles) { @@ -252,22 +253,16 @@ public class FindInProjectUtil { progress.setText2(FindBundle.message("find.searching.for.string.in.file.occurrences.progress", count)); } - int countInFile = processUsagesInFile(psiFile, findModel, consumer); + int countInFile = processUsagesInFile(psiFile, findModel, consumer, count, warningShown); if (countInFile > 0) { totalFilesSize += fileLength; - if (totalFilesSize > FILES_SIZE_LIMIT && !warningShown) { + if (totalFilesSize > FILES_SIZE_LIMIT && !warningShown[0]) { showTooManyUsagesWaring(project, FindBundle.message("find.excessive.total.size.prompt", presentableSize(totalFilesSize), ApplicationNamesInfo.getInstance().getProductName())); - warningShown = true; + warningShown[0] = true; } } - - count += countInFile; - if (count > USAGES_LIMIT && !warningShown) { - showTooManyUsagesWaring(project, FindBundle.message("find.excessive.usage.count.prompt", count)); - warningShown = true; - } } if (!largeFiles.isEmpty()) { @@ -317,22 +312,37 @@ public class FindInProjectUtil { } } - private static int processUsagesInFile(final PsiFile psiFile, final FindModel findModel, final Processor consumer) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - public Integer compute() { - if (psiFile.isValid()) { - VirtualFile virtualFile = psiFile.getVirtualFile(); - // Check once more if valid and text since we're in new read action and things might have been changed. - if (FileTypeManager.getInstance().getFileTypeByFile(virtualFile).isBinary()) return 0; // do not decompile .class files - final Document document = FileDocumentManager.getInstance().getDocument(virtualFile); - if (document != null) { - return addToUsages(document, consumer, findModel, psiFile); - } + private static int processUsagesInFile(final PsiFile psiFile, + final FindModel findModel, + final Processor consumer, + int alreadyCounted, + boolean[] warningShown) { + final VirtualFile virtualFile = psiFile.getVirtualFile(); + if (virtualFile == null) return 0; + if (FileTypeManager.getInstance().getFileTypeByFile(virtualFile).isBinary()) return 0; // do not decompile .class files + final Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + if (document == null) return 0; + final int[] offset = new int[] {0}; + int count = 0; + int found; + do { + found = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + @NotNull + public Integer compute() { + if (!psiFile.isValid()) return 0; + return addToUsages(document, consumer, findModel, psiFile, offset, USAGES_PER_READ_ACTION); } - - return 0; + }); + count += found; + if (found > 0 && count + alreadyCounted > USAGES_LIMIT && !warningShown[0]) { + showTooManyUsagesWaring(psiFile.getProject(), FindBundle.message("find.excessive.usage.count.prompt", count)); + warningShown[0] = true; } - }).intValue(); + + } + while (found != 0); + return count; } private static String getPresentablePath(final VirtualFile virtualFile) { @@ -605,12 +615,11 @@ public class FindInProjectUtil { } private static int addToUsages(@NotNull Document document, @NotNull Processor consumer, @NotNull FindModel findModel, - @NotNull final PsiFile psiFile) { - + @NotNull final PsiFile psiFile, int[] offsetRef, int maxUsages) { int count = 0; CharSequence text = document.getCharsSequence(); int textLength = document.getTextLength(); - int offset = 0; + int offset = offsetRef[0]; Project project = psiFile.getProject(); @@ -632,7 +641,11 @@ public class FindInProjectUtil { // for regular expr the size of the match could be zero -> could be infinite loop in finding usages! ++offset; } + if (maxUsages > 0 && count >= maxUsages) { + break; + } } + offsetRef[0] = offset; return count; } diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java index 636ad3ff8b54..e7df19e8c17b 100644 --- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java +++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java @@ -29,14 +29,19 @@ import com.intellij.openapi.fileTypes.SyntaxHighlighter; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IElementType; import com.intellij.usageView.UsageTreeColors; import com.intellij.usageView.UsageTreeColorsScheme; +import com.intellij.util.containers.FactoryMap; +import org.jetbrains.annotations.NotNull; import java.awt.*; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; /** * @author peter @@ -44,29 +49,65 @@ import java.util.List; public class ChunkExtractor { private static final Logger LOG = Logger.getInstance("#com.intellij.usages.ChunkExtractor"); - private final PsiElement myElement; - private final Document myDocument; - private final int myLineNumber; - private final int myColumnNumber; - - private final List myRangeMarkers; private final EditorColorsScheme myColorsScheme; - public ChunkExtractor(final PsiElement element, final List rangeMarkers) { - myElement = element; - myRangeMarkers = new ArrayList(rangeMarkers.size()); - for (RangeMarker rangeMarker : rangeMarkers) { - if (rangeMarker.isValid()) myRangeMarkers.add(rangeMarker); + private final Document myDocument; + private final SyntaxHighlighter myHighlighter; + + private final Lexer myLexer; + + private static abstract class WeakFactory { + + private WeakReference myRef; + + @NotNull + protected abstract T create(); + + @NotNull + public T getValue() { + final T cur = myRef == null ? null : myRef.get(); + if (cur != null) return cur; + final T result = create(); + myRef = new WeakReference(result); + return result; } - Collections.sort(myRangeMarkers, RangeMarker.BY_START_OFFSET); + + } + + private static final ThreadLocal>> ourExtractors = new ThreadLocal>>() { + @Override + protected WeakFactory> initialValue() { + return new WeakFactory>() { + @NotNull + @Override + protected Map create() { + return new FactoryMap() { + @Override + protected ChunkExtractor create(PsiFile key) { + return new ChunkExtractor(key); + } + }; + } + }; + } + }; + + public static TextChunk[] extractChunks(PsiElement element, List rangeMarkers) { + return ourExtractors.get().getValue().get(element.getContainingFile()).extractChunks(rangeMarkers); + } + + + private ChunkExtractor(PsiFile file) { myColorsScheme = UsageTreeColorsScheme.getInstance().getScheme(); - int absoluteStartOffset = getStartOffset(myRangeMarkers); - assert absoluteStartOffset != -1; - - myDocument = PsiDocumentManager.getInstance(myElement.getProject()).getDocument(myElement.getContainingFile()); - myLineNumber = myDocument.getLineNumber(absoluteStartOffset); - myColumnNumber = absoluteStartOffset - myDocument.getLineStartOffset(myLineNumber); + myDocument = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); + LOG.assertTrue(myDocument != null); + final FileType fileType = file.getFileType(); + final SyntaxHighlighter highlighter = + SyntaxHighlighter.PROVIDER.create(fileType, file.getProject(), file.getVirtualFile()); + myHighlighter = highlighter == null ? new PlainSyntaxHighlighter() : highlighter; + myLexer = myHighlighter.getHighlightingLexer(); + myLexer.start(myDocument.getCharsSequence()); } public static int getStartOffset(final List rangeMarkers) { @@ -80,30 +121,40 @@ public class ChunkExtractor { return minStart == Integer.MAX_VALUE ? -1 : minStart; } - public TextChunk[] extractChunks() { - final int lineStartOffset = myDocument.getLineStartOffset(myLineNumber); - final int lineEndOffset = lineStartOffset < myDocument.getTextLength() ? myDocument.getLineEndOffset(myLineNumber):0; - if (lineStartOffset > lineEndOffset) return new TextChunk[0]; - final FileType fileType = myElement.getContainingFile().getFileType(); - SyntaxHighlighter highlighter = - SyntaxHighlighter.PROVIDER.create(fileType, myElement.getProject(), myElement.getContainingFile().getVirtualFile()); - if (highlighter == null) { - highlighter = new PlainSyntaxHighlighter(); + public TextChunk[] extractChunks(List rangeMarkers) { + final ArrayList markers = new ArrayList(rangeMarkers.size()); + for (RangeMarker rangeMarker : rangeMarkers) { + if (rangeMarker.isValid()) markers.add(rangeMarker); } - return createTextChunks(myDocument.getCharsSequence(), highlighter, lineStartOffset, lineEndOffset); + int absoluteStartOffset = getStartOffset(markers); + assert absoluteStartOffset != -1; + + final int lineNumber = myDocument.getLineNumber(absoluteStartOffset); + final int columnNumber = absoluteStartOffset - myDocument.getLineStartOffset(lineNumber); + + Collections.sort(markers, RangeMarker.BY_START_OFFSET); + final int lineStartOffset = myDocument.getLineStartOffset(lineNumber); + final int lineEndOffset = lineStartOffset < myDocument.getTextLength() ? myDocument.getLineEndOffset(lineNumber) : 0; + if (lineStartOffset > lineEndOffset) return TextChunk.EMPTY_ARRAY; + + final CharSequence chars = myDocument.getCharsSequence(); + if (myLexer.getTokenStart() > absoluteStartOffset) { + myLexer.start(chars); + } + final List result = new ArrayList(); + appendPrefix(result, lineNumber, columnNumber); + return createTextChunks(markers, chars, lineStartOffset, lineEndOffset, result); } - private TextChunk[] createTextChunks(final CharSequence chars, - SyntaxHighlighter highlighter, + private TextChunk[] createTextChunks(final List markers, + final CharSequence chars, int start, - int end) { + int end, + final List result) { + final Lexer lexer = myLexer; + final SyntaxHighlighter highlighter = myHighlighter; + LOG.assertTrue(start <= end); - List result = new ArrayList(); - - appendPrefix(result); - - Lexer lexer = highlighter.getHighlightingLexer(); - lexer.start(chars); int i = StringUtil.indexOf(chars, '\n', start, end); if (i != -1) end = i; @@ -127,7 +178,7 @@ public class ChunkExtractor { IElementType tokenType = lexer.getTokenType(); TextAttributesKey[] tokenHighlights = highlighter.getTokenHighlights(tokenType); - processIntersectingRange(chars, hiStart, hiEnd, tokenHighlights, result); + processIntersectingRange(markers, chars, hiStart, hiEnd, tokenHighlights, result); } finally { lexer.advance(); @@ -137,14 +188,15 @@ public class ChunkExtractor { return result.toArray(new TextChunk[result.size()]); } - private void processIntersectingRange(CharSequence chars, + private void processIntersectingRange(List markers, + CharSequence chars, int hiStart, int hiEnd, TextAttributesKey[] tokenHighlights, List result) { TextAttributes originalAttrs = convertAttributes(tokenHighlights); int lastOffset = hiStart; - for(RangeMarker rangeMarker: myRangeMarkers) { + for(RangeMarker rangeMarker: markers) { int usageStart = rangeMarker.getStartOffset(); int usageEnd = rangeMarker.getEndOffset(); if (rangeMarker.isValid() && rangeIntersect(lastOffset, hiEnd, usageStart, usageEnd)) { @@ -191,11 +243,11 @@ public class ChunkExtractor { return attrs; } - private void appendPrefix(List result) { + private void appendPrefix(List result, int lineNumber, int columnNumber) { StringBuilder buffer = new StringBuilder("("); - buffer.append(myLineNumber + 1); + buffer.append(lineNumber + 1); buffer.append(", "); - buffer.append(myColumnNumber + 1); + buffer.append(columnNumber + 1); buffer.append(") "); TextChunk prefixChunk = new TextChunk(myColorsScheme.getAttributes(UsageTreeColors.USAGE_LOCATION), buffer.toString()); result.add(prefixChunk); diff --git a/platform/usageView/src/com/intellij/usages/TextChunk.java b/platform/usageView/src/com/intellij/usages/TextChunk.java index bc2cabcef047..2ab65cc469dd 100644 --- a/platform/usageView/src/com/intellij/usages/TextChunk.java +++ b/platform/usageView/src/com/intellij/usages/TextChunk.java @@ -20,6 +20,9 @@ import com.intellij.openapi.editor.markup.TextAttributes; import org.jetbrains.annotations.NotNull; public class TextChunk { + + public static final TextChunk[] EMPTY_ARRAY = new TextChunk[0]; + private final AttributesFlyweight myAttributes; private final String myText; diff --git a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java index 40b2bc9fa2f8..97873b7fde99 100644 --- a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java +++ b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java @@ -125,7 +125,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us } private void initChunks() { - myTextChunks = new ChunkExtractor(getElement(), myRangeMarkers).extractChunks(); + myTextChunks = ChunkExtractor.extractChunks(getElement(), myRangeMarkers); } @NotNull From d04ac9e21f174cc5d61770a93ed084bc4b968db8 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Fri, 23 Jul 2010 21:40:26 +0400 Subject: [PATCH 055/102] deadlock fix (multithreaded search replaced by singlethreaded) --- .../PatternEditorContextMembersProvider.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/PatternEditorContextMembersProvider.java b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/PatternEditorContextMembersProvider.java index 04e21e9cde4c..0ed28380d1f8 100644 --- a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/PatternEditorContextMembersProvider.java +++ b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/PatternEditorContextMembersProvider.java @@ -16,11 +16,14 @@ package org.intellij.plugins.intelliLang.inject.groovy; import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.patterns.compiler.PatternClassBean; import com.intellij.patterns.compiler.PatternCompilerFactory; import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerEx; +import com.intellij.psi.impl.search.LowLevelSearchUtil; import com.intellij.psi.impl.source.resolve.FileContextUtil; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.GlobalSearchScope; @@ -33,7 +36,10 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlText; import com.intellij.util.ArrayUtil; +import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.text.StringSearcher; +import com.intellij.util.xml.DomManager; import org.intellij.plugins.intelliLang.inject.InjectorUtils; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.jetbrains.annotations.NotNull; @@ -132,7 +138,7 @@ public class PatternEditorContextMembersProvider extends NonCodeMembersContribut if (beanClass != null) { final GlobalSearchScope scope = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), StdFileTypes.XML); - beanClass.getManager().getSearchHelper().processElementsWithWord(new TextOccurenceProcessor() { + final TextOccurenceProcessor occurenceProcessor = new TextOccurenceProcessor() { @Override public boolean execute(PsiElement element, int offsetInElement) { final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class); @@ -142,7 +148,15 @@ public class PatternEditorContextMembersProvider extends NonCodeMembersContribut } return true; } - }, scope, "patterns.patternClass", UsageSearchContext.IN_FOREIGN_LANGUAGES, true); + }; + final StringSearcher searcher = new StringSearcher("patternClass", true, true); + ((PsiManagerEx)beanClass.getManager()).getCacheManager().processFilesWithWord(new Processor() { + @Override + public boolean process(PsiFile psiFile) { + LowLevelSearchUtil.processElementsContainingWordInElement(occurenceProcessor, psiFile, searcher, false, new EmptyProgressIndicator()); + return true; + } + }, searcher.getPattern(), UsageSearchContext.IN_FOREIGN_LANGUAGES, scope, searcher.isCaseSensitive()); } final Class[] classes = PatternCompilerFactory.getFactory().getPatternClasses(type); if (classes.length != 0) { From 133e5855799299d5ad6cef2e25d024fe2d9f4c26 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Fri, 23 Jul 2010 21:54:57 +0400 Subject: [PATCH 056/102] Basic declaration level keyword completion, implements/overrides icons for methods. --- .../intellij/codeInsight/completion/CompletionData.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java index fc8e266060f6..83657d7b1caa 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionData.java @@ -204,7 +204,7 @@ public class CompletionData { return null; } - public static String findPrefixStatic(final PsiElement insertedElement, final int offsetInFile) { + public static String findPrefixStatic(final PsiElement insertedElement, final int offsetInFile, ElementPattern prefixStartTrim) { if(insertedElement == null) return ""; final String prefix = ApplicationManager.getApplication().runReadAction(new Computable() { @@ -221,7 +221,11 @@ public class CompletionData { return CompletionUtil.findJavaIdentifierPrefix(insertedElement, offsetInFile); } - return findPrefixDefault(insertedElement, offsetInFile, not(character().javaIdentifierPart())); + return findPrefixDefault(insertedElement, offsetInFile, prefixStartTrim); + } + + public static String findPrefixStatic(final PsiElement insertedElement, final int offsetInFile) { + return findPrefixStatic(insertedElement, offsetInFile, not(character().javaIdentifierPart())); } protected static String findPrefixDefault(final PsiElement insertedElement, final int offset, @NotNull final ElementPattern trimStart) { From 7a5ed76cc074e7c69efccd1f208f634b30ccb17f Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Sat, 24 Jul 2010 07:14:38 +0400 Subject: [PATCH 057/102] support modules & PsiReferenceProviderBean. And fix missing Action/Group methods. --- plugins/devkit/src/dom/Action.java | 7 +- plugins/devkit/src/dom/Actions.java | 2 + plugins/devkit/src/dom/Group.java | 2 +- .../src/dom/impl/ExtensionDomExtender.java | 130 ++++++++++++++---- .../src/dom/impl/IdeaPluginConverter.java | 20 ++- .../codeInsight/DependsHighlighting.xml | 2 +- .../codeInsight/PluginXmlFunctionalTest.java | 1 + 7 files changed, 127 insertions(+), 37 deletions(-) diff --git a/plugins/devkit/src/dom/Action.java b/plugins/devkit/src/dom/Action.java index 773d3a5ebfa5..bd03efde2566 100644 --- a/plugins/devkit/src/dom/Action.java +++ b/plugins/devkit/src/dom/Action.java @@ -142,6 +142,9 @@ public interface Action extends DomElement { */ AddToGroup addAddToGroup(); - @NotNull - GenericAttributeValue getUseShortcutOf(); + @NotNull + GenericAttributeValue getUseShortcutOf(); + + @NotNull + GenericAttributeValue getKeymap(); } diff --git a/plugins/devkit/src/dom/Actions.java b/plugins/devkit/src/dom/Actions.java index 4e06ec6da85f..3fa4320c2596 100644 --- a/plugins/devkit/src/dom/Actions.java +++ b/plugins/devkit/src/dom/Actions.java @@ -39,4 +39,6 @@ public interface Actions extends DomElement { @NotNull List getReferences(); + + Reference addReference(); } diff --git a/plugins/devkit/src/dom/Group.java b/plugins/devkit/src/dom/Group.java index cadec21dc3aa..0fc11ff8aa6d 100644 --- a/plugins/devkit/src/dom/Group.java +++ b/plugins/devkit/src/dom/Group.java @@ -28,7 +28,7 @@ import java.util.List; /** * plugin.dtd:group interface. */ -public interface Group extends DomElement { +public interface Group extends Actions { /** * Returns the value of the popup child. diff --git a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java index 071e6450b422..0387e2fcc025 100644 --- a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java +++ b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java @@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.xml.XmlElement; import com.intellij.psi.xml.XmlFile; import com.intellij.util.containers.ContainerUtil; @@ -27,7 +28,10 @@ import com.intellij.util.xml.*; import com.intellij.util.xml.reflect.DomExtender; import com.intellij.util.xml.reflect.DomExtension; import com.intellij.util.xml.reflect.DomExtensionsRegistrar; +import com.intellij.util.xmlb.Constants; +import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.Attribute; +import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.xmlb.annotations.Tag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -65,7 +69,8 @@ public class ExtensionDomExtender extends DomExtender { final Collection dependencies = getDependencies(ideaPlugin); for (IdeaPlugin plugin : IdeaPluginConverter.collectAllVisiblePlugins(DomUtil.getFile(extensions))) { final String value = plugin.getPluginId(); - if (value != null && dependencies.contains(value)) { + // value == null for "included" platform plugins like DomPlugin.xml, XmlPlugin.xml, etc. + if (value == null || dependencies.contains(value)) { registerExtensions(prefix, plugin, registrar, psiManager); } } @@ -74,7 +79,7 @@ public class ExtensionDomExtender extends DomExtender { private static void registerExtensions(final String prefix, final IdeaPlugin plugin, final DomExtensionsRegistrar registrar, final PsiManager psiManager) { - final String pluginId = plugin.getPluginId(); + final String pluginId = StringUtil.notNullize(plugin.getPluginId(), "com.intellij"); for (ExtensionPoints points : plugin.getExtensionPoints()) { for (ExtensionPoint point : points.getExtensionPoints()) { registerExtensionPoint(registrar, point, psiManager, prefix, pluginId); @@ -129,36 +134,109 @@ public class ExtensionDomExtender extends DomExtender { } private static void registerField(final DomExtensionsRegistrar registrar, @NotNull final PsiField field) { - final PsiAnnotation[] annotations = field.getModifierList().getAnnotations(); + final PsiModifierList modifierList = field.getModifierList(); + if (modifierList == null) return; final PsiConstantEvaluationHelper evalHelper = JavaPsiFacade.getInstance(field.getProject()).getConstantEvaluationHelper(); - for (PsiAnnotation annotation : annotations) { - final String qName = annotation.getQualifiedName(); - if (qName != null) { - if (qName.equals(Attribute.class.getName())) { - final PsiAnnotationMemberValue attributeName = annotation.findAttributeValue("value"); - if (attributeName != null && attributeName instanceof PsiExpression) { - final Class type = String.class; - PsiExpression expression = (PsiExpression)attributeName; - final Object evaluatedExpression = evalHelper.computeConstantExpression(expression, false); - if (evaluatedExpression != null) { - registrar.registerGenericAttributeValueChildExtension(new XmlName(evaluatedExpression.toString()), type); - } - } - } else if (qName.equals(Tag.class.getName())) { - final PsiAnnotationMemberValue attributeName = annotation.findAttributeValue("value"); - if (attributeName != null && attributeName instanceof PsiExpression) { - PsiExpression expression = (PsiExpression)attributeName; - final Object evaluatedExpression = evalHelper.computeConstantExpression(expression, false); - if (evaluatedExpression != null) { - // I guess this actually needs something like registrar.registerGenericTagValueChildExtension... - registrar.registerFixedNumberChildExtension(new XmlName(evaluatedExpression.toString()), SimpleTagValue.class); - } - } + final PsiAnnotation attrAnno = modifierList.findAnnotation(Attribute.class.getName()); + if (attrAnno != null) { + final PsiAnnotationMemberValue attributeName = attrAnno.findAttributeValue("value"); + if (attributeName != null && attributeName instanceof PsiExpression) { + final Class type = String.class; + PsiExpression expression = (PsiExpression)attributeName; + final Object evaluatedExpression = evalHelper.computeConstantExpression(expression, false); + if (evaluatedExpression != null) { + registrar.registerGenericAttributeValueChildExtension(new XmlName(evaluatedExpression.toString()), type); } } + return; + } + final PsiAnnotation tagAnno = modifierList.findAnnotation(Tag.class.getName()); + final PsiAnnotation propAnno = modifierList.findAnnotation(Property.class.getName()); + final PsiAnnotation absColAnno = modifierList.findAnnotation(AbstractCollection.class.getName()); + //final PsiAnnotation colAnno = modifierList.findAnnotation(Collection.class.getName()); // todo + final String tagName = tagAnno != null? getStringAttribute(tagAnno, "value", evalHelper) : + propAnno != null && getBooleanAttribute(propAnno, "surroundWithTag", evalHelper)? Constants.OPTION : null; + if (tagName != null) { + if (absColAnno == null) { + registrar.registerFixedNumberChildExtension(new XmlName(tagName), SimpleTagValue.class); + } + else { + registrar.registerFixedNumberChildExtension(new XmlName(tagName), DomElement.class).addExtender(new DomExtender() { + @Override + public void registerExtensions(@NotNull DomElement domElement, @NotNull DomExtensionsRegistrar registrar) { + registerCollectionBinding(field.getType(), registrar, absColAnno, evalHelper); + } + }); + } + } + else if (absColAnno != null) { + registerCollectionBinding(field.getType(), registrar, absColAnno, evalHelper); + } + } + + private static void registerCollectionBinding(PsiType type, + DomExtensionsRegistrar registrar, + PsiAnnotation anno, + PsiConstantEvaluationHelper evalHelper) { + final boolean surroundWithTag = getBooleanAttribute(anno, "surroundWithTag", evalHelper); + if (surroundWithTag) return; // todo Set, List, Array + final String tagName = getStringAttribute(anno, "elementTag", evalHelper); + final String attrName = getStringAttribute(anno, "elementValueAttribute", evalHelper); + final PsiClass psiClass = getElementType(type); + if (tagName != null && attrName == null) { + registrar.registerCollectionChildrenExtension(new XmlName(tagName), SimpleTagValue.class); + } + else if (tagName != null) { + registrar.registerCollectionChildrenExtension(new XmlName(tagName), DomElement.class).addExtender(new DomExtender() { + @Override + public void registerExtensions(@NotNull DomElement domElement, @NotNull DomExtensionsRegistrar registrar) { + registrar.registerGenericAttributeValueChildExtension(new XmlName(attrName), String.class); + } + }); + } + else if (psiClass != null) { + final PsiModifierList modifierList = psiClass.getModifierList(); + final PsiAnnotation tagAnno = modifierList == null? null : modifierList.findAnnotation(Tag.class.getName()); + final String classTagName = tagAnno == null? psiClass.getName() : getStringAttribute(tagAnno, "value", evalHelper); + if (classTagName != null) { + registrar.registerCollectionChildrenExtension(new XmlName(classTagName), DomElement.class).addExtender(new DomExtender() { + @Override + public void registerExtensions(@NotNull DomElement domElement, @NotNull DomExtensionsRegistrar registrar) { + registerXmlb(registrar, psiClass); + } + }); + } } } + @Nullable + private static String getStringAttribute(final PsiAnnotation annotation, + final String name, + final PsiConstantEvaluationHelper evalHelper) { + final Object o = evalHelper.computeConstantExpression(annotation.findAttributeValue(name), false); + return o instanceof String && StringUtil.isNotEmpty((String)o)? (String)o : null; + } + + private static boolean getBooleanAttribute(final PsiAnnotation annotation, + final String name, + final PsiConstantEvaluationHelper evalHelper) { + final Object o = evalHelper.computeConstantExpression(annotation.findAttributeValue(name), false); + return o instanceof Boolean? ((Boolean)o).booleanValue() : false; + } + + @Nullable + public static PsiClass getElementType(final PsiType psiType) { + final PsiType elementType; + if (psiType instanceof PsiArrayType) elementType = ((PsiArrayType)psiType).getComponentType(); + else if (psiType instanceof PsiClassType) { + final PsiType[] types = ((PsiClassType)psiType).getParameters(); + elementType = types.length == 1? types[0] : null; + } + else elementType = null; + return PsiTypesUtil.getPsiClass(elementType); + } + + public static Collection getDependencies(IdeaPlugin ideaPlugin) { Set result = new HashSet(); diff --git a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java index 3e5e18deeb30..766603b59f51 100644 --- a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java +++ b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java @@ -19,17 +19,18 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.xml.XmlFile; import com.intellij.util.Function; -import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xml.ConvertContext; import com.intellij.util.xml.DomFileElement; import com.intellij.util.xml.DomService; import com.intellij.util.xml.ResolvingConverter; +import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.devkit.DevKitBundle; import org.jetbrains.idea.devkit.dom.IdeaPlugin; +import org.jetbrains.idea.devkit.dom.PluginModule; import java.util.Collection; import java.util.List; @@ -39,11 +40,6 @@ import java.util.Set; * @author mike */ public class IdeaPluginConverter extends ResolvingConverter { - @NonNls private static final Set PLATFORM_MODULES = CollectionFactory.newTroveSet("com.intellij.modules.platform", - "com.intellij.modules.lang", - "com.intellij.modules.vcs", - "com.intellij.modules.xdebugger", - "com.intellij.modules.xml"); @NotNull public Collection getVariants(final ConvertContext context) { @@ -53,7 +49,13 @@ public class IdeaPluginConverter extends ResolvingConverter { @NotNull @Override public Set getAdditionalVariants(@NotNull final ConvertContext context) { - return PLATFORM_MODULES; + final THashSet result = new THashSet(); + for (IdeaPlugin ideaPlugin : getVariants(context)) { + for (PluginModule module : ideaPlugin.getModules()) { + ContainerUtil.addIfNotNull(module.getValue().getValue(), result); + } + } + return result; } @Override @@ -78,6 +80,10 @@ public class IdeaPluginConverter extends ResolvingConverter { final String otherId = ideaPlugin.getPluginId(); if (otherId == null) continue; if (otherId.equals(s)) return ideaPlugin; + for (PluginModule module : ideaPlugin.getModules()) { + final String moduleName = module.getValue().getValue(); + if (moduleName != null && moduleName.equals(s)) return ideaPlugin; + } } return null; } diff --git a/plugins/devkit/testData/codeInsight/DependsHighlighting.xml b/plugins/devkit/testData/codeInsight/DependsHighlighting.xml index 8f64ff62008b..243fc2fffcad 100644 --- a/plugins/devkit/testData/codeInsight/DependsHighlighting.xml +++ b/plugins/devkit/testData/codeInsight/DependsHighlighting.xml @@ -2,7 +2,7 @@ com.intellij.myPlugin com.intellij - com.intellij.modules.vcs + com.intellij.modules.vcs com.intellij.custom com.intellij.xxx diff --git a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java index b9a3ec0226ea..1a5ad0f47b4a 100644 --- a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java +++ b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.java @@ -67,6 +67,7 @@ public class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase { final String root = "idea_core"; addPluginXml(root, "\n" + " com.intellij\n" + + " \n" + ""); addPluginXml("custom", "\n" + " com.intellij.custom\n" + From e652e0ddca0a3914614e43553c4cea193d5af5f3 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 24 Jul 2010 13:43:24 +0100 Subject: [PATCH 058/102] IDEA-50729 Don't insert closing ) when typing before identifier or string in a custom file type similar things with quotes --- .../editorActions/TypedHandler.java | 24 +++++++++++-------- .../impl/CustomFileTypeBraceMatcher.java | 2 +- .../impl/CustomFileTypeQuoteHandler.java | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java index eed38f1a3d7b..f1a1ff3dac5c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java @@ -282,13 +282,13 @@ public class TypedHandler implements TypedActionHandler { if (!iterator.atEnd()) { iterator.advance(); - IElementType tokenType = iterator.atEnd() ? null : iterator.getTokenType(); - if (!BraceMatchingUtil.isPairedBracesAllowedBeforeTypeInFileType(braceTokenType, tokenType, fileType)) { - return; - } - - if (!iterator.atEnd() && BraceMatchingUtil.isLBraceToken(iterator, fileText, fileType)) { - return; + if (!iterator.atEnd()) { + if (!BraceMatchingUtil.isPairedBracesAllowedBeforeTypeInFileType(braceTokenType, iterator.getTokenType(), fileType)) { + return; + } + if (BraceMatchingUtil.isLBraceToken(iterator, fileText, fileType)) { + return; + } } iterator.retreat(); @@ -393,8 +393,9 @@ public class TypedHandler implements TypedActionHandler { int offset = editor.getCaretModel().getOffset(); - CharSequence chars = editor.getDocument().getCharsSequence(); - int length = editor.getDocument().getTextLength(); + final Document document = editor.getDocument(); + CharSequence chars = document.getCharsSequence(); + int length = document.getTextLength(); if (isTypingEscapeQuote(editor, quoteHandler, offset)) return false; if (offset < length && chars.charAt(offset) == quote){ @@ -424,7 +425,10 @@ public class TypedHandler implements TypedActionHandler { if (isOpeningQuote(editor, quoteHandler, offset - 1) && hasNonClosedLiterals(editor, quoteHandler, offset - 1)) { - editor.getDocument().insertString(offset, String.valueOf(quote)); + if (offset == document.getTextLength() || + !Character.isUnicodeIdentifierPart(document.getCharsSequence().charAt(offset))) { //any better heuristic or an API? + document.insertString(offset, String.valueOf(quote)); + } } return true; diff --git a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java index a33cd28629f0..1c099650b269 100644 --- a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java +++ b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeBraceMatcher.java @@ -80,7 +80,7 @@ class CustomFileTypeBraceMatcher implements BraceMatcher { } public boolean isPairedBracesAllowedBeforeType(@NotNull final IElementType lbraceType, @Nullable final IElementType contextType) { - return true; + return contextType == CustomHighlighterTokenType.WHITESPACE; } public int getCodeConstructStart(final PsiFile file, final int openingBraceOffset) { diff --git a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java index 2c9c64c8550b..277528d2bf8f 100644 --- a/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeQuoteHandler.java @@ -73,7 +73,7 @@ class CustomFileTypeQuoteHandler implements QuoteHandler { iterator.advance(); } } finally { - while(iterator.getStart() != offset) iterator.retreat(); + while (!iterator.atEnd() && iterator.getStart() != offset) iterator.retreat(); } return false; From df52d596d0e7f0b63b18a065ca82431a07decc3d Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Sat, 24 Jul 2010 21:47:53 +0400 Subject: [PATCH 059/102] use correct converter --- plugins/devkit/src/dom/Component.java | 2 ++ plugins/devkit/src/dom/Group.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/plugins/devkit/src/dom/Component.java b/plugins/devkit/src/dom/Component.java index c21a21f1ef18..0ec760843349 100644 --- a/plugins/devkit/src/dom/Component.java +++ b/plugins/devkit/src/dom/Component.java @@ -39,9 +39,11 @@ public interface Component extends DomElement { @NotNull @ExtendClass(instantiatable = false) + @Convert(PluginPsiClassConverter.class) GenericDomValue getInterfaceClass(); @NotNull + @Convert(PluginPsiClassConverter.class) GenericDomValue getHeadlessImplementationClass(); @NotNull diff --git a/plugins/devkit/src/dom/Group.java b/plugins/devkit/src/dom/Group.java index 0fc11ff8aa6d..451e036f551a 100644 --- a/plugins/devkit/src/dom/Group.java +++ b/plugins/devkit/src/dom/Group.java @@ -22,6 +22,7 @@ package org.jetbrains.idea.devkit.dom; import com.intellij.psi.PsiClass; import com.intellij.util.xml.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.impl.PluginPsiClassConverter; import java.util.List; @@ -66,6 +67,7 @@ public interface Group extends Actions { @com.intellij.util.xml.Attribute ("class") @ExtendClass(value = "com.intellij.openapi.actionSystem.ActionGroup", instantiatable = true, allowAbstract = false, allowInterface = false) + @Convert(PluginPsiClassConverter.class) GenericAttributeValue getClazz(); From a52e00b17fb42e174114531b8a595e6f8b6ffcae Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 24 Jul 2010 20:35:46 +0200 Subject: [PATCH 060/102] IDEA-55746 (EqualsWhichDoesntCheckParameterClass does not understand "isInstance") --- .../com/siyeh/HardcodedMethodConstants.java | 1 + .../ig/bugs/ParameterClassCheckVisitor.java | 56 ++++++++++++--- ...chDoesntCheckParameterClassInspection.java | 21 ------ .../EqualsWhichDoesntCheckParameterClass.java | 70 +++++++++++++++++++ .../expected.xml | 9 +++ ...esntCheckParameterClassInspectionTest.java | 27 +++++++ 6 files changed, 154 insertions(+), 30 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/EqualsWhichDoesntCheckParameterClassInspection.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/expected.xml create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspectionTest.java diff --git a/plugins/InspectionGadgets/src/com/siyeh/HardcodedMethodConstants.java b/plugins/InspectionGadgets/src/com/siyeh/HardcodedMethodConstants.java index 466f3b7ea992..48cc684756d7 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/HardcodedMethodConstants.java +++ b/plugins/InspectionGadgets/src/com/siyeh/HardcodedMethodConstants.java @@ -40,6 +40,7 @@ import org.jetbrains.annotations.NonNls; public static final String HAS_NEXT = "hasNext"; public static final String INDEX_OF = "indexOf"; public static final String JAVA_LANG = "java.lang"; + public static final String IS_INSTANCE = "isInstance"; public static final String ITERATOR = "iterator"; public static final String LAST_INDEX_OF = "lastIndexOf"; public static final String LENGTH = "length"; diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ParameterClassCheckVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ParameterClassCheckVisitor.java index 9dfe2a6ff3d5..1b5212991129 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ParameterClassCheckVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ParameterClassCheckVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,22 +43,60 @@ class ParameterClassCheckVisitor extends JavaRecursiveElementVisitor{ return; } super.visitMethodCallExpression(expression); + if (isGetClassCall(expression)) { + checked = true; + } else if (isGetInstanceCall(expression)) { + checked = true; + } + } + + private boolean isGetInstanceCall( + PsiMethodCallExpression methodCallExpression) { final PsiReferenceExpression methodExpression = - expression.getMethodExpression(); + methodCallExpression.getMethodExpression(); + final String methodName = methodExpression.getReferenceName(); + if (!HardcodedMethodConstants.IS_INSTANCE.equals(methodName)) { + return false; + } + final PsiMethod method = methodCallExpression.resolveMethod(); + final PsiClass aClass = method.getContainingClass(); + final String className = aClass.getQualifiedName(); + if (!"java.lang.Class".equals(className)) { + return false; + } + final PsiExpressionList argumentList = + methodCallExpression.getArgumentList(); + final PsiExpression[] expressions = argumentList.getExpressions(); + if (expressions.length != 1) { + return false; + } + final PsiExpression expression = expressions[0]; + return isParameterReference(expression); + } + + private boolean isGetClassCall( + PsiMethodCallExpression methodCallExpression) { + final PsiReferenceExpression methodExpression = + methodCallExpression.getMethodExpression(); final String methodName = methodExpression.getReferenceName(); if(!HardcodedMethodConstants.GET_CLASS.equals(methodName)){ - return; + return false; } - final PsiExpressionList argumentList = expression.getArgumentList(); + final PsiExpressionList argumentList = + methodCallExpression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); - if(arguments.length != 0){ - return; + if (arguments.length != 0) { + return false; + } + final PsiMethod method = methodCallExpression.resolveMethod(); + final PsiClass aClass = method.getContainingClass(); + final String className = aClass.getQualifiedName(); + if (!"java.lang.Object".equals(className)) { + return false; } final PsiExpression qualifier = methodExpression.getQualifierExpression(); - if(isParameterReference(qualifier)){ - checked = true; - } + return isParameterReference(qualifier); } @Override public void visitInstanceOfExpression( diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/EqualsWhichDoesntCheckParameterClassInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/EqualsWhichDoesntCheckParameterClassInspection.java deleted file mode 100644 index 0714ea42ae8b..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/EqualsWhichDoesntCheckParameterClassInspection.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.siyeh.igtest.bugs; - -public class EqualsWhichDoesntCheckParameterClassInspection { - private int foo; - - public boolean equals(Object o) { - if (this == o) return true; - //if (o instanceof EqualsWhichDoesntCheckParameterClassInspection) return false; - //if (getClass() != o.getClass()) return false; - - final EqualsWhichDoesntCheckParameterClassInspection equalsWhichDoesntCheckParameterClassInspection = (EqualsWhichDoesntCheckParameterClassInspection) o; - - if (foo != equalsWhichDoesntCheckParameterClassInspection.foo) return false; - - return true; - } - - public int hashCode() { - return foo; - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java new file mode 100644 index 000000000000..7bedea513d3e --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java @@ -0,0 +1,70 @@ +package com.siyeh.igtest.bugs.equals_which_doesnt_check_parameter; + +public class EqualsWhichDoesntCheckParameterClass { + private int foo; + + public boolean equals(Object o) { + if (this == o) return true; + //if (o instanceof EqualsWhichDoesntCheckParameterClassInspection) return false; + //if (getClass() != o.getClass()) return false; + + final EqualsWhichDoesntCheckParameterClass equalsWhichDoesntCheckParameterClass = (EqualsWhichDoesntCheckParameterClass) o; + + if (foo != equalsWhichDoesntCheckParameterClass.foo) return false; + + return true; + } + + public int hashCode() { + return foo; + } +} +class One { + private int one; + + @Override + public boolean equals(Object o) { + if (!(o instanceof One)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return one; + } +} +class Two { + private int two; + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return two; + } +} +class Three { + private int three; + + @Override + public boolean equals(Object o) { + if (!getClass().isInstance(o)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return three; + } +} + diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/expected.xml new file mode 100644 index 000000000000..536503764c14 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/expected.xml @@ -0,0 +1,9 @@ + + + + EqualsWhichDoesntCheckParameterClass.java + 6 + 'equals()' method which does not check class of parameter + <code>equals()</code> should check the class of its parameter #loc + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspectionTest.java new file mode 100644 index 000000000000..e8ec871426a1 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspectionTest.java @@ -0,0 +1,27 @@ +/* + * 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.siyeh.ig.bugs; + +import com.IGInspectionTestCase; + +public class EqualsWhichDoesntCheckParameterClassInspectionTest + extends IGInspectionTestCase { + + public void test() throws Exception { + doTest("com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter", + new EqualsWhichDoesntCheckParameterClassInspection()); + } +} From 62c1709b9a004dd6981b31254cc681211960a05e Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Sat, 24 Jul 2010 19:05:36 +0400 Subject: [PATCH 061/102] build flex stubs for indexing only once --- .../intellij/psi/stubs/StubUpdatingIndex.java | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index bf9dfab1df33..f20b020e2681 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -27,6 +27,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.LanguageFileType; +import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IFileElementType; @@ -126,24 +127,37 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi }; } + private static Key stubElementKey = Key.create("stub.tree.for.file.content"); + @Nullable - static StubElement buildStubTree(final FileContent inputData) { - final FileType fileType = inputData.getFileType(); + public static StubElement buildStubTree(final FileContent inputData) { + StubElement data = inputData.getUserData(stubElementKey); + if (data != null) return data; - if (fileType.isBinary()) { - final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); - assert builder != null; + synchronized (inputData) { + data = inputData.getUserData(stubElementKey); + if (data != null) return data; - return builder.buildStubTree(inputData.getFile(), inputData.getContent(), inputData.getProject()); + final FileType fileType = inputData.getFileType(); + + if (fileType.isBinary()) { + final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); + assert builder != null; + + data = builder.buildStubTree(inputData.getFile(), inputData.getContent(), inputData.getProject()); + } else { + final LanguageFileType filetype = (LanguageFileType)fileType; + Language l = filetype.getLanguage(); + final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType(); + + PsiFile psi = inputData.getPsiFile(); + + data = ((IStubFileElementType)type).getBuilder().buildStubTree(psi); + } + + inputData.putUserData(stubElementKey, data); + return data; } - - final LanguageFileType filetype = (LanguageFileType)fileType; - Language l = filetype.getLanguage(); - final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType(); - - PsiFile psi = inputData.getPsiFile(); - - return ((IStubFileElementType)type).getBuilder().buildStubTree(psi); } public KeyDescriptor getKeyDescriptor() { From d70a243bdbc04c617d2836dc25cc7b6617da41c5 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Sun, 25 Jul 2010 17:04:16 +0400 Subject: [PATCH 062/102] add converter on *Class attributes --- plugins/devkit/src/dom/impl/ExtensionDomExtender.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java index 0387e2fcc025..f23270e3ba6a 100644 --- a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java +++ b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java @@ -100,8 +100,7 @@ public class ExtensionDomExtender extends DomExtender { public void registerExtensions(@NotNull final DomElement domElement, @NotNull final DomExtensionsRegistrar registrar) { final String interfaceName = extensionPoint.getInterface().getStringValue(); if (interfaceName != null) { - registrar.registerGenericAttributeValueChildExtension(new XmlName("implementation"), PsiClass.class).setConverter( - CLASS_CONVERTER); + registrar.registerGenericAttributeValueChildExtension(new XmlName("implementation"), PsiClass.class).setConverter(CLASS_CONVERTER); final PsiClass implClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(interfaceName, GlobalSearchScope.allScope(manager.getProject())); @@ -136,6 +135,7 @@ public class ExtensionDomExtender extends DomExtender { private static void registerField(final DomExtensionsRegistrar registrar, @NotNull final PsiField field) { final PsiModifierList modifierList = field.getModifierList(); if (modifierList == null) return; + final String fieldName = field.getName(); final PsiConstantEvaluationHelper evalHelper = JavaPsiFacade.getInstance(field.getProject()).getConstantEvaluationHelper(); final PsiAnnotation attrAnno = modifierList.findAnnotation(Attribute.class.getName()); if (attrAnno != null) { @@ -145,7 +145,11 @@ public class ExtensionDomExtender extends DomExtender { PsiExpression expression = (PsiExpression)attributeName; final Object evaluatedExpression = evalHelper.computeConstantExpression(expression, false); if (evaluatedExpression != null) { - registrar.registerGenericAttributeValueChildExtension(new XmlName(evaluatedExpression.toString()), type); + final DomExtension extension = + registrar.registerGenericAttributeValueChildExtension(new XmlName(evaluatedExpression.toString()), type); + if (fieldName.length()>5 && fieldName.endsWith("Class")) { + extension.setConverter(new PluginPsiClassConverter()); + } } } return; From b4b519e86344b4808b90a042fa946c16425fc9fb Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Sun, 25 Jul 2010 18:03:38 +0400 Subject: [PATCH 063/102] do not index xml stuff in zip files and when no schema reference inside --- .../lang/xpath/xslt/impl/XsltSymbolIndex.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java index 49d229f70036..a6f7a518c616 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java @@ -19,6 +19,7 @@ package org.intellij.lang.xpath.xslt.impl; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; @@ -32,6 +33,7 @@ import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumDataDescriptor; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; +import com.intellij.util.text.CharArrayUtil; import com.intellij.util.xml.NanoXmlUtil; import org.intellij.lang.xpath.xslt.XsltSupport; import org.intellij.lang.xpath.xslt.psi.*; @@ -40,10 +42,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.ByteArrayInputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /* * Created by IntelliJ IDEA. @@ -90,6 +89,10 @@ public class XsltSymbolIndex extends FileBasedIndexExtension() { @NotNull public Map map(FileContent inputData) { + CharSequence inputDataContentAsText = inputData.getContentAsText(); + if (CharArrayUtil.indexOf(inputDataContentAsText, XsltSupport.XSLT_NS, 0) == -1) { + return Collections.emptyMap(); + } final HashMap map = new HashMap(); NanoXmlUtil.parse(new ByteArrayInputStream(inputData.getContent()), new NanoXmlUtil.IXMLBuilderAdapter() { NanoXmlUtil.IXMLBuilderAdapter attributeHandler; @@ -139,6 +142,9 @@ public class XsltSymbolIndex extends FileBasedIndexExtension Date: Sun, 25 Jul 2010 18:12:34 +0400 Subject: [PATCH 064/102] SQL: enter in comments --- .../intellij/codeInsight/editorActions/EnterHandler.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java index d1fd46e0a907..5f8f2360b1c2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java @@ -149,13 +149,15 @@ public class EnterHandler extends BaseEnterHandler { private static boolean isCommentComplete(PsiComment comment, CodeDocumentationAwareCommenter commenter) { String commentText = comment.getText(); - final String expectedCommentEnd = isDocComment(comment, commenter) ? commenter.getDocumentationCommentSuffix():commenter.getBlockCommentSuffix(); + final boolean docComment = isDocComment(comment, commenter); + final String expectedCommentEnd = docComment ? commenter.getDocumentationCommentSuffix():commenter.getBlockCommentSuffix(); if (!commentText.endsWith(expectedCommentEnd)) return false; final PsiFile containingFile = comment.getContainingFile(); final Language language = comment.getParent().getLanguage(); Lexer lexer = LanguageParserDefinitions.INSTANCE.forLanguage(language).createLexer(containingFile.getProject()); - lexer.start(commentText, commenter.getDocumentationCommentPrefix().length(), commentText.length()); + final String commentPrefix = docComment? commenter.getDocumentationCommentPrefix() : commenter.getBlockCommentPrefix(); + lexer.start(commentText, commentPrefix == null? 0 : commentPrefix.length(), commentText.length()); QuoteHandler fileTypeHandler = TypedHandler.getQuoteHandler(containingFile); JavaLikeQuoteHandler javaLikeQuoteHandler = fileTypeHandler instanceof JavaLikeQuoteHandler ? (JavaLikeQuoteHandler)fileTypeHandler:null; From bf78f508fb5a26f52aef699b932ea2cb44932b75 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Sun, 25 Jul 2010 18:41:56 +0400 Subject: [PATCH 065/102] minor fix --- resources/src/META-INF/IdeaPlugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index cb94afd07460..3798aaae98e2 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -82,7 +82,7 @@ interface="com.intellij.debugger.engine.JVMDebugProvider"/> + interface="com.intellij.execution.runners.JavaProgramPatcher"/> From b215721ec8dd8305a1c74e7a69a5329fb8df45b3 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Mon, 26 Jul 2010 11:54:51 +0400 Subject: [PATCH 066/102] more class converters --- .../psi/PsiReferenceProviderBean.java | 2 +- .../src/dom/impl/ExtensionDomExtender.java | 22 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/PsiReferenceProviderBean.java b/platform/lang-impl/src/com/intellij/psi/PsiReferenceProviderBean.java index 70a54020c424..ec4b893043c5 100644 --- a/platform/lang-impl/src/com/intellij/psi/PsiReferenceProviderBean.java +++ b/platform/lang-impl/src/com/intellij/psi/PsiReferenceProviderBean.java @@ -27,7 +27,7 @@ import org.jetbrains.annotations.Nullable; public class PsiReferenceProviderBean extends AbstractExtensionPointBean { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiReferenceProviderBean"); - @Tag("className") + @Attribute("providerClass") public String className; @Tag("description") public String description; diff --git a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java index f23270e3ba6a..c4f7df3613da 100644 --- a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java +++ b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java @@ -139,17 +139,12 @@ public class ExtensionDomExtender extends DomExtender { final PsiConstantEvaluationHelper evalHelper = JavaPsiFacade.getInstance(field.getProject()).getConstantEvaluationHelper(); final PsiAnnotation attrAnno = modifierList.findAnnotation(Attribute.class.getName()); if (attrAnno != null) { - final PsiAnnotationMemberValue attributeName = attrAnno.findAttributeValue("value"); - if (attributeName != null && attributeName instanceof PsiExpression) { - final Class type = String.class; - PsiExpression expression = (PsiExpression)attributeName; - final Object evaluatedExpression = evalHelper.computeConstantExpression(expression, false); - if (evaluatedExpression != null) { - final DomExtension extension = - registrar.registerGenericAttributeValueChildExtension(new XmlName(evaluatedExpression.toString()), type); - if (fieldName.length()>5 && fieldName.endsWith("Class")) { - extension.setConverter(new PluginPsiClassConverter()); - } + final String attrName = getStringAttribute(attrAnno, "value", evalHelper); + if (attrName != null) { + final DomExtension extension = + registrar.registerGenericAttributeValueChildExtension(new XmlName(attrName), String.class); + if (fieldName.endsWith("Class")) { + extension.setConverter(CLASS_CONVERTER); } } return; @@ -162,7 +157,10 @@ public class ExtensionDomExtender extends DomExtender { propAnno != null && getBooleanAttribute(propAnno, "surroundWithTag", evalHelper)? Constants.OPTION : null; if (tagName != null) { if (absColAnno == null) { - registrar.registerFixedNumberChildExtension(new XmlName(tagName), SimpleTagValue.class); + final DomExtension extension = registrar.registerFixedNumberChildExtension(new XmlName(tagName), SimpleTagValue.class); + if (fieldName.endsWith("Class")) { + extension.setConverter(CLASS_CONVERTER); + } } else { registrar.registerFixedNumberChildExtension(new XmlName(tagName), DomElement.class).addExtender(new DomExtender() { From 39ad10acc02930e0ac9235e99852bc9bd9e6e243 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 18:06:37 +0400 Subject: [PATCH 067/102] eclipse: do not make writable unchanged files (IDEA-54951) --- .../roots/impl/storage/ClasspathStorage.java | 25 +++++++++++++------ .../openapi/roots/impl/storage/FileSet.java | 3 +++ .../eclipse/config/CachedXmlDocumentSet.java | 19 +++++++++++--- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java index e54ee4ccecd7..da85b9a01c41 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java @@ -199,19 +199,23 @@ public class ClasspathStorage implements StateStorage { } public Collection getStorageFilesToSave() throws StateStorageException { - return needsSave() ? getAllStorageFiles() : Collections.emptyList(); + if (needsSave()) { + final List list = new ArrayList(); + final ArrayList virtualFiles = new ArrayList(); + getFileSet().listModifiedFiles(virtualFiles); + convert2Io(list, virtualFiles); + return list; + } + else { + return Collections.emptyList(); + } } public List getAllStorageFiles() { final List list = new ArrayList(); final ArrayList virtualFiles = new ArrayList(); getFileSet().listFiles(virtualFiles); - - for (VirtualFile virtualFile : virtualFiles) { - final File ioFile = VfsUtil.virtualToIoFile(virtualFile); - list.add(FileSystem.FILE_SYSTEM.createFile(ioFile.getAbsolutePath())); - } - + convert2Io(list, virtualFiles); return list; } }; @@ -220,6 +224,13 @@ public class ClasspathStorage implements StateStorage { return session; } + private static void convert2Io(List list, ArrayList virtualFiles) { + for (VirtualFile virtualFile : virtualFiles) { + final File ioFile = VfsUtil.virtualToIoFile(virtualFile); + list.add(FileSystem.FILE_SYSTEM.createFile(ioFile.getAbsolutePath())); + } + } + public void finishSave(final SaveSession saveSession) { try { LOG.assertTrue(mySession == saveSession); diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/FileSet.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/FileSet.java index 8ca2b9848395..9fc5e9fbdc80 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/FileSet.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/FileSet.java @@ -17,8 +17,10 @@ package com.intellij.openapi.roots.impl.storage; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.io.fs.IFile; import java.io.IOException; +import java.util.Collection; import java.util.List; public interface FileSet { @@ -28,4 +30,5 @@ public interface FileSet { void commit() throws IOException; + void listModifiedFiles(List list); } diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/CachedXmlDocumentSet.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/CachedXmlDocumentSet.java index 8b81adf3b2fd..548d19048989 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/CachedXmlDocumentSet.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/CachedXmlDocumentSet.java @@ -23,6 +23,7 @@ import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.HashMap; +import com.intellij.util.io.fs.IFile; import org.jdom.Document; import org.jdom.JDOMException; import org.jdom.output.EclipseJDOMUtil; @@ -30,10 +31,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.*; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class CachedXmlDocumentSet implements FileSet { protected final Map nameToDir = new HashMap(); @@ -183,6 +181,19 @@ public class CachedXmlDocumentSet implements FileSet { } } + @Override + public void listModifiedFiles(List list) { + for (String key : modifiedContent.keySet()) { + try { + if (hasChanged(key)) { + list.add(getOrCreateVFile(key)); + } + } + catch (IOException ignore) { + } + } + } + public boolean hasChanged() { for (String key : modifiedContent.keySet()) { if (hasChanged(key)) { From 19e299f9ed05436f7c432125f88aa5021b4f1adb Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 18:55:11 +0400 Subject: [PATCH 068/102] testframework: make test proxy disposable --- .../execution/testframework/AbstractTestProxy.java | 9 +++++++++ .../execution/testframework/CompositePrintable.java | 9 ++++++++- .../intellij/execution/testframework/TestTreeView.java | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java index 4f78a229d8a8..0acc7f978cb4 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java @@ -24,6 +24,7 @@ import com.intellij.execution.Location; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.pom.Navigatable; import java.util.List; @@ -82,4 +83,12 @@ public abstract class AbstractTestProxy extends CompositePrintable { super.addLast(printable); fireOnNewPrintable(printable); } + + @Override + public void dispose() { + super.dispose(); + for (AbstractTestProxy proxy : getChildren()) { + Disposer.dispose(proxy); + } + } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java index e1ccc285041c..18035b78ff2d 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/CompositePrintable.java @@ -15,11 +15,13 @@ */ package com.intellij.execution.testframework; +import com.intellij.openapi.Disposable; + import java.util.ArrayList; import java.util.List; -public class CompositePrintable implements Printable { +public class CompositePrintable implements Printable, Disposable { public static final String NEW_LINE = "\n"; protected final ArrayList myNestedPrintables = new ArrayList(); @@ -45,5 +47,10 @@ public class CompositePrintable implements Printable { printable.printOn(console); } } + + @Override + public void dispose() { + clear(); + } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java index 24d681c68a72..c7159cef636a 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java @@ -54,6 +54,7 @@ public abstract class TestTreeView extends Tree implements DataProvider { setModel(new DefaultTreeModel(new DefaultMutableTreeNode(model.getRoot()))); getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); myModel = model; + Disposer.register(myModel, myModel.getRoot()); Disposer.register(myModel, new Disposable() { public void dispose() { setModel(null); From 5c430dd73a96af726e651b0a7f4c323fabe65967 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 20:49:21 +0400 Subject: [PATCH 069/102] create getter from usage: return type fixed when field with name already exist --- .../impl/quickfix/CreatePropertyFromUsageFix.java | 5 +++-- .../createMethodFromUsage/afterExistingField.java | 11 +++++++++++ .../createMethodFromUsage/beforeExistingField.java | 7 +++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterExistingField.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeExistingField.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java index 7315e1dcf7c1..229c972c126c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java @@ -187,8 +187,9 @@ public class CreatePropertyFromUsageFix extends CreateFromUsageBaseFix { LOG.assertTrue(callText != null, myMethodCall.getMethodExpression()); PsiType[] expectedTypes; PsiType type; + PsiField field = targetClass.findFieldByName(fieldName, true); if (callText.startsWith(GET_PREFIX)) { - expectedTypes = CreateFromUsageUtils.guessType(myMethodCall, false); + expectedTypes = field != null ? new PsiType[]{field.getType()} : CreateFromUsageUtils.guessType(myMethodCall, false); type = expectedTypes[0]; } else if (callText.startsWith(IS_PREFIX)) { @@ -206,7 +207,7 @@ public class CreatePropertyFromUsageFix extends CreateFromUsageBaseFix { IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace(); try { - PsiField field = targetClass.findFieldByName(fieldName, true); + if (field == null) { field = factory.createField(fieldName, type); PsiUtil.setModifierProperty(field, PsiModifier.STATIC, isStatic); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterExistingField.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterExistingField.java new file mode 100644 index 000000000000..0bf86ed32308 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterExistingField.java @@ -0,0 +1,11 @@ +// "Create Getter" "true" +public class Test { + Integer field; + public foo() { + getField(); + } + + public Integer getField() { + return field; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeExistingField.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeExistingField.java new file mode 100644 index 000000000000..a1ca74ebdc0d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeExistingField.java @@ -0,0 +1,7 @@ +// "Create Getter" "true" +public class Test { + Integer field; + public foo() { + getField(); + } +} From 353f331ea780cbaf590f3cd71d0416f0c19e4398 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 23 Jul 2010 21:29:33 +0400 Subject: [PATCH 070/102] safe delete: delete method hierarchy down to the bottom --- .../safeDelete/JavaSafeDeleteProcessor.java | 8 +++++--- .../methodDeepHierarchy/after/Super.java | 9 +++++++++ .../methodDeepHierarchy/before/Super.java | 19 +++++++++++++++++++ .../intellij/refactoring/SafeDeleteTest.java | 5 +++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/refactoring/safeDelete/methodDeepHierarchy/after/Super.java create mode 100644 java/java-tests/testData/refactoring/safeDelete/methodDeepHierarchy/before/Super.java diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java index ff55de638015..84848acce924 100644 --- a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java @@ -427,7 +427,7 @@ public class JavaSafeDeleteProcessor implements SafeDeleteProcessorDelegate { break; } } - if (!anyOverridingRefs && isMultipleInterfacesImplementation(overridingMethod, allElementsToDelete)) { + if (!anyOverridingRefs && isMultipleInterfacesImplementation(overridingMethod, originalMethod, allElementsToDelete)) { anyOverridingRefs = true; multipleInterfaceImplementations.add(overridingMethod); } @@ -468,10 +468,12 @@ public class JavaSafeDeleteProcessor implements SafeDeleteProcessorDelegate { return validOverriding; } - private static boolean isMultipleInterfacesImplementation(final PsiMethod method, final PsiElement[] allElementsToDelete) { + private static boolean isMultipleInterfacesImplementation(final PsiMethod method, + PsiMethod originalMethod, + final PsiElement[] allElementsToDelete) { final PsiMethod[] methods = method.findSuperMethods(); for(PsiMethod superMethod: methods) { - if (ArrayUtil.find(allElementsToDelete, superMethod) < 0) { + if (ArrayUtil.find(allElementsToDelete, superMethod) < 0 && !MethodSignatureUtil.isSuperMethod(originalMethod, superMethod)) { return true; } } diff --git a/java/java-tests/testData/refactoring/safeDelete/methodDeepHierarchy/after/Super.java b/java/java-tests/testData/refactoring/safeDelete/methodDeepHierarchy/after/Super.java new file mode 100644 index 000000000000..c8d653af0ae2 --- /dev/null +++ b/java/java-tests/testData/refactoring/safeDelete/methodDeepHierarchy/after/Super.java @@ -0,0 +1,9 @@ +public class Super { + +} + +class Child extends Super { + } + +class ChildChild extends Child { + } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/safeDelete/methodDeepHierarchy/before/Super.java b/java/java-tests/testData/refactoring/safeDelete/methodDeepHierarchy/before/Super.java new file mode 100644 index 000000000000..ee8fa046f87a --- /dev/null +++ b/java/java-tests/testData/refactoring/safeDelete/methodDeepHierarchy/before/Super.java @@ -0,0 +1,19 @@ +public class Super { + void foo() { + } + +} + +class Child extends Super { + void foo(){ + super.foo(); + System.out.println("do some staff"); + } +} + +class ChildChild extends Child { + void foo(){ + super.foo(); + System.out.println("here do smth else"); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java index 499e9a281a32..add28931cb5b 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java @@ -82,6 +82,11 @@ public class SafeDeleteTest extends MultiFileTestCase { doTest("Super"); } + public void testMethodDeepHierarchy() throws Exception { + myDoCompare = false; + doTest("Super"); + } + public void testLocalVariableSideEffect() throws Exception { myDoCompare = false; try { From 3eb87ecf10cf17c1a888f7a2000e519352794a1e Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 23 Jul 2010 19:26:17 +0400 Subject: [PATCH 071/102] BaseJspFileImpl refactored --- .../src/com/intellij/lang/jsp/JspFileViewProvider.java | 5 ----- .../src/com/intellij/psi/jsp/BaseJspFile.java | 4 ++++ .../templateLanguages/TemplateLanguageFileViewProvider.java | 2 ++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspFileViewProvider.java b/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspFileViewProvider.java index d0bb429508c0..b92a311519b4 100644 --- a/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspFileViewProvider.java +++ b/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspFileViewProvider.java @@ -16,17 +16,12 @@ package com.intellij.lang.jsp; -import com.intellij.lang.Language; -import org.jetbrains.annotations.NotNull; - import java.util.Set; /** * @author ik */ public interface JspFileViewProvider extends JspxFileViewProvider { - @NotNull - Language getTemplateDataLanguage(); Set getKnownTaglibPrefixes(); } diff --git a/java/jsp-base-openapi/src/com/intellij/psi/jsp/BaseJspFile.java b/java/jsp-base-openapi/src/com/intellij/psi/jsp/BaseJspFile.java index 08e182bfc842..4b39c8b346d9 100644 --- a/java/jsp-base-openapi/src/com/intellij/psi/jsp/BaseJspFile.java +++ b/java/jsp-base-openapi/src/com/intellij/psi/jsp/BaseJspFile.java @@ -34,6 +34,10 @@ public interface BaseJspFile extends XmlFile { XmlTag[] getDirectiveTags(JspDirectiveKind directiveKind, final boolean searchInIncludes); XmlTag createDirective(XmlTag context, JspDirectiveKind directiveKind); + /** + * Method with a bad name. Returns file corresponding to getTemplateDataLanguage() method of ViewProvider + * @see com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider#getTemplateDataLanguage() + */ PsiFile getBaseLanguageRoot(); /** * @return file which the errorPage directive references, diff --git a/platform/lang-api/src/com/intellij/psi/templateLanguages/TemplateLanguageFileViewProvider.java b/platform/lang-api/src/com/intellij/psi/templateLanguages/TemplateLanguageFileViewProvider.java index f14a9f662771..9ba8f9191692 100644 --- a/platform/lang-api/src/com/intellij/psi/templateLanguages/TemplateLanguageFileViewProvider.java +++ b/platform/lang-api/src/com/intellij/psi/templateLanguages/TemplateLanguageFileViewProvider.java @@ -25,12 +25,14 @@ import org.jetbrains.annotations.NotNull; public interface TemplateLanguageFileViewProvider extends FileViewProvider { /** + * e.g. JSP * @return instanceof {@link com.intellij.psi.templateLanguages.TemplateLanguage} */ @NotNull Language getBaseLanguage(); /** + * e.g. HTML for JSP files * @return not instanceof {@link com.intellij.lang.DependentLanguage} */ @NotNull From b416fed872d56c3f482ef51d9dc5b1a89f497f4e Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Mon, 26 Jul 2010 13:17:57 +0400 Subject: [PATCH 072/102] ProcessHandler: synchronization problem fixed --- .../src/com/intellij/execution/process/ProcessHandler.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/execution/process/ProcessHandler.java b/platform/platform-api/src/com/intellij/execution/process/ProcessHandler.java index 2bc018efdd6a..dc78a8c950fa 100644 --- a/platform/platform-api/src/com/intellij/execution/process/ProcessHandler.java +++ b/platform/platform-api/src/com/intellij/execution/process/ProcessHandler.java @@ -52,7 +52,7 @@ public abstract class ProcessHandler extends UserDataHolderBase { myWaitSemaphore.down(); } - public void startNotify() { + public synchronized void startNotify() { if(myState.compareAndSet(STATE_INITIAL, STATE_RUNNING)) { myEventMulticaster.startNotified(new ProcessEvent(this)); } @@ -173,7 +173,7 @@ public abstract class ProcessHandler extends UserDataHolderBase { myEventMulticaster.processWillTerminate(new ProcessEvent(this), willBeDestroyed); } - private void afterStartNotified(final Runnable runnable) { + private synchronized void afterStartNotified(final Runnable runnable) { if (isStartNotified()) { runnable.run(); } @@ -184,7 +184,6 @@ public abstract class ProcessHandler extends UserDataHolderBase { runnable.run(); } }); - assert !isStartNotified(); } } From 222e2cb2233b4edc0270be36d41c6c9bf5f0491e Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Mon, 26 Jul 2010 11:17:47 +0400 Subject: [PATCH 073/102] CIDR-debugger: error reporting refactored --- .../src/com/intellij/util/ExceptionUtil.java | 36 +++++++++++++++++++ .../util/concurrency/FutureResult.java | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 platform/util/src/com/intellij/util/ExceptionUtil.java diff --git a/platform/util/src/com/intellij/util/ExceptionUtil.java b/platform/util/src/com/intellij/util/ExceptionUtil.java new file mode 100644 index 000000000000..87723dad03c6 --- /dev/null +++ b/platform/util/src/com/intellij/util/ExceptionUtil.java @@ -0,0 +1,36 @@ +/* + * 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.util; + +public class ExceptionUtil { + public static Throwable getRootCause(Throwable e) { + while (true) { + if (e.getCause() == null) return e; + e = e.getCause(); + } + } + + public static T findCause(Throwable e, Class klass) { + while (e != null && !klass.isInstance(e)) { + e = e.getCause(); + } + return (T)e; + } + + public static boolean causedBy(Throwable e, Class klass) { + return findCause(e, klass) != null; + } +} diff --git a/platform/util/src/com/intellij/util/concurrency/FutureResult.java b/platform/util/src/com/intellij/util/concurrency/FutureResult.java index 356ec5845238..0f115e660b16 100644 --- a/platform/util/src/com/intellij/util/concurrency/FutureResult.java +++ b/platform/util/src/com/intellij/util/concurrency/FutureResult.java @@ -58,7 +58,7 @@ public class FutureResult implements Future { private T doGet() throws ExecutionException { Pair pair = myValue.get(); - if (!pair.second) throw new ExecutionException((Throwable)pair.first); + if (!pair.second) throw new ExecutionException(((Throwable)pair.first).getMessage(), (Throwable)pair.first); return (T)pair.first; } } From d73223c48d9cfc5918bc767902a73c9e3947918b Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Mon, 26 Jul 2010 13:50:11 +0400 Subject: [PATCH 074/102] compilation fix --- .../codeInsight/completion/JavaSmartCompletionContributor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index e1c7d5cbba5d..32808d2f7520 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.*; +import com.intellij.codeInsight.ExceptionUtil; import com.intellij.codeInsight.lookup.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Computable; From 5a15094db67339818443bd441f9423be9691e60b Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 26 Jul 2010 14:02:50 +0400 Subject: [PATCH 075/102] Revert "[config cleanup] fix eclipse tests" This reverts commit eb4b2698091729af6602aedb408c105553fdecee. --- plugins/eclipse/testData/iml/allProps/expected/expected.iml | 4 ++++ plugins/eclipse/testData/iml/emptySrc/expected/expected.iml | 1 + .../testData/iml/resolvedVariables/expected/expected.iml | 2 ++ 3 files changed, 7 insertions(+) diff --git a/plugins/eclipse/testData/iml/allProps/expected/expected.iml b/plugins/eclipse/testData/iml/allProps/expected/expected.iml index 03ebc91eb508..e859b2f34993 100644 --- a/plugins/eclipse/testData/iml/allProps/expected/expected.iml +++ b/plugins/eclipse/testData/iml/allProps/expected/expected.iml @@ -94,6 +94,8 @@ + +
@@ -101,6 +103,8 @@ + +
diff --git a/plugins/eclipse/testData/iml/emptySrc/expected/expected.iml b/plugins/eclipse/testData/iml/emptySrc/expected/expected.iml index 6043d6eda204..739c0f9ea674 100644 --- a/plugins/eclipse/testData/iml/emptySrc/expected/expected.iml +++ b/plugins/eclipse/testData/iml/emptySrc/expected/expected.iml @@ -12,6 +12,7 @@ + diff --git a/plugins/eclipse/testData/iml/resolvedVariables/expected/expected.iml b/plugins/eclipse/testData/iml/resolvedVariables/expected/expected.iml index 24c383002455..0eced5ed6f50 100644 --- a/plugins/eclipse/testData/iml/resolvedVariables/expected/expected.iml +++ b/plugins/eclipse/testData/iml/resolvedVariables/expected/expected.iml @@ -12,6 +12,7 @@ + @@ -22,6 +23,7 @@ + From 8b760079e9495cc4cb55d8e6c1bd2660f70003b9 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 26 Jul 2010 14:03:38 +0400 Subject: [PATCH 076/102] Revert "config cleanup" This reverts commit 4b386e9af0eee047f065155ace4ba792e124b8ca. --- .../com/intellij/openapi/roots/impl/libraries/LibraryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index 762e7b6bd738..091ccf348d86 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -277,7 +277,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { if (roots.size() == 0 && rootType.skipWriteIfEmpty()) continue; //compatibility iml/ipr final Element rootTypeElement = new Element(rootType.name()); roots.writeExternal(rootTypeElement, ROOT_PATH_ELEMENT); - if (rootTypeElement.getAttributes().size() > 0 || rootTypeElement.getContent().size() > 0) element.addContent(rootTypeElement); + element.addContent(rootTypeElement); } List urls = new ArrayList(myJarDirectories.keySet()); Collections.sort(urls, new Comparator() { From d72e0273c40c5630ce437c7ca6bd8599aa733057 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 26 Jul 2010 14:04:34 +0400 Subject: [PATCH 077/102] Revert "idea config cleanup" This reverts commit dccb1f8f664ac81e104e9b5e358c16cbf6090bb0. --- java/compiler/impl/compiler-impl.iml | 2 ++ .../intellij/roots/libraries/LibraryTest.java | 2 +- plugins/cvs/cvs-core/cvs-core.iml | 1 + plugins/git4idea/git4idea.iml | 1 + plugins/groovy/jetgroovy.iml | 2 ++ plugins/maven/facade-api/maven-facade-api.iml | 2 ++ .../maven/facade-impl/maven-facade-impl.iml | 28 +++++++++++++++++++ plugins/relaxng/relaxng.iml | 7 +++++ plugins/svn4idea/svn4idea-tests.iml | 3 ++ plugins/svn4idea/svn4idea.iml | 5 ++++ 10 files changed, 52 insertions(+), 1 deletion(-) diff --git a/java/compiler/impl/compiler-impl.iml b/java/compiler/impl/compiler-impl.iml index 381f3496886b..4f7473c9ff2a 100644 --- a/java/compiler/impl/compiler-impl.iml +++ b/java/compiler/impl/compiler-impl.iml @@ -23,6 +23,8 @@ + +
diff --git a/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java b/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java index b1bbd7a29e74..a9578c24654e 100644 --- a/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java @@ -47,7 +47,7 @@ public class LibraryTest extends IdeaTestCase { final Element element = new Element("root"); library.writeExternal(element); - assertEquals("", + assertEquals("", new XMLOutputter().outputString(element)); ApplicationManager.getApplication().runWriteAction(new Runnable() { diff --git a/plugins/cvs/cvs-core/cvs-core.iml b/plugins/cvs/cvs-core/cvs-core.iml index f170b4099106..53189febbd11 100644 --- a/plugins/cvs/cvs-core/cvs-core.iml +++ b/plugins/cvs/cvs-core/cvs-core.iml @@ -15,6 +15,7 @@ + diff --git a/plugins/git4idea/git4idea.iml b/plugins/git4idea/git4idea.iml index 5fa1b17970c1..aa21265058b8 100644 --- a/plugins/git4idea/git4idea.iml +++ b/plugins/git4idea/git4idea.iml @@ -16,6 +16,7 @@ + diff --git a/plugins/groovy/jetgroovy.iml b/plugins/groovy/jetgroovy.iml index 3ead47ab4a1e..3b210de157c4 100644 --- a/plugins/groovy/jetgroovy.iml +++ b/plugins/groovy/jetgroovy.iml @@ -26,6 +26,8 @@ + + diff --git a/plugins/maven/facade-api/maven-facade-api.iml b/plugins/maven/facade-api/maven-facade-api.iml index 56173f227d95..8ba63b8dc7db 100644 --- a/plugins/maven/facade-api/maven-facade-api.iml +++ b/plugins/maven/facade-api/maven-facade-api.iml @@ -14,6 +14,8 @@ + + diff --git a/plugins/maven/facade-impl/maven-facade-impl.iml b/plugins/maven/facade-impl/maven-facade-impl.iml index ae61f67a346f..9240cd8ba91c 100644 --- a/plugins/maven/facade-impl/maven-facade-impl.iml +++ b/plugins/maven/facade-impl/maven-facade-impl.iml @@ -16,6 +16,8 @@ + + @@ -23,6 +25,8 @@ + + @@ -30,6 +34,8 @@ + + @@ -37,6 +43,8 @@ + + @@ -44,6 +52,8 @@ + + @@ -51,6 +61,8 @@ + + @@ -58,6 +70,8 @@ + + @@ -65,6 +79,8 @@ + + @@ -72,6 +88,8 @@ + + @@ -79,6 +97,8 @@ + + @@ -86,6 +106,8 @@ + + @@ -93,6 +115,8 @@ + + @@ -100,6 +124,8 @@ + + @@ -107,6 +133,8 @@ + + diff --git a/plugins/relaxng/relaxng.iml b/plugins/relaxng/relaxng.iml index 6ff34b95fc39..d7d35d40c904 100644 --- a/plugins/relaxng/relaxng.iml +++ b/plugins/relaxng/relaxng.iml @@ -18,6 +18,7 @@ + @@ -28,6 +29,8 @@ + + @@ -35,6 +38,8 @@ + + @@ -42,6 +47,8 @@ + + diff --git a/plugins/svn4idea/svn4idea-tests.iml b/plugins/svn4idea/svn4idea-tests.iml index 5039b6b4a9f5..798757278775 100644 --- a/plugins/svn4idea/svn4idea-tests.iml +++ b/plugins/svn4idea/svn4idea-tests.iml @@ -16,6 +16,7 @@ + @@ -29,6 +30,8 @@ + + diff --git a/plugins/svn4idea/svn4idea.iml b/plugins/svn4idea/svn4idea.iml index e00b72d68d9c..fd765b400568 100644 --- a/plugins/svn4idea/svn4idea.iml +++ b/plugins/svn4idea/svn4idea.iml @@ -22,6 +22,7 @@ + @@ -32,6 +33,8 @@ + + @@ -40,6 +43,8 @@ + + From 21ed12d96a6983b9416dcf9deca39ba79dc9a145 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 26 Jul 2010 14:35:36 +0400 Subject: [PATCH 078/102] fix ModuleRootsExternalizationTest --- .../com/intellij/roots/ModuleRootsExternalizationTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/java-tests/testSrc/com/intellij/roots/ModuleRootsExternalizationTest.java b/java/java-tests/testSrc/com/intellij/roots/ModuleRootsExternalizationTest.java index a8b32cbc3614..3850ea4052e6 100644 --- a/java/java-tests/testSrc/com/intellij/roots/ModuleRootsExternalizationTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/ModuleRootsExternalizationTest.java @@ -159,11 +159,15 @@ public class ModuleRootsExternalizationTest extends ModuleTestCase { "" + "" + "" + + "" + + "" + "" + "" + "" + "" + "" + + "" + + "" + "" + "" + "", module); From 66048ee5482c20ae6b1978dcb4947990e4bbf66c Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 26 Jul 2010 16:39:56 +0400 Subject: [PATCH 079/102] Fix: IDEA-56788 (Grails, GSP: plugin taglibs are no more resolved from application's .gsp files) --- .../intellij/util/containers/MultiMap.java | 74 ++++++++++++++++++- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/MultiMap.java b/platform/util/src/com/intellij/util/containers/MultiMap.java index d8e5dcd4b838..57af35d547d0 100644 --- a/platform/util/src/com/intellij/util/containers/MultiMap.java +++ b/platform/util/src/com/intellij/util/containers/MultiMap.java @@ -25,8 +25,17 @@ import java.util.*; */ public class MultiMap { + public static final MultiMap EMPTY = new MultiMap() { + @Override + protected Map createMap() { + return Collections.emptyMap(); + } + }; + private final Map> myMap; + private Collection values; + public MultiMap() { myMap = createMap(); } @@ -117,11 +126,64 @@ public class MultiMap { } public Collection values() { - ArrayList result = new ArrayList(); - for (Collection vs : myMap.values()) { - result.addAll(vs); + if (values == null) { + values = new AbstractCollection() { + @Override + public Iterator iterator() { + return new Iterator() { + + private Iterator> mapIterator = myMap.values().iterator(); + + private Iterator itr = EmptyIterator.getInstance(); + + @Override + public boolean hasNext() { + do { + if (itr.hasNext()) return true; + if (!mapIterator.hasNext()) return false; + itr = mapIterator.next().iterator(); + } while (true); + } + + @Override + public V next() { + do { + if (itr.hasNext()) return itr.next(); + if (!mapIterator.hasNext()) throw new NoSuchElementException(); + itr = mapIterator.next().iterator(); + } while (true); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public int size() { + int res = 0; + for (Collection vs : myMap.values()) { + res += vs.size(); + } + + return res; + } + + // Don't remove this method!!! + @Override + public boolean contains(Object o) { + for (Collection vs : myMap.values()) { + if (vs.contains(o)) return true; + } + + return false; + } + }; } - return result; + + return values; } public void clear() { @@ -131,4 +193,8 @@ public class MultiMap { public Collection remove(K key) { return myMap.remove(key); } + + public static MultiMap emptyInstance() { + return EMPTY; + } } From 12846f12040b308055b74598a2a3ff6ff663f851 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 26 Jul 2010 16:29:30 +0400 Subject: [PATCH 080/102] dependencies are searched for inside CompileDriver --- .../intellij/compiler/impl/CompileDriver.java | 265 +++++++++++++----- .../impl/TranslatingCompilerFilesMonitor.java | 36 ++- .../javaCompiler/BackendCompilerWrapper.java | 171 ++--------- .../intellij/compiler/make/CacheUtils.java | 19 ++ 4 files changed, 277 insertions(+), 214 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index b1f30cf4e2e5..dff37de3da1f 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -77,15 +77,13 @@ import com.intellij.psi.PsiCompiledElement; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; -import com.intellij.util.Chunk; -import com.intellij.util.LocalTimeCounter; -import com.intellij.util.StringBuilderSpinAllocator; -import com.intellij.util.ThrowableRunnable; +import com.intellij.util.*; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.OrderedSet; +import gnu.trove.TIntHashSet; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -957,70 +955,145 @@ public class CompileDriver { final Set generatedTypes = new HashSet(); Collection chunkFiles = chunkMap.get(currentChunk); try { - for (int currentCompiler = 0, translatorsLength = translators.length; currentCompiler < translatorsLength; currentCompiler++) { - sink.setCurrentCompilerIndex(currentCompiler); - final TranslatingCompiler compiler = translators[currentCompiler]; - if (context.getProgressIndicator().isCanceled()) { - throw new ExitException(ExitStatus.CANCELLED); - } - - DumbService.getInstance(myProject).waitForSmartMode(); - - if (snapshot == null || ContainerUtil.intersects(generatedTypes, compilerManager.getRegisteredInputTypes(compiler))) { - // rescan snapshot if previously generated files may influence the input of this compiler - snapshot = ApplicationManager.getApplication().runReadAction(new Computable() { - public VirtualFile[] compute() { - return context.getCompileScope().getFiles(null, true); - } - }); - final Map> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(context, snapshot); - for (Chunk moduleChunk : sortedChunks) { - List files = Collections.emptyList(); - for (Module module : moduleChunk.getNodes()) { - final List moduleFiles = moduleToFilesMap.get(module); - if (moduleFiles != null) { - files = ContainerUtil.concat(files, moduleFiles); - } - } - chunkMap.put(moduleChunk, files); + int round = 0; + final Set filesToRecompile = new HashSet(); + final Set allDependent = new HashSet(); + Collection dependentFiles = Collections.emptyList(); + final Function>, Pair>> dependencyFilter = new DependentClassesCumulativeFilter(); + + do { + for (int currentCompiler = 0, translatorsLength = translators.length; currentCompiler < translatorsLength; currentCompiler++) { + sink.setCurrentCompilerIndex(currentCompiler); + final TranslatingCompiler compiler = translators[currentCompiler]; + if (context.getProgressIndicator().isCanceled()) { + throw new ExitException(ExitStatus.CANCELLED); } - total = snapshot.length * translatorsLength; - chunkFiles = chunkMap.get(currentChunk); + + DumbService.getInstance(myProject).waitForSmartMode(); + + if (round == 0) { + if (snapshot == null || ContainerUtil.intersects(generatedTypes, compilerManager.getRegisteredInputTypes(compiler))) { + // rescan snapshot if previously generated files may influence the input of this compiler + snapshot = ApplicationManager.getApplication().runReadAction(new Computable() { + public VirtualFile[] compute() { + return context.getCompileScope().getFiles(null, true); + } + }); + recalculateChunkToFilesMap(context, sortedChunks, snapshot, chunkMap); + chunkFiles = chunkMap.get(currentChunk); + total = snapshot.length * translatorsLength; + } + } + + final CompileContextEx _context; + if (compiler instanceof IntermediateOutputCompiler) { + // wrap compile context so that output goes into intermediate directories + final IntermediateOutputCompiler _compiler = (IntermediateOutputCompiler)compiler; + _context = new CompileContextExProxy(context) { + public VirtualFile getModuleOutputDirectory(final Module module) { + return getGenerationOutputDir(_compiler, module, false); + } + + public VirtualFile getModuleOutputDirectoryForTests(final Module module) { + return getGenerationOutputDir(_compiler, module, true); + } + }; + } + else { + _context = context; + } + final boolean compiledSomething = + compileSources(_context, currentChunk, compiler, chunkFiles, round == 0? forceCompile : true, isRebuild, trackDependencies, onlyCheckStatus, sink); + + processed += chunkFiles.size(); + _context.getProgressIndicator().setFraction(((double)processed) / total); + + if (compiledSomething) { + generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(compiler)); + } + + if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + throw new ExitException(ExitStatus.ERRORS); + } + + didSomething |= compiledSomething; } - final CompileContextEx _context; - if (compiler instanceof IntermediateOutputCompiler) { - // wrap compile context so that output goes into intermediate directories - final IntermediateOutputCompiler _compiler = (IntermediateOutputCompiler)compiler; - _context = new CompileContextExProxy(context) { - public VirtualFile getModuleOutputDirectory(final Module module) { - return getGenerationOutputDir(_compiler, module, false); - } - - public VirtualFile getModuleOutputDirectoryForTests(final Module module) { - return getGenerationOutputDir(_compiler, module, true); - } - }; + final Set compiledWithSuccess; + final Set compiledWithErrors = CacheUtils.getFilesCompiledWithErrors(context); + if (compiledWithErrors.isEmpty()) { + compiledWithSuccess = sink.getCompiledSources(); } else { - _context = context; + compiledWithSuccess = new HashSet(); + compiledWithSuccess.addAll(sink.getCompiledSources()); + compiledWithSuccess.removeAll(compiledWithErrors); } - final boolean compiledSomething = - compileSources(_context, currentChunk, compiler, chunkFiles, forceCompile, isRebuild, trackDependencies, onlyCheckStatus, sink); - - processed += chunkFiles.size(); - _context.getProgressIndicator().setFraction(((double)processed) / total); - - if (compiledSomething) { - generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(compiler)); + filesToRecompile.removeAll(compiledWithSuccess); + filesToRecompile.addAll(compiledWithErrors); + + // TODO: use something to obtain additional processor EXTENSION POINT? + dependentFiles = CacheUtils.findDependentFiles(context, compiledWithSuccess, null, dependencyFilter); + + if (ourDebugMode) { + if (!dependentFiles.isEmpty()) { + for (VirtualFile dependentFile : dependentFiles) { + System.out.println("FOUND TO RECOMPILE: " + dependentFile.getPresentableUrl()); + } + } + else { + System.out.println("NO FILES TO RECOMPILE"); + } } - - if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { - throw new ExitException(ExitStatus.ERRORS); + + if (!dependentFiles.isEmpty()) { + filesToRecompile.addAll(dependentFiles); + allDependent.addAll(dependentFiles); + if (context.getProgressIndicator().isCanceled() || context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + break; + } + final List filesInScope = getFilesInScope(context, currentChunk, dependentFiles); + if (filesInScope.isEmpty()) { + break; + } + context.getDependencyCache().clearTraverseRoots(); + chunkFiles = filesInScope; + total += chunkFiles.size() * translators.length; } - - didSomething |= compiledSomething; + + round++; } + while (!dependentFiles.isEmpty() && context.getMessageCount(CompilerMessageCategory.ERROR) == 0); + + if (CompilerConfiguration.MAKE_ENABLED) { + if (!context.getProgressIndicator().isCanceled()) { + // when cancelled pretend nothing was compiled and next compile will compile everything from the scratch + final ProgressIndicator indicator = context.getProgressIndicator(); + final DependencyCache cache = context.getDependencyCache(); + + indicator.pushState(); + indicator.setText(CompilerBundle.message("progress.updating.caches")); + indicator.setText2(""); + + cache.update(); + + indicator.setText(CompilerBundle.message("progress.saving.caches")); + cache.resetState(); + + indicator.popState(); + } + } + + if (context.getMessageCount(CompilerMessageCategory.ERROR) != 0) { + filesToRecompile.addAll(allDependent); + } + if (filesToRecompile.size() > 0) { + sink.add(null, Collections.emptyList(), VfsUtil.toVirtualFileArray(filesToRecompile)); + } + } + catch (CacheCorruptedException e) { + LOG.info(e); + context.requestRebuildNextTime(e.getMessage()); } finally { if (context.getMessageCount(CompilerMessageCategory.ERROR) == 0) { @@ -1059,6 +1132,37 @@ public class CompileDriver { return didSomething; } + private static List getFilesInScope(final CompileContextEx context, final Chunk chunk, final Collection files) { + final List filesInScope = new ArrayList(files.size()); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (VirtualFile file : files) { + if (context.getCompileScope().belongs(file.getUrl())) { + final Module module = context.getModuleByFile(file); + if (chunk.getNodes().contains(module)) { + filesInScope.add(file); + } + } + } + } + }); + return filesInScope; + } + + private static void recalculateChunkToFilesMap(CompileContextEx context, List> allChunks, VirtualFile[] snapshot, Map, Collection> chunkMap) { + final Map> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(context, snapshot); + for (Chunk moduleChunk : allChunks) { + List files = Collections.emptyList(); + for (Module module : moduleChunk.getNodes()) { + final List moduleFiles = moduleToFilesMap.get(module); + if (moduleFiles != null) { + files = ContainerUtil.concat(files, moduleFiles); + } + } + chunkMap.put(moduleChunk, files); + } + } + private interface FileProcessingCompilerAdapterFactory { FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler); } @@ -1167,11 +1271,14 @@ public class CompileDriver { final ArrayList> toDelete = new ArrayList>(); ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { - TranslatingCompilerFilesMonitor.getInstance() - .collectFiles(context, (TranslatingCompiler)compiler, Arrays.asList(allSources).iterator(), true - /*pass true to make sure that every source in scope file is processed*/, false - /*important! should pass false to enable collection of files to delete*/, - new ArrayList(), toDelete); + TranslatingCompilerFilesMonitor.getInstance().collectFiles( + context, + (TranslatingCompiler)compiler, Arrays.asList(allSources).iterator(), + true /*pass true to make sure that every source in scope file is processed*/, + false /*important! should pass false to enable collection of files to delete*/, + new ArrayList(), + toDelete + ); } }); for (Trinity trinity : toDelete) { @@ -2277,6 +2384,7 @@ public class CompileDriver { private final CompileContextEx myContext; private final TranslatingCompiler[] myCompilers; private int myCurrentCompilerIdx; + private final Set myCompiledSources = new HashSet(); //private LinkedBlockingQueue myFutures = new LinkedBlockingQueue(); private TranslatorsOutputSink(CompileContextEx context, TranslatingCompiler[] compilers) { @@ -2288,7 +2396,17 @@ public class CompileDriver { myCurrentCompilerIdx = index; } + public Set getCompiledSources() { + return Collections.unmodifiableSet(myCompiledSources); + } + public void add(final String outputRoot, final Collection items, final VirtualFile[] filesToRecompile) { + for (TranslatingCompiler.OutputItem item : items) { + final VirtualFile file = item.getSourceFile(); + if (file != null) { + myCompiledSources.add(file); + } + } final TranslatingCompiler compiler = myCompilers[myCurrentCompilerIdx]; if (compiler instanceof IntermediateOutputCompiler) { final LocalFileSystem lfs = LocalFileSystem.getInstance(); @@ -2368,7 +2486,7 @@ public class CompileDriver { } } - private void addItemToMap(Map> map, String outputDir, TranslatingCompiler.OutputItem item) { + private static void addItemToMap(Map> map, String outputDir, TranslatingCompiler.OutputItem item) { Collection collection = map.get(outputDir); if (collection == null) { collection = new ArrayList(); @@ -2392,4 +2510,21 @@ public class CompileDriver { } } } + + private static class DependentClassesCumulativeFilter implements Function>, Pair>> { + + private final TIntHashSet myProcessedNames = new TIntHashSet(); + private final Set myProcessedFiles = new HashSet(); + + public Pair> fun(Pair> deps) { + final TIntHashSet currentDeps = new TIntHashSet(deps.getFirst()); + currentDeps.removeAll(myProcessedNames.toArray()); + myProcessedNames.addAll(deps.getFirst()); + + final Set depFiles = new HashSet(deps.getSecond()); + depFiles.removeAll(myProcessedFiles); + myProcessedFiles.addAll(deps.getSecond()); + return new Pair>(currentDeps.toArray(), depFiles); + } + } } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java index 5c8a5679c08c..f4abe40f4b9d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java @@ -1212,9 +1212,22 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { if (srcFile != null) { final SourceFileInfo srcInfo = loadSourceInfo(srcFile); if (srcInfo != null) { + final boolean srcWillBeDeleted = VfsUtil.isAncestor(eventFile, srcFile, false); for (int projectId : srcInfo.getProjectIds().toArray()) { if (srcInfo.isAssociated(projectId, filePath)) { - addSourceForRecompilation(projectId, srcFile, srcInfo); + if (srcWillBeDeleted) { + if (LOG.isDebugEnabled() || ourDebugMode) { + final String message = "Unschedule recompilation because of deletion " + srcFile.getPresentableUrl(); + LOG.debug(message); + if (ourDebugMode) { + System.out.println(message); + } + } + removeSourceForRecompilation(projectId, Math.abs(getFileId(srcFile))); + } + else { + addSourceForRecompilation(projectId, srcFile, srcInfo); + } } } } @@ -1226,6 +1239,8 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { final TIntHashSet projects = srcInfo.getProjectIds(); if (!projects.isEmpty()) { final ScheduleOutputsForDeletionProc deletionProc = new ScheduleOutputsForDeletionProc(file.getUrl()); + deletionProc.setRootBeingDeleted(eventFile); + final int sourceFileId = Math.abs(getFileId(file)); for (int projectId : projects.toArray()) { // mark associated outputs for deletion srcInfo.processOutputPaths(projectId, deletionProc); @@ -1236,7 +1251,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { System.out.println(message); } } - removeSourceForRecompilation(projectId, Math.abs(getFileId(file))); + removeSourceForRecompilation(projectId, sourceFileId); } } } @@ -1381,18 +1396,29 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { private class ScheduleOutputsForDeletionProc implements Proc { private final String mySrcUrl; private final LocalFileSystem myFileSystem; + @Nullable + private VirtualFile myRootBeingDeleted; private ScheduleOutputsForDeletionProc(final String srcUrl) { mySrcUrl = srcUrl; myFileSystem = LocalFileSystem.getInstance(); } + public void setRootBeingDeleted(@Nullable VirtualFile rootBeingDeleted) { + myRootBeingDeleted = rootBeingDeleted; + } + public boolean execute(final int projectId, String outputPath) { final VirtualFile outFile = myFileSystem.findFileByPath(outputPath); if (outFile != null) { // not deleted yet - final OutputFileInfo outputInfo = loadOutputInfo(outFile); - final String classname = outputInfo != null? outputInfo.getClassName() : null; - markOutputPathForDeletion(projectId, outputPath, classname, mySrcUrl); + if (myRootBeingDeleted != null && VfsUtil.isAncestor(myRootBeingDeleted, outFile, false)) { + unmarkOutputPathForDeletion(outputPath); + } + else { + final OutputFileInfo outputInfo = loadOutputInfo(outFile); + final String classname = outputInfo != null? outputInfo.getClassName() : null; + markOutputPathForDeletion(projectId, outputPath, classname, mySrcUrl); + } } return true; } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java index ff0ee19259cb..3e41738c0d3e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java @@ -26,7 +26,10 @@ import com.intellij.compiler.*; import com.intellij.compiler.classParsing.AnnotationConstantValue; import com.intellij.compiler.classParsing.MethodInfo; import com.intellij.compiler.impl.CompilerUtil; -import com.intellij.compiler.make.*; +import com.intellij.compiler.make.Cache; +import com.intellij.compiler.make.CacheCorruptedException; +import com.intellij.compiler.make.DependencyCache; +import com.intellij.compiler.make.MakeUtil; import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter; import com.intellij.ide.util.projectWizard.JavaModuleBuilder; import com.intellij.openapi.application.Application; @@ -38,7 +41,6 @@ import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.module.JavaModuleType; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JavaSdkType; import com.intellij.openapi.projectRoots.Sdk; @@ -52,10 +54,8 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Chunk; -import com.intellij.util.Function; import com.intellij.util.cls.ClsFormatException; import gnu.trove.THashMap; -import gnu.trove.TIntHashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -74,20 +74,18 @@ public class BackendCompilerWrapper { private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.BackendCompilerWrapper"); private final BackendCompiler myCompiler; - private final Set mySuccesfullyCompiledJavaFiles; // VirtualFile private final CompileContextEx myCompileContext; private final List myFilesToCompile; private final TranslatingCompiler.OutputSink mySink; private final Chunk myChunk; private final Project myProject; - private final Set myFilesToRecompile; private final Map myModuleToTempDirMap = new THashMap(); private final ProjectFileIndex myProjectFileIndex; @NonNls private static final String PACKAGE_ANNOTATION_FILE_NAME = "package-info.java"; private static final FileObject myStopThreadToken = new FileObject(new File(""), new byte[0]); public final Map> myFileNameToSourceMap= new THashMap>(); - + private final Set myProcessedPackageInfos = new HashSet(); public BackendCompilerWrapper(Chunk chunk, @NotNull final Project project, @NotNull List filesToCompile, @@ -98,44 +96,19 @@ public class BackendCompilerWrapper { myCompiler = compiler; myCompileContext = compileContext; myFilesToCompile = filesToCompile; - myFilesToRecompile = new HashSet(filesToCompile); mySink = sink; myProjectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); - mySuccesfullyCompiledJavaFiles = new HashSet(filesToCompile.size()); } public void compile() throws CompilerException, CacheCorruptedException { Application application = ApplicationManager.getApplication(); - final Set allDependent = new HashSet(); - COMPILE: try { if (!myFilesToCompile.isEmpty()) { if (application.isUnitTestMode()) { saveTestData(); } - compileModules(buildModuleToFilesMap(myFilesToCompile)); } - - Collection dependentFiles; - do { - dependentFiles = CacheUtils.findDependentFiles(myCompileContext, mySuccesfullyCompiledJavaFiles, myCompiler.getDependencyProcessor(), DEPENDENCY_FILTER); - - if (!dependentFiles.isEmpty()) { - myFilesToRecompile.addAll(dependentFiles); - allDependent.addAll(dependentFiles); - if (myCompileContext.getProgressIndicator().isCanceled() || myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) { - break COMPILE; - } - final List filesInScope = getFilesInScope(dependentFiles); - if (filesInScope.isEmpty()) { - break; - } - myCompileContext.getDependencyCache().clearTraverseRoots(); - compileModules(buildModuleToFilesMap(filesInScope)); - } - } - while (!dependentFiles.isEmpty() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0); } catch (SecurityException e) { throw new CompilerException(CompilerBundle.message("error.compiler.process.not.started", e.getMessage()), e); @@ -153,34 +126,22 @@ public class BackendCompilerWrapper { myModuleToTempDirMap.clear(); } - // do not update caches if cancelled because there is a chance that they will be incomplete - if (CompilerConfiguration.MAKE_ENABLED) { - if (!myCompileContext.getProgressIndicator().isCanceled()) { - // when cancelled pretend nothing was compiled and next compile will compile everything from the scratch - final ProgressIndicator indicator = myCompileContext.getProgressIndicator(); - final DependencyCache cache = myCompileContext.getDependencyCache(); - - indicator.pushState(); - indicator.setText(CompilerBundle.message("progress.updating.caches")); - indicator.setText2(""); - - cache.update(); - - indicator.setText(CompilerBundle.message("progress.saving.caches")); - cache.resetState(); - - indicator.popState(); + if (!myFilesToCompile.isEmpty() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) { + // package-info.java hack + final List outputs = new ArrayList(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + for (final VirtualFile file : myFilesToCompile) { + if (PACKAGE_ANNOTATION_FILE_NAME.equals(file.getName()) && !myProcessedPackageInfos.contains(file)) { + outputs.add(new OutputItemImpl(file)); + } + } + } + }); + if (!outputs.isEmpty()) { + mySink.add(null, outputs, VirtualFile.EMPTY_ARRAY); } } - - myFilesToRecompile.removeAll(mySuccesfullyCompiledJavaFiles); - if (myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) != 0) { - myFilesToRecompile.addAll(allDependent); - } - final List outputs = processPackageInfoFiles(); - if (myFilesToRecompile.size() > 0 || outputs.size() > 0) { - mySink.add(null, outputs, VfsUtil.toVirtualFileArray(myFilesToRecompile)); - } } private Map> buildModuleToFilesMap(final List filesToCompile) { @@ -190,51 +151,6 @@ public class BackendCompilerWrapper { return CompilerUtil.buildModuleToFilesMap(myCompileContext, filesToCompile); } - // package-info.java hack - private List processPackageInfoFiles() { - if (myFilesToRecompile.isEmpty()) { - return Collections.emptyList(); - } - final List outputs = new ArrayList(); - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - final List packageInfoFiles = new ArrayList(myFilesToRecompile.size()); - for (final VirtualFile file : myFilesToRecompile) { - if (PACKAGE_ANNOTATION_FILE_NAME.equals(file.getName())) { - packageInfoFiles.add(file); - } - } - if (!packageInfoFiles.isEmpty()) { - final Set badFiles = getFilesCompiledWithErrors(); - for (final VirtualFile packageInfoFile : packageInfoFiles) { - if (!badFiles.contains(packageInfoFile)) { - outputs.add(new OutputItemImpl(packageInfoFile)); - myFilesToRecompile.remove(packageInfoFile); - } - } - } - } - }); - return outputs; - } - - private List getFilesInScope(final Collection files) { - final List filesInScope = new ArrayList(files.size()); - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - for (VirtualFile file : files) { - if (myCompileContext.getCompileScope().belongs(file.getUrl())) { - final Module module = myCompileContext.getModuleByFile(file); - if (myChunk.getNodes().contains(module)) { - filesInScope.add(file); - } - } - } - } - }); - return filesInScope; - } - private void compileModules(final Map> moduleToFilesMap) throws CompilerException { myProcessedFilesCount = 0; try { @@ -347,21 +263,6 @@ public class BackendCompilerWrapper { }); } - private final TIntHashSet myProcessedNames = new TIntHashSet(); - private final Set myProcessedFiles = new HashSet(); - private final Function>, Pair>> DEPENDENCY_FILTER = new Function>, Pair>>() { - public Pair> fun(Pair> deps) { - final TIntHashSet currentDeps = new TIntHashSet(deps.getFirst()); - currentDeps.removeAll(myProcessedNames.toArray()); - myProcessedNames.addAll(deps.getFirst()); - - final Set depFiles = new HashSet(deps.getSecond()); - depFiles.removeAll(myProcessedFiles); - myProcessedFiles.addAll(deps.getSecond()); - return new Pair>(currentDeps.toArray(), depFiles); - } - }; - private final Object lock = new Object(); private class SynchedCompilerParsing extends CompilerParsingThread { @@ -599,8 +500,7 @@ public class BackendCompilerWrapper { } private void compileFinished(int exitValue, final ModuleChunk chunk, final String outputDir) { - if (exitValue != 0 && !myCompileContext.getProgressIndicator().isCanceled() && - myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) { + if (exitValue != 0 && !myCompileContext.getProgressIndicator().isCanceled() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) { myCompileContext.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("error.compiler.internal.error", exitValue), null, -1, -1); } @@ -610,7 +510,6 @@ public class BackendCompilerWrapper { try { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { - final Set compiledWithErrors = getFilesCompiledWithErrors(); final FileTypeManager typeManager = FileTypeManager.getInstance(); final String outputDirPath = outputDir.replace(File.separatorChar, '/'); try { @@ -620,7 +519,7 @@ public class BackendCompilerWrapper { if (LOG.isDebugEnabled()) { LOG.debug("Building output items for " + root.getPresentableUrl() + "; output dir = " + outputDirPath + "; packagePrefix = \"" + packagePrefix + "\""); } - buildOutputItemsList(outputDirPath, module, root, typeManager, compiledWithErrors, root, packagePrefix, toRefresh, results); + buildOutputItemsList(outputDirPath, module, root, typeManager, root, packagePrefix, toRefresh, results); } } } @@ -644,24 +543,8 @@ public class BackendCompilerWrapper { myFileNameToSourceMap.clear(); // clear the map before the next use } - private Set getFilesCompiledWithErrors() { - CompilerMessage[] messages = myCompileContext.getMessages(CompilerMessageCategory.ERROR); - Set compiledWithErrors = Collections.emptySet(); - if (messages.length > 0) { - compiledWithErrors = new HashSet(messages.length); - for (CompilerMessage message : messages) { - final VirtualFile file = message.getVirtualFile(); - if (file != null) { - compiledWithErrors.add(file); - } - } - } - return compiledWithErrors; - } - private void buildOutputItemsList(final String outputDir, Module module, VirtualFile from, final FileTypeManager typeManager, - final Set compiledWithErrors, final VirtualFile sourceRoot, final String packagePrefix, final List filesToRefresh, final Map> results) throws CacheCorruptedException { final Ref exRef = new Ref(null); @@ -671,7 +554,7 @@ public class BackendCompilerWrapper { try { assert child.isValid(); if (!child.isDirectory() && myCompiler.getCompilableFileTypes().contains(typeManager.getFileTypeByFile(child))) { - updateOutputItemsList(outputDir, child, compiledWithErrors, sourceRoot, packagePrefix, filesToRefresh, results); + updateOutputItemsList(outputDir, child, sourceRoot, packagePrefix, filesToRefresh, results); } return true; } @@ -720,7 +603,7 @@ public class BackendCompilerWrapper { paths.add(new CompiledClass(classQName, relativePathToSource, pathToClass)); } - private void updateOutputItemsList(final String outputDir, VirtualFile srcFile, Set compiledWithErrors, + private void updateOutputItemsList(final String outputDir, VirtualFile srcFile, VirtualFile sourceRoot, final String packagePrefix, final List filesToRefresh, Map> results) throws CacheCorruptedException { @@ -745,6 +628,9 @@ public class BackendCompilerWrapper { results.put(realLocation.getFirst(), outputs); } outputs.add(new OutputItemImpl(realLocation.getSecond(), srcFile)); + if (PACKAGE_ANNOTATION_FILE_NAME.equals(srcFile.getName())) { + myProcessedPackageInfos.add(srcFile); + } if (CompilerConfiguration.MAKE_ENABLED) { newCache.setPath(cc.qName, realLocation.getSecond()); } @@ -752,9 +638,6 @@ public class BackendCompilerWrapper { LOG.debug("Added output item: [outputDir; outputPath; sourceFile] = [" + realLocation.getFirst() + "; " + realLocation.getSecond() + "; " + srcFile.getPresentableUrl() + "]"); } - if (!compiledWithErrors.contains(srcFile)) { - mySuccesfullyCompiledJavaFiles.add(srcFile); - } } else { myCompileContext.addMessage(CompilerMessageCategory.ERROR, "Failed to copy from temporary location to output directory: " + outputPath + " (see idea.log for details)", null, -1, -1); @@ -773,7 +656,7 @@ public class BackendCompilerWrapper { * @param packagePrefix * @return A 'package'-path to a given src file relative to a specified root. "/" slashes must be used */ - protected String calcPackagePath(VirtualFile srcFile, VirtualFile sourceRoot, String packagePrefix) { + protected static String calcPackagePath(VirtualFile srcFile, VirtualFile sourceRoot, String packagePrefix) { final String prefix = packagePrefix != null && packagePrefix.length() > 0 ? packagePrefix.replace('.', '/') + "/" : ""; return prefix + VfsUtil.getRelativePath(srcFile, sourceRoot, '/'); } diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java index e2ce0fa640d7..4dbae4ca626d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java @@ -22,6 +22,8 @@ import com.intellij.compiler.classParsing.MethodInfo; import com.intellij.compiler.impl.javaCompiler.DependencyProcessor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompilerBundle; +import com.intellij.openapi.compiler.CompilerMessage; +import com.intellij.openapi.compiler.CompilerMessageCategory; import com.intellij.openapi.compiler.ex.CompileContextEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Pair; @@ -31,6 +33,7 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.StringBuilderSpinAllocator; import gnu.trove.TIntHashSet; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -187,4 +190,20 @@ public class CacheUtils { return dependentFiles; } + + @NotNull + public static Set getFilesCompiledWithErrors(final CompileContextEx context) { + CompilerMessage[] messages = context.getMessages(CompilerMessageCategory.ERROR); + Set compiledWithErrors = Collections.emptySet(); + if (messages.length > 0) { + compiledWithErrors = new HashSet(messages.length); + for (CompilerMessage message : messages) { + final VirtualFile file = message.getVirtualFile(); + if (file != null) { + compiledWithErrors.add(file); + } + } + } + return compiledWithErrors; + } } From 38d3091442a66a52a7e5ba7051667c2311dfdb1e Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 26 Jul 2010 16:49:37 +0400 Subject: [PATCH 081/102] IDEA-53596 Soft wrap for editors Corrected editor navigation in case of document with tab symbols (cases when tabulations are on soft-wrapped lines and occupy various number of visual columns) --- .../editor/actions/EditorActionUtil.java | 57 +++++---- .../openapi/editor/ex/util/EditorUtil.java | 114 ++++++++---------- .../openapi/editor/impl/CaretModelImpl.java | 27 +++-- .../openapi/editor/impl/EditorImpl.java | 58 ++++++--- .../editor/impl/SoftWrapModelImpl.java | 15 ++- .../impl/softwrap/SoftWrapDataMapper.java | 4 +- 6 files changed, 158 insertions(+), 117 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java index 80932b63a6d8..2a801fde55be 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java @@ -268,16 +268,19 @@ public class EditorActionUtil { private static void moveCaretToStartOfSoftWrappedLine(Editor editor, VisualPosition currentVisual) { CaretModel caretModel = editor.getCaretModel(); int line = currentVisual.line; - int column = 0; - if (currentVisual.column == 0) { + // We use default column value as '1' below in assumption that we work with soft-wrapped line and don't want to put cursor + // before 'after soft wrap' drawing. + int column = 1; + + if (currentVisual.column <= 1) { line--; int nonSpaceColumn = findFirstNonSpaceColumnOnTheLine(editor, line); - column = nonSpaceColumn >= 0 ? nonSpaceColumn : 0; + column = nonSpaceColumn >= 1 ? nonSpaceColumn : 1; } else { int nonSpaceColumn = findFirstNonSpaceColumnOnTheLine(editor, currentVisual.line); - if (nonSpaceColumn > 0 /* current visual line is not empty */ && nonSpaceColumn < currentVisual.column) { + if (nonSpaceColumn > 1 /* current visual line is not empty */ && nonSpaceColumn < currentVisual.column) { column = nonSpaceColumn; } } @@ -364,18 +367,13 @@ public class EditorActionUtil { // There are soft wrap-introduced visual lines after the target one return -1; } - - end = findFirstNonSpaceOffsetInRange(document.getCharsSequence(), softWrap.getStart(), logLineEndOffset); - if (end >= 0) { - // Width of soft wrap virtual text that is located at the target visual line. - int result = EditorUtil.calcColumnNumber(editor, softWrapText, j, softWrapTextLength); - result++; // For column reserved for 'after soft wrap' sign. - result += EditorUtil.calcColumnNumber(editor, document.getCharsSequence(), softWrap.getStart(), end); - return result; - } - else { - return -1; - } + } + int end = findFirstNonSpaceOffsetInRange(document.getCharsSequence(), softWrap.getStart(), logLineEndOffset); + if (end >= 0) { + return EditorUtil.calcColumnNumber(editor, document.getCharsSequence(), softWrap.getStart(), end); + } + else { + return -1; } } return -1; @@ -415,6 +413,7 @@ public class EditorActionUtil { LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection() ? selectionModel.getBlockStart() : caretModel.getLogicalPosition(); + SoftWrapModel softWrapModel = editor.getSoftWrapModel(); int lineNumber = editor.getCaretModel().getLogicalPosition().line; if (lineNumber >= document.getLineCount()) { @@ -434,7 +433,7 @@ public class EditorActionUtil { LogicalPosition logical = editor.visualToLogicalPosition(visualEndOfLineWithCaret); int offset = editor.logicalPositionToOffset(logical); if (offset < editor.getDocument().getTextLength()) { - SoftWrapModel softWrapModel = editor.getSoftWrapModel(); + TextChange softWrap = softWrapModel.getSoftWrap(offset); if (softWrap == null) { // Same offset may correspond to positions on different visual lines in case of soft wraps presence @@ -442,21 +441,33 @@ public class EditorActionUtil { // Hence, we check for soft wraps presence at two offsets. softWrap = softWrapModel.getSoftWrap(offset + 1); } + int line = currentVisualCaret.line; + int column = currentVisualCaret.column; if (softWrap != null) { - int line = currentVisualCaret.line + 1; - int column = EditorUtil.getLastVisualLineColumnNumber(editor, line); - visualEndOfLineWithCaret = new VisualPosition(line, column); + line++; + column = EditorUtil.getLastVisualLineColumnNumber(editor, line); } + // There is a possible case that the last visual line of particular logical line contains only white spaces. We want to move + // caret just after 'after soft wrap' drawing then. + else if (line == editor.offsetToVisualPosition(document.getLineEndOffset(lineNumber)).line) { + column = 1; + } + visualEndOfLineWithCaret = new VisualPosition(line, column); } } - + + int offset; + int newOffset; LogicalPosition logLineEnd = editor.visualToLogicalPosition(visualEndOfLineWithCaret); - int offset = editor.logicalPositionToOffset(logLineEnd); + offset = editor.logicalPositionToOffset(logLineEnd); lineNumber = logLineEnd.line; - int newOffset = offset; + newOffset = offset; CharSequence text = document.getCharsSequence(); for (int i = newOffset - 1; i >= document.getLineStartOffset(lineNumber); i--) { + if (softWrapModel.getSoftWrap(i) != null) { + break; + } if (text.charAt(i) != ' ' && text.charAt(i) != '\t') { break; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java index e0e517dbbad9..61895d40e15a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java @@ -22,7 +22,6 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry; import com.intellij.openapi.editor.impl.FontInfo; -import com.intellij.openapi.editor.impl.IterationState; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; @@ -158,17 +157,42 @@ public class EditorUtil { } public static int calcOffset(Editor editor, CharSequence text, int start, int end, int columnNumber, int tabSize) { - // If all tabs here goes before any other chars in the line we may use an optimization here. - boolean useOptimization = true; + final int maxScanIndex = Math.min(start + columnNumber + 1, end); + if (editor == null) { + return calcSoftWrapUnawareOffset(text, start, maxScanIndex, columnNumber, tabSize); + } + + int column = 0; + int tabAnchor = 0; + SoftWrapModel softWrapModel = editor.getSoftWrapModel(); + for (int i = start; i < maxScanIndex; i++) { + TextChange softWrap = softWrapModel.getSoftWrap(i); + if (softWrap != null) { + tabAnchor = softWrapModel.getSoftWrapIndentWidthInColumns(softWrap); + } + if (column >= columnNumber) { + return i; + } + int diff = textWidthInColumns(editor, text, i, i + 1, tabAnchor); + if (column + diff > columnNumber) { + // We want to return offset that points to the tabulation symbol if it's represented in multiple columns and target visual + // column points inside it. + return i; + } + column += diff; + tabAnchor += diff; + } + return end; + } + + private static int calcSoftWrapUnawareOffset(CharSequence text, int start, int end, int columnNumber, int tabSize) { boolean hasNonTabs = false; boolean hasTabs = false; - final int maxScanIndex = Math.min(start + columnNumber + 1, end); - for (int i = start; i < maxScanIndex; i++) { + for (int i = start; i < end; i++) { if (text.charAt(i) == '\t') { hasTabs = true; if (hasNonTabs) { - useOptimization = false; break; } } else { @@ -176,52 +200,18 @@ public class EditorUtil { } } - if (editor == null || useOptimization) { - if (!hasTabs) return Math.min(start + columnNumber, end); + if (!hasTabs) return Math.min(start + columnNumber, end); - int shift = 0; - int offset = start; - for (; offset < end && offset + shift < start + columnNumber; offset++) { - if (text.charAt(offset) == '\t') { - shift += getTabLength(offset + shift - start, tabSize) - 1; - } - } - if (offset + shift > start + columnNumber) { - offset--; - } - - return offset; - } - - EditorEx editorImpl = (EditorEx)editor; + int shift = 0; int offset = start; - IterationState state = new IterationState(editorImpl, offset, false); - int fontType = state.getMergedAttributes().getFontType(); - int column = 0; - int x = 0; - int spaceSize = getSpaceWidth(fontType, editorImpl); - while (column < columnNumber) { - if (offset >= state.getEndOffset()) { - state.advance(); - - fontType = state.getMergedAttributes().getFontType(); - } - - char c = offset < end ? text.charAt(offset++) : ' '; - if (c == '\t') { - int prevX = x; - x = nextTabStop(x, editorImpl); - column += (x - prevX) / spaceSize; - } - else { - x += charWidth(c, fontType, editorImpl); - column++; + for (; offset < end && offset + shift < start + columnNumber; offset++) { + if (text.charAt(offset) == '\t') { + shift += getTabLength(offset + shift - start, tabSize) - 1; } } - if (column == columnNumber && offset < end && text.charAt(offset) == '\t' && (nextTabStop(x, editorImpl) - x) / spaceSize == 0) { - offset++; + if (offset + shift > start + columnNumber) { + offset--; } - if (column > columnNumber) offset--; return offset; } @@ -239,15 +229,21 @@ public class EditorUtil { public static int calcColumnNumber(Editor editor, CharSequence text, int start, int offset, int tabSize) { boolean useOptimization = true; + if (editor != null) { + TextChange softWrap = editor.getSoftWrapModel().getSoftWrap(start); + useOptimization = softWrap == null; + } boolean hasNonTabs = false; - for (int i = start; i < offset; i++) { - if (text.charAt(i) == '\t') { - if (hasNonTabs) { - useOptimization = false; - break; + if (useOptimization) { + for (int i = start; i < offset; i++) { + if (text.charAt(i) == '\t') { + if (hasNonTabs) { + useOptimization = false; + break; + } + } else { + hasNonTabs = true; } - } else { - hasNonTabs = true; } } @@ -315,9 +311,6 @@ public class EditorUtil { * @return number of visual columns required to represent tabulation symbols that starts at the given column */ public static int tabWidthInColumns(@NotNull Editor editor, int visualColumn) { - if (!editor.getSettings().isWhitespacesShown()) { - return 1; - } int tabSize = getTabSize(editor); int tabsNumber = visualColumn / tabSize; return (tabsNumber + 1) * tabSize - visualColumn; @@ -365,12 +358,7 @@ public class EditorUtil { continue; } - if (editor.getSettings().isWhitespacesShown()) { - result += nextTabStop(x + result, editor) - result - x; - } - else { - result += getSpaceWidth(fontType, editor); - } + result += nextTabStop(x + result, editor) - result - x; } return result; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java index b62353d3467d..6f4d4290843a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java @@ -179,34 +179,43 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener { if (newColumnNumber < 0) newColumnNumber = 0; if (newLineNumber < 0) newLineNumber = 0; + VisualPosition pos = new VisualPosition(newLineNumber, newColumnNumber); int lastColumnNumber = newColumnNumber; - if (!editorSettings.isCaretInsideTabs()) { + if (!editorSettings.isCaretInsideTabs() && !myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) { LogicalPosition log = myEditor.visualToLogicalPosition(new VisualPosition(newLineNumber, newColumnNumber)); int offset = myEditor.logicalPositionToOffset(log); CharSequence text = myEditor.getDocument().getCharsSequence(); if (offset >= 0 && offset < myEditor.getDocument().getTextLength()) { - if (text.charAt(offset) == '\t') { + if (text.charAt(offset) == '\t' && (columnShift <= 0 || offset == myOffset)) { if (columnShift <= 0) { newColumnNumber = myEditor.offsetToVisualPosition(offset).column; } else { - if (myEditor.offsetToVisualPosition(offset).column < newColumnNumber) { + TextChange softWrap = myEditor.getSoftWrapModel().getSoftWrap(offset + 1); + // There is a possible case that tabulation symbol is the last document symbol represented on a visual line before + // soft wrap. We can't just use column from 'offset + 1' because it would point on a next visual line. + if (softWrap == null) { newColumnNumber = myEditor.offsetToVisualPosition(offset + 1).column; } + else { + newColumnNumber = EditorUtil.getLastVisualLineColumnNumber(myEditor, newLineNumber); + } } } } } - VisualPosition pos = new VisualPosition(newLineNumber, newColumnNumber); + pos = new VisualPosition(newLineNumber, newColumnNumber); if (columnShift != 0 && lineShift == 0 && myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) { LogicalPosition logical = myEditor.visualToLogicalPosition(pos); - int offsetToUse = myEditor.logicalPositionToOffset(logical); - if (columnShift < 0) { - offsetToUse--; - + int softWrapOffset = myEditor.logicalPositionToOffset(logical); + if (columnShift >= 0) { + moveToOffset(softWrapOffset); + } + else { + int line = myEditor.offsetToVisualPosition(softWrapOffset - 1).line; + moveToVisualPosition(new VisualPosition(line, EditorUtil.getLastVisualLineColumnNumber(myEditor, line))); } - moveToOffset(offsetToUse); } else { moveToVisualPosition(pos); 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 6a64a132032b..b3a4b5d666c3 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 @@ -839,8 +839,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi int spaceSize = EditorUtil.getSpaceWidth(fontType, this); int x = 0; + int charWidth; outer: while (true) { + charWidth = -1; if (offset >= textLength) { break; } @@ -879,12 +881,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi continue; } prevX = x; - int diff = charToVisibleWidth(c, fontType, x); - if (diff == 0) { + charWidth = charToVisibleWidth(c, fontType, x); + if (charWidth == 0) { break outer; } - x += diff; + x += charWidth; if (x >= px) { break outer; } @@ -894,7 +896,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi // Process 'after soft wrap' sign. prevX = x; - x += mySoftWrapModel.getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP); + charWidth = mySoftWrapModel.getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP); + x += charWidth; if (x >= px) { break outer; } @@ -903,11 +906,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi prevX = x; c = text.charAt(offset); - int diff = charToVisibleWidth(c, fontType, x); - if (diff == 0) { + charWidth = charToVisibleWidth(c, fontType, x); + if (charWidth == 0) { break; } else { - x += diff; + x += charWidth; } if (x >= px) { @@ -919,17 +922,17 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } } - int charWidth = EditorUtil.charWidth(c, fontType, this); + if (charWidth < 0) { + charWidth = EditorUtil.charWidth(c, fontType, this); + } if (x >= px && c == '\t') { if (mySettings.isCaretInsideTabs()) { column += (px - prevX) / spaceSize; if ((px - prevX) % spaceSize > spaceSize / 2) column++; } - else { - if ((x - px) * 2 < x - prevX) { - column += (x - prevX) / spaceSize; - } + else if ((x - px) * 2 < x - prevX) { + column += columnsNumber(c, x, prevX, spaceSize); } } else { @@ -977,7 +980,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (c != '\t') { return 1; } - return (x - prevX) / spaceSize; + int result = (x - prevX) / spaceSize; + if ((x - prevX) % spaceSize > 0) { + result++; + } + return result; } @NotNull @@ -1080,12 +1087,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } } - int x = getTabbedTextWidth(lineStartOffset, column); - return new Point(x + reserved, y); + int x = getTabbedTextWidth(lineStartOffset, column, reserved); + return new Point(x, y); } - private int getTabbedTextWidth(int startOffset, int length) { - int x = 0; + private int getTabbedTextWidth(int startOffset, int length, int xOffset) { + int x = xOffset; if (startOffset == 0 && myPrefixText != null) { for (char c : myPrefixText) { x += EditorUtil.charWidth(c, myPrefixAttributes.getFontType(), this); @@ -1128,7 +1135,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (c == '\t') { int prevX = x; x = EditorUtil.nextTabStop(x, this); - column += (x - prevX) / spaceSize; + int columnDiff = (x - prevX) / spaceSize; + if ((x - prevX) % spaceSize > 0) { + // There is a possible case that tabulation symbol takes more than one visual column to represent and it's shown at + // soft-wrapped line. Soft wrap sign width may be not divisible by space size, hence, part of tabulation symbol represented + // as a separate visual column may take less space than space width. + columnDiff++; + } + column += columnDiff; } else { x += EditorUtil.charWidth(c, fontType, this); @@ -4843,11 +4857,17 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi fontType = state.getMergedAttributes().getFontType(); } + TextChange softWrap = getSoftWrapModel().getSoftWrap(i); + if (softWrap != null) { + column++; // For 'after soft wrap' drawing. + x = getSoftWrapModel().getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP); + } + char c = text.charAt(i); if (c == '\t') { int prevX = x; x = EditorUtil.nextTabStop(x, this); - column += (x - prevX) / spaceSize; + column += columnsNumber(c, x, prevX, spaceSize); //column += Math.max(1, (x - prevX) / spaceSize); } else { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index f0fdd6eda822..90b592a2112d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -253,12 +253,23 @@ public class SoftWrapModelImpl implements SoftWrapModelEx { // We consider visual positions that point after the last symbol before soft wrap and the first symbol after soft wrap to not // belong to soft wrap-introduced virtual space. VisualPosition visualAfterSoftWrap = myEditor.offsetToVisualPosition(offset); - if (visualAfterSoftWrap.equals(visual)) { + if (visualAfterSoftWrap.line == visual.line && visualAfterSoftWrap.column <= visual.column) { return false; } VisualPosition visualBeforeSoftWrap = myEditor.offsetToVisualPosition(offset - 1); - return visual.line > visualBeforeSoftWrap.line || visual.column > visualBeforeSoftWrap.column + 1; + int columnOffset = 0; + LogicalPosition logLineStart = myEditor.visualToLogicalPosition(new VisualPosition(visualBeforeSoftWrap.line, 0)); + if (logLineStart.softWrapLinesOnCurrentLogicalLine > 0) { + int offsetLineStart = myEditor.logicalPositionToOffset(logLineStart); + softWrap = getSoftWrap(offsetLineStart); + if (softWrap != null) { + columnOffset = getSoftWrapIndentWidthInColumns(softWrap); + } + } + int width = EditorUtil.textWidthInColumns(myEditor, myEditor.getDocument().getCharsSequence(), offset - 1, offset, columnOffset); + int softWrapStartColumn = visualBeforeSoftWrap.column + width; + return visual.line > visualBeforeSoftWrap.line || visual.column > softWrapStartColumn; } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java index 96a840e27902..dbc9c6070f7e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java @@ -114,7 +114,9 @@ public class SoftWrapDataMapper { return result; } } - context.onSoftWrapSymbol('a'); // Emulate 'after soft wrap' sign + // Emulate 'after soft wrap' sign + //int afterSoftWrapColumns = myEditor.getSoftWrapModel().get + context.onSoftWrapSymbol('a'); } // Process document symbol. From e5e13267d3ad4f3bd0de3af3efbf44cc896fae2b Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 26 Jul 2010 18:26:24 +0400 Subject: [PATCH 082/102] DependencyProcessor extension point --- .../javaCompiler => }/DependencyProcessor.java | 5 ++++- .../com/intellij/compiler/impl/CompileDriver.java | 5 ++--- .../impl/javaCompiler/BackendCompiler.java | 2 -- .../impl/javaCompiler/ExternalCompiler.java | 4 ---- .../impl/javaCompiler/api/CompilerAPICompiler.java | 5 ----- .../eclipse/EclipseEmbeddedCompiler.java | 5 ----- .../src/com/intellij/compiler/make/CacheUtils.java | 11 ++++++----- .../intellij/compiler/make/DependencyCache.java | 14 ++++++-------- resources/src/META-INF/IdeaPlugin.xml | 3 +++ 9 files changed, 21 insertions(+), 33 deletions(-) rename java/compiler/impl/src/com/intellij/compiler/{impl/javaCompiler => }/DependencyProcessor.java (78%) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DependencyProcessor.java b/java/compiler/impl/src/com/intellij/compiler/DependencyProcessor.java similarity index 78% rename from java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DependencyProcessor.java rename to java/compiler/impl/src/com/intellij/compiler/DependencyProcessor.java index 5f09a8c25d53..dbf3703c2337 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DependencyProcessor.java +++ b/java/compiler/impl/src/com/intellij/compiler/DependencyProcessor.java @@ -13,14 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.compiler.impl.javaCompiler; +package com.intellij.compiler; import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.extensions.ExtensionPointName; /** * @author Eugene Zhuravlev * Date: Aug 19, 2008 */ public interface DependencyProcessor { + ExtensionPointName EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.makeDependencyProcessor"); + void processDependencies(CompileContext context, int classQualifiedName); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index dff37de3da1f..5a0d69840443 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -1032,8 +1032,7 @@ public class CompileDriver { filesToRecompile.removeAll(compiledWithSuccess); filesToRecompile.addAll(compiledWithErrors); - // TODO: use something to obtain additional processor EXTENSION POINT? - dependentFiles = CacheUtils.findDependentFiles(context, compiledWithSuccess, null, dependencyFilter); + dependentFiles = CacheUtils.findDependentFiles(context, compiledWithSuccess, dependencyFilter); if (ourDebugMode) { if (!dependentFiles.isEmpty()) { @@ -1107,7 +1106,7 @@ public class CompileDriver { ProgressManager.getInstance().executeNonCancelableSection(new Runnable() { public void run() { try { - final Collection deps = CacheUtils.findDependentFiles(context, Collections.emptySet(), null, null); + final Collection deps = CacheUtils.findDependentFiles(context, Collections.emptySet(), null); if (deps.size() > 0) { TranslatingCompilerFilesMonitor.getInstance().update(context, null, Collections.emptyList(), VfsUtil.toVirtualFileArray(deps)); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java index 7659c56a3927..9da4a3952baf 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java @@ -47,6 +47,4 @@ public interface BackendCompiler { void compileFinished(); - @Nullable - DependencyProcessor getDependencyProcessor(); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ExternalCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ExternalCompiler.java index 22a9f66d715c..c882cc2c27de 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ExternalCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ExternalCompiler.java @@ -41,10 +41,6 @@ public abstract class ExternalCompiler implements BackendCompiler { return COMPILABLE_TYPES; } - public DependencyProcessor getDependencyProcessor() { - return null; - } - @NotNull public Process launchProcess(@NotNull final ModuleChunk chunk, @NotNull final String outputDir, @NotNull final CompileContext compileContext) throws IOException { final String[] commands = createStartupCommand(chunk, compileContext, outputDir); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java index a70bd9418afe..110b05a05edc 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java @@ -17,7 +17,6 @@ package com.intellij.compiler.impl.javaCompiler.api; import com.intellij.compiler.OutputParser; import com.intellij.compiler.impl.javaCompiler.BackendCompiler; -import com.intellij.compiler.impl.javaCompiler.DependencyProcessor; import com.intellij.compiler.impl.javaCompiler.ModuleChunk; import com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler; import com.intellij.compiler.impl.javaCompiler.javac.JavacConfigurable; @@ -56,10 +55,6 @@ public class CompilerAPICompiler implements BackendCompiler { myProject = project; } - public DependencyProcessor getDependencyProcessor() { - return null; - } - public boolean checkCompiler(final CompileScope scope) { return true; } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java index 29febbecc1ea..550543ec2779 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java @@ -17,7 +17,6 @@ package com.intellij.compiler.impl.javaCompiler.eclipse; import com.intellij.compiler.OutputParser; import com.intellij.compiler.impl.javaCompiler.BackendCompiler; -import com.intellij.compiler.impl.javaCompiler.DependencyProcessor; import com.intellij.compiler.impl.javaCompiler.ModuleChunk; import com.intellij.compiler.impl.javaCompiler.javac.JavacSettings; import com.intellij.openapi.application.ApplicationManager; @@ -58,10 +57,6 @@ public class EclipseEmbeddedCompiler implements BackendCompiler { myEclipseCompilerDriver = new EclipseCompilerDriver(); } - public DependencyProcessor getDependencyProcessor() { - return null; - } - public boolean checkCompiler(final CompileScope scope) { return myEclipseCompilerDriver != null && myEclipseExternalCompiler.checkCompiler(scope); } diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java index 4dbae4ca626d..69bfd9d5254d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java @@ -19,7 +19,6 @@ import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.CompilerManagerImpl; import com.intellij.compiler.SymbolTable; import com.intellij.compiler.classParsing.MethodInfo; -import com.intellij.compiler.impl.javaCompiler.DependencyProcessor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompilerBundle; import com.intellij.openapi.compiler.CompilerMessage; @@ -129,9 +128,11 @@ public class CacheUtils { return true; } - public static Collection findDependentFiles(final CompileContextEx context, final Set succesfullyCompiledJavaFiles, - final @Nullable DependencyProcessor additionalDependencyProcessor, - final @Nullable Function>, Pair>> filter) throws CacheCorruptedException { + public static Collection findDependentFiles( + final CompileContextEx context, + final Set succesfullyCompiledJavaFiles, + final @Nullable Function>, Pair>> filter) throws CacheCorruptedException { + if (!CompilerConfiguration.MAKE_ENABLED) { return Collections.emptyList(); } @@ -140,7 +141,7 @@ public class CacheUtils { final DependencyCache dependencyCache = context.getDependencyCache(); final Pair> deps = - dependencyCache.findDependentClasses(context, context.getProject(), succesfullyCompiledJavaFiles, additionalDependencyProcessor); + dependencyCache.findDependentClasses(context, context.getProject(), succesfullyCompiledJavaFiles); final Pair> filteredDeps = filter != null? filter.fun(deps) : deps; final Set dependentFiles = new HashSet(); diff --git a/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java index f58f6b6df770..05fd42531799 100644 --- a/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java +++ b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java @@ -20,9 +20,9 @@ */ package com.intellij.compiler.make; +import com.intellij.compiler.DependencyProcessor; import com.intellij.compiler.SymbolTable; import com.intellij.compiler.classParsing.*; -import com.intellij.compiler.impl.javaCompiler.DependencyProcessor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.diagnostic.Logger; @@ -37,7 +37,6 @@ import com.intellij.util.cls.ClsUtil; import gnu.trove.TIntHashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -390,15 +389,14 @@ public class DependencyCache { /** * @return qualified names of the classes that should be additionally recompiled */ - public Pair> findDependentClasses(CompileContext context, Project project, Set successfullyCompiled, @Nullable final DependencyProcessor additionalProcessor) - throws CacheCorruptedException { + public Pair> findDependentClasses(CompileContext context, Project project, Set successfullyCompiled) + throws CacheCorruptedException { - markDependencies(context, project, successfullyCompiled, additionalProcessor); + markDependencies(context, project, successfullyCompiled); return new Pair>(myMarkedInfos.toArray(), Collections.unmodifiableSet(myMarkedFiles)); } - private void markDependencies(CompileContext context, Project project, final Set successfullyCompiled, - @Nullable final DependencyProcessor additionalProcessor) throws CacheCorruptedException { + private void markDependencies(CompileContext context, Project project, final Set successfullyCompiled) throws CacheCorruptedException { try { if (LOG.isDebugEnabled()) { LOG.debug("====================Marking dependent files====================="); @@ -427,7 +425,7 @@ public class DependencyCache { ).run(); } changedRetentionPolicyDependencyProcessor.checkAnnotationRetentionPolicyChanges(qName); - if (additionalProcessor != null) { + for (DependencyProcessor additionalProcessor : DependencyProcessor.EXTENSION_POINT_NAME.getExtensions()) { additionalProcessor.processDependencies(context, qName); } } diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 3798aaae98e2..987ca08568ee 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -72,6 +72,9 @@ + + From f88a1c4787e8271446555bfe30e498790d1946ec Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Mon, 26 Jul 2010 18:31:19 +0400 Subject: [PATCH 083/102] Spring: 1. "insert bean dependency" action(IDEA-56620) and 2. Generate @Qualifier quick fix --- .../com/intellij/codeInsight/template/TemplateBuilder.java | 7 +++++++ .../intellij/codeInsight/template/TemplateBuilderImpl.java | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/platform/lang-api/src/com/intellij/codeInsight/template/TemplateBuilder.java b/platform/lang-api/src/com/intellij/codeInsight/template/TemplateBuilder.java index 565e50870ac1..c921ac1da354 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/template/TemplateBuilder.java +++ b/platform/lang-api/src/com/intellij/codeInsight/template/TemplateBuilder.java @@ -53,6 +53,13 @@ public interface TemplateBuilder { */ void replaceRange(TextRange rangeWithinElement, String replacementText); + /** + * Creates a replacement box for the specified text range within the container element. + * @param rangeWithinElement range within the container element. + * @param expression the replacement expression. + */ + public void replaceRange(TextRange rangeWithinElement, Expression expression); + /** * Shows the live template and initiates editing process. */ diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/TemplateBuilderImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/template/TemplateBuilderImpl.java index 3f50d8b4642f..1b2fb89b798f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/TemplateBuilderImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/TemplateBuilderImpl.java @@ -123,6 +123,12 @@ public class TemplateBuilderImpl implements TemplateBuilder { myElements.add(key); } + public void replaceRange(TextRange rangeWithinElement, Expression expression) { + final RangeMarker key = myDocument.createRangeMarker(rangeWithinElement); + myExpressions.put(key, expression); + myElements.add(key); + } + /** * Adds end variable after the specified element */ From 5ce2891148812392d996d4041e194358d8d278c6 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 26 Jul 2010 19:01:08 +0400 Subject: [PATCH 084/102] do not search dependencies in rebuild mode and when nothing was compiled before --- .../intellij/compiler/impl/CompileDriver.java | 86 ++++++++++--------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 5a0d69840443..230c9e999ec9 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -1019,47 +1019,52 @@ public class CompileDriver { didSomething |= compiledSomething; } - final Set compiledWithSuccess; - final Set compiledWithErrors = CacheUtils.getFilesCompiledWithErrors(context); - if (compiledWithErrors.isEmpty()) { - compiledWithSuccess = sink.getCompiledSources(); - } - else { - compiledWithSuccess = new HashSet(); - compiledWithSuccess.addAll(sink.getCompiledSources()); - compiledWithSuccess.removeAll(compiledWithErrors); - } - filesToRecompile.removeAll(compiledWithSuccess); - filesToRecompile.addAll(compiledWithErrors); - - dependentFiles = CacheUtils.findDependentFiles(context, compiledWithSuccess, dependencyFilter); - - if (ourDebugMode) { - if (!dependentFiles.isEmpty()) { - for (VirtualFile dependentFile : dependentFiles) { - System.out.println("FOUND TO RECOMPILE: " + dependentFile.getPresentableUrl()); - } + final boolean hasUnprocessedTraverseRoots = context.getDependencyCache().hasUnprocessedTraverseRoots(); + if (!isRebuild && (didSomething || hasUnprocessedTraverseRoots)) { + final Set compiledWithSuccess; + final Set compiledWithErrors = CacheUtils.getFilesCompiledWithErrors(context); + if (compiledWithErrors.isEmpty()) { + compiledWithSuccess = sink.getCompiledSources(); } else { - System.out.println("NO FILES TO RECOMPILE"); + compiledWithSuccess = new HashSet(); + compiledWithSuccess.addAll(sink.getCompiledSources()); + compiledWithSuccess.removeAll(compiledWithErrors); } + filesToRecompile.removeAll(compiledWithSuccess); + filesToRecompile.addAll(compiledWithErrors); + + dependentFiles = CacheUtils.findDependentFiles(context, compiledWithSuccess, dependencyFilter); + + if (ourDebugMode) { + if (!dependentFiles.isEmpty()) { + for (VirtualFile dependentFile : dependentFiles) { + System.out.println("FOUND TO RECOMPILE: " + dependentFile.getPresentableUrl()); + } + } + else { + System.out.println("NO FILES TO RECOMPILE"); + } + } + + if (!dependentFiles.isEmpty()) { + filesToRecompile.addAll(dependentFiles); + allDependent.addAll(dependentFiles); + if (context.getProgressIndicator().isCanceled() || context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + break; + } + final List filesInScope = getFilesInScope(context, currentChunk, dependentFiles); + if (filesInScope.isEmpty()) { + break; + } + context.getDependencyCache().clearTraverseRoots(); + chunkFiles = filesInScope; + total += chunkFiles.size() * translators.length; + } + + didSomething |= (hasUnprocessedTraverseRoots != context.getDependencyCache().hasUnprocessedTraverseRoots()); } - - if (!dependentFiles.isEmpty()) { - filesToRecompile.addAll(dependentFiles); - allDependent.addAll(dependentFiles); - if (context.getProgressIndicator().isCanceled() || context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { - break; - } - final List filesInScope = getFilesInScope(context, currentChunk, dependentFiles); - if (filesInScope.isEmpty()) { - break; - } - context.getDependencyCache().clearTraverseRoots(); - chunkFiles = filesInScope; - total += chunkFiles.size() * translators.length; - } - + round++; } while (!dependentFiles.isEmpty() && context.getMessageCount(CompilerMessageCategory.ERROR) == 0); @@ -1638,7 +1643,6 @@ public class CompileDriver { context.getProgressIndicator().pushState(); final boolean[] wereFilesDeleted = new boolean[]{false}; - boolean traverseRootsProcessed = false; try { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { @@ -1695,16 +1699,14 @@ public class CompileDriver { } } - final boolean hadUnprocessedTraverseRoots = context.getDependencyCache().hasUnprocessedTraverseRoots(); - if ((wereFilesDeleted[0] || hadUnprocessedTraverseRoots || !toCompile.isEmpty()) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) { + if ((wereFilesDeleted[0] || !toCompile.isEmpty()) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) { compiler.compile(context, moduleChunk, VfsUtil.toVirtualFileArray(toCompile), sink); - traverseRootsProcessed = hadUnprocessedTraverseRoots != context.getDependencyCache().hasUnprocessedTraverseRoots(); } } finally { context.getProgressIndicator().popState(); } - return !toCompile.isEmpty() || traverseRootsProcessed || wereFilesDeleted[0]; + return !toCompile.isEmpty() || wereFilesDeleted[0]; } private static boolean syncOutputDir(final CompileContextEx context, final Collection> toDelete) throws CacheCorruptedException { From 83fe33b137ddeee619697c4560242bee3a9f8ef2 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 26 Jul 2010 18:59:56 +0400 Subject: [PATCH 085/102] Fix NPE in GroovyNameSuggestionProvider. --- .../groovy/refactoring/GroovyNameSuggestionProvider.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionProvider.java index 08a0a2ff85dc..2e1afdbbff02 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionProvider.java @@ -22,6 +22,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.statistics.JavaStatisticsManager; import com.intellij.refactoring.rename.NameSuggestionProvider; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; @@ -34,8 +35,8 @@ import java.util.Set; */ public class GroovyNameSuggestionProvider implements NameSuggestionProvider { @Override - public SuggestedNameInfo getSuggestedNames(final PsiElement element, PsiElement nameSuggestionContext, Set result) { - if (!(element instanceof GroovyPsiElement)) return null; + public SuggestedNameInfo getSuggestedNames(final PsiElement element, @Nullable PsiElement nameSuggestionContext, Set result) { + if (nameSuggestionContext == null || !(element instanceof GroovyPsiElement)) return null; if (element instanceof GrVariable) { final PsiType type = ((GrVariable)element).getTypeGroovy(); if (type != null) { @@ -56,7 +57,7 @@ public class GroovyNameSuggestionProvider implements NameSuggestionProvider { } @Override - public Collection completeName(PsiElement element, PsiElement nameSuggestionContext, String prefix) { + public Collection completeName(PsiElement element, @Nullable PsiElement nameSuggestionContext, String prefix) { return null; } } From cea9846cee76bbd4099eb14d476bd6c47bf012c6 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 26 Jul 2010 19:08:26 +0400 Subject: [PATCH 086/102] Fix NPE in GroovyNameSuggestionProvider. --- .../intellij/refactoring/rename/NameSuggestionProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-api/src/com/intellij/refactoring/rename/NameSuggestionProvider.java b/platform/lang-api/src/com/intellij/refactoring/rename/NameSuggestionProvider.java index 456d583038c6..21e8ed12dc36 100644 --- a/platform/lang-api/src/com/intellij/refactoring/rename/NameSuggestionProvider.java +++ b/platform/lang-api/src/com/intellij/refactoring/rename/NameSuggestionProvider.java @@ -32,8 +32,8 @@ public interface NameSuggestionProvider { ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.nameSuggestionProvider"); @Nullable - SuggestedNameInfo getSuggestedNames(PsiElement element, PsiElement nameSuggestionContext, Set result); + SuggestedNameInfo getSuggestedNames(PsiElement element, @Nullable PsiElement nameSuggestionContext, Set result); @Nullable - Collection completeName(PsiElement element, final PsiElement nameSuggestionContext, final String prefix); + Collection completeName(PsiElement element, @Nullable final PsiElement nameSuggestionContext, final String prefix); } From 1b4e4575ce26b4a97d51e838add0ba9e9c27895a Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 26 Jul 2010 19:17:17 +0400 Subject: [PATCH 087/102] IDEA-56356 Soft wrap: varargs type declaration could be considered as a whole Soft wrap appliance point selection algorithm is corrected --- .../DefaultSoftWrapApplianceManager.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java index 36b90dd4f12a..876d7bd3ea71 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java @@ -269,7 +269,17 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager // Try to find target offset that is not greater than preferred position. for (int i = preferred; i > min; i--) { char c = text[i]; - if ((i < preferred) && (SPECIAL_SYMBOLS_TO_WRAP_AFTER.contains(c) || WHITE_SPACES.contains(c))) { + + if (i < preferred && WHITE_SPACES.contains(c)) { + return i + 1; + } + + // Don't wrap on the non-id symbol preceded by another non-id symbol. E.g. consider that we have a statement + // like 'foo(int... args)'. We don't want to wrap on the second or third dots then. + if (i > min + 1 && !isIdSymbol(c) && !isIdSymbol(text[i - 1])) { + continue; + } + if ((i < preferred) && SPECIAL_SYMBOLS_TO_WRAP_AFTER.contains(c)) { return i + 1; } if (SPECIAL_SYMBOLS_TO_WRAP_BEFORE.contains(c) || WHITE_SPACES.contains(c)) { @@ -286,7 +296,15 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager // Try to find target offset that is greater than preferred position. for (int i = preferred + 1; i < max; i++) { char c = text[i]; - if (SPECIAL_SYMBOLS_TO_WRAP_BEFORE.contains(c) || WHITE_SPACES.contains(c)) { + if (WHITE_SPACES.contains(c)) { + return i; + } + // Don't wrap on the non-id symbol preceded by another non-id symbol. E.g. consider that we have a statement + // like 'foo(int... args)'. We don't want to wrap on the second or third dots then. + if (i < max - 1 && !isIdSymbol(c) && !isIdSymbol(text[i + 1]) && !isIdSymbol(text[i - 1])) { + continue; + } + if (SPECIAL_SYMBOLS_TO_WRAP_BEFORE.contains(c)) { return i; } if (SPECIAL_SYMBOLS_TO_WRAP_AFTER.contains(c) && i < max - 1) { From eb96c914edec100b620a83a714518cb01cbce102 Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Mon, 26 Jul 2010 19:24:55 +0400 Subject: [PATCH 088/102] 'Extract Interface' and 'Extract Module' are now two separate first-class actions --- .../java/JavaRefactoringSupportProvider.java | 2 +- .../DefaultRefactoringSupportProvider.java | 4 +++ .../RefactoringSupportProvider.java | 6 ++++ .../actions/ExtractInterfaceAction.java | 35 +++++++++++++++++++ .../actions/ExtractModuleAction.java | 16 ++++----- ...ction.java => ExtractSuperActionBase.java} | 26 +++++++------- .../actions/ExtractSuperclassAction.java | 34 +++--------------- .../src/messages/ActionsBundle.properties | 2 ++ .../src/idea/LangActions.xml | 4 ++- resources/src/idea/IdeaActions.xml | 4 --- 10 files changed, 76 insertions(+), 57 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/refactoring/actions/ExtractInterfaceAction.java rename java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceAction.java => platform/lang-impl/src/com/intellij/refactoring/actions/ExtractModuleAction.java (62%) rename platform/lang-impl/src/com/intellij/refactoring/actions/{BaseExtractModuleAction.java => ExtractSuperActionBase.java} (62%) diff --git a/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java index 59dd9463b2d4..aa153df182ab 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java @@ -78,7 +78,7 @@ public class JavaRefactoringSupportProvider extends DefaultRefactoringSupportPro return new JavaPushDownHandler(); } - public RefactoringActionHandler getExtractModuleHandler() { + public RefactoringActionHandler getExtractInterfaceHandler() { return new ExtractInterfaceHandler(); } diff --git a/platform/lang-api/src/com/intellij/lang/refactoring/DefaultRefactoringSupportProvider.java b/platform/lang-api/src/com/intellij/lang/refactoring/DefaultRefactoringSupportProvider.java index 3db3337d1493..5a4cb9c1b077 100644 --- a/platform/lang-api/src/com/intellij/lang/refactoring/DefaultRefactoringSupportProvider.java +++ b/platform/lang-api/src/com/intellij/lang/refactoring/DefaultRefactoringSupportProvider.java @@ -59,6 +59,10 @@ public class DefaultRefactoringSupportProvider implements RefactoringSupportProv return null; } + public RefactoringActionHandler getExtractInterfaceHandler() { + return null; + } + public RefactoringActionHandler getExtractModuleHandler() { return null; } diff --git a/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java b/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java index 7aa9480d5e7b..ac244743397b 100644 --- a/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java +++ b/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java @@ -80,6 +80,12 @@ public interface RefactoringSupportProvider { */ @Nullable RefactoringActionHandler getPushDownHandler(); + /** + * @return handler for extracting members to an interface in this language + * @see com.intellij.refactoring.RefactoringActionHandler + */ + @Nullable RefactoringActionHandler getExtractInterfaceHandler(); + /** * @return handler for extracting members to some module in this language * @see com.intellij.refactoring.RefactoringActionHandler diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractInterfaceAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractInterfaceAction.java new file mode 100644 index 000000000000..88fbf0801347 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractInterfaceAction.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2009 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.actions; + +import com.intellij.lang.refactoring.RefactoringSupportProvider; +import com.intellij.refactoring.RefactoringActionHandler; +import org.jetbrains.annotations.Nullable; + +public class ExtractInterfaceAction extends ExtractSuperActionBase { + + public ExtractInterfaceAction() { + setInjectedContext(true); + } + + @Nullable + @Override + protected RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider) { + return supportProvider.getExtractInterfaceHandler(); + } + +} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractModuleAction.java similarity index 62% rename from java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceAction.java rename to platform/lang-impl/src/com/intellij/refactoring/actions/ExtractModuleAction.java index 401e454ecc32..0715cdcfa350 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractModuleAction.java @@ -13,19 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.refactoring.extractInterface; -import com.intellij.refactoring.actions.BaseExtractModuleAction; -import com.intellij.lang.Language; -import com.intellij.lang.java.JavaLanguage; +package com.intellij.refactoring.actions; + +import com.intellij.lang.refactoring.RefactoringSupportProvider; +import com.intellij.refactoring.RefactoringActionHandler; /** * @author Dennis.Ushakov */ -public class ExtractInterfaceAction extends BaseExtractModuleAction { +public class ExtractModuleAction extends ExtractSuperActionBase { @Override - protected boolean isEnabledOnLanguage(Language language) { - return language instanceof JavaLanguage; + protected RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider) { + return supportProvider.getExtractModuleHandler(); } -} +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/BaseExtractModuleAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractSuperActionBase.java similarity index 62% rename from platform/lang-impl/src/com/intellij/refactoring/actions/BaseExtractModuleAction.java rename to platform/lang-impl/src/com/intellij/refactoring/actions/ExtractSuperActionBase.java index d20e83f49be3..8c0a5c83f5bf 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/actions/BaseExtractModuleAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractSuperActionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -25,8 +25,10 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.lang.ElementsHandler; +import org.jetbrains.annotations.Nullable; + +public abstract class ExtractSuperActionBase extends BasePlatformRefactoringAction { -public abstract class BaseExtractModuleAction extends BaseRefactoringAction { public boolean isAvailableInEditorOnly() { return false; } @@ -34,27 +36,25 @@ public abstract class BaseExtractModuleAction extends BaseRefactoringAction { public boolean isEnabledOnElements(PsiElement[] elements) { if (elements.length > 0) { final Language language = elements[0].getLanguage(); - final RefactoringActionHandler handler = getRefactoringSupport(language).getExtractModuleHandler(); - return isEnabledOnLanguage(language) && handler instanceof ElementsHandler && ((ElementsHandler)handler).isEnabledOnElements(elements); + final RefactoringActionHandler handler = getRefactoringHandler(LanguageRefactoringSupport.INSTANCE.forLanguage(language)); + return handler instanceof ElementsHandler && ((ElementsHandler)handler).isEnabledOnElements(elements); } return false; } - protected RefactoringSupportProvider getRefactoringSupport(Language language) { - return LanguageRefactoringSupport.INSTANCE.forLanguage(language); - } - - public RefactoringActionHandler getHandler(DataContext dataContext) { PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext); if (file == null) return null; - final RefactoringSupportProvider supportProvider = getRefactoringSupport(file.getViewProvider().getBaseLanguage()); - return supportProvider != null ? supportProvider.getExtractModuleHandler() : null; + final RefactoringSupportProvider supportProvider = + LanguageRefactoringSupport.INSTANCE.forLanguage(file.getViewProvider().getBaseLanguage()); + return supportProvider != null ? getRefactoringHandler(supportProvider) : null; } + @Nullable + protected abstract RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider); + protected boolean isAvailableForLanguage(final Language language) { - return isEnabledOnLanguage(language) && getRefactoringSupport(language).getExtractModuleHandler() != null; + return getRefactoringHandler(LanguageRefactoringSupport.INSTANCE.forLanguage(language)) != null; } - protected abstract boolean isEnabledOnLanguage(final Language language); } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractSuperclassAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractSuperclassAction.java index 02290346a898..d9d99b71c95a 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractSuperclassAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/ExtractSuperclassAction.java @@ -16,38 +16,12 @@ package com.intellij.refactoring.actions; -import com.intellij.lang.Language; -import com.intellij.lang.LanguageRefactoringSupport; import com.intellij.lang.refactoring.RefactoringSupportProvider; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.LangDataKeys; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; import com.intellij.refactoring.RefactoringActionHandler; -import com.intellij.refactoring.lang.ElementsHandler; -public class ExtractSuperclassAction extends BasePlatformRefactoringAction { - public boolean isAvailableInEditorOnly() { - return false; - } - - public boolean isEnabledOnElements(PsiElement[] elements) { - if (elements.length > 0) { - final Language language = elements[0].getLanguage(); - final RefactoringActionHandler handler = LanguageRefactoringSupport.INSTANCE.forLanguage(language).getExtractModuleHandler(); - return handler instanceof ElementsHandler && ((ElementsHandler)handler).isEnabledOnElements(elements); - } - return false; - } - - public RefactoringActionHandler getHandler(DataContext dataContext) { - PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext); - if (file == null) return null; - final RefactoringSupportProvider supportProvider = LanguageRefactoringSupport.INSTANCE.forLanguage(file.getViewProvider().getBaseLanguage()); - return supportProvider != null ? supportProvider.getExtractSuperClassHandler() : null; - } - - protected boolean isAvailableForLanguage(final Language language) { - return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getExtractSuperClassHandler() != null; +public class ExtractSuperclassAction extends ExtractSuperActionBase { + @Override + protected RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider) { + return supportProvider.getExtractSuperClassHandler(); } } \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 527d5e8b0da8..bb4a5d8623d7 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -508,6 +508,8 @@ action.IntroduceParameter.text=Introduce _Parameter... action.IntroduceParameter.description=Turn the selected expression into method parameter action.ExtractInterface.text=Extract _Interface... action.ExtractInterface.description=Extract interface from the selected class +action.ExtractModule.text=Extract _Module... +action.ExtractModule.description=Extract module from the selected class action.ExtractSuperclass.text=Extract S_uperclass... action.ExtractSuperclass.description=Extract superclass from the selected class action.TurnRefsToSuper.text=Use Interface _Where Possible... diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 31398574a513..077cba2d4153 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -6,7 +6,7 @@ - + @@ -285,6 +285,8 @@ + + diff --git a/resources/src/idea/IdeaActions.xml b/resources/src/idea/IdeaActions.xml index 57745c3c45dc..c34d1bd90657 100644 --- a/resources/src/idea/IdeaActions.xml +++ b/resources/src/idea/IdeaActions.xml @@ -161,10 +161,6 @@ - - - - From f5d1eb37ed1bbe928fe22c24bb25d239636fd4bf Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Mon, 26 Jul 2010 18:39:25 +0400 Subject: [PATCH 089/102] NULL object --- .../src/com/intellij/psi/impl/PsiCachedValueImpl.java | 3 +++ .../intellij/psi/impl/PsiParameterizedCachedValue.java | 3 +++ .../src/com/intellij/util/CachedValueBase.java | 5 +++-- .../src/com/intellij/util/CachedValueImpl.java | 4 ++-- .../com/intellij/util/ParameterizedCachedValueImpl.java | 2 ++ .../src/com/intellij/openapi/util/NullableLazyKey.java | 6 +++--- platform/util/src/com/intellij/util/ObjectUtils.java | 2 ++ .../util/src/com/intellij/util/containers/FactoryMap.java | 3 ++- .../src/com/intellij/util/containers/SoftFactoryMap.java | 8 +++++--- .../src/com/intellij/util/containers/WeakFactoryMap.java | 8 +++++--- 10 files changed, 30 insertions(+), 14 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiCachedValueImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiCachedValueImpl.java index d4af0c93a429..e301e75b77fd 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiCachedValueImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiCachedValueImpl.java @@ -19,8 +19,11 @@ package com.intellij.psi.impl; import com.intellij.psi.PsiManager; import com.intellij.psi.util.CachedValue; import com.intellij.psi.util.CachedValueProvider; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.Nullable; +import static com.intellij.util.ObjectUtils.*; + /** * @author Dmitry Avdeev */ diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiParameterizedCachedValue.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiParameterizedCachedValue.java index 5d93119e8550..778931575c04 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiParameterizedCachedValue.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiParameterizedCachedValue.java @@ -28,9 +28,12 @@ import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.ParameterizedCachedValueProvider; import com.intellij.psi.util.ParameterizedCachedValue; import com.intellij.psi.PsiManager; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.intellij.util.ObjectUtils.*; + public abstract class PsiParameterizedCachedValue extends PsiCachedValue implements ParameterizedCachedValue { private final ParameterizedCachedValueProvider myProvider; diff --git a/platform/platform-impl/src/com/intellij/util/CachedValueBase.java b/platform/platform-impl/src/com/intellij/util/CachedValueBase.java index 80133bde1163..13edf8142a59 100644 --- a/platform/platform-impl/src/com/intellij/util/CachedValueBase.java +++ b/platform/platform-impl/src/com/intellij/util/CachedValueBase.java @@ -35,11 +35,12 @@ import java.lang.ref.Reference; import java.util.ArrayList; import java.util.List; +import static com.intellij.util.ObjectUtils.*; + /** * @author Dmitry Avdeev */ public abstract class CachedValueBase { - protected static final Object NULL = new Object(); private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.CachedValueImpl"); private final MyTimedReference myData = new MyTimedReference(); @@ -66,7 +67,7 @@ public abstract class CachedValueBase { } protected void setValue(final T value, final CachedValueProvider.Result result) { - myData.setData(computeData(value == null ? (T) NULL : value, getDependencies(result))); + myData.setData(computeData(value == null ? (T)NULL : value, getDependencies(result))); if (result != null) { myData.setIsLocked(result.isLockValue()); } diff --git a/platform/platform-impl/src/com/intellij/util/CachedValueImpl.java b/platform/platform-impl/src/com/intellij/util/CachedValueImpl.java index f6a9890319b4..aef384fae2d7 100644 --- a/platform/platform-impl/src/com/intellij/util/CachedValueImpl.java +++ b/platform/platform-impl/src/com/intellij/util/CachedValueImpl.java @@ -47,7 +47,7 @@ public abstract class CachedValueImpl extends CachedValueBase implements C try { value = getUpToDateOrNull(); if (value != null) { - return value == NULL ? null : value; + return value == ObjectUtils.NULL ? null : value; } } finally { r.unlock(); @@ -58,7 +58,7 @@ public abstract class CachedValueImpl extends CachedValueBase implements C try { value = getUpToDateOrNull(); if (value != null) { - return value == NULL ? null : value; + return value == ObjectUtils.NULL ? null : value; } CachedValueProvider.Result result = myProvider.compute(); diff --git a/platform/platform-impl/src/com/intellij/util/ParameterizedCachedValueImpl.java b/platform/platform-impl/src/com/intellij/util/ParameterizedCachedValueImpl.java index e83faa460ad2..32aa6f157f11 100644 --- a/platform/platform-impl/src/com/intellij/util/ParameterizedCachedValueImpl.java +++ b/platform/platform-impl/src/com/intellij/util/ParameterizedCachedValueImpl.java @@ -30,6 +30,8 @@ import com.intellij.psi.util.ParameterizedCachedValueProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.intellij.util.ObjectUtils.*; + public abstract class ParameterizedCachedValueImpl extends CachedValueBase implements ParameterizedCachedValue { private final ParameterizedCachedValueProvider myProvider; diff --git a/platform/util/src/com/intellij/openapi/util/NullableLazyKey.java b/platform/util/src/com/intellij/openapi/util/NullableLazyKey.java index 7b17675b3c3c..a4e4924f2eee 100644 --- a/platform/util/src/com/intellij/openapi/util/NullableLazyKey.java +++ b/platform/util/src/com/intellij/openapi/util/NullableLazyKey.java @@ -16,6 +16,7 @@ package com.intellij.openapi.util; import com.intellij.util.NullableFunction; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -23,7 +24,6 @@ import org.jetbrains.annotations.Nullable; * @author peter */ public class NullableLazyKey extends Key{ - private static final Object NULL = new Object(); private final NullableFunction myFunction; private NullableLazyKey(@NonNls String name, final NullableFunction function) { @@ -36,9 +36,9 @@ public class NullableLazyKey extends Key{ T data = h.getUserData(this); if (data == null) { data = myFunction.fun(h); - h.putUserData(this, data == null ? (T)NULL : data); + h.putUserData(this, data == null ? (T)ObjectUtils.NULL : data); } - return data == NULL ? null : data; + return data == ObjectUtils.NULL ? null : data; } public static NullableLazyKey create(@NonNls String name, final NullableFunction function) { diff --git a/platform/util/src/com/intellij/util/ObjectUtils.java b/platform/util/src/com/intellij/util/ObjectUtils.java index 82adc4900eb9..bf0c2de574a9 100644 --- a/platform/util/src/com/intellij/util/ObjectUtils.java +++ b/platform/util/src/com/intellij/util/ObjectUtils.java @@ -25,6 +25,8 @@ public class ObjectUtils { private ObjectUtils() { } + public static final Object NULL = new Object(); + @NotNull public static T assertNotNull(@Nullable final T t) { return _assertNotNull(t); diff --git a/platform/util/src/com/intellij/util/containers/FactoryMap.java b/platform/util/src/com/intellij/util/containers/FactoryMap.java index 0133310a92ca..08395cbd08df 100644 --- a/platform/util/src/com/intellij/util/containers/FactoryMap.java +++ b/platform/util/src/com/intellij/util/containers/FactoryMap.java @@ -21,11 +21,12 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.HashSet; +import static com.intellij.util.ObjectUtils.NULL; + /** * @author peter */ public abstract class FactoryMap implements Map { - static final Object NULL = new Object(); protected Map myMap; protected Map createMap() { diff --git a/platform/util/src/com/intellij/util/containers/SoftFactoryMap.java b/platform/util/src/com/intellij/util/containers/SoftFactoryMap.java index 24748e7d9501..17ba065ea122 100644 --- a/platform/util/src/com/intellij/util/containers/SoftFactoryMap.java +++ b/platform/util/src/com/intellij/util/containers/SoftFactoryMap.java @@ -19,6 +19,8 @@ package com.intellij.util.containers; import java.lang.ref.SoftReference; import java.util.concurrent.ConcurrentMap; +import static com.intellij.util.ObjectUtils.NULL; + /** * @author peter */ @@ -32,15 +34,15 @@ public abstract class SoftFactoryMap { if (reference != null) { final V v = reference.get(); if (v != null) { - return v == FactoryMap.NULL ? null : v; + return v == NULL ? null : v; } } final V value = create(key); - SoftReference valueRef = new SoftReference(value == null ? (V)FactoryMap.NULL : value); + SoftReference valueRef = new SoftReference(value == null ? (V)NULL : value); SoftReference prevRef = myMap.putIfAbsent(key, valueRef); V prev = prevRef == null ? null : prevRef.get(); - return prev == null || prev == FactoryMap.NULL? value : prev; + return prev == null || prev == NULL ? value : prev; } public final boolean containsKey(T key) { diff --git a/platform/util/src/com/intellij/util/containers/WeakFactoryMap.java b/platform/util/src/com/intellij/util/containers/WeakFactoryMap.java index e01baa50b28a..2df74cd24c94 100644 --- a/platform/util/src/com/intellij/util/containers/WeakFactoryMap.java +++ b/platform/util/src/com/intellij/util/containers/WeakFactoryMap.java @@ -18,6 +18,8 @@ package com.intellij.util.containers; import java.lang.ref.WeakReference; import java.util.concurrent.ConcurrentMap; +import static com.intellij.util.ObjectUtils.NULL; + /** * @author peter */ @@ -31,15 +33,15 @@ public abstract class WeakFactoryMap { if (reference != null) { final V v = reference.get(); if (v != null) { - return v == FactoryMap.NULL ? null : v; + return v == NULL ? null : v; } } final V value = create(key); - WeakReference valueRef = new WeakReference(value == null ? (V)FactoryMap.NULL : value); + WeakReference valueRef = new WeakReference(value == null ? (V)NULL : value); WeakReference prevRef = myMap.putIfAbsent(key, valueRef); V prev = prevRef == null ? null : prevRef.get(); - return prev == null || prev == FactoryMap.NULL? value : prev; + return prev == null || prev == NULL ? value : prev; } public final boolean containsKey(T key) { From adb873e5988520f75d9ddccd047e62d8b5e5d799 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Mon, 26 Jul 2010 18:56:27 +0400 Subject: [PATCH 090/102] better fix for missing binary indexer --- .../intellij/psi/stubs/StubUpdatingIndex.java | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index f20b020e2681..1d4734a43ac6 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -32,6 +32,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.IStubFileElementType; +import com.intellij.util.ObjectUtils; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.IntInlineKeyDescriptor; @@ -127,37 +128,43 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi }; } - private static Key stubElementKey = Key.create("stub.tree.for.file.content"); + private static Key stubElementKey = Key.create("stub.tree.for.file.content"); @Nullable public static StubElement buildStubTree(final FileContent inputData) { - StubElement data = inputData.getUserData(stubElementKey); - if (data != null) return data; + Object data = inputData.getUserData(stubElementKey); + if (data == null) { + synchronized (inputData) { + data = inputData.getUserData(stubElementKey); + if (data == null) { + final FileType fileType = inputData.getFileType(); - synchronized (inputData) { - data = inputData.getUserData(stubElementKey); - if (data != null) return data; + if (fileType.isBinary()) { + final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); + if (builder != null) { + data = builder.buildStubTree(inputData.getFile(), inputData.getContent(), inputData.getProject()); + } + else { + data = ObjectUtils.NULL; + } + } + else { + final LanguageFileType filetype = (LanguageFileType)fileType; + Language l = filetype.getLanguage(); + final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType(); - final FileType fileType = inputData.getFileType(); + PsiFile psi = inputData.getPsiFile(); - if (fileType.isBinary()) { - final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); - assert builder != null; + data = ((IStubFileElementType)type).getBuilder().buildStubTree(psi); + } - data = builder.buildStubTree(inputData.getFile(), inputData.getContent(), inputData.getProject()); - } else { - final LanguageFileType filetype = (LanguageFileType)fileType; - Language l = filetype.getLanguage(); - final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType(); - - PsiFile psi = inputData.getPsiFile(); - - data = ((IStubFileElementType)type).getBuilder().buildStubTree(psi); + inputData.putUserData(stubElementKey, data); + } } - - inputData.putUserData(stubElementKey, data); - return data; } + if (data == ObjectUtils.NULL) return null; + if (data instanceof StubElement) return (StubElement)data; + throw new AssertionError(data); } public KeyDescriptor getKeyDescriptor() { From f8b6740da8a18221540ccfa7a60c948f2bd0370e Mon Sep 17 00:00:00 2001 From: Alexander Chernikov Date: Mon, 26 Jul 2010 23:58:04 +0400 Subject: [PATCH 091/102] Eclipse integration: lib/var collision test data. --- .../varAddJavadoc/expected/.classpath | 9 +++++++++ .../varAddJavadoc/expected/ws-internals.eml | 8 ++++++++ .../modification/varAddJavadoc/jars/test.jar | Bin 0 -> 840 bytes .../modification/varAddJavadoc/test/.classpath | 5 +++++ .../modification/varAddJavadoc/test/.project | 17 +++++++++++++++++ .../varAddJavadoc/variableidea/test.jar | Bin 0 -> 840 bytes .../EclipseLibrariesModificationsTest.java | 6 ++++++ 7 files changed, 45 insertions(+) create mode 100644 plugins/eclipse/testData/modification/varAddJavadoc/expected/.classpath create mode 100644 plugins/eclipse/testData/modification/varAddJavadoc/expected/ws-internals.eml create mode 100644 plugins/eclipse/testData/modification/varAddJavadoc/jars/test.jar create mode 100644 plugins/eclipse/testData/modification/varAddJavadoc/test/.classpath create mode 100644 plugins/eclipse/testData/modification/varAddJavadoc/test/.project create mode 100644 plugins/eclipse/testData/modification/varAddJavadoc/variableidea/test.jar diff --git a/plugins/eclipse/testData/modification/varAddJavadoc/expected/.classpath b/plugins/eclipse/testData/modification/varAddJavadoc/expected/.classpath new file mode 100644 index 000000000000..f53870069b97 --- /dev/null +++ b/plugins/eclipse/testData/modification/varAddJavadoc/expected/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/varAddJavadoc/expected/ws-internals.eml b/plugins/eclipse/testData/modification/varAddJavadoc/expected/ws-internals.eml new file mode 100644 index 000000000000..7025e8384962 --- /dev/null +++ b/plugins/eclipse/testData/modification/varAddJavadoc/expected/ws-internals.eml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/varAddJavadoc/jars/test.jar b/plugins/eclipse/testData/modification/varAddJavadoc/jars/test.jar new file mode 100644 index 0000000000000000000000000000000000000000..69d35ecffe38daa9f5223585d031f42787e479ea GIT binary patch literal 840 zcmWIWW@h1H0D*&D*;Zf%l;C7wVeoYgan$wnbJPEKih&^js+5D_08pvpv?#qOpwcuT z76D?oQeQ_uPdC@#5ItYF&%S3)`*`c>UF7xF)jD_P{N^BoE5;9=7M*bxD%A1tIp-0| z(8Z{F_A5{2&Nakr?==Sg2p zDtA`wgu8`-VKbVuxq)s;P0qCj$a%FO#%hK-c`}?QrKSM!hEq7^&@0(dSlq0?$e0+Da{fl;IC-WIy zOFsln?A;q6t|c8WEMtHESyYOZ&`YOn7nDu%LzaEfU07EnCCFnh@7W~1!snZ~{zjcP zCBM{})76!FT^4%n%aW>E^sJ@XL2c!%v#AS`^v{U9D#=S!E>H~?wfD3=>FyI2zG}-Z z>AS8!gQRu0aPF<2%rW<@S#yP!u&=@Nr$X-G7H+-!85Lv>IW%Waj^tI7*GiVueOD3F znf>?;@0TdgZ4$FXH}lTE_)qY_!7|Yo>&`wGJs!XK^J$Olwxj^j c2(tPCsz&sL5#Y_r22#udg#UrGF%yUf0C~Xuh5!Hn literal 0 HcmV?d00001 diff --git a/plugins/eclipse/testData/modification/varAddJavadoc/test/.classpath b/plugins/eclipse/testData/modification/varAddJavadoc/test/.classpath new file mode 100644 index 000000000000..65e495d45cd3 --- /dev/null +++ b/plugins/eclipse/testData/modification/varAddJavadoc/test/.classpath @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/varAddJavadoc/test/.project b/plugins/eclipse/testData/modification/varAddJavadoc/test/.project new file mode 100644 index 000000000000..3c7030a86519 --- /dev/null +++ b/plugins/eclipse/testData/modification/varAddJavadoc/test/.project @@ -0,0 +1,17 @@ + + + ws-internals + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/plugins/eclipse/testData/modification/varAddJavadoc/variableidea/test.jar b/plugins/eclipse/testData/modification/varAddJavadoc/variableidea/test.jar new file mode 100644 index 0000000000000000000000000000000000000000..69d35ecffe38daa9f5223585d031f42787e479ea GIT binary patch literal 840 zcmWIWW@h1H0D*&D*;Zf%l;C7wVeoYgan$wnbJPEKih&^js+5D_08pvpv?#qOpwcuT z76D?oQeQ_uPdC@#5ItYF&%S3)`*`c>UF7xF)jD_P{N^BoE5;9=7M*bxD%A1tIp-0| z(8Z{F_A5{2&Nakr?==Sg2p zDtA`wgu8`-VKbVuxq)s;P0qCj$a%FO#%hK-c`}?QrKSM!hEq7^&@0(dSlq0?$e0+Da{fl;IC-WIy zOFsln?A;q6t|c8WEMtHESyYOZ&`YOn7nDu%LzaEfU07EnCCFnh@7W~1!snZ~{zjcP zCBM{})76!FT^4%n%aW>E^sJ@XL2c!%v#AS`^v{U9D#=S!E>H~?wfD3=>FyI2zG}-Z z>AS8!gQRu0aPF<2%rW<@S#yP!u&=@Nr$X-G7H+-!85Lv>IW%Waj^tI7*GiVueOD3F znf>?;@0TdgZ4$FXH}lTE_)qY_!7|Yo>&`wGJs!XK^J$Olwxj^j c2(tPCsz&sL5#Y_r22#udg#UrGF%yUf0C~Xuh5!Hn literal 0 HcmV?d00001 diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseLibrariesModificationsTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseLibrariesModificationsTest.java index 08a2d1c44152..9a6fcdb8b5e0 100644 --- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseLibrariesModificationsTest.java +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseLibrariesModificationsTest.java @@ -128,6 +128,12 @@ public class EclipseLibrariesModificationsTest extends EclipseVarsTest { new String[]{}); } + public void testVarAddJavadoc() throws Exception { + doTestExisting(new String[]{"/variableidea/test.jar!/"}, + new String[]{"/variableidea/test.jar!/"}, + new String[]{"/jars/test.jar!/"}); + } + public void testVarAddVarSource() throws Exception { doTestExisting(new String[]{"/variableidea/test.jar!/"}, new String[]{"/variableidea/test.jar!/", "/srcvariableidea/test.jar!/"}, From 284d2492473d2b80ebf569908d2f42623c5b247d Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 26 Jul 2010 17:46:59 +0100 Subject: [PATCH 092/102] recompile classes that depend on the changed Groovy classes --- .../groovy/compiler/GroovyCompilerBase.java | 32 +++++++++++++++++++ .../groovy/compiler/GppCompilerTest.groovy | 12 +++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java index a308f70f04f4..e1dca6a60a14 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java @@ -20,6 +20,8 @@ import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.impl.CompilerUtil; import com.intellij.compiler.impl.FileSetCompileScope; import com.intellij.compiler.impl.javaCompiler.ModuleChunk; +import com.intellij.compiler.make.CacheCorruptedException; +import com.intellij.compiler.make.DependencyCache; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.configurations.JavaParameters; @@ -34,6 +36,8 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JavaSdkType; import com.intellij.openapi.projectRoots.JdkUtil; @@ -58,6 +62,7 @@ import com.intellij.util.Chunk; import com.intellij.util.PathUtil; import com.intellij.util.PathsList; import com.intellij.util.SmartList; +import com.intellij.util.cls.ClsFormatException; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -207,6 +212,33 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { } addStubsToCompileScope(outputPaths, compileContext, module); outputItems = Collections.emptyList(); + } else { + final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null) { + indicator.setText("Updating caches..."); + } + + final DependencyCache dependencyCache = ((CompileContextEx)compileContext).getDependencyCache(); + for (OutputItem outputItem : outputItems) { + if (indicator != null) { + indicator.setText2(outputItem.getSourceFile().getName()); + } + + final String path = outputItem.getOutputPath(); + final File classFile = new File(path); + try { + dependencyCache.reparseClassFile(classFile, FileUtil.loadFileBytes(classFile)); + } + catch (ClsFormatException e) { + LOG.error(e); + } + catch (CacheCorruptedException e) { + LOG.error(e); + } + catch (IOException e) { + LOG.error(e); + } + } } sink.add(outputDir.getPath(), outputItems, VfsUtil.toVirtualFileArray(toRecompile)); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy index 94ccc740d1da..7d951d2ef99d 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GppCompilerTest.groovy @@ -59,7 +59,7 @@ class Foo implements SomeTrait { assertEmpty(make()); } - public void _testRecompileDependentGroovyClasses() throws Exception { + public void testRecompileDependentGroovyClasses() throws Exception { def a = myFixture.addFileToProject("A.gpp", """ class A { void foo() { @@ -85,7 +85,7 @@ class A { assertOutput "b", "239" } - public void _testRecompileDependentJavaClasses() throws Exception { + public void testRecompileDependentJavaClasses() throws Exception { def a = myFixture.addFileToProject("A.gpp", """ class A { void foo() { @@ -93,15 +93,15 @@ class A { } } """) - myFixture.addFileToProject("B.gpp", """ + myFixture.addFileToProject("B.java", """ public class B { - public static void main() { + public static void main(String[] args) { new A().foo(); } } """) assertEmpty make() - assertOutput "b", "239" + assertOutput "B", "239" VfsUtil.saveText a.virtualFile, """ class A { @@ -112,7 +112,7 @@ class A { """ assertEmpty make() - assertOutput "b", "239" + assertOutput "B", "239" } } From 04c01a352c30be0a84847c66adb2706fb1534cb9 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 26 Jul 2010 21:30:31 +0400 Subject: [PATCH 093/102] play nice when swf is not mapped --- .../intellij/psi/stubs/StubUpdatingIndex.java | 51 ++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index 1d4734a43ac6..f20b020e2681 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -32,7 +32,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.IStubFileElementType; -import com.intellij.util.ObjectUtils; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.IntInlineKeyDescriptor; @@ -128,43 +127,37 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi }; } - private static Key stubElementKey = Key.create("stub.tree.for.file.content"); + private static Key stubElementKey = Key.create("stub.tree.for.file.content"); @Nullable public static StubElement buildStubTree(final FileContent inputData) { - Object data = inputData.getUserData(stubElementKey); - if (data == null) { - synchronized (inputData) { - data = inputData.getUserData(stubElementKey); - if (data == null) { - final FileType fileType = inputData.getFileType(); + StubElement data = inputData.getUserData(stubElementKey); + if (data != null) return data; - if (fileType.isBinary()) { - final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); - if (builder != null) { - data = builder.buildStubTree(inputData.getFile(), inputData.getContent(), inputData.getProject()); - } - else { - data = ObjectUtils.NULL; - } - } - else { - final LanguageFileType filetype = (LanguageFileType)fileType; - Language l = filetype.getLanguage(); - final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType(); + synchronized (inputData) { + data = inputData.getUserData(stubElementKey); + if (data != null) return data; - PsiFile psi = inputData.getPsiFile(); + final FileType fileType = inputData.getFileType(); - data = ((IStubFileElementType)type).getBuilder().buildStubTree(psi); - } + if (fileType.isBinary()) { + final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType); + assert builder != null; - inputData.putUserData(stubElementKey, data); - } + data = builder.buildStubTree(inputData.getFile(), inputData.getContent(), inputData.getProject()); + } else { + final LanguageFileType filetype = (LanguageFileType)fileType; + Language l = filetype.getLanguage(); + final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType(); + + PsiFile psi = inputData.getPsiFile(); + + data = ((IStubFileElementType)type).getBuilder().buildStubTree(psi); } + + inputData.putUserData(stubElementKey, data); + return data; } - if (data == ObjectUtils.NULL) return null; - if (data instanceof StubElement) return (StubElement)data; - throw new AssertionError(data); } public KeyDescriptor getKeyDescriptor() { From 769533685cbd738fb9ac285e9a530ce43d8d00be Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 26 Jul 2010 21:37:27 +0400 Subject: [PATCH 094/102] fixed race condition in afterStartNotified --- .../execution/process/ProcessHandler.java | 61 +++++++++++++------ 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/platform/platform-api/src/com/intellij/execution/process/ProcessHandler.java b/platform/platform-api/src/com/intellij/execution/process/ProcessHandler.java index dc78a8c950fa..b33dab18a0bb 100644 --- a/platform/platform-api/src/com/intellij/execution/process/ProcessHandler.java +++ b/platform/platform-api/src/com/intellij/execution/process/ProcessHandler.java @@ -27,6 +27,7 @@ import java.io.OutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -45,14 +46,16 @@ public abstract class ProcessHandler extends UserDataHolderBase { private final Semaphore myWaitSemaphore; private final ProcessListener myEventMulticaster; + private final TasksRunner myAfterStartNotifiedRunner; protected ProcessHandler() { myEventMulticaster = createEventMulticaster(); myWaitSemaphore = new Semaphore(); myWaitSemaphore.down(); + addProcessListener(myAfterStartNotifiedRunner = new TasksRunner()); } - public synchronized void startNotify() { + public void startNotify() { if(myState.compareAndSet(STATE_INITIAL, STATE_RUNNING)) { myEventMulticaster.startNotified(new ProcessEvent(this)); } @@ -86,7 +89,7 @@ public abstract class ProcessHandler extends UserDataHolderBase { } public void destroyProcess() { - afterStartNotified(new Runnable() { + myAfterStartNotifiedRunner.execute(new Runnable() { public void run() { if (myState.compareAndSet(STATE_RUNNING, STATE_TERMINATING)) { fireProcessWillTerminate(true); @@ -97,7 +100,7 @@ public abstract class ProcessHandler extends UserDataHolderBase { } public void detachProcess() { - afterStartNotified(new Runnable() { + myAfterStartNotifiedRunner.execute(new Runnable() { public void run() { if (myState.compareAndSet(STATE_RUNNING, STATE_TERMINATING)) { fireProcessWillTerminate(false); @@ -132,7 +135,7 @@ public abstract class ProcessHandler extends UserDataHolderBase { } private void notifyTerminated(final int exitCode, final boolean willBeDestroyed) { - afterStartNotified(new Runnable() { + myAfterStartNotifiedRunner.execute(new Runnable() { public void run() { LOG.assertTrue(isStartNotified(), "Start notify is not called"); @@ -173,20 +176,6 @@ public abstract class ProcessHandler extends UserDataHolderBase { myEventMulticaster.processWillTerminate(new ProcessEvent(this), willBeDestroyed); } - private synchronized void afterStartNotified(final Runnable runnable) { - if (isStartNotified()) { - runnable.run(); - } - else { - addProcessListener(new ProcessAdapter() { - public void startNotified(ProcessEvent event) { - removeProcessListener(this); - runnable.run(); - } - }); - } - } - public boolean isStartNotified() { return myState.get() > STATE_INITIAL; } @@ -207,4 +196,40 @@ public abstract class ProcessHandler extends UserDataHolderBase { } }); } + + private final class TasksRunner extends ProcessAdapter { + private final List myPendingTasks = new ArrayList(); + + public void startNotified(ProcessEvent event) { + removeProcessListener(this); + // at this point it is guaranteed that nothing will be added to myPendingTasks + runPendingTasks(); + } + + public void execute(Runnable task) { + if (isStartNotified()) { + task.run(); + } + else { + synchronized (myPendingTasks) { + myPendingTasks.add(task); + } + if (isStartNotified()) { + runPendingTasks(); + } + } + } + + private void runPendingTasks() { + final Runnable[] tasks; + synchronized (myPendingTasks) { + tasks = myPendingTasks.toArray(new Runnable[myPendingTasks.size()]); + myPendingTasks.clear(); + } + for (Runnable task : tasks) { + task.run(); + } + } + + } } From 9af2d15c1c365c3ce848165e91e031b9beaf54d8 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Mon, 26 Jul 2010 21:50:22 +0400 Subject: [PATCH 095/102] rename standalone iml --- .../IntelliLang/{IntelliLang.iml => IntelliLang-standalone.iml} | 0 plugins/IntelliLang/IntelliLang-standalone.ipr | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename plugins/IntelliLang/{IntelliLang.iml => IntelliLang-standalone.iml} (100%) diff --git a/plugins/IntelliLang/IntelliLang.iml b/plugins/IntelliLang/IntelliLang-standalone.iml similarity index 100% rename from plugins/IntelliLang/IntelliLang.iml rename to plugins/IntelliLang/IntelliLang-standalone.iml diff --git a/plugins/IntelliLang/IntelliLang-standalone.ipr b/plugins/IntelliLang/IntelliLang-standalone.ipr index 602e7f2214d6..569835e49db6 100644 --- a/plugins/IntelliLang/IntelliLang-standalone.ipr +++ b/plugins/IntelliLang/IntelliLang-standalone.ipr @@ -530,7 +530,7 @@ - + From 00f26797287ca5176a8fa1a449cfde55dcf4da3f Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Mon, 26 Jul 2010 21:52:38 +0400 Subject: [PATCH 096/102] rename IntelliLangJava -> IntelliLang --- .idea/modules.xml | 2 +- java/compiler/impl/compiler-impl.iml | 2 -- plugins/IntelliLang/IntelliLang-java.iml | 2 +- plugins/IntelliLang/IntelliLang-javaee.iml | 2 +- plugins/IntelliLang/IntelliLang-xml.iml | 2 +- .../{IntelliLangJava.iml => IntelliLang.iml} | 0 plugins/cvs/cvs-core/cvs-core.iml | 1 - plugins/git4idea/git4idea.iml | 1 - plugins/groovy/jetgroovy.iml | 4 +-- plugins/maven/facade-api/maven-facade-api.iml | 2 -- .../maven/facade-impl/maven-facade-impl.iml | 28 ------------------- plugins/relaxng/relaxng.iml | 7 ----- plugins/svn4idea/svn4idea-tests.iml | 3 -- plugins/svn4idea/svn4idea.iml | 5 ---- 14 files changed, 5 insertions(+), 56 deletions(-) rename plugins/IntelliLang/{IntelliLangJava.iml => IntelliLang.iml} (100%) diff --git a/.idea/modules.xml b/.idea/modules.xml index f5a152e858e6..ea2d70bbde97 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -6,7 +6,7 @@ - + diff --git a/java/compiler/impl/compiler-impl.iml b/java/compiler/impl/compiler-impl.iml index 4f7473c9ff2a..381f3496886b 100644 --- a/java/compiler/impl/compiler-impl.iml +++ b/java/compiler/impl/compiler-impl.iml @@ -23,8 +23,6 @@ - - diff --git a/plugins/IntelliLang/IntelliLang-java.iml b/plugins/IntelliLang/IntelliLang-java.iml index a9a38446a280..998ca93c3ae5 100644 --- a/plugins/IntelliLang/IntelliLang-java.iml +++ b/plugins/IntelliLang/IntelliLang-java.iml @@ -15,7 +15,7 @@ - + diff --git a/plugins/IntelliLang/IntelliLang-javaee.iml b/plugins/IntelliLang/IntelliLang-javaee.iml index bfbccd5a1eac..00e420c8ab6f 100644 --- a/plugins/IntelliLang/IntelliLang-javaee.iml +++ b/plugins/IntelliLang/IntelliLang-javaee.iml @@ -7,7 +7,7 @@ - + diff --git a/plugins/IntelliLang/IntelliLang-xml.iml b/plugins/IntelliLang/IntelliLang-xml.iml index d57e3f2a4b2d..62d3a331f7ee 100644 --- a/plugins/IntelliLang/IntelliLang-xml.iml +++ b/plugins/IntelliLang/IntelliLang-xml.iml @@ -16,7 +16,7 @@ - + diff --git a/plugins/IntelliLang/IntelliLangJava.iml b/plugins/IntelliLang/IntelliLang.iml similarity index 100% rename from plugins/IntelliLang/IntelliLangJava.iml rename to plugins/IntelliLang/IntelliLang.iml diff --git a/plugins/cvs/cvs-core/cvs-core.iml b/plugins/cvs/cvs-core/cvs-core.iml index 53189febbd11..f170b4099106 100644 --- a/plugins/cvs/cvs-core/cvs-core.iml +++ b/plugins/cvs/cvs-core/cvs-core.iml @@ -15,7 +15,6 @@ - diff --git a/plugins/git4idea/git4idea.iml b/plugins/git4idea/git4idea.iml index aa21265058b8..5fa1b17970c1 100644 --- a/plugins/git4idea/git4idea.iml +++ b/plugins/git4idea/git4idea.iml @@ -16,7 +16,6 @@ - diff --git a/plugins/groovy/jetgroovy.iml b/plugins/groovy/jetgroovy.iml index 3b210de157c4..75c0ecccfd80 100644 --- a/plugins/groovy/jetgroovy.iml +++ b/plugins/groovy/jetgroovy.iml @@ -26,13 +26,11 @@ - - - + diff --git a/plugins/maven/facade-api/maven-facade-api.iml b/plugins/maven/facade-api/maven-facade-api.iml index 8ba63b8dc7db..56173f227d95 100644 --- a/plugins/maven/facade-api/maven-facade-api.iml +++ b/plugins/maven/facade-api/maven-facade-api.iml @@ -14,8 +14,6 @@ - - diff --git a/plugins/maven/facade-impl/maven-facade-impl.iml b/plugins/maven/facade-impl/maven-facade-impl.iml index 9240cd8ba91c..ae61f67a346f 100644 --- a/plugins/maven/facade-impl/maven-facade-impl.iml +++ b/plugins/maven/facade-impl/maven-facade-impl.iml @@ -16,8 +16,6 @@ - - @@ -25,8 +23,6 @@ - - @@ -34,8 +30,6 @@ - - @@ -43,8 +37,6 @@ - - @@ -52,8 +44,6 @@ - - @@ -61,8 +51,6 @@ - - @@ -70,8 +58,6 @@ - - @@ -79,8 +65,6 @@ - - @@ -88,8 +72,6 @@ - - @@ -97,8 +79,6 @@ - - @@ -106,8 +86,6 @@ - - @@ -115,8 +93,6 @@ - - @@ -124,8 +100,6 @@ - - @@ -133,8 +107,6 @@ - - diff --git a/plugins/relaxng/relaxng.iml b/plugins/relaxng/relaxng.iml index d7d35d40c904..6ff34b95fc39 100644 --- a/plugins/relaxng/relaxng.iml +++ b/plugins/relaxng/relaxng.iml @@ -18,7 +18,6 @@ - @@ -29,8 +28,6 @@ - - @@ -38,8 +35,6 @@ - - @@ -47,8 +42,6 @@ - - diff --git a/plugins/svn4idea/svn4idea-tests.iml b/plugins/svn4idea/svn4idea-tests.iml index 798757278775..5039b6b4a9f5 100644 --- a/plugins/svn4idea/svn4idea-tests.iml +++ b/plugins/svn4idea/svn4idea-tests.iml @@ -16,7 +16,6 @@ - @@ -30,8 +29,6 @@ - - diff --git a/plugins/svn4idea/svn4idea.iml b/plugins/svn4idea/svn4idea.iml index fd765b400568..e00b72d68d9c 100644 --- a/plugins/svn4idea/svn4idea.iml +++ b/plugins/svn4idea/svn4idea.iml @@ -22,7 +22,6 @@ - @@ -33,8 +32,6 @@ - - @@ -43,8 +40,6 @@ - - From dddad0f9794d54b6556e7e0028d0bb39933eec5c Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Mon, 26 Jul 2010 21:57:41 +0400 Subject: [PATCH 097/102] rename IntelliLangJava->IntelliLang --- .idea/modules.xml | 4 ++-- .idea/runConfigurations/IDEA.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.idea/modules.xml b/.idea/modules.xml index ea2d70bbde97..6c7b87a32dd8 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,15 +3,14 @@ + - - @@ -68,6 +67,7 @@ + diff --git a/.idea/runConfigurations/IDEA.xml b/.idea/runConfigurations/IDEA.xml index 75c3b359ab37..16d0af8f13ff 100644 --- a/.idea/runConfigurations/IDEA.xml +++ b/.idea/runConfigurations/IDEA.xml @@ -1,6 +1,6 @@ - +