diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 6157ab88a59a..a63b81fe9e5e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -247,6 +247,8 @@ public class JavaCompletionContributor extends CompletionContributor { if (reference instanceof PsiJavaReference) { final ElementFilter filter = getReferenceFilter(position); if (filter != null) { + boolean filterVoid = JavaSmartCompletionContributor.getExpectedTypes(parameters).length > 0 && parameters.getInvocationCount() < 2; + final boolean isSwitchLabel = SWITCH_LABEL.accepts(position); final PsiFile originalFile = parameters.getOriginalFile(); for (LookupElement element : JavaCompletionUtil.processJavaReference(position, @@ -268,6 +270,11 @@ public class JavaCompletionContributor extends CompletionContributor { item.setTailType(TailType.NONE); } + Object object = element.getObject(); + if (filterVoid && object instanceof PsiMethod && PsiType.VOID.equals(((PsiMethod)object).getReturnType())) { + continue; + } + result.addElement(element); } } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java index bba38dd08fd2..4bde80b3d036 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java @@ -13,10 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * @author max - */ package com.intellij.psi.impl.compiled; import com.intellij.openapi.vfs.VirtualFile; @@ -26,6 +22,9 @@ import com.intellij.psi.stubs.BinaryFileStubBuilder; import com.intellij.psi.stubs.StubElement; import com.intellij.util.cls.ClsFormatException; +/** + * @author max + */ public class ClassFileStubBuilder implements BinaryFileStubBuilder { public boolean acceptsFile(final VirtualFile file) { return !isInner(file.getNameWithoutExtension(), new ParentDirectory(file)); @@ -37,8 +36,7 @@ public class ClassFileStubBuilder implements BinaryFileStubBuilder { private static boolean isInner(final String name, final int from, final Directory directory) { final int index = name.indexOf('$', from); - return index == -1 ? false - : containsPart(directory, name, index) ? true : isInner(name, index + 1, directory); + return index != -1 && (containsPart(directory, name, index) || isInner(name, index + 1, directory)); } private static boolean containsPart(Directory directory, String name, int endIndex) { @@ -55,7 +53,7 @@ public class ClassFileStubBuilder implements BinaryFileStubBuilder { } public int getStubVersion() { - return JavaFileElementType.STUB_VERSION; + return JavaFileElementType.STUB_VERSION + 1; } @@ -74,7 +72,7 @@ public class ClassFileStubBuilder implements BinaryFileStubBuilder { public boolean contains(final String name) { final String fullName = myExtension == null ? name : name + "." + myExtension; - return myDirectory == null ? false : myDirectory.findChild(fullName) != null; + return myDirectory != null && myDirectory.findChild(fullName) != null; } } } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java index 566b3100cd8d..9cde504521f9 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java @@ -44,7 +44,7 @@ public class ClsAnnotationImpl extends ClsRepositoryPsiElement 0) buffer.append(", "); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java index c4615730b454..43f7a723d24f 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java @@ -319,7 +319,7 @@ public class ClsClassImpl extends ClsRepositoryPsiElement> imple return getStub().isEnum(); } - public void appendMirrorText(final int indentLevel, @NonNls final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, @NonNls final StringBuilder buffer) { ClsDocCommentImpl docComment = (ClsDocCommentImpl)getDocComment(); if (docComment != null) { docComment.appendMirrorText(indentLevel, buffer); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsClassObjectAccessExpressionImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsClassObjectAccessExpressionImpl.java index 2303c840cc9e..9d84f5158b48 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsClassObjectAccessExpressionImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsClassObjectAccessExpressionImpl.java @@ -41,7 +41,7 @@ public class ClsClassObjectAccessExpressionImpl extends ClsElementImpl implement myTypeElement = new ClsTypeElementImpl(this, canonicalClassText, ClsTypeElementImpl.VARIANCE_NONE); } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { myTypeElement.appendMirrorText(0, buffer); buffer.append(CLASS_ENDING); } @@ -81,7 +81,7 @@ public class ClsClassObjectAccessExpressionImpl extends ClsElementImpl implement } public String getText() { - StringBuffer buffer = new StringBuffer(); + final StringBuilder buffer = new StringBuilder(); appendMirrorText(0, buffer); return buffer.toString(); } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsDocCommentImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsDocCommentImpl.java index cc5d98a28476..6a8a5bec9957 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsDocCommentImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsDocCommentImpl.java @@ -36,7 +36,7 @@ class ClsDocCommentImpl extends ClsElementImpl implements PsiDocComment, JavaTok myTags = tags; } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { buffer.append("/**"); for (PsiDocTag tag : getTags()) { goNextLine(indentLevel + 1, buffer); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsDocTagImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsDocTagImpl.java index 06737615c4b1..a625f6a1a38c 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsDocTagImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsDocTagImpl.java @@ -41,7 +41,7 @@ class ClsDocTagImpl extends ClsElementImpl implements PsiDocTag { myNameElement = new NameElement(name); } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { buffer.append(myNameElement.getText()); } @@ -129,7 +129,7 @@ class ClsDocTagImpl extends ClsElementImpl implements PsiDocTag { return PsiElement.EMPTY_ARRAY; } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { } public void setMirror(@NotNull TreeElement element) { diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java index a0f7f94d2036..51a67aa2b740 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java @@ -104,9 +104,9 @@ public abstract class ClsElementImpl extends PsiElementBase implements PsiCompil protected static final String CAN_NOT_MODIFY_MESSAGE = PsiBundle.message("psi.error.attempt.to.edit.class.file"); - public abstract void appendMirrorText(final int indentLevel, final StringBuffer buffer); + public abstract void appendMirrorText(final int indentLevel, final StringBuilder buffer); - protected static void goNextLine(int indentLevel, StringBuffer buffer) { + protected static void goNextLine(int indentLevel, StringBuilder buffer) { buffer.append('\n'); for (int i = 0; i < indentLevel; i++) buffer.append(' '); } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsEnumConstantImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsEnumConstantImpl.java index 5d41a8576d83..3a99b4428e68 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsEnumConstantImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsEnumConstantImpl.java @@ -32,7 +32,7 @@ public class ClsEnumConstantImpl extends ClsFieldImpl implements PsiEnumConstant super(stub); } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { ClsDocCommentImpl docComment = (ClsDocCommentImpl)getDocComment(); if (docComment != null) { docComment.appendMirrorText(indentLevel, buffer); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java index f5bb53a64d0d..77d6efdf9c1d 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java @@ -183,7 +183,7 @@ public class ClsFieldImpl extends ClsRepositoryPsiElement implemen public void normalizeDeclaration() throws IncorrectOperationException { } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { ClsDocCommentImpl docComment = (ClsDocCommentImpl)getDocComment(); if (docComment != null) { docComment.appendMirrorText(indentLevel, buffer); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java index 585984b34444..0e43b5833212 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java @@ -209,7 +209,7 @@ public class ClsFileImpl extends ClsRepositoryPsiElement return false; } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { buffer.append(PsiBundle.message("psi.decompiled.text.header")); goNextLine(indentLevel, buffer); goNextLine(indentLevel, buffer); @@ -358,7 +358,7 @@ public class ClsFileImpl extends ClsRepositoryPsiElement psiFile = new ClsFileImpl((PsiManagerImpl)manager, new ClassFileViewProvider(manager, file), true); } - StringBuffer buffer = new StringBuffer(); + final StringBuilder buffer = new StringBuilder(); psiFile.appendMirrorText(0, buffer); return buffer.toString(); } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsIdentifierImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsIdentifierImpl.java index a58414beaa6b..85369cd80845 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsIdentifierImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsIdentifierImpl.java @@ -50,7 +50,7 @@ class ClsIdentifierImpl extends ClsElementImpl implements PsiIdentifier, PsiJava return myParent; } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer){ + public void appendMirrorText(final int indentLevel, final StringBuilder buffer){ buffer.append(getText()); } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java index 4282ffb82440..7b6bd3d6daf9 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java @@ -234,7 +234,7 @@ public class ClsJavaCodeReferenceElementImpl extends ClsElementImpl implements P return false; } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { buffer.append(getCanonicalText()); } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsLiteralExpressionImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsLiteralExpressionImpl.java index 8b27d2fc8d04..0a80cd27aec8 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsLiteralExpressionImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsLiteralExpressionImpl.java @@ -53,7 +53,7 @@ public class ClsLiteralExpressionImpl extends ClsElementImpl implements PsiLiter return null; } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { buffer.append(getText()); } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java index b93f40fd269b..7969d9163aa7 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java @@ -242,7 +242,7 @@ public class ClsMethodImpl extends ClsRepositoryPsiElement implem return MethodSignatureBackedByPsiMethod.create(this, substitutor); } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { appendMethodHeader(buffer, indentLevel); if (hasModifierProperty(PsiModifier.ABSTRACT) || hasModifierProperty(PsiModifier.NATIVE)) { @@ -255,7 +255,7 @@ public class ClsMethodImpl extends ClsRepositoryPsiElement implem } } - private void appendMethodHeader(@NonNls StringBuffer buffer, final int indentLevel) { + private void appendMethodHeader(@NonNls StringBuilder buffer, final int indentLevel) { ClsDocCommentImpl docComment = (ClsDocCommentImpl)getDocComment(); if (docComment != null) { docComment.appendMirrorText(indentLevel, buffer); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsModifierListImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsModifierListImpl.java index 77939afac236..8f9ec219ef1d 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsModifierListImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsModifierListImpl.java @@ -84,30 +84,33 @@ public class ClsModifierListImpl extends ClsRepositoryPsiElementtreeToPsiNotNull(element).getAnnotations(); PsiAnnotation[] annotations = getAnnotations(); LOG.assertTrue(annotations.length == mirrorAnnotations.length); for (int i = 0; i < annotations.length; i++) { - ((ClsElementImpl)annotations[i]).setMirror((TreeElement)SourceTreeToPsiMap.psiElementToTree(mirrorAnnotations[i])); + ((ClsElementImpl)annotations[i]).setMirror(SourceTreeToPsiMap.psiToTreeNotNull(mirrorAnnotations[i])); } } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsNameValuePairImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsNameValuePairImpl.java index c2f45ed984e0..78f564aba307 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsNameValuePairImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsNameValuePairImpl.java @@ -37,7 +37,7 @@ public class ClsNameValuePairImpl extends ClsElementImpl implements PsiNameValue myMemberValue = ClsParsingUtil.getMemberValue(value, this); } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { if (myNameIdentifier.getText() != null) { myNameIdentifier.appendMirrorText(0, buffer); buffer.append(" = "); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsPackageStatementImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsPackageStatementImpl.java index 6701698cf456..478782e4b2c2 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsPackageStatementImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsPackageStatementImpl.java @@ -68,7 +68,7 @@ class ClsPackageStatementImpl extends ClsElementImpl implements PsiPackageStatem return myPackageName; } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { buffer.append("package "); buffer.append(getPackageName()); buffer.append(";"); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java index 63dbd4fbd8f3..5c8362fee1a4 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java @@ -125,7 +125,7 @@ public class ClsParameterImpl extends ClsRepositoryPsiElement public void normalizeDeclaration() throws IncorrectOperationException { } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer) { + public void appendMirrorText(final int indentLevel, final StringBuilder buffer) { PsiAnnotation[] annotations = getModifierList().getAnnotations(); for (PsiAnnotation annotation : annotations) { ((ClsAnnotationImpl)annotation).appendMirrorText(indentLevel, buffer); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterListImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterListImpl.java index 18a661899237..980b75476b1a 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterListImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterListImpl.java @@ -49,7 +49,7 @@ public class ClsParameterListImpl extends ClsRepositoryPsiElementemptyList()); //todo read annos from .class file } - @Nullable public MethodVisitor visitMethod(final int access, final String name, @@ -372,7 +400,7 @@ public class ClsStubBuilder { PsiMethodStubImpl stub = new PsiMethodStubImpl(myResult, StringRef.fromString(canonicalMethodName), flags, null); - final PsiModifierListStub modlist = new PsiModifierListStubImpl(stub, packMethodFlags(access)); + final PsiModifierListStub modList = new PsiModifierListStubImpl(stub, packMethodFlags(access)); boolean parsedViaGenericSignature = false; String returnType; if (signature == null) { @@ -392,7 +420,7 @@ public class ClsStubBuilder { final boolean isNonStaticInnerClassConstructor = - isConstructor && !(myParent instanceof PsiFileStub) && (myModlist.getModifiersMask() & Opcodes.ACC_STATIC) == 0; + isConstructor && !(myParent instanceof PsiFileStub) && (myModList.getModifiersMask() & Opcodes.ACC_STATIC) == 0; final boolean shouldSkipFirstParamForNonStaticInnerClassConstructor = !parsedViaGenericSignature && isNonStaticInnerClassConstructor; final PsiParameterListStubImpl parameterList = new PsiParameterListStubImpl(stub); @@ -420,7 +448,7 @@ public class ClsStubBuilder { localVarIgnoreCount += 2; } final int paramIgnoreCount = isEnumConstructor? 2 : isNonStaticInnerClassConstructor ? 1 : 0; - return new AnnotationParamCollectingVisitor(stub, modlist, localVarIgnoreCount, paramIgnoreCount, paramCount, paramStubs); + return new AnnotationParamCollectingVisitor(stub, modList, localVarIgnoreCount, paramIgnoreCount, paramCount, paramStubs); } private static String[] buildThrowsList(String[] exceptions, List throwables, boolean parsedViaGenericSignature) { @@ -445,15 +473,6 @@ public class ClsStubBuilder { } } - private static int packMethodFlags(final int access) { - int commonFlags = packModlistFlags(access); - if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) { - commonFlags |= ModifierFlags.SYNCHRONIZED_MASK; - } - - return commonFlags; - } - private static String parseMethodViaDescription(final String desc, final PsiMethodStubImpl stub, final List args) { final String returnType = getTypeText(Type.getReturnType(desc)); final Type[] argTypes = Type.getArgumentTypes(desc); @@ -691,10 +710,10 @@ public class ClsStubBuilder { private static String getTypeText(final Type type) { final String raw = type.getClassName(); - // As the '$' char is a valid java identifier and is actively used by bytecode genarators, the problem is + // As the '$' char is a valid java identifier and is actively used by byte code generators, the problem is // which occurrences of this char should be replaced and which should not. // Heuristic: replace only those $ occurrences that are surrounded non-"$" chars - // (most likely generated by javac to separate inner or anonymoys class name) + // (most likely generated by javac to separate inner or anonymous class name) // Leading and trailing $ chars should be left unchanged. return raw.contains("$")? REGEX_PATTERN.matcher(raw).replaceAll("\\.") : raw; } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java index 82b8ff692fe2..ca14f003cdaf 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java @@ -84,7 +84,7 @@ public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement return decorateTypeText(myTypeText); } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer){ + public void appendMirrorText(final int indentLevel, final StringBuilder buffer){ buffer.append(decorateTypeText(myTypeText)); } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java index e2eb663e4295..494b9d859d36 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java @@ -266,7 +266,7 @@ public class ClsTypeParameterImpl extends ClsRepositoryPsiElement 0) { diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterReferenceImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterReferenceImpl.java index 4133b98a8123..ddf924df1095 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterReferenceImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterReferenceImpl.java @@ -156,7 +156,7 @@ public class ClsTypeParameterReferenceImpl extends ClsElementImpl implements Psi return false; } - public void appendMirrorText(final int indentLevel, final StringBuffer buffer){ + public void appendMirrorText(final int indentLevel, final StringBuilder buffer){ buffer.append(getCanonicalText()); } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParametersListImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParametersListImpl.java index e5d57ba81090..371737a65242 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParametersListImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsTypeParametersListImpl.java @@ -37,7 +37,7 @@ public class ClsTypeParametersListImpl extends ClsRepositoryPsiElement { +public class StringLiteralEscaper extends LiteralTextEscaper { private int[] outSourceOffsets; - public StringLiteralEscaper(PsiLiteralExpressionImpl host) { + public StringLiteralEscaper(T host) { super(host); } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java index 49891e75539e..873ad30ea6af 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java @@ -547,7 +547,7 @@ public class PsiLiteralExpressionImpl @NotNull public LiteralTextEscaper createLiteralTextEscaper() { - return new StringLiteralEscaper(this); + return new StringLiteralEscaper(this); } public void processInjectedPsi(@NotNull InjectedPsiVisitor visitor) { diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/OutputObjectRegistry.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/OutputObjectRegistry.java index 8b7132d6bd37..fba1ee3a5314 100644 --- a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/OutputObjectRegistry.java +++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/OutputObjectRegistry.java @@ -23,8 +23,9 @@ public abstract class OutputObjectRegistry { private int myLastIndex = 0; private PacketProcessor myMainTransport; - public OutputObjectRegistry(PacketProcessor transport) { - myMainTransport = transport; + protected OutputObjectRegistry(PacketProcessor mainTransport, int lastIndex) { + myLastIndex = lastIndex; + myMainTransport = mainTransport; } public String referenceTo(Object test) { @@ -97,4 +98,12 @@ public abstract class OutputObjectRegistry { public void forget(Object test) { myKnownKeys.remove(test); } + + public int getKnownObject(Object description) { + final Object o = myKnownKeys.get(description); + if (o instanceof String) { + return Integer.parseInt((String)o); + } + return 0; + } } diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedOutputStream.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedOutputStream.java index d6596347971a..f504d9d5227e 100644 --- a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedOutputStream.java +++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedOutputStream.java @@ -24,7 +24,12 @@ public class SegmentedOutputStream extends OutputStream implements PacketProcess private boolean myStarted = false; public SegmentedOutputStream(PrintStream transportStream) { + this(transportStream, false); + } + + public SegmentedOutputStream(PrintStream transportStream, boolean started) { myPrintStream = transportStream; + myStarted = started; try { flush(); } @@ -75,4 +80,8 @@ public class SegmentedOutputStream extends OutputStream implements PacketProcess writeNext(SegmentedStream.STARTUP_MESSAGE); myStarted = true; } + + public PrintStream getPrintStream() { + return myPrintStream; + } } diff --git a/java/java-tests/testData/codeInsight/completion/normal/DoubleFalse.java b/java/java-tests/testData/codeInsight/completion/normal/DoubleFalse.java index a1a631e5f032..eeae2718b36c 100644 --- a/java/java-tests/testData/codeInsight/completion/normal/DoubleFalse.java +++ b/java/java-tests/testData/codeInsight/completion/normal/DoubleFalse.java @@ -8,4 +8,6 @@ public class Foo { }); } + boolean fefefef() {} + } diff --git a/java/java-tests/testData/codeInsight/completion/normal/VoidMethodsInNonVoidContext.java b/java/java-tests/testData/codeInsight/completion/normal/VoidMethodsInNonVoidContext.java new file mode 100644 index 000000000000..b0564b6e4878 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/VoidMethodsInNonVoidContext.java @@ -0,0 +1,5 @@ +public class Foo { + Object foo(){ + return noti + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/VoidMethodsInNonVoidContext_after.java b/java/java-tests/testData/codeInsight/completion/normal/VoidMethodsInNonVoidContext_after.java new file mode 100644 index 000000000000..6e1389582825 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/VoidMethodsInNonVoidContext_after.java @@ -0,0 +1,5 @@ +public class Foo { + Object foo(){ + return notify + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/ReturnF.java b/java/java-tests/testData/codeInsight/completion/normalSorting/ReturnF.java index 842b8fd3c3d2..065a361e1098 100644 --- a/java/java-tests/testData/codeInsight/completion/normalSorting/ReturnF.java +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/ReturnF.java @@ -1,5 +1,5 @@ class Foo { boolean zoo(String s) { - return f + return fx } } \ No newline at end of file diff --git a/java/java-tests/testData/psi/cls/stubBuilder/AnnotatedEnumConstructor.txt b/java/java-tests/testData/psi/cls/stubBuilder/AnnotatedEnumConstructor.txt index 28f66661e8a3..d8df903180e9 100644 --- a/java/java-tests/testData/psi/cls/stubBuilder/AnnotatedEnumConstructor.txt +++ b/java/java-tests/testData/psi/cls/stubBuilder/AnnotatedEnumConstructor.txt @@ -23,7 +23,7 @@ PsiJavaFileStub [] PsiModifierListStub[mask=0] PsiRefListStub[THROWS_LIST:] PsiMethodStub[cons varargs AnnotatedEnumConstructor:void] - PsiModifierListStub[mask=130] + PsiModifierListStub[mask=2] PsiTypeParameterListStub PsiParameterListStub PsiParameterStub[names:java.lang.String...] diff --git a/java/java-tests/testData/psi/cls/stubBuilder/Modifiers.txt b/java/java-tests/testData/psi/cls/stubBuilder/Modifiers.txt new file mode 100644 index 000000000000..a608ee7ea7e9 --- /dev/null +++ b/java/java-tests/testData/psi/cls/stubBuilder/Modifiers.txt @@ -0,0 +1,27 @@ +PsiJavaFileStub [pack] + PsiClassStub[name=Modifiers fqn=pack.Modifiers] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiRefListStub[EXTENDS_LIST:] + PsiRefListStub[IMPLEMENTS_LIST:] + PsiFieldStub[f1:int] + PsiModifierListStub[mask=130] + PsiFieldStub[f2:int] + PsiModifierListStub[mask=66] + PsiMethodStub[cons Modifiers:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[varargs m1:void] + PsiModifierListStub[mask=2] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[i:int...] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[m2:void] + PsiModifierListStub[mask=34] + PsiTypeParameterListStub + PsiParameterListStub + PsiRefListStub[THROWS_LIST:] diff --git a/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt b/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt index d294d868a3e9..d58e2e68de90 100644 --- a/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt +++ b/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt @@ -2289,7 +2289,7 @@ PsiJavaFileStub [java.util] PsiModifierListStub[mask=0] PsiRefListStub[THROWS_LIST:] PsiMethodStub[varargs addAll:boolean] - PsiModifierListStub[mask=137] + PsiModifierListStub[mask=9] PsiTypeParameterListStub PsiTypeParameter[T] PsiRefListStub[EXTENDS_BOUNDS_LIST:] diff --git a/java/java-tests/testData/psi/repositoryUse/cls/pack/Modifiers.class b/java/java-tests/testData/psi/repositoryUse/cls/pack/Modifiers.class new file mode 100644 index 000000000000..0ea879469d28 Binary files /dev/null and b/java/java-tests/testData/psi/repositoryUse/cls/pack/Modifiers.class differ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java index 01d60d2af9c2..69de8cb40eaa 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java @@ -46,7 +46,7 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { } public void testReturnF() throws Throwable { - checkPreferredItems(0, "false", "finalize"); + checkPreferredItems(0, "false"); } public void testPreferDefaultTypeToExpected() throws Throwable { @@ -84,7 +84,10 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { } public void testClassStaticMembersInBooleanContext() throws Throwable { - checkPreferredItems(0, "booleanMethod", "voidMethod", "BOOLEAN", "AN_OBJECT", "class"); + final String path = getTestName(false) + ".java"; + myFixture.configureByFile(path); + myFixture.complete(CompletionType.BASIC, 2); + assertPreferredItems(0, "booleanMethod", "voidMethod", "registerNatives", "BOOLEAN", "AN_OBJECT"); } public void testDispreferDeclared() throws Throwable { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index ce92618fb7dc..17ada288cc3e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -5,6 +5,7 @@ import com.intellij.JavaTestUtil import com.intellij.codeInsight.CodeInsightSettings import com.intellij.codeInsight.lookup.Lookup import com.intellij.codeInsight.lookup.LookupElement +import com.intellij.codeInsight.lookup.LookupElementPresentation import com.intellij.codeInsight.lookup.LookupManager import com.intellij.openapi.command.WriteCommandAction import com.intellij.openapi.fileTypes.StdFileTypes @@ -14,7 +15,6 @@ import com.intellij.psi.PsiFile import com.intellij.psi.PsiMethod import com.intellij.psi.codeStyle.CodeStyleSettings import com.intellij.psi.codeStyle.CodeStyleSettingsManager -import com.intellij.codeInsight.lookup.LookupElementPresentation public class NormalCompletionTest extends LightFixtureCompletionTestCase { @Override @@ -677,7 +677,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { public void testDoubleFalse() throws Throwable { configureByFile(getTestName(false) + ".java"); - assertStringItems("false", "finalize"); + assertStringItems("false", "fefefef"); } public void testSameNamedVariableInNestedClasses() throws Throwable { @@ -822,6 +822,16 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { public void testMethodParameterAnnotationClass() throws Throwable { doTest(); } + public void testVoidMethodsInNonVoidContext() throws Throwable { + configure() + checkResultByFile(getTestName(false) + ".java") + assertEmpty(myItems) + assertNull(getLookup()); + + myFixture.complete(CompletionType.BASIC, 2) + checkResult() + } + public void testEnumConstantFromEnumMember() throws Throwable { doTest(); } public void testPrimitiveMethodParameter() throws Throwable { doTest(); } @@ -892,9 +902,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { } public void testClassNameInsideIdentifierInIf() throws Throwable { - configure() - type '\n' - checkResult() + doTest '\n' } public void testSuggestMembersOfStaticallyImportedClasses() throws Exception { diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java index 142fee97dbae..2ecad41d87f7 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java @@ -61,15 +61,23 @@ public class ClsBuilderTest extends LightIdeaTestCase { doTestFromTestData(); } + public void testModifiers() throws Exception { + final String clsFilePath = JavaTestUtil.getJavaTestDataPath() + "/psi/repositoryUse/cls/pack/" + getTestName(false) + ".class"; + final VirtualFile clsFile = LocalFileSystem.getInstance().findFileByPath(clsFilePath); + assert clsFile != null : clsFilePath; + doTest(clsFile, getTestName(false) + ".txt"); + } + private void doTestFromTestData() throws ClsFormatException, IOException { final String clsFilePath = JavaTestUtil.getJavaTestDataPath() + "/psi/cls/stubBuilder/" + getTestName(false) + ".class"; - VirtualFile clsFile = LocalFileSystem.getInstance().findFileByPath(clsFilePath); + final VirtualFile clsFile = LocalFileSystem.getInstance().findFileByPath(clsFilePath); + assert clsFile != null : clsFilePath; doTest(clsFile, getTestName(false) + ".txt"); } private void doTest(final String className) throws IOException, ClsFormatException { - VirtualFile vFile = findFile(className); - doTest(vFile, getTestName(false)+".txt"); + final VirtualFile clsFile = findFile(className); + doTest(clsFile, getTestName(false) + ".txt"); } private static void doTest(VirtualFile vFile, String goldFile) throws ClsFormatException, IOException { diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java index 2eba4f944073..73e361f29f84 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java @@ -752,4 +752,20 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertTrue(substitution instanceof PsiWildcardType); assertEquals(PsiWildcardType.createUnbounded(myPsiManager), substitution); } + + public void testModifiers() throws Exception { + final PsiClass psiClass = myJavaFacade.findClass("pack.Modifiers", RESOLVE_SCOPE); + assertNotNull(psiClass); + assertEquals("public class Modifiers {\n" + + " private transient int f1;\n" + + " private volatile int f2;\n" + + " \n" + + " public Modifiers() { /* compiled code */ }\n" + + " \n" + + " private void m1(int... i) { /* compiled code */ }\n" + + " \n" + + " private synchronized void m2() { /* compiled code */ }\n" + + "}", + psiClass.getText().trim()); + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 636cea0537b0..6ba8cbf046b8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -569,9 +569,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } public void addWatchedPrefix(int startOffset, ElementPattern restartCondition) { - if (isAutopopupCompletion()) { - myRestartingPrefixConditions.add(Pair.create(startOffset, restartCondition)); - } + myRestartingPrefixConditions.add(Pair.create(startOffset, restartCondition)); } public void prefixUpdated() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java index 340edb756560..c0c44849337e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java @@ -27,6 +27,7 @@ import com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper; import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings; import com.intellij.codeInspection.ex.QuickFixWrapper; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.*; @@ -47,6 +48,8 @@ import java.util.*; * @author cdr */ class IntentionListStep implements ListPopupStep, SpeedSearchFilter { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.impl.IntentionListStep"); + private final Set myCachedIntentions = new THashSet(ACTION_TEXT_AND_CLASS_EQUALS); private final Set myCachedErrorFixes = new THashSet(ACTION_TEXT_AND_CLASS_EQUALS); private final Set myCachedInspectionFixes = new THashSet(ACTION_TEXT_AND_CLASS_EQUALS); @@ -311,7 +314,11 @@ class IntentionListStep implements ListPopupStep @NotNull public String getTextFor(final IntentionActionWithTextCaching action) { - return action.getAction().getText(); + final String text = action.getAction().getText(); + if (text.startsWith("")) { + LOG.info("IntentionAction.getText() returned HTML: action=" + action + " text=" + text); + } + return text; } public Icon getIconFor(final IntentionActionWithTextCaching value) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java index 3b013cddab42..a5dab4e0dbdc 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java @@ -15,98 +15,100 @@ */ package com.intellij.codeInsight.lookup.impl; -import com.intellij.openapi.Disposable; -import com.intellij.openapi.util.Disposer; -import com.intellij.util.ui.Animator; +import com.google.common.collect.ImmutableMap; +import com.intellij.util.ui.GridBag; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.font.TextAttribute; import java.util.ArrayList; import java.util.List; +import java.util.Random; import java.util.concurrent.CopyOnWriteArrayList; /** * @author peter */ -public class Advertiser implements Disposable { - private static final int ourScrollingResolution = 15; +public class Advertiser { private final List myTexts = new CopyOnWriteArrayList(); - private final JPanel myComponent = new JPanel() { - + private final JPanel myComponent = new JPanel(new GridBagLayout()) { @Override public Dimension getPreferredSize() { List texts = getTexts(); - if (texts.isEmpty()) return new Dimension(0, 0); - - FontMetrics fm = getFontMetrics(adFont()); - int w = 0; - for (String text : texts) { - w = Math.max(w, fm.stringWidth(text)); + if (texts.isEmpty()) { + return new Dimension(-1, 0); } - Insets insets = getBorder().getBorderInsets(this); - return new Dimension(w + insets.left + insets.right, fm.getHeight() + insets.top + insets.bottom); - } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - - int currentItem = myCurrentItem; - List texts = getTexts(); - if (texts.isEmpty() || currentItem >= texts.size()) return; - - Font font = adFont(); - FontMetrics metrics = g.getFontMetrics(font); - g.setFont(font); - - int height = getHeight(); - int y = (height - metrics.getHeight()) / 2 + metrics.getAscent() - (myScrollingOffset * height / ourScrollingResolution); - int x = getBorder().getBorderInsets(this).left; - - if (currentItem >= 0) { - g.drawString(texts.get(currentItem), x, y); - } - if (myScrollingOffset != 0) { - g.drawString(texts.get((currentItem + 1) % texts.size()), x, y + height); + int maxSize = 0; + for (String label : texts) { + maxSize = Math.max(maxSize, createLabel(label).getPreferredSize().width); } + + Dimension sup = super.getPreferredSize(); + return new Dimension(maxSize + sup.width - myTextPanel.getPreferredSize().width, sup.height); } }; - private int myCurrentItem = 0; - private int myScrollingOffset = 0; + private volatile int myCurrentItem = 0; + private JPanel myTextPanel; + private JLabel myNextLabel; - public Advertiser(Disposable parentDisposable) { - Disposer.register(parentDisposable, this); - int interCycleGap = 4000; - Animator animator = new Animator("completion ad", ourScrollingResolution, 800, true, interCycleGap, -1) { + public Advertiser() { + myTextPanel = new JPanel(new BorderLayout()); + + myNextLabel = new JLabel(">>"); + myNextLabel.setFont(adFont().deriveFont(ImmutableMap.builder().put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON).build())); + myNextLabel.setForeground(Color.blue); + myNextLabel.addMouseListener(new MouseAdapter() { @Override - public void paintNow(float frame, float totalFrames, float cycle) { - int adCount = getTexts().size(); - if (adCount <= 1) { - myCurrentItem = myScrollingOffset = 0; - myComponent.repaint(); - return; - } - - myScrollingOffset = ((int)frame + 1) % ourScrollingResolution; - if (myScrollingOffset == 0) { - myCurrentItem = (myCurrentItem + 1) % adCount; - } - myComponent.paintImmediately(0, 0, myComponent.getWidth(), myComponent.getHeight()); + public void mouseClicked(MouseEvent e) { + myCurrentItem++; + updateAdvertisements(); } - }; - animator.resume(); - Disposer.register(this, animator); + }); + myNextLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + + GridBag gb = new GridBag(); + myComponent.add(myTextPanel, gb.next()); + myComponent.add(myNextLabel, gb.next()); + myComponent.add(new JPanel(), gb.next().fillCellHorizontally().weightx(1)); + } + + private void updateAdvertisements() { + List texts = getTexts(); + myNextLabel.setVisible(texts.size() > 1); + myTextPanel.removeAll(); + if (!texts.isEmpty()) { + String text = texts.get(myCurrentItem % texts.size()); + myTextPanel.add(createLabel(text)); + } + myComponent.revalidate(); + myComponent.repaint(); + } + + private static JLabel createLabel(String text) { + JLabel label = new JLabel(text + " "); + label.setFont(adFont()); + return label; } private synchronized List getTexts() { return new ArrayList(myTexts); } + public void showRandomText() { + int count = myTexts.size(); + myCurrentItem = count > 0 ? new Random().nextInt(count) : 0; + updateAdvertisements(); + } + public synchronized void clearAdvertisements() { myTexts.clear(); + myCurrentItem = 0; + updateAdvertisements(); } private static Font adFont() { @@ -116,18 +118,16 @@ public class Advertiser implements Disposable { public synchronized void addAdvertisement(@NotNull String text) { myTexts.add(text); - if (myTexts.size() == 2) { - if (!myComponent.isShowing()) { - myCurrentItem = -1; + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + updateAdvertisements(); } - } + }); } public JComponent getAdComponent() { return myComponent; } - @Override - public void dispose() { - } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java index b0d7626287ed..e8dcbf017672 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java @@ -338,6 +338,11 @@ public class LookupCellRenderer implements ListCellRenderer { setFocusBorderAroundIcon(true); setBorderInsets(new Insets(0, 0, 0, 0)); } + + @Override + protected void applyAdditionalHints(Graphics g) { + UISettings.setupAntialiasing(g); + } } private class LookupPanel extends JPanel { @@ -346,7 +351,6 @@ public class LookupCellRenderer implements ListCellRenderer { } public void paint(Graphics g){ - UISettings.setupAntialiasing(g); if (!myLookup.isFocused() && myLookup.isCompletion()) { ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f)); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 23113716c227..a2775f74286b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -159,7 +159,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { getComponent().add(myScrollPane, BorderLayout.NORTH); myScrollPane.setBorder(null); - myAdComponent = new Advertiser(this); + myAdComponent = new Advertiser(); JComponent adComponent = myAdComponent.getAdComponent(); adComponent.setBorder(new EmptyBorder(0, 1, 1, 2 + relevanceSortIcon.getIconWidth())); getComponent().add(adComponent, BorderLayout.SOUTH); @@ -581,7 +581,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { public Point calculatePosition(final JComponent component) { Dimension dim = component.getPreferredSize(); int lookupStart = getLookupStart(); - if (lookupStart < 0 || lookupStart >= myEditor.getDocument().getTextLength()) { + if (lookupStart < 0 || lookupStart > myEditor.getDocument().getTextLength()) { LOG.error(lookupStart + "; offset=" + myEditor.getCaretModel().getOffset() + "; element=" + getPsiElement()); } @@ -706,12 +706,16 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { if (ApplicationManager.getApplication().isUnitTestMode()) return; + myAdComponent.showRandomText(); + getComponent().setBorder(null); updateScrollbarVisibility(); Point p = calculatePosition(getComponent()); HintManagerImpl.getInstanceImpl().showEditorHint(this, myEditor, p, HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false, HintManagerImpl.createHintHint(myEditor, p, this, HintManager.UNDER).setAwtTooltip(false)); + LOG.assertTrue(isVisible(), "!visible, disposed=" + myDisposed); + LOG.assertTrue(myList.isShowing(), "!showing, disposed=" + myDisposed); final JLayeredPane layeredPane = getComponent().getRootPane().getLayeredPane(); layeredPane.add(myIconPanel, 42, 0); diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameToIgnoredDirectoryFileInputValidator.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameToIgnoredDirectoryFileInputValidator.java index 88bc7d1fbcf5..64b81363708b 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameToIgnoredDirectoryFileInputValidator.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameToIgnoredDirectoryFileInputValidator.java @@ -46,6 +46,6 @@ public class RenameToIgnoredDirectoryFileInputValidator implements RenameInputVa @Override public boolean isInputValid(String newName, PsiElement element, ProcessingContext context) { - return newName != null && newName.length() > 0; + return newName != null && newName.length() > 0 && newName.indexOf('\\') < 0 && newName.indexOf('/') < 0; } } diff --git a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java index 8070ec8d2236..2976bb2cf59a 100644 --- a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java +++ b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java @@ -405,8 +405,8 @@ public class SimpleColoredComponent extends JComponent implements Accessible { final List searchMatches = new ArrayList(); // Paint text - applyAdditionalHints(g); UIUtil.applyRenderingHints(g); + applyAdditionalHints(g); for (int i = 0; i < myFragments.size(); i++) { final SimpleTextAttributes attributes = myAttributes.get(i); Font font = g.getFont(); diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java index 02ba4200c9a1..8626acdb780c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.keymap.impl; +import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; @@ -187,6 +188,7 @@ public final class IdeMouseEventDispatcher { } private static boolean doHorizontalScrolling(Component c, MouseWheelEvent me) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("ui.horizontal.scrolling"); final JScrollBar scrollBar = findHorizontalScrollBar(c); if (scrollBar != null) { scrollBar.setValue(scrollBar.getValue() + getScrollAmount(c, me, scrollBar)); diff --git a/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties b/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties index cb008d728f92..36f379cc0036 100644 --- a/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties +++ b/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties @@ -77,6 +77,7 @@ refactoring.rename=Rename refactoring.copyClass=Copy Class refactoring ui.tree.speedsearch=Speed search in trees ui.scheme.quickswitch=Quick switch scheme +ui.horizontal.scrolling=Horizontal Scrolling # suppress inspection "UnusedProperty" ui.recentchanges=Recent changes diff --git a/platform/platform-resources-en/src/tips/HorizontalScrolling.html b/platform/platform-resources-en/src/tips/HorizontalScrolling.html new file mode 100644 index 000000000000..44e1340f7e42 --- /dev/null +++ b/platform/platform-resources-en/src/tips/HorizontalScrolling.html @@ -0,0 +1,9 @@ + + + + + + +
Enable Horizontal Scrolling with mouse wheel by holding SHIFT button
+ + \ No newline at end of file diff --git a/platform/util/src/com/intellij/openapi/util/FieldCache.java b/platform/util/src/com/intellij/openapi/util/FieldCache.java index 23e70510eadc..886efe5f1fe7 100644 --- a/platform/util/src/com/intellij/openapi/util/FieldCache.java +++ b/platform/util/src/com/intellij/openapi/util/FieldCache.java @@ -21,6 +21,7 @@ import com.intellij.util.concurrency.JBReentrantReadWriteLock; import com.intellij.util.concurrency.LockFactory; public abstract class FieldCache { + private static final RecursionGuard ourGuard = RecursionManager.createGuard("fieldCache"); private final JBLock r; private final JBLock w; @@ -46,8 +47,11 @@ public abstract class FieldCache { try { result = getValue(owner, a); if (result == null) { + RecursionGuard.StackStamp stamp = ourGuard.markStack(); result = compute(owner, p); - putValue(result, owner, a); + if (stamp.mayCacheNow()) { + putValue(result, owner, a); + } } } finally { diff --git a/platform/platform-api/src/com/intellij/openapi/util/RecursionGuard.java b/platform/util/src/com/intellij/openapi/util/RecursionGuard.java similarity index 100% rename from platform/platform-api/src/com/intellij/openapi/util/RecursionGuard.java rename to platform/util/src/com/intellij/openapi/util/RecursionGuard.java diff --git a/platform/platform-api/src/com/intellij/openapi/util/RecursionManager.java b/platform/util/src/com/intellij/openapi/util/RecursionManager.java similarity index 100% rename from platform/platform-api/src/com/intellij/openapi/util/RecursionManager.java rename to platform/util/src/com/intellij/openapi/util/RecursionManager.java diff --git a/platform/util/src/com/intellij/openapi/util/UserDataCache.java b/platform/util/src/com/intellij/openapi/util/UserDataCache.java index c4da2c94525f..410cde1fa5f2 100644 --- a/platform/util/src/com/intellij/openapi/util/UserDataCache.java +++ b/platform/util/src/com/intellij/openapi/util/UserDataCache.java @@ -19,6 +19,7 @@ package com.intellij.openapi.util; import org.jetbrains.annotations.NonNls; public abstract class UserDataCache extends FieldCache, Param> { + private static final RecursionGuard ourGuard = RecursionManager.createGuard("userDataCache"); private final Key myKey; protected UserDataCache() { @@ -49,8 +50,11 @@ public abstract class UserDataCache exte public T get(Key a, Owner owner, Param p) { T value = owner.getUserData(a); if (value == null) { + RecursionGuard.StackStamp stamp = ourGuard.markStack(); value = compute(owner, p); - value = ((UserDataHolderEx)owner).putUserDataIfAbsent(a, value); + if (stamp.mayCacheNow()) { + value = ((UserDataHolderEx)owner).putUserDataIfAbsent(a, value); + } } return value; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java index 335b77697a24..a6fc5cf3da55 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java @@ -45,6 +45,7 @@ import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.XSourcePositionImpl; import com.intellij.xdebugger.impl.actions.ViewBreakpointsAction; import com.intellij.xdebugger.ui.DebuggerColors; +import com.intellij.xdebugger.ui.DebuggerIcons; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -124,6 +125,8 @@ public class XLineBreakpointImpl

extends XBreak @NotNull private Icon calculateIcon() { if (!isEnabled()) { + // disabled icon takes precedence to other to visually distinguish it and provide feedback then it is enabled/disabled + // (e.g. in case of mute-mode we would like to differentiate muted but enabled breakpoints from simply disabled ones) return myType.getDisabledIcon(); } @@ -135,7 +138,7 @@ public class XLineBreakpointImpl

extends XBreak } else { if (session.areBreakpointsMuted()) { - return myType.getDisabledIcon(); + return DebuggerIcons.MUTED_BREAKPOINT_ICON; } if (session.isDisabledSlaveBreakpoint(this)) { return myType.getDisabledDependentIcon(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index 28ab8a5d3e9f..2ce27636e6d4 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1871,3 +1871,7 @@ try.finally.can.be.try.with.resources.problem.descriptor=#ref can u try.finally.can.be.try.with.resources.quickfix=Replace with 'try' with resources array.comparison.display.name=Array comparison using '==', instead of 'Arrays.equals()' array.comparison.problem.descriptor=Array objects are compared using #ref, not 'Arrays.equals()' #loc +array.hash.code.display.name='hashCode()' called on array +array.hash.code.problem.descriptor=#ref() called on array should probably be 'Arrays.hashCode()' #loc +arrays.deep.hash.code.quickfix=Replace with 'Arrays.deepHashCode()' +arrays.hash.code.quickfix=Replace with 'Arrays.hashCode()' diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java index 53afc9934869..0deceeba6822 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java @@ -518,6 +518,7 @@ public class InspectionGadgetsPlugin implements ApplicationComponent, m_inspectionClasses.add(ArchaicSystemPropertyAccessInspection.class); m_inspectionClasses.add(ArrayEqualityInspection.class); m_inspectionClasses.add(ArrayEqualsInspection.class); + m_inspectionClasses.add(ArrayHashCodeInspection.class); m_inspectionClasses.add(AssertWithSideEffectsInspection.class); m_inspectionClasses.add(ConstantAssertConditionInspection.class); m_inspectionClasses.add(CastConflictsWithInstanceofInspection.class); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayEqualsInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayEqualsInspection.java index fad4e57a6d69..0ff6781ea541 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayEqualsInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayEqualsInspection.java @@ -19,6 +19,7 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; +import com.siyeh.HardcodedMethodConstants; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -120,14 +121,15 @@ public class ArrayEqualsInspection extends BaseInspection { @Override public void visitMethodCallExpression( @NotNull PsiMethodCallExpression expression){ super.visitMethodCallExpression(expression); - if(!MethodCallUtils.isEqualsCall(expression)){ - return; - } final PsiReferenceExpression methodExpression = expression.getMethodExpression(); + final String methodName = methodExpression.getReferenceName(); + if (!HardcodedMethodConstants.EQUALS.equals(methodName)) { + return; + } final PsiExpressionList argumentList = expression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); - if (arguments.length == 0) { + if (arguments.length != 1) { return; } final PsiExpression argument = arguments[0]; @@ -150,4 +152,4 @@ public class ArrayEqualsInspection extends BaseInspection { registerMethodCallError(expression, qualifierType); } } -} \ No newline at end of file +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayHashCodeInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayHashCodeInspection.java new file mode 100644 index 000000000000..5f763730198b --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayHashCodeInspection.java @@ -0,0 +1,145 @@ +/* + * Copyright 2011 Bas Leijdekkers + * + * 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.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import com.siyeh.HardcodedMethodConstants; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.InspectionGadgetsFix; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class ArrayHashCodeInspection extends BaseInspection { + + @Nls + @NotNull + @Override + public String getDisplayName() { + return InspectionGadgetsBundle.message("array.hash.code.display.name"); + } + + @NotNull + @Override + protected String buildErrorString(Object... infos) { + return InspectionGadgetsBundle.message( + "array.hash.code.problem.descriptor"); + } + + @Override + public boolean isEnabledByDefault() { + return true; + } + + @Override + protected InspectionGadgetsFix buildFix(Object... infos) { + final PsiArrayType type = (PsiArrayType) infos[0]; + if (type.getComponentType() instanceof PsiArrayType) { + return new ArrayHashCodeFix(true); + } + return new ArrayHashCodeFix(false); + } + + private static class ArrayHashCodeFix extends InspectionGadgetsFix { + + private final boolean deepHashCode; + + public ArrayHashCodeFix(boolean deepHashCode) { + this.deepHashCode = deepHashCode; + } + + @NotNull + public String getName() { + if (deepHashCode) { + return InspectionGadgetsBundle.message( + "arrays.deep.hash.code.quickfix"); + } else { + return InspectionGadgetsBundle.message( + "arrays.hash.code.quickfix"); + } + } + + @Override + protected void doFix(Project project, ProblemDescriptor descriptor) + throws IncorrectOperationException { + final PsiElement element = descriptor.getPsiElement(); + final PsiElement parent = element.getParent(); + final PsiElement grandParent = parent.getParent(); + if (!(grandParent instanceof PsiMethodCallExpression)) { + return; + } + final PsiMethodCallExpression methodCallExpression = + (PsiMethodCallExpression) grandParent; + final PsiReferenceExpression methodExpression = + methodCallExpression.getMethodExpression(); + final PsiExpression qualifier = + methodExpression.getQualifierExpression(); + if (qualifier == null) { + return; + } + @NonNls final StringBuilder newExpressionText = new StringBuilder(); + if (deepHashCode) { + newExpressionText.append("java.util.Arrays.deepHashCode("); + } else { + newExpressionText.append("java.util.Arrays.hashCode("); + } + newExpressionText.append(qualifier.getText()); + newExpressionText.append(')'); + replaceExpressionAndShorten(methodCallExpression, + newExpressionText.toString()); + } + } + + @Override + public BaseInspectionVisitor buildVisitor() { + return new ArrayHashCodeVisitor(); + } + + private static class ArrayHashCodeVisitor extends BaseInspectionVisitor { + + @Override + public void visitMethodCallExpression( + PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); + final PsiReferenceExpression methodExpression = + expression.getMethodExpression(); + final String methodName = methodExpression.getReferenceName(); + if (!HardcodedMethodConstants.HASH_CODE.equals(methodName)) { + return; + } + final PsiExpressionList argumentList = expression.getArgumentList(); + final PsiExpression[] arguments = argumentList.getExpressions(); + if (arguments.length != 0) { + return; + } + final PsiExpression qualifier = + methodExpression.getQualifierExpression(); + if (qualifier == null) { + return; + } + final PsiType type = qualifier.getType(); + if (!(type instanceof PsiArrayType)) { + return; + } + registerMethodCallError(expression, type); + } + } +} diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquals.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquals.html index c1f318031b21..92b1fc1a0411 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquals.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquals.html @@ -1,11 +1,12 @@ -This inspection reports .equals() being called -to compare two arrays. Calling .equals() on an array +This inspection reports equals() being called +to compare two arrays. Calling equals() on an array compares identity and is equivalent to using ==. Use -== to see if two references reference the same array and -Arrays.equals() to compare the contents of two arrays. +Arrays.equals() to compare the contents of two arrays +or Arrays.deepEquals() to compare the content of two +multi-dimensional arrays.

Powered by InspectionGadgets - \ No newline at end of file + diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayHashCode.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayHashCode.html new file mode 100644 index 000000000000..49642c20b1bf --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayHashCode.html @@ -0,0 +1,11 @@ + + +This inspection reports hashCode() being called +on an array. To get the same hash code for two arrays +with identical contents call Arrays.hashCode(). +Use Arrays.deepHashCode() to calculate the hash +code of a multi-dimensional array. +

+New in 10.5, Powered by InspectionGadgets + + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralEscaper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralEscaper.java index 4e371961f868..64f0ae72624c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralEscaper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/literals/GrLiteralEscaper.java @@ -16,32 +16,14 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals; -import com.intellij.psi.LiteralTextEscaper; -import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.ProperTextRange; -import org.jetbrains.annotations.NotNull; +import com.intellij.psi.impl.source.tree.injected.StringLiteralEscaper; -public class GrLiteralEscaper extends LiteralTextEscaper { - private int[] outSourceOffsets; +public class GrLiteralEscaper extends StringLiteralEscaper { public GrLiteralEscaper(final GrLiteralImpl literal) { super(literal); } - public boolean decode(@NotNull final TextRange rangeInsideHost, @NotNull StringBuilder outChars) { - ProperTextRange.assertProperRange(rangeInsideHost); - String subText = rangeInsideHost.substring(myHost.getText()); - outSourceOffsets = new int[subText.length() + 1]; - return PsiLiteralExpressionImpl.parseStringCharacters(subText, outChars, outSourceOffsets); - } - - public int getOffsetInHost(int offsetInDecoded, @NotNull final TextRange rangeInsideHost) { - int result = offsetInDecoded < outSourceOffsets.length ? outSourceOffsets[offsetInDecoded] : -1; - if (result == -1) return -1; - return (result <= rangeInsideHost.getLength() ? result : rangeInsideHost.getLength()) + rangeInsideHost.getStartOffset(); - } - public boolean isOneLine() { final Object value = myHost.getValue(); return value instanceof String && ((String)value).indexOf('\n') < 0; diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java index dd3c56934bc0..18b55e10dcc8 100644 --- a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java +++ b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java @@ -322,6 +322,14 @@ public class JUnitConfiguration extends ModuleBasedConfiguration myPattern = new LinkedHashSet(); //iws/ipr compatibility @@ -349,7 +358,8 @@ public class JUnitConfiguration extends ModuleBasedConfiguration

- + @@ -69,7 +69,7 @@ - + @@ -84,15 +84,6 @@ - - - - - - - - - @@ -181,6 +172,15 @@ + + + + + + + + + @@ -193,7 +193,7 @@ - + @@ -223,6 +223,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 b104ec33aa12..6689822ff7a1 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java +++ b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java @@ -45,6 +45,7 @@ import com.intellij.psi.PsiPackage; import com.intellij.psi.search.SearchScope; import com.intellij.util.Icons; import gnu.trove.TIntArrayList; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -92,6 +93,11 @@ public class JUnitConfigurable extends SettingsEditor { private final BrowseModuleValueActionListener[] myBrowsers; private AlternativeJREPanel myAlternativeJREPanel; + private JComboBox myForkCb; + @NonNls private static final String NONE = "none"; + @NonNls private static final String METHOD = "method"; + private static final String[] FORK_MODE_ALL = {NONE, METHOD, "class"}; + private static final String[] FORK_MODE = {NONE, METHOD}; public JUnitConfigurable(final Project project) { myModel = new JUnitConfigurationModel(project); @@ -142,8 +148,8 @@ public class JUnitConfigurable extends SettingsEditor { myModel.setType(i); break; } + changePanel(); } - changePanel(); } }); myModel.setType(JUnitConfigurationModel.CLASS); @@ -175,6 +181,7 @@ public class JUnitConfigurable extends SettingsEditor { configuration.setAlternativeJrePathEnabled(myAlternativeJREPanel.isPathEnabled()); myCommonJavaParameters.applyTo(configuration); + configuration.setForkMode((String)myForkCb.getSelectedItem()); } public void resetEditorFrom(final JUnitConfiguration configuration) { @@ -192,7 +199,7 @@ public class JUnitConfigurable extends SettingsEditor { myWholeProjectScope.setSelected(true); } myAlternativeJREPanel.init(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled()); - + myForkCb.setSelectedItem(configuration.getForkMode()); } private void changePanel () { @@ -201,23 +208,34 @@ public class JUnitConfigurable extends SettingsEditor { myPattern.setVisible(false); myClass.setVisible(false); myMethod.setVisible(false); + myForkCb.setEnabled(true); + myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL)); + myForkCb.setSelectedItem(NONE); } else if (myClassButton.isSelected()){ myPackagePanel.setVisible(false); myPattern.setVisible(false); myClass.setVisible(true); myMethod.setVisible(false); + myForkCb.setEnabled(true); + myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE)); + myForkCb.setSelectedItem(NONE); } else if (myTestMethodButton.isSelected()){ myPackagePanel.setVisible(false); myPattern.setVisible(false); myClass.setVisible(true); myMethod.setVisible(true); + myForkCb.setEnabled(false); + myForkCb.setSelectedItem(NONE); } else { myPackagePanel.setVisible(false); myPattern.setVisible(true); myClass.setVisible(false); myMethod.setVisible(false); + myForkCb.setEnabled(true); + myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL)); + myForkCb.setSelectedItem(NONE); } } diff --git a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurationModel.java b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurationModel.java index ed59e4822982..bdda347c55d1 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurationModel.java +++ b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurationModel.java @@ -56,11 +56,12 @@ public class JUnitConfigurationModel { myProject = project; } - public void setType(int type) { - if (type == myType) return; + public boolean setType(int type) { + if (type == myType) return false; if (type < 0 || type >= ourTestObjects.size()) type = CLASS; myType = type; fireTypeChanged(type); + return true; } private void fireTypeChanged(final int newType) { diff --git a/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java b/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java index a9cf05ee5cd9..26562ca417b0 100644 --- a/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java +++ b/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java @@ -15,28 +15,37 @@ */ package com.intellij.junit3; -import com.intellij.rt.execution.junit.DeafStream; -import com.intellij.rt.execution.junit.IdeaTestRunner; -import com.intellij.rt.execution.junit.IDEAJUnitListener; -import com.intellij.rt.execution.junit.segments.PoolOfDelimiters; +import com.intellij.rt.execution.junit.*; +import com.intellij.rt.execution.junit.segments.OutputObjectRegistry; import com.intellij.rt.execution.junit.segments.SegmentedOutputStream; import junit.framework.*; import junit.textui.ResultPrinter; import junit.textui.TestRunner; import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Vector; public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner { private TestListener myTestsListener; private JUnit3OutputObjectRegistry myRegistry; private ArrayList myListeners; + private boolean mySendTree; public JUnit3IdeaTestRunner() { super(DeafStream.DEAF_PRINT_STREAM); } - public int startRunnerWithArgs(String[] args, ArrayList listeners) { + public int startRunnerWithArgs(String[] args, ArrayList listeners, boolean sendTree) { myListeners = listeners; + mySendTree = sendTree; + if (sendTree) { + setPrinter(new TimeSender(myRegistry)); + } + else { + setPrinter(new MockResultPrinter()); + } try { Test suite = TestRunnerUtil.getTestSuite(this, args); if (suite == null) return -1; @@ -60,12 +69,31 @@ public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner { super.runFailed(message); } - public void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr) { - setPrinter(new TimeSender()); - myRegistry = new JUnit3OutputObjectRegistry(segmentedOut); + public void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr, int lastIdx) { + myRegistry = new JUnit3OutputObjectRegistry(segmentedOut, lastIdx); myTestsListener = new TestResultsSender(myRegistry); } + public Object getTestToStart(String[] args) { + return TestRunnerUtil.getTestSuite(this, args); + } + + public List getChildTests(Object description) { + return getTestCasesOf((Test)description); + } + + public OutputObjectRegistry getRegistry() { + return myRegistry; + } + + public String getStartDescription(Object child) { + final Test test = (Test)child; + if (test instanceof TestCase) { + return test.getClass().getName() + "," + ((TestCase)test).getName(); + } + return test.toString(); + } + protected TestResult createTestResult() { TestResult testResult = super.createTestResult(); testResult.addListener(myTestsListener); @@ -97,31 +125,40 @@ public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner { return testResult; } - public TestResult doRun(Test suite, boolean wait) { - try { - TreeSender.sendSuite(myRegistry, suite); - } - catch (Exception e) { - //noinspection HardCodedStringLiteral - System.err.println("Internal Error occured."); - e.printStackTrace(System.err); + public TestResult doRun(Test suite, boolean wait) { //todo + if (mySendTree) { + try { + TreeSender.sendTree(this, suite); + } + catch (Exception e) { + //noinspection HardCodedStringLiteral + System.err.println("Internal Error occured."); + e.printStackTrace(System.err); + } } return super.doRun(suite, wait); } + static Vector getTestCasesOf(Test test) { + Vector testCases = new Vector(); + if (test instanceof TestRunnerUtil.SuiteMethodWrapper) { + test = ((TestRunnerUtil.SuiteMethodWrapper)test).getSuite(); + } + if (test instanceof TestSuite) { + TestSuite testSuite = (TestSuite)test; + + for (Enumeration each = testSuite.tests(); each.hasMoreElements();) { + Object childTest = each.nextElement(); + if (childTest instanceof TestSuite && !((TestSuite)childTest).tests().hasMoreElements()) continue; + testCases.addElement(childTest); + } + } + return testCases; + } + public static class MockResultPrinter extends ResultPrinter { public MockResultPrinter() { super(DeafStream.DEAF_PRINT_STREAM); } } - - private class TimeSender extends ResultPrinter { - public TimeSender() { - super(DeafStream.DEAF_PRINT_STREAM); - } - - protected void printHeader(long runTime) { - myRegistry.createPacket().addString(PoolOfDelimiters.TESTS_DONE).addLong(runTime).send(); - } - } } diff --git a/plugins/junit_rt/src/com/intellij/junit3/JUnit3OutputObjectRegistry.java b/plugins/junit_rt/src/com/intellij/junit3/JUnit3OutputObjectRegistry.java index 87deb5857916..2cf89bd7cc09 100644 --- a/plugins/junit_rt/src/com/intellij/junit3/JUnit3OutputObjectRegistry.java +++ b/plugins/junit_rt/src/com/intellij/junit3/JUnit3OutputObjectRegistry.java @@ -28,8 +28,9 @@ import junit.framework.TestCase; import junit.framework.TestSuite; public class JUnit3OutputObjectRegistry extends OutputObjectRegistry { - public JUnit3OutputObjectRegistry(PacketProcessor mainTransport) { - super(mainTransport); + + public JUnit3OutputObjectRegistry(PacketProcessor mainTransport, int lastIndex) { + super(mainTransport, lastIndex); } protected int getTestCont(Object test) { diff --git a/plugins/junit_rt/src/com/intellij/junit3/TreeSender.java b/plugins/junit_rt/src/com/intellij/junit3/TreeSender.java deleted file mode 100644 index caf4791548c9..000000000000 --- a/plugins/junit_rt/src/com/intellij/junit3/TreeSender.java +++ /dev/null @@ -1,64 +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.junit3; - -import com.intellij.rt.execution.junit.segments.OutputObjectRegistry; -import com.intellij.rt.execution.junit.segments.PoolOfDelimiters; -import com.intellij.rt.execution.junit.segments.Packet; -import junit.framework.Test; -import junit.framework.TestSuite; - -import java.util.*; - -public class TreeSender { - private static void sendNode(Test test, Packet packet, Collection objects) { - Vector testCases = getTestCasesOf(test); - packet.addObject(test, objects).addLong(testCases.size()); - for (int i = 0; i < testCases.size(); i++) { - Test nextTest = (Test)testCases.get(i); - sendNode(nextTest, packet, objects); - } - } - - private static Vector getTestCasesOf(Test test) { - Vector testCases = new Vector(); - if (test instanceof TestRunnerUtil.SuiteMethodWrapper) { - test = ((TestRunnerUtil.SuiteMethodWrapper)test).getSuite(); - } - if (test instanceof TestSuite) { - TestSuite testSuite = (TestSuite)test; - - for (Enumeration each = testSuite.tests(); each.hasMoreElements();) { - Object childTest = each.nextElement(); - if (childTest instanceof TestSuite && !((TestSuite)childTest).tests().hasMoreElements()) continue; - testCases.addElement(childTest); - } - } - return testCases; - } - - public static void sendSuite(OutputObjectRegistry registry, Test suite) { - Packet packet = registry.createPacket(); - packet.addString(PoolOfDelimiters.TREE_PREFIX); - Collection objects = new ArrayList(); - sendNode(suite, packet, objects); - for (Iterator iterator = objects.iterator(); iterator.hasNext();) { - ((Packet)iterator.next()).send(); - } - packet.addString("\n"); - packet.send(); - } -} diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java index 905d43be072d..a9d7be453853 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java @@ -15,14 +15,9 @@ */ package com.intellij.junit4; -import com.intellij.rt.execution.junit.DeafStream; -import com.intellij.rt.execution.junit.IDEAJUnitListener; -import com.intellij.rt.execution.junit.IdeaTestRunner; +import com.intellij.rt.execution.junit.*; import com.intellij.rt.execution.junit.segments.OutputObjectRegistry; -import com.intellij.rt.execution.junit.segments.Packet; -import com.intellij.rt.execution.junit.segments.PoolOfDelimiters; import com.intellij.rt.execution.junit.segments.SegmentedOutputStream; -import junit.textui.ResultPrinter; import org.junit.internal.requests.ClassRequest; import org.junit.internal.requests.FilterRequest; import org.junit.runner.*; @@ -37,49 +32,28 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner { private RunListener myTestsListener; private OutputObjectRegistry myRegistry; - private static void sendNode(Description test, Packet packet, Collection objectPackets) { - final ArrayList children = test.getChildren(); - packet.addObject(test, objectPackets).addLong(children.size()); - for (int i = 0; i < children.size(); i++) { - sendNode((Description)children.get(i), packet, objectPackets); - } - } + public int startRunnerWithArgs(String[] args, ArrayList listeners, boolean sendTree) { - public void sendTree(OutputObjectRegistry registry, Description suite) { - Packet packet = registry.createPacket(); - packet.addString(PoolOfDelimiters.TREE_PREFIX); - Set objects = new HashSet(); - sendNode(suite, packet, objects); - for (Iterator iterator = objects.iterator(); iterator.hasNext();) { - ((Packet)iterator.next()).send(); + final Request request = JUnit4TestRunnerUtil.buildRequest(args); + final Runner testRunner = request.getRunner(); + try { + Description description = testRunner.getDescription(); + if (request instanceof ClassRequest) { + description = getSuiteMethodDescription(request, description); + } + else if (request instanceof FilterRequest) { + description = getFilteredDescription(request, description); + } + if (sendTree) TreeSender.sendTree(this, description); + } + catch (Exception e) { + //noinspection HardCodedStringLiteral + System.err.println("Internal Error occured."); + e.printStackTrace(System.err); } - packet.addString("\n"); - packet.send(); - } - public int startRunnerWithArgs(String[] args, ArrayList listeners) { try { final JUnitCore runner = new JUnitCore(); - - final Request request = JUnit4TestRunnerUtil.buildRequest(args); - - final Runner testRunner = request.getRunner(); - try { - Description description = testRunner.getDescription(); - if (request instanceof ClassRequest) { - description = getSuiteMethodDescription(request, description); - } - else if (request instanceof FilterRequest) { - description = getFilteredDescription(request, description); - } - sendTree(myRegistry, description); - } - catch (Exception e) { - //noinspection HardCodedStringLiteral - System.err.println("Internal Error occured."); - e.printStackTrace(System.err); - } - runner.addListener(myTestsListener); for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { final IDEAJUnitListener junitListener = (IDEAJUnitListener)Class.forName((String)iterator.next()).newInstance(); @@ -101,7 +75,7 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner { })*/); long endTime = System.currentTimeMillis(); long runTime = endTime - startTime; - new TimeSender().printHeader(runTime); + if (sendTree) new TimeSender(myRegistry).printHeader(runTime); if (!result.wasSuccessful()) { return -1; @@ -152,18 +126,43 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner { } - public void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr) { - myRegistry = new JUnit4OutputObjectRegistry(segmentedOut); + public void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr, int lastIdx) { + myRegistry = new JUnit4OutputObjectRegistry(segmentedOut, lastIdx); myTestsListener = new JUnit4TestResultsSender(myRegistry); } - private class TimeSender extends ResultPrinter { - public TimeSender() { - super(DeafStream.DEAF_PRINT_STREAM); + public Object getTestToStart(String[] args) { + final Request request = JUnit4TestRunnerUtil.buildRequest(args); + final Runner testRunner = request.getRunner(); + Description description = null; + try { + description = testRunner.getDescription(); + if (request instanceof ClassRequest) { + description = getSuiteMethodDescription(request, description); + } + else if (request instanceof FilterRequest) { + description = getFilteredDescription(request, description); + } } + catch (Exception e) { + //noinspection HardCodedStringLiteral + System.err.println("Internal Error occured."); + e.printStackTrace(System.err); + } + return description; + } - protected void printHeader(long runTime) { - myRegistry.createPacket().addString(PoolOfDelimiters.TESTS_DONE).addLong(runTime).send(); - } + public List getChildTests(Object description) { + return ((Description)description).getChildren(); + } + + public OutputObjectRegistry getRegistry() { + return myRegistry; + } + + public String getStartDescription(Object child) { + final Description description = (Description)child; + final String methodName = description.getMethodName(); + return methodName != null ? description.getClassName() + "," + methodName : description.getClassName(); } } diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4OutputObjectRegistry.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4OutputObjectRegistry.java index d628da9a062b..2d5366b44130 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4OutputObjectRegistry.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4OutputObjectRegistry.java @@ -27,8 +27,9 @@ import org.junit.runner.Description; public class JUnit4OutputObjectRegistry extends OutputObjectRegistry { - public JUnit4OutputObjectRegistry(PacketProcessor mainTransport) { - super(mainTransport); + + public JUnit4OutputObjectRegistry(PacketProcessor mainTransport, int lastIndex) { + super(mainTransport, lastIndex); } protected int getTestCont(Object test) { diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/ForkedVMWrapper.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/ForkedVMWrapper.java new file mode 100644 index 000000000000..ba88cefb9a4c --- /dev/null +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/ForkedVMWrapper.java @@ -0,0 +1,117 @@ +/* + * Copyright 2000-2011 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.rt.execution.junit; + +import java.io.*; + +/** +* User: anna +* Date: 4/6/11 +*/ +class ForkedVMWrapper extends DataOutputStream { + + private FileOutputStream myOutputStream; + private boolean myError; + + public ForkedVMWrapper(FileOutputStream outputStream, boolean error) throws FileNotFoundException { + super(outputStream); + myOutputStream = outputStream; + myError = error; + } + + public synchronized void write(int b) throws IOException { + printPrefix(); + myOutputStream.write(b); + } + + private void printPrefix() throws IOException { + myOutputStream.write("/K".getBytes()); + if (myError) { + myOutputStream.write("e".getBytes()); + } + else { + myOutputStream.write("o".getBytes()); + } + } + + public void write(byte[] b) throws IOException { + printPrefix(); + myOutputStream.write(b); + } + + public synchronized void write(byte[] b, int off, int len) throws IOException { + printPrefix(); + myOutputStream.write(b, off, len); + } + + public void close() throws IOException { + myOutputStream.close(); + } + + public void flush() throws IOException { + myOutputStream.flush(); + } + + public static void readWrapped(String path, PrintStream out, PrintStream err) throws IOException { + FileInputStream stream = new FileInputStream(path); + try { + boolean error = false; + boolean afterSymbol = false; + boolean afterM = false; + while (stream.available() > 0) { + char read = (char)stream.read(); + if (read == '/') { + afterSymbol = true; + continue; + } + if (afterSymbol) { + if (afterM) { + error = read == 'e'; + afterSymbol = false; + afterM = false; + continue; + } + if (read != 'K') { + if (error) { + err.write("/".getBytes()); + err.write(read); + } + else { + out.write("/".getBytes()); + out.write(read); + } + afterSymbol = false; + afterM = false; + continue; + } + else { + afterM = true; + continue; + } + } + if (error) { + err.write(read); + } + else { + out.write(read); + } + } + } + finally { + if (stream != null) stream.close(); + } + } +} diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/IdeaTestRunner.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/IdeaTestRunner.java index 6dfe03aaecce..66a181a95336 100644 --- a/plugins/junit_rt/src/com/intellij/rt/execution/junit/IdeaTestRunner.java +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/IdeaTestRunner.java @@ -20,12 +20,22 @@ */ package com.intellij.rt.execution.junit; +import com.intellij.rt.execution.junit.segments.OutputObjectRegistry; import com.intellij.rt.execution.junit.segments.SegmentedOutputStream; +import org.junit.runner.Description; +import java.io.IOException; import java.util.ArrayList; +import java.util.List; public interface IdeaTestRunner { - int startRunnerWithArgs(String[] args, ArrayList listeners); - void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr); + int startRunnerWithArgs(String[] args, ArrayList listeners, boolean sendTree); + void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr, int lastIdx); + + Object getTestToStart(String[] args); + List getChildTests(Object description); + String getStartDescription(Object child); + + OutputObjectRegistry getRegistry(); } \ No newline at end of file diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java new file mode 100644 index 000000000000..80808d8a0f52 --- /dev/null +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java @@ -0,0 +1,132 @@ +/* + * Copyright 2000-2011 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.rt.execution.junit; + +import com.intellij.rt.execution.junit.segments.SegmentedOutputStream; + +import java.io.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** +* User: anna +* Date: 4/6/11 +*/ +public class JUnitForkedStarter { + private JUnitForkedStarter() { + } + + public static void main(String[] args) throws Exception { + final String testOutputPath = args[0]; + final int lastIdx = Integer.parseInt(args[1]); + final boolean isJUnit4 = args[2].equalsIgnoreCase("true"); + final String[] childTestDescription = {args[3]}; + final ArrayList listeners = new ArrayList(); + for (int i = 4, argsLength = args.length; i < argsLength; i++) { + listeners.add(args[i]); + } + + final File file = new File(testOutputPath); + if (!file.exists()) { + if (!file.createNewFile()) return; + } + final FileOutputStream stream = new FileOutputStream(testOutputPath); + PrintStream oldOut = System.out; + PrintStream oldErr = System.err; + try { + final PrintStream out = new PrintStream(new ForkedVMWrapper(stream, false)); + final PrintStream err = new PrintStream(new ForkedVMWrapper(stream, true)); + System.setOut(out); + System.setErr(err); + IdeaTestRunner testRunner = (IdeaTestRunner)JUnitStarter.getAgentClass(isJUnit4).newInstance(); + testRunner.setStreams(new SegmentedOutputStream(out, true), new SegmentedOutputStream(err, true), lastIdx); + System.exit(testRunner.startRunnerWithArgs(childTestDescription, listeners, false)); + } finally { + System.setOut(oldOut); + System.setErr(oldErr); + stream.close(); + } + } + + static int startForkedVMs(String[] args, + boolean isJUnit4, + ArrayList listeners, + SegmentedOutputStream out, + SegmentedOutputStream err, String path) throws Exception { + final BufferedReader reader = new BufferedReader(new FileReader(path)); + final String commandline = reader.readLine(); + final String forkMode = reader.readLine(); + reader.close(); + IdeaTestRunner testRunner = (IdeaTestRunner)JUnitStarter.getAgentClass(isJUnit4).newInstance(); + testRunner.setStreams(out, err, 0); + final Object description = testRunner.getTestToStart(args); + + TreeSender.sendTree(testRunner, description); + + long startTime = System.currentTimeMillis(); + + final List children = testRunner.getChildTests(description); + final boolean forkTillMethod = forkMode.equalsIgnoreCase("method"); + int result = processChildren(isJUnit4, listeners, out, err, commandline, testRunner, children, 0, forkTillMethod); + + long endTime = System.currentTimeMillis(); + long runTime = endTime - startTime; + new TimeSender(testRunner.getRegistry()).printHeader(runTime); + return result; + } + + private static int processChildren(boolean isJUnit4, + ArrayList listeners, + SegmentedOutputStream out, + SegmentedOutputStream err, + String commandline, IdeaTestRunner testRunner, List children, int result, boolean forkTillMethod) + throws IOException, InterruptedException { + for (int i = 0, argsLength = children.size(); i < argsLength; i++) { + final Object child = children.get(i); + final List childTests = testRunner.getChildTests(child); + if (childTests.isEmpty() || !forkTillMethod) { + result = Math.min(runChild(child, isJUnit4, listeners, out, err, commandline, testRunner, forkTillMethod), result); + } else { + result = Math.min(processChildren(isJUnit4, listeners, out, err, commandline, testRunner, childTests, result, forkTillMethod), result); + } + } + return result; + } + + private static int runChild(Object child, + boolean isJUnit4, + ArrayList listeners, + SegmentedOutputStream out, + SegmentedOutputStream err, + String commandline, IdeaTestRunner testRunner, + boolean forkTillMethod) + throws IOException, InterruptedException { + final File tempFile = File.createTempFile("fork", "test"); + final String testOutputPath = tempFile.getAbsolutePath(); + final int knownObject = testRunner.getRegistry().getKnownObject(child); + String command = commandline + " " + JUnitForkedStarter.class.getName()+ " " + testOutputPath + " " + (knownObject + (forkTillMethod ? 0 : 1)) + " " + + isJUnit4 + " " + testRunner.getStartDescription(child) ; + for (Iterator iterator = listeners.iterator(); iterator.hasNext(); ) { + command += " " + iterator.next(); + } + final Process exec = Runtime.getRuntime().exec(command); + int result = exec.waitFor(); + ForkedVMWrapper.readWrapped(testOutputPath, out.getPrintStream(), err.getPrintStream()); + // tempFile.deleteOnExit(); + return result; + } +} diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java index debdd06441bb..c3d281dae47a 100644 --- a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java @@ -16,6 +16,7 @@ package com.intellij.rt.execution.junit; import com.intellij.rt.execution.junit.segments.SegmentedOutputStream; + import java.io.*; import java.net.InetAddress; import java.net.Socket; @@ -33,6 +34,7 @@ public class JUnitStarter { public static final String IDE_VERSION = "-ideVersion"; public static final String JUNIT4_PARAMETER = "-junit4"; private static final String SOCKET = "-socket"; + private static String ourCommandLine; public static void main(String[] args) throws IOException { SegmentedOutputStream out = new SegmentedOutputStream(System.out); @@ -74,7 +76,10 @@ public class JUnitStarter { isJunit4 = true; } else { - if (arg.startsWith("@@")) { + if (arg.startsWith("@@@")) { + ourCommandLine = arg.substring(3); + continue; + } else if (arg.startsWith("@@")) { if (new File(arg.substring(2)).exists()) { try { final BufferedReader reader = new BufferedReader(new FileReader(arg.substring(2))); @@ -183,26 +188,27 @@ public class JUnitStarter { SegmentedOutputStream err) { PrintStream oldOut = System.out; PrintStream oldErr = System.err; - int result; try { System.setOut(new PrintStream(out)); System.setErr(new PrintStream(err)); + if (ourCommandLine != null) { + return JUnitForkedStarter.startForkedVMs(args, isJUnit4, listeners, out, err, ourCommandLine); + } IdeaTestRunner testRunner = (IdeaTestRunner)getAgentClass(isJUnit4).newInstance(); - testRunner.setStreams(out, err); - result = testRunner.startRunnerWithArgs(args, listeners); + testRunner.setStreams(out, err, 0); + return testRunner.startRunnerWithArgs(args, listeners, true); } catch (Exception e) { e.printStackTrace(System.err); - result = -2; + return -2; } finally { System.setOut(oldOut); System.setErr(oldErr); } - return result; } - private static Class getAgentClass(boolean isJUnit4) throws ClassNotFoundException { + static Class getAgentClass(boolean isJUnit4) throws ClassNotFoundException { return isJUnit4 ? Class.forName("com.intellij.junit4.JUnit4IdeaTestRunner") : Class.forName("com.intellij.junit3.JUnit3IdeaTestRunner"); diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/TimeSender.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/TimeSender.java new file mode 100644 index 000000000000..9821f439574e --- /dev/null +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/TimeSender.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2011 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.rt.execution.junit; + +import com.intellij.rt.execution.junit.segments.OutputObjectRegistry; +import com.intellij.rt.execution.junit.segments.PoolOfDelimiters; +import junit.textui.ResultPrinter; + +/** +* User: anna +* Date: 4/5/11 +*/ +public class TimeSender extends ResultPrinter { + private final OutputObjectRegistry myRegistry; + + public TimeSender(OutputObjectRegistry registry) { + super(DeafStream.DEAF_PRINT_STREAM); + myRegistry = registry; + } + + public void printHeader(long runTime) { + myRegistry.createPacket().addString(PoolOfDelimiters.TESTS_DONE).addLong(runTime).send(); + } +} diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/TreeSender.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/TreeSender.java new file mode 100644 index 000000000000..df805ee8756b --- /dev/null +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/TreeSender.java @@ -0,0 +1,47 @@ +/* + * 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.rt.execution.junit; + +import com.intellij.rt.execution.junit.segments.Packet; +import com.intellij.rt.execution.junit.segments.PoolOfDelimiters; + +import java.util.*; + +public class TreeSender { + + private TreeSender() { + } + + public static void sendTree(IdeaTestRunner runner, Object suite) { + Packet packet = runner.getRegistry().createPacket(); + packet.addString(PoolOfDelimiters.TREE_PREFIX); + Set objects = new HashSet(); + sendNode(runner, suite, packet, objects); + for (Iterator iterator = objects.iterator(); iterator.hasNext();) { + ((Packet)iterator.next()).send(); + } + packet.addString("\n"); + packet.send(); + } + + private static void sendNode(IdeaTestRunner runner, Object test, Packet packet, Collection objectPackets) { + final List children = runner.getChildTests(test); + packet.addObject(test, objectPackets).addLong(children.size()); + for (int i = 0; i < children.size(); i++) { + sendNode(runner, children.get(i), packet, objectPackets); + } + } +} diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenWorkspaceMap.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenWorkspaceMap.java index 6782305e47ee..68c8770e3c5c 100644 --- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenWorkspaceMap.java +++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenWorkspaceMap.java @@ -29,8 +29,12 @@ public class MavenWorkspaceMap implements Serializable { private final THashMap myMapping = new THashMap(); public void register(@NotNull MavenId id, @NotNull File file) { + register(id, file, null); + } + + public void register(@NotNull MavenId id, @NotNull File file, @Nullable File outputFile) { for (MavenId each : getAllIDs(id)) { - myMapping.put(each, new Data(id, file)); + myMapping.put(each, new Data(id, file, outputFile)); } } @@ -70,11 +74,17 @@ public class MavenWorkspaceMap implements Serializable { public static class Data implements Serializable { public final MavenId originalId; - public final File file; + private final File file; + private final File outputFile; - private Data(MavenId originalId, File file) { + private Data(MavenId originalId, File file, File outputFile) { this.originalId = originalId; this.file = file; + this.outputFile = outputFile; + } + + public File getFile(String type) { + return outputFile == null || MavenConstants.POM_EXTENSION.equalsIgnoreCase(type) ? file : outputFile; } } } diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomArtifactResolver.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomArtifactResolver.java index 0946deb9e08a..75aeeb42f272 100644 --- a/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomArtifactResolver.java +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomArtifactResolver.java @@ -76,9 +76,9 @@ public class CustomArtifactResolver extends DefaultArtifactResolver { if (resolved == null) return false; a.setResolved(true); - a.setFile(resolved.file); + a.setFile(resolved.getFile(a.getType())); a.selectVersion(resolved.originalId.getVersion()); return true; } -} +} \ No newline at end of file diff --git a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3ArtifactResolver.java b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3ArtifactResolver.java index 94d16836cde4..daa9dcbfb3a9 100644 --- a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3ArtifactResolver.java +++ b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3ArtifactResolver.java @@ -78,7 +78,7 @@ public class CustomMaven3ArtifactResolver extends DefaultArtifactResolver { if (resolved == null) return false; a.setResolved(true); - a.setFile(resolved.file); + a.setFile(resolved.getFile(a.getType())); a.selectVersion(resolved.originalId.getVersion()); return true; diff --git a/resources/src/ProductivityFeaturesRegistry.xml b/resources/src/ProductivityFeaturesRegistry.xml index aee5801c3a1c..7662364d87a1 100644 --- a/resources/src/ProductivityFeaturesRegistry.xml +++ b/resources/src/ProductivityFeaturesRegistry.xml @@ -414,6 +414,13 @@ successive-show="5" min-usage-count="1" /> +